# # Copyright 2003 (c) Pointwise, Inc. # All rights reserved. # # This sample Gridgen script is not supported by Pointwise, Inc. # It is provided freely for demonstration purposes only. # SEE THE WARRANTY DISCLAIMER AT THE BOTTOM OF THIS FILE. # gg::aswSet GENERIC -dim 3 set oFraction .25 set oDimension 10 set Preview 1 set Mode "BLOCKS" set Propagage 0 set orig_cons [gg::conGetAll] set Clean 1 set oScaleFac [list 0.5 0.5 0.5] set locatorH_prop {} # The value is 1 when multi-dom butterfly faces are detected. Since project method might # produce duplicated ogrid connectors if slope discontinuity occurs on the butterfly face(s), # Connector merging is necessary in this case. # set slopeDiscont "False" set Structured_Blocks [list] set Structured_Domains [list] set Duplicate_Direction ALL # See details in proc blkMakeBflyBlocks. set createdBflyBlks {} gg::tkLoad catch { set scriptDir [file dirname [info script]] source [file join $scriptDir pwiLogo.glf] } proc blkGetIJK { dir ind1 ind2 ind3 } { if { $dir == "I" } { set i $ind3 set j $ind1 set k $ind2 } elseif { $dir == "J" } { set j $ind3 set i $ind1 set k $ind2 } else { set k $ind3 set i $ind1 set j $ind2 } return "$i $j $k" } proc copyConDistribution { con edge } { gg::conDistFunc $con -scale $edge } # Copy the scale of the corresponding block edge to the butterfly connectors that # are perpendicular to the butterfly faces. proc copyConDistribution_test { con edge } { set tol [gg::tolGP] gg::conDistFunc $con -scale $edge set conBeginSpacing [gg::conBeginSpacing $con] set edgeBeginSpacing [gg::conBeginSpacing [lindex $edge 0]] set conLength [gg::conGetLength $con] set edgeLength 0.0 foreach conEdge $edge { set edgeLength [expr $edgeLength + [gg::conGetLength $conEdge]] } set scaledConBeginSpacing [expr $conBeginSpacing / $conLength * $edgeLength] set diff [expr abs( $scaledConBeginSpacing - $edgeBeginSpacing ) ] if { $diff > $tol } { # Two edges are running in the opposite directions. So the distribution needs to # be reversed. set edge_reverse {} set conNum [llength $edge] if { $conNum == 1 } { gg::conDistFunc $con -scale [list $edge -1] } else { for { set i 0 } { $i < $conNum } { incr i 1 } { lappend edge_reverse [lindex $edge [expr $conNum-$i-1 ]] } gg::conDistFunc $con -scale $edge_reverse } } } # Use Glyph utility commands ggu::vec3Length and ggu::vec3Sub. proc GetDist {pt1 pt2} { set 2sub1 [ggu::vec3Sub $pt2 $pt1] set dist [ggu::vec3Length $2sub1] return $dist } proc getPossibleEdges { edgelists } { set ret "" if { [llength $edgelists] == 1 } { return [lindex $edgelists 0] } foreach edge [lindex $edgelists 0] { foreach ap [getPossibleEdges [lrange $edgelists 1 end]] { lappend ret "$edge $ap" } } return $ret; } # Occasionally topology might cause the cons returned by GetBlkEdgeCons are # not connected in order. This needs to be corrected. con1 and con2 are the # two corner connectors adjacent to the block edge. proc edgeConsOrganizer { con1 Hcon con2 edge } { set nodeTol [gg::tolNode] set H_pta [gg::conGetPt $Hcon -arc 0.0] set H_ptb [gg::conGetPt $Hcon -arc 1.0] set cor1_pta [gg::conGetPt $con1 -arc 0.0] set cor1_ptb [gg::conGetPt $con1 -arc 1.0] foreach Hnode [list $H_pta $H_ptb] { foreach node [list $cor1_pta $cor1_ptb] { if { [GetDist $node $Hnode] > $nodeTol } { set edgeNode_1 $node } } } set conNum [llength $edge] set beginNode $edgeNode_1 for { set i 0 } { $i < $conNum } { incr i 1 } { set actualCon [lindex $edge $i] set temp [ getConByNode $beginNode [lrange $edge $i end] ] set rightCon [lindex $temp 0] set rightConId [lsearch $edge $rightCon] set beginNode [lrange $temp 1 end] if { [string equal $actualCon $rightCon] != 1 } { set edge [lreplace $edge $i $i $rightCon] set edge [lreplace $edge $rightConId $rightConId $actualCon] } } return $edge } proc getConByNode { pt conList } { set tol [gg::tolNode] foreach con $conList { set pta [gg::conGetPt $con -arc 0] set ptb [gg::conGetPt $con -arc 1] set dist_a [GetDist $pt $pta] set dist_b [GetDist $pt $ptb] if { $dist_a < $tol } { return "$con $ptb" } elseif { $dist_b < $tol } { return "$con $pta" } } } # Simplify the finding sharing edge method. proc GetBlkEdgeCons {blk face1 face2} { set dom_1 [lindex [gg::blkGetFace $blk $face1] 0] set dom_2 [lindex [gg::blkGetFace $blk $face2] 0] set face_2_BoundCons {} foreach dom $dom_2 { set edgeList [gg::domGetEdge $dom] foreach edge $edgeList { foreach con $edge { if { [lsearch $face_2_BoundCons $con] >= 0 } { ############# } else { lappend face_2_BoundCons $con } } } } set sharingCons {} foreach dom $dom_1 { set edgeList [gg::domGetEdge $dom] foreach edge $edgeList { foreach con $edge { if { [lsearch $face_2_BoundCons $con] >= 0 } { lappend sharingCons $con } } } } if { [llength $sharingCons] == 0 } { puts "INFO: Cannot find sharing edge of $blk between faces $face1 and $face2." } return $sharingCons } proc GetBlkEdgeCons_old {blk face1 face2} { set dom_1 [lindex [gg::blkGetFace $blk $face1] 0] set dom_2 [lindex [gg::blkGetFace $blk $face2] 0] set dom_1_edges "" set dom_2_edges "" foreach dom $dom_1 { lappend dom_1_edges "[gg::domGetEdge $dom]" } foreach dom $dom_2 { lappend dom_2_edges "[gg::domGetEdge $dom]" } set p_edges1 [getPossibleEdges $dom_1_edges] set p_edges2 [getPossibleEdges $dom_2_edges] foreach dom $dom_1 { foreach edge [gg::domGetEdge $dom] { lappend p_edges1 $edge } } foreach dom $dom_2 { foreach edge [gg::domGetEdge $dom] { lappend p_edges2 $edge } } foreach edge1 $p_edges1 { foreach edge2 $p_edges2 { if { [string equal [lsort $edge1] [lsort $edge2]] } { puts "$edge1" return $edge1 } } } return } proc blkMakeBflyBlocks { blk dir } { global createdBflyBlks # This is to prevent duplicated block entities in the propagating list caused by invalid # user slection. For example, a user selects several blocks and check the propagate box. if { [lsearch -exact $createdBflyBlks $blk] >= 0 } { #puts "INFO -- Duplicated block is found in the propagating block list. It is skipped." return } gg::blkReport $blk blkInfo STRUCTURE set id [lindex $blkInfo(dimensions) 0] set jd [lindex $blkInfo(dimensions) 1] set kd [lindex $blkInfo(dimensions) 2] # Determine the butterfly face IDs, ind3_min_face and ind3_max_face. # The dimension in the propagating direction is ind3_max. if {$dir == "I"} { set max1 $jd set max2 $kd set ind3_max $id set ind1_min_face JMIN set ind1_max_face JMAX set ind2_min_face KMIN set ind2_max_face KMAX set ind3_min_face IMIN set ind3_max_face IMAX } elseif {$dir == "J"} { set max1 $id set max2 $kd set ind3_max $jd set ind1_min_face IMIN set ind1_max_face IMAX set ind2_min_face KMIN set ind2_max_face KMAX set ind3_min_face JMIN set ind3_max_face JMAX } else { set max1 $id set max2 $jd set ind3_max $kd set ind1_min_face IMIN set ind1_max_face IMAX set ind2_min_face JMIN set ind2_max_face JMAX set ind3_min_face KMIN set ind3_max_face KMAX } if { $dir == "ALL" } { set capMin 1 set capMax 1 } else { set capMin 0 set capMax 0 } if { [blkMakeBflyDomains $blk $dir doms] == 0 } { return 0; } set face1 [lindex [gg::blkGetFace $blk $ind2_min_face] 0] set face2 [lindex [gg::blkGetFace $blk $ind1_max_face] 0] set face3 [lindex [gg::blkGetFace $blk $ind2_max_face] 0] set face4 [lindex [gg::blkGetFace $blk $ind1_min_face] 0] set face5 [lindex [gg::blkGetFace $blk $ind3_min_face] 0] set face6 [lindex [gg::blkGetFace $blk $ind3_max_face] 0] set base [gg::blkName $blk] gg::blkDelete $blk # Check bugs in block assembling process. #-- Center block gg::blkBegin -type STRUCTURED gg::faceBegin gg::faceAddDom $doms(center,ind3_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(center,ind3_max) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(center,ind1_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(center,ind1_max) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(center,ind2_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(center,ind2_max) gg::faceEnd set blks(center) [gg::blkEnd] #-- Ogrid 1 (ind2_min) block # Check bugs in block assembling process. gg::blkBegin -type STRUCTURED gg::faceBegin gg::faceAddDom $doms(ogrid1,ind3_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(ogrid1,ind3_max) gg::faceEnd gg::faceBegin foreach dm $face1 { gg::faceAddDom $dm } gg::faceEnd gg::faceBegin gg::faceAddDom $doms(center,ind2_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(corner1) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(corner2) gg::faceEnd set blks(ogrid1) [gg::blkEnd] #-- Ogrid 2 (ind1_max) block gg::blkBegin -type STRUCTURED gg::faceBegin gg::faceAddDom $doms(ogrid2,ind3_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(ogrid2,ind3_max) gg::faceEnd gg::faceBegin foreach dm $face2 { gg::faceAddDom $dm } gg::faceEnd gg::faceBegin gg::faceAddDom $doms(center,ind1_max) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(corner2) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(corner3) gg::faceEnd set blks(ogrid2) [gg::blkEnd] #-- Ogrid 3 (ind2_max) block gg::blkBegin -type STRUCTURED gg::faceBegin gg::faceAddDom $doms(ogrid3,ind3_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(ogrid3,ind3_max) gg::faceEnd gg::faceBegin foreach dm $face3 { gg::faceAddDom $dm } gg::faceEnd gg::faceBegin gg::faceAddDom $doms(center,ind2_max) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(corner3) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(corner4) gg::faceEnd set blks(ogrid3) [gg::blkEnd] #-- Ogrid 4 (ind1_min) block gg::blkBegin -type STRUCTURED gg::faceBegin gg::faceAddDom $doms(ogrid4,ind3_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(ogrid4,ind3_max) gg::faceEnd gg::faceBegin foreach dm $face4 { gg::faceAddDom $dm } gg::faceEnd gg::faceBegin gg::faceAddDom $doms(center,ind1_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(corner4) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(corner1) gg::faceEnd set blks(ogrid4) [gg::blkEnd] set base [string trim $base] catch { gg::blkName $blks(center) "${base}_center" } catch { gg::blkName $blks(ogrid1) "${base}_ogrid1" } catch { gg::blkName $blks(ogrid2) "${base}_ogrid2" } catch { gg::blkName $blks(ogrid3) "${base}_ogrid3" } catch { gg::blkName $blks(ogrid4) "${base}_ogrid4" } if { $capMin } { #-- Cap min (ind3_min) block gg::blkBegin -type STRUCTURED gg::faceBegin foreach dm $face5 { gg::faceAddDom $dm } gg::faceEnd gg::faceBegin gg::faceAddDom $doms(center,ind3_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(ogrid1,ind3_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(ogrid2,ind3_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(ogrid3,ind3_min) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(ogrid4,ind3_min) gg::faceEnd set blks(capmin) [gg::blkEnd] catch { gg::blkName $blks(capmin) "${base}_capmin" } } if { $capMax } { #-- Cap max (ind3_max) block gg::blkBegin -type STRUCTURED gg::faceBegin foreach dm $face6 { gg::faceAddDom $dm } gg::faceEnd gg::faceBegin gg::faceAddDom $doms(center,ind3_max) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(ogrid1,ind3_max) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(ogrid2,ind3_max) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(ogrid3,ind3_max) gg::faceEnd gg::faceBegin gg::faceAddDom $doms(ogrid4,ind3_max) gg::faceEnd set blks(capmax) [gg::blkEnd] catch { gg::blkName $blks(capmax) "${base}_capmax" } } lappend createdBflyBlks $blk return 1 } ################################################################################################# proc blkMakeBflyDomains { blk dir var } { global butterflyDBFile global oFraction oDimension upvar $var doms # Write out plot3D file of the butterfly faces of selected blocks. if { $dir == "I" || $dir == "J" || $dir == "K" } { createBflyDBSurf $blk $dir } set splitEdges 1 if { $dir == "ALL" } { set capMin 1 set capMax 1 } else { set capMin 0 set capMax 0 } gg::blkReport $blk blkInfo STRUCTURE if { $blkInfo(type) != "STRUCTURED" } { return 0 } set id [lindex $blkInfo(dimensions) 0] set jd [lindex $blkInfo(dimensions) 1] set kd [lindex $blkInfo(dimensions) 2] # ind3_min -- the minimum I/J/K index to start with. It is always 1. # ind3_min_face and ind3_max_face are the butterfly faces. set ind3_min 1 if {$dir == "I"} { set max1 $jd set max2 $kd set ind3_max $id set ind1_min_face JMIN set ind1_max_face JMAX set ind2_min_face KMIN set ind2_max_face KMAX set ind3_min_face IMIN set ind3_max_face IMAX } elseif {$dir == "J"} { set max1 $id set max2 $kd set ind3_max $jd set ind1_min_face IMIN set ind1_max_face IMAX set ind2_min_face KMIN set ind2_max_face KMAX set ind3_min_face JMIN set ind3_max_face JMAX } else { # Comment added by Wenny (Aug 5, 2008). # Note this is applied to two cases: K and ALL modes. set max1 $id set max2 $jd set ind3_max $kd set ind1_min_face IMIN set ind1_max_face IMAX set ind2_min_face JMIN set ind2_max_face JMAX set ind3_min_face KMIN set ind3_max_face KMAX } # Determine the other 2 indices (J and K) of H domain given one (I) of butterfly faces. # # Jmax o---------------o o---------------o # | | | | # | | | | # | | | | # |ind1_max | |ind2_min | # | o-------o | | o-------o | # | | | | | | | | #J index of H | | | | | | | | K index of H # | | | | | | | | # | o-------o | | o-------o | # |ind1_min | | ind2_max| # | | | | # | | | | # Jmin=1 o---------------o Kmin=1 o---------------o Kmax # # Imin butterfly face Imax butterfly face # # if { $max1 < $max2 } { set ogrid_i [expr int($max1*$oFraction)] set id2 [expr $max1/2] if {$ogrid_i > $id2} { set ogrid_i $id2 } if {$ogrid_i < 2 } { set ogrid_i 2 } } else { set ogrid_i [expr int($max2*$oFraction)] set jd2 [expr $max2/2] if {$ogrid_i > $jd2} { set ogrid_i $jd2 } if {$ogrid_i < 2 } { set ogrid_i 2 } } set ogrid_j $ogrid_i set ind1_min $ogrid_i set ind1_max [expr $max1-$ogrid_i+1] set ind2_min $ogrid_j set ind2_max [expr $max2-$ogrid_j+1] #-- Create connectors blkMakeBflyConnectors $blk $dir con # Create 4 connectors based on the four nodes of H domain. foreach end {ind3_min ind3_max} { foreach beg {ind1_min ind1_max} { set pt0 [gg::conGetPt $con($beg,$end) -arc 0] set pt1 [gg::conGetPt $con($beg,$end) -arc 1] if { [catch {gg::conDim $con($beg,$end) $max2}] == 1 } { gg::conRedimBegin; gg::conRedim $con($beg,$end) $max2; gg::conRedimEnd } if [catch {gg::conGetPt $con($beg,$end) -arc 0}] { set con($beg,$end) [getConnectorByEndPoints $pt0 $pt1] } } foreach beg {ind2_min ind2_max} { set pt0 [gg::conGetPt $con($beg,$end) -arc 0] set pt1 [gg::conGetPt $con($beg,$end) -arc 1] if { [catch {gg::conDim $con($beg,$end) $max1}] == 1 } { gg::conRedimBegin; gg::conRedim $con($beg,$end) $max1; gg::conRedimEnd } if [catch {gg::conGetPt $con($beg,$end) -arc 0}] { set con($beg,$end) [getConnectorByEndPoints $pt0 $pt1] } } foreach beg {corner1 corner2 corner3 corner4} { set pt0 [gg::conGetPt $con($beg,$end) -arc 0] set pt1 [gg::conGetPt $con($beg,$end) -arc 1] if { [catch {gg::conDim $con($beg,$end) $oDimension}] == 1 } { gg::conRedimBegin; gg::conRedim $con($beg,$end) $oDimension; gg::conRedimEnd } if [catch {gg::conGetPt $con($beg,$end) -arc 0}] { set con($beg,$end) [getConnectorByEndPoints $pt0 $pt1] } } } foreach end {ind1_min ind1_max} { foreach beg {ind2_min ind2_max} { set pt0 [gg::conGetPt $con($beg,$end) -arc 0] set pt1 [gg::conGetPt $con($beg,$end) -arc 1] if { [catch {gg::conDim $con($beg,$end) $ind3_max}] == 1 } { gg::conRedimBegin; gg::conRedim $con($beg,$end) $ind3_max; gg::conRedimEnd } if [catch {gg::conGetPt $con($beg,$end) -arc 0}] { set con($beg,$end) [getConnectorByEndPoints $pt0 $pt1] } } } # Create the 2 H domains on butterfly faces, say, Imin and Imax if I selected. # con(ind2_min,ind3_min) -- Kmin H connector on Imin face. # con(ind1_max,ind3_min) -- Jmax H connector on Imin face. # con(ind2_max,ind3_min) -- Kmax H connector on Imin face. # con(ind1_min,ind3_min) -- Jmin H connector on Imin face. # Please note they have to be added in order such that a closed perimeter loop is created. # # Jmax Con # o---------------o # | | # | | # | | # Kmin Con| | Kmax Con # | | # | | # o---------------o # Jmin Con # #-- Center domains gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(ind2_min,ind3_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind1_max,ind3_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_max,ind3_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind1_min,ind3_min) gg::edgeEnd if [catch { gg::domEnd } doms(center,ind3_min)] { set doms(center,ind3_min) [getDomainByCorners [gg::conGetPt $con(ind2_min,ind3_min) -arc 0] \ [gg::conGetPt $con(ind2_min,ind3_min) -arc 1] \ [gg::conGetPt $con(ind2_max,ind3_min) -arc 0] \ [gg::conGetPt $con(ind2_max,ind3_min) -arc 1]] } gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(ind2_min,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind1_max,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_max,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind1_min,ind3_max) gg::edgeEnd if [catch { gg::domEnd } doms(center,ind3_max)] { set doms(center,ind3_max) [getDomainByCorners [gg::conGetPt $con(ind2_min,ind3_max) -arc 0] \ [gg::conGetPt $con(ind2_min,ind3_max) -arc 1] \ [gg::conGetPt $con(ind2_max,ind3_max) -arc 0] \ [gg::conGetPt $con(ind2_max,ind3_max) -arc 1]] } # Create Jmin domain(s) of the center block if I mode is selected. #-- ind1_min face gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(ind2_min,ind1_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind1_min,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_max,ind1_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind1_min,ind3_min) gg::edgeEnd if [catch { gg::domEnd } doms(center,ind1_min)] { set doms(center,ind1_min) [getDomainByCorners [gg::conGetPt $con(ind2_min,ind1_min) -arc 0] \ [gg::conGetPt $con(ind2_min,ind1_min) -arc 1] \ [gg::conGetPt $con(ind2_max,ind1_min) -arc 0] \ [gg::conGetPt $con(ind2_max,ind1_min) -arc 1]] } # Create Jmax domain(s) of the center blockif I mode is selected. #-- ind1_max face gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(ind2_min,ind1_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind1_max,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_max,ind1_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind1_max,ind3_min) gg::edgeEnd if [catch { gg::domEnd } doms(center,ind1_max)] { set doms(center,ind1_max) [getDomainByCorners [gg::conGetPt $con(ind2_min,ind1_max) -arc 0] \ [gg::conGetPt $con(ind2_min,ind1_max) -arc 1] \ [gg::conGetPt $con(ind2_max,ind1_max) -arc 0] \ [gg::conGetPt $con(ind2_max,ind1_max) -arc 1]] } # Comment added by Wenny (Aug 5, 2008) # Create Kmin domain(s) of the center block if I mode is selected. #-- ind2_min face gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(ind2_min,ind1_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_min,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_min,ind1_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_min,ind3_min) gg::edgeEnd if [catch { gg::domEnd } doms(center,ind2_min)] { set doms(center,ind2_min) [getDomainByCorners [gg::conGetPt $con(ind2_min,ind1_min) -arc 0] \ [gg::conGetPt $con(ind2_min,ind1_min) -arc 1] \ [gg::conGetPt $con(ind2_min,ind1_max) -arc 0] \ [gg::conGetPt $con(ind2_min,ind1_max) -arc 1]] } # Create Kmin domain(s) of the center block if I mode is selected. #-- ind2_max face gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(ind2_max,ind1_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_max,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_max,ind1_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_max,ind3_min) gg::edgeEnd if [catch { gg::domEnd } doms(center,ind2_max)] { set doms(center,ind2_max) [getDomainByCorners [gg::conGetPt $con(ind2_max,ind1_min) -arc 0] \ [gg::conGetPt $con(ind2_max,ind1_min) -arc 1] \ [gg::conGetPt $con(ind2_max,ind1_max) -arc 0] \ [gg::conGetPt $con(ind2_max,ind1_max) -arc 1]] } # Create 4 Ogrid domains on the 1st butterfly face, say Imin if I mode is selected. #-- Ogrid domain 1 ind3_min face set edge1 [GetBlkEdgeCons $blk $ind2_min_face $ind3_min_face] if {$edge1 == ""} { ErrorMsg "Unable to get block edge" return 0 } gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(corner2,ind3_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_min,ind3_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(corner1,ind3_min) gg::edgeEnd gg::edgeBegin while { [llength $edge1] > 0 } { set temp 0; for { set ii 0 } { $ii < [llength $edge1] } { incr ii } { if { [catch { gg::edgeAddCon [lindex $edge1 $ii] } msg] == 0 } { set edge1 [lreplace $edge1 $ii $ii] set temp 1 break; } } if { $temp != 1 } { ErrorMsg "Adding Edge Failed"; break; } } gg::edgeEnd if [catch { gg::domEnd } doms(ogrid1,ind3_min)] { set doms(ogrid1,ind3_min) [getDomainByCorners [gg::conGetPt $con(corner2,ind3_min) -arc 0] \ [gg::conGetPt $con(corner2,ind3_min) -arc 1] \ [gg::conGetPt $con(corner1,ind3_min) -arc 0] \ [gg::conGetPt $con(corner1,ind3_min) -arc 1]] } set num_in_edge [llength $edge1] if {$splitEdges && $num_in_edge > 1} { #-- split opposing con set opcon $con(ind2_min,ind3_min) incr num_in_edge -1 for {set ii 0} {$ii < $num_in_edge} {incr ii} { set cn [lindex $edge1 $ii] set i [gg::conDim $cn] set pt [gg::conGetPt $opcon $i] set opcon [gg::conSplit $opcon $pt] } } #-- Ogrid domain 2 ind3_min face set edge1 [GetBlkEdgeCons $blk $ind1_max_face $ind3_min_face] if {$edge1 == ""} { ErrorMsg "Unable to get block edge" return 0 } gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(corner3,ind3_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind1_max,ind3_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(corner2,ind3_min) gg::edgeEnd gg::edgeBegin while { [llength $edge1] > 0 } { set temp 0; for { set ii 0 } { $ii < [llength $edge1] } { incr ii } { if { [catch { gg::edgeAddCon [lindex $edge1 $ii] } msg] == 0 } { set edge1 [lreplace $edge1 $ii $ii] set temp 1 break; } } if { $temp != 1 } { ErrorMsg "Adding Edge Failed"; break; } } gg::edgeEnd if [catch { gg::domEnd } doms(ogrid2,ind3_min)] { set doms(ogrid2,ind3_min) [getDomainByCorners [gg::conGetPt $con(corner3,ind3_min) -arc 0] \ [gg::conGetPt $con(corner3,ind3_min) -arc 1] \ [gg::conGetPt $con(corner2,ind3_min) -arc 0] \ [gg::conGetPt $con(corner2,ind3_min) -arc 1]] } set num_in_edge [llength $edge1] if {$splitEdges && $num_in_edge > 1} { #-- split opposing con set opcon $con(ind1_max,ind3_min) incr num_in_edge -1 for {set ii 0} {$ii < $num_in_edge} {incr ii} { set cn [lindex $edge1 $ii] set i [gg::conDim $cn] set pt [gg::conGetPt $opcon $i] set opcon [gg::conSplit $opcon $pt] } } #-- Ogrid domain 3 ind3_min face set edge1 [GetBlkEdgeCons $blk $ind2_max_face $ind3_min_face] if {$edge1 == ""} { ErrorMsg "Unable to get block edge" return 0 } gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(corner4,ind3_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_max,ind3_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(corner3,ind3_min) gg::edgeEnd gg::edgeBegin while { [llength $edge1] > 0 } { set temp 0; for { set ii 0 } { $ii < [llength $edge1] } { incr ii } { if { [catch { gg::edgeAddCon [lindex $edge1 $ii] } msg] == 0 } { set edge1 [lreplace $edge1 $ii $ii] set temp 1 break; } } if { $temp != 1 } { ErrorMsg "Adding Edge Failed"; break; } } gg::edgeEnd if [catch { gg::domEnd } doms(ogrid3,ind3_min)] { set doms(ogrid3,ind3_min) [getDomainByCorners [gg::conGetPt $con(corner4,ind3_min) -arc 0] \ [gg::conGetPt $con(corner4,ind3_min) -arc 1] \ [gg::conGetPt $con(corner3,ind3_min) -arc 0] \ [gg::conGetPt $con(corner3,ind3_min) -arc 1]] } set num_in_edge [llength $edge1] if {$splitEdges && $num_in_edge > 1} { #-- split opposing con set opcon $con(ind2_max,ind3_min) incr num_in_edge -1 for {set ii 0} {$ii < $num_in_edge} {incr ii} { set cn [lindex $edge1 $ii] set i [gg::conDim $cn] set pt [gg::conGetPt $opcon $i] set opcon [gg::conSplit $opcon $pt] } } #-- Ogrid domain 4 ind3_min face set edge1 [GetBlkEdgeCons $blk $ind1_min_face $ind3_min_face] if {$edge1 == ""} { ErrorMsg "Unable to get block edge" return 0 } gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(corner1,ind3_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind1_min,ind3_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(corner4,ind3_min) gg::edgeEnd gg::edgeBegin while { [llength $edge1] > 0 } { set temp 0; for { set ii 0 } { $ii < [llength $edge1] } { incr ii } { if { [catch { gg::edgeAddCon [lindex $edge1 $ii] } msg] == 0 } { set edge1 [lreplace $edge1 $ii $ii] set temp 1 break; } } if { $temp != 1 } { ErrorMsg "Adding Edge Failed"; break; } } gg::edgeEnd if [catch { gg::domEnd } doms(ogrid4,ind3_min)] { set doms(ogrid4,ind3_min) [getDomainByCorners [gg::conGetPt $con(corner1,ind3_min) -arc 0] \ [gg::conGetPt $con(corner1,ind3_min) -arc 1] \ [gg::conGetPt $con(corner4,ind3_min) -arc 0] \ [gg::conGetPt $con(corner4,ind3_min) -arc 1]] } set num_in_edge [llength $edge1] if {$splitEdges && $num_in_edge > 1} { #-- split opposing con set opcon $con(ind1_min,ind3_min) incr num_in_edge -1 for {set ii 0} {$ii < $num_in_edge} {incr ii} { set cn [lindex $edge1 $ii] set i [gg::conDim $cn] set pt [gg::conGetPt $opcon $i] set opcon [gg::conSplit $opcon $pt] } } # Create 4 Ogrid domains on the 2st butterfly face, say Imax if I mode is selected. #-- Ogrid domain 1 ind3_max face set edge1 [GetBlkEdgeCons $blk $ind2_min_face $ind3_max_face] if {$edge1 == ""} { ErrorMsg "Unable to get block edge" return 0 } gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(corner2,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_min,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(corner1,ind3_max) gg::edgeEnd gg::edgeBegin while { [llength $edge1] > 0 } { set temp 0; for { set ii 0 } { $ii < [llength $edge1] } { incr ii } { if { [catch { gg::edgeAddCon [lindex $edge1 $ii] } msg] == 0 } { set edge1 [lreplace $edge1 $ii $ii] set temp 1 break; } } if { $temp != 1 } { ErrorMsg "Adding Edge Failed"; break; } } gg::edgeEnd if [catch { gg::domEnd } doms(ogrid1,ind3_max)] { set doms(ogrid1,ind3_max) [getDomainByCorners [gg::conGetPt $con(corner2,ind3_max) -arc 0] \ [gg::conGetPt $con(corner2,ind3_max) -arc 1] \ [gg::conGetPt $con(corner1,ind3_max) -arc 0] \ [gg::conGetPt $con(corner1,ind3_max) -arc 1]] } set num_in_edge [llength $edge1] if {$splitEdges && $num_in_edge > 1} { #-- split opposing con set opcon $con(ind2_min,ind3_max) incr num_in_edge -1 for {set ii 0} {$ii < $num_in_edge} {incr ii} { set cn [lindex $edge1 $ii] set i [gg::conDim $cn] set pt [gg::conGetPt $opcon $i] set opcon [gg::conSplit $opcon $pt] } } #-- Ogrid domain 2 ind3_max face set edge1 [GetBlkEdgeCons $blk $ind1_max_face $ind3_max_face] if {$edge1 == ""} { ErrorMsg "Unable to get block edge" return 0 } gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(corner3,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind1_max,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(corner2,ind3_max) gg::edgeEnd gg::edgeBegin while { [llength $edge1] > 0 } { set temp 0; for { set ii 0 } { $ii < [llength $edge1] } { incr ii } { if { [catch { gg::edgeAddCon [lindex $edge1 $ii] } msg] == 0 } { set edge1 [lreplace $edge1 $ii $ii] set temp 1 break; } } if { $temp != 1 } { ErrorMsg "Adding Edge Failed"; break; } } gg::edgeEnd if [catch { gg::domEnd } doms(ogrid2,ind3_max)] { set doms(ogrid2,ind3_max) [getDomainByCorners [gg::conGetPt $con(corner3,ind3_max) -arc 0] \ [gg::conGetPt $con(corner3,ind3_max) -arc 1] \ [gg::conGetPt $con(corner2,ind3_max) -arc 0] \ [gg::conGetPt $con(corner2,ind3_max) -arc 1]] } set num_in_edge [llength $edge1] if {$splitEdges && $num_in_edge > 1} { #-- split opposing con set opcon $con(ind1_max,ind3_max) incr num_in_edge -1 for {set ii 0} {$ii < $num_in_edge} {incr ii} { set cn [lindex $edge1 $ii] set i [gg::conDim $cn] set pt [gg::conGetPt $opcon $i] set opcon [gg::conSplit $opcon $pt] } } #-- Ogrid domain 3 ind3_max face set edge1 [GetBlkEdgeCons $blk $ind2_max_face $ind3_max_face] if {$edge1 == ""} { ErrorMsg "Unable to get block edge" return 0 } gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(corner4,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_max,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(corner3,ind3_max) gg::edgeEnd gg::edgeBegin while { [llength $edge1] > 0 } { set temp 0; for { set ii 0 } { $ii < [llength $edge1] } { incr ii } { if { [catch { gg::edgeAddCon [lindex $edge1 $ii] } msg] == 0 } { set edge1 [lreplace $edge1 $ii $ii] set temp 1 break; } } if { $temp != 1 } { ErrorMsg "Adding Edge Failed"; break; } } gg::edgeEnd if [catch { gg::domEnd } doms(ogrid3,ind3_max)] { set doms(ogrid3,ind3_max) [getDomainByCorners [gg::conGetPt $con(corner4,ind3_max) -arc 0] \ [gg::conGetPt $con(corner4,ind3_max) -arc 1] \ [gg::conGetPt $con(corner3,ind3_max) -arc 0] \ [gg::conGetPt $con(corner3,ind3_max) -arc 1]] } set num_in_edge [llength $edge1] if {$splitEdges && $num_in_edge > 1} { #-- split opposing con set opcon $con(ind2_max,ind3_max) incr num_in_edge -1 for {set ii 0} {$ii < $num_in_edge} {incr ii} { set cn [lindex $edge1 $ii] set i [gg::conDim $cn] set pt [gg::conGetPt $opcon $i] set opcon [gg::conSplit $opcon $pt] } } #-- Ogrid domain 4 ind3_max face set edge1 [GetBlkEdgeCons $blk $ind1_min_face $ind3_max_face] if {$edge1 == ""} { ErrorMsg "Unable to get block edge" return 0 } gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(corner1,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind1_min,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(corner4,ind3_max) gg::edgeEnd gg::edgeBegin while { [llength $edge1] > 0 } { set temp 0; for { set ii 0 } { $ii < [llength $edge1] } { incr ii } { if { [catch { gg::edgeAddCon [lindex $edge1 $ii] } msg] == 0 } { set edge1 [lreplace $edge1 $ii $ii] set temp 1 break; } } if { $temp != 1 } { ErrorMsg "Adding Edge Failed"; break; } } gg::edgeEnd if [catch { gg::domEnd } doms(ogrid4,ind3_max)] { set doms(ogrid4,ind3_max) [getDomainByCorners [gg::conGetPt $con(corner1,ind3_max) -arc 0] \ [gg::conGetPt $con(corner1,ind3_max) -arc 1] \ [gg::conGetPt $con(corner4,ind3_max) -arc 0] \ [gg::conGetPt $con(corner4,ind3_max) -arc 1]] } set num_in_edge [llength $edge1] if {$splitEdges && $num_in_edge > 1} { #-- split opposing con set opcon $con(ind1_min,ind3_max) incr num_in_edge -1 for {set ii 0} {$ii < $num_in_edge} {incr ii} { set cn [lindex $edge1 $ii] set i [gg::conDim $cn] set pt [gg::conGetPt $opcon $i] set opcon [gg::conSplit $opcon $pt] } } #-- Corner 1 domain set edge1 [GetBlkEdgeCons $blk $ind2_min_face $ind1_min_face] if {$edge1 == ""} { ErrorMsg "Unable to get block edge" return 0 } # Make sure the edge connectors are in order. set edge1 [edgeConsOrganizer $con(corner1,ind3_max) $con(ind2_min,ind1_min) \ $con(corner1,ind3_min) $edge1] # Copy the distribution of the corresponding edge of the block to the Butterfly connector # that is perpendicular to the butterfly faces. # For debugging only. #set edge1 "CN10274 CN10266 CN10286" copyConDistribution $con(ind2_min,ind1_min) $edge1 gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(corner1,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_min,ind1_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(corner1,ind3_min) gg::edgeEnd gg::edgeBegin while { [llength $edge1] > 0 } { set temp 0; for { set ii 0 } { $ii < [llength $edge1] } { incr ii } { if { [catch { gg::edgeAddCon [lindex $edge1 $ii] } msg] == 0 } { set edge1 [lreplace $edge1 $ii $ii] set temp 1 break; } } if { $temp != 1 } { ErrorMsg "Adding Edge Failed"; break; } } gg::edgeEnd if [catch { gg::domEnd } doms(corner1)] { set doms(corner1) [getDomainByCorners [gg::conGetPt $con(corner1,ind3_max) -arc 0] \ [gg::conGetPt $con(corner1,ind3_max) -arc 1] \ [gg::conGetPt $con(corner1,ind3_min) -arc 0] \ [gg::conGetPt $con(corner1,ind3_min) -arc 1]] } #-- Corner 2 domain set edge1 [GetBlkEdgeCons $blk $ind2_min_face $ind1_max_face] if {$edge1 == ""} { ErrorMsg "Unable to get block edge" return 0 } # Make sure the edge connectors are in order. set edge1 [edgeConsOrganizer $con(corner2,ind3_max) $con(ind2_min,ind1_max) \ $con(corner2,ind3_min) $edge1] # Copy the distribution of the corresponding edge of the block to the Butterfly connector # that is perpendicular to the butterfly faces. copyConDistribution $con(ind2_min,ind1_max) $edge1 gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(corner2,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_min,ind1_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(corner2,ind3_min) gg::edgeEnd gg::edgeBegin while { [llength $edge1] > 0 } { set temp 0; for { set ii 0 } { $ii < [llength $edge1] } { incr ii } { if { [catch { gg::edgeAddCon [lindex $edge1 $ii] } msg] == 0 } { set edge1 [lreplace $edge1 $ii $ii] set temp 1 break } } if { $temp != 1 } { ErrorMsg "Adding Edge Failed" break; } } gg::edgeEnd if [catch { gg::domEnd } doms(corner2)] { set doms(corner2) [getDomainByCorners [gg::conGetPt $con(corner2,ind3_max) -arc 0] \ [gg::conGetPt $con(corner2,ind3_max) -arc 1] \ [gg::conGetPt $con(corner2,ind3_min) -arc 0] \ [gg::conGetPt $con(corner2,ind3_min) -arc 1]] } #-- Corner 3 domain set edge1 [GetBlkEdgeCons $blk $ind2_max_face $ind1_max_face] if {$edge1 == ""} { ErrorMsg "Unable to get block edge" return 0 } # Make sure the edge connectors are in order. set edge1 [edgeConsOrganizer $con(corner3,ind3_max) $con(ind2_max,ind1_max) \ $con(corner3,ind3_min) $edge1] # Copy the distribution of the corresponding edge of the block to the Butterfly connector # that is perpendicular to the butterfly faces. copyConDistribution $con(ind2_max,ind1_max) $edge1 gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(corner3,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_max,ind1_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(corner3,ind3_min) gg::edgeEnd gg::edgeBegin while { [llength $edge1] > 0 } { set temp 0; for { set ii 0 } { $ii < [llength $edge1] } { incr ii } { if { [catch { gg::edgeAddCon [lindex $edge1 $ii] } msg] == 0 } { set edge1 [lreplace $edge1 $ii $ii] set temp 1 break; } } if { $temp != 1 } { ErrorMsg "Adding Edge Failed"; break; } } gg::edgeEnd if [catch { gg::domEnd } doms(corner3)] { set doms(corner3) [getDomainByCorners [gg::conGetPt $con(corner3,ind3_max) -arc 0] \ [gg::conGetPt $con(corner3,ind3_max) -arc 1] \ [gg::conGetPt $con(corner3,ind3_min) -arc 0] \ [gg::conGetPt $con(corner3,ind3_min) -arc 1]] } #-- Corner 4 domain set edge1 [GetBlkEdgeCons $blk $ind2_max_face $ind1_min_face] if {$edge1 == ""} { ErrorMsg "Unable to get block edge" return 0 } # Make sure the edge connectors are in order. set edge1 [edgeConsOrganizer $con(corner4,ind3_max) $con(ind2_max,ind1_min) \ $con(corner4,ind3_min) $edge1] # Copy the distribution of the corresponding edge of the block to the Butterfly connector # that is perpendicular to the butterfly faces. copyConDistribution $con(ind2_max,ind1_min) $edge1 gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(corner4,ind3_max) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(ind2_max,ind1_min) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(corner4,ind3_min) gg::edgeEnd gg::edgeBegin while { [llength $edge1] > 0 } { set temp 0; for { set ii 0 } { $ii < [llength $edge1] } { incr ii } { if { [catch { gg::edgeAddCon [lindex $edge1 $ii] } msg] == 0 } { set edge1 [lreplace $edge1 $ii $ii] set temp 1 break; } } if { $temp != 1 } { ErrorMsg "Adding Edge Failed" break; } } gg::edgeEnd if [catch { gg::domEnd } doms(corner4)] { set doms(corner4) [getDomainByCorners [gg::conGetPt $con(corner4,ind3_max) -arc 0] \ [gg::conGetPt $con(corner4,ind3_max) -arc 1] \ [gg::conGetPt $con(corner4,ind3_min) -arc 0] \ [gg::conGetPt $con(corner4,ind3_min) -arc 1]] } #Project the created butterfly domains onto the original block surfaces. if { $dir == "I" || $dir == "J" || $dir == "K" } { set butterflyDomList [list $doms(center,ind3_min) $doms(center,ind3_max) \ $doms(ogrid1,ind3_min) $doms(ogrid1,ind3_max) \ $doms(ogrid2,ind3_min) $doms(ogrid2,ind3_max) \ $doms(ogrid3,ind3_min) $doms(ogrid3,ind3_max) \ $doms(ogrid4,ind3_min) $doms(ogrid4,ind3_max)] gg::dbImport $butterflyDBFile -style PLOT3D -format ASCII -precision DOUBLE # Please note -maintain_linkage is a must in this command. Otherwise, connectors need to # be merged when slope discontinuity occurs on butterfly faces. gg::domProject $butterflyDomList -type CLOSEST_PT -maintain_linkage # Disable the imported DB entities, 2 surfaces and one group. set dbList [gg::dbGetAll -enabled] set dbTurnOff [lrange $dbList end-3 end-1] gg::dbEnable $dbTurnOff 0 } return 1 } # Replace the old guessing scheme which is incorrect. proc HDomLocatori_old { blk dir max1 max2 ind3_min ind3_max faceID } { global oScaleFac Propagate locatorH_prop Preview # For propagate mode only. If H location is already obtained for the first block in # the propagating block list, the old location information will be returned. # This method saves tremendous time if the topology change will be propagated through # many blocks. if { $Propagate == 1 && [llength $locatorH_prop] > 1 && $dir != "ALL" } { return $locatorH_prop } # # Improve the performance by simlifying the method of obtaining the ogrid_i/j/k. # The old method above has to go through lots of iterations to decide the cooresponding ijk # index for the H region. Moreover, its guessing scheme is based on the normalized dimention # so the H region location highly depends on the connector distribution. # # Determine the 2 indices (J and K) of H domain given one (I) of butterfly faces. # # index3 index4 # Jmax o---?-------?---o o---------------o # | | | | # | | | | # | | | | # | | | | # index2 ? o-------o | | o-------o | # | | | | | | | | # | | | | | | | | # | | | | | | | | # index1 ? o-------o | | o-------o | # | | | | # | | | | # | | | | # Jmin=1 o---------------o Kmin=1 o---------------o Kmax # # Imin butterfly face Imax butterfly face # # Case 1: Multiple domains on butterfly face(s). # Case 2: Single domain butterfly face but multi-con edge(s). # # Note that although multi domains can be joined on a H face, connectors may not due to the # topology on adjacent non-butterfly faces. set ogrid_k 2 set faceList [gg::blkGetFace $blk {IMIN IMAX JMIN JMAX KMIN KMAX}] set domBflyFac [lindex $faceList $faceID] if { [llength $domBflyFac] > 1 } { multiDomFaceOccurs $blk $dir } set faceList [gg::blkGetFace $blk {IMIN IMAX JMIN JMAX KMIN KMAX}] set domBflyFac [lindex $faceList $faceID] set edgeList [gg::domGetEdge $domBflyFac { 1 2 3 4}] # It is likely that a butterfly face has one domain but multi-con edges. If so, ghost connectors # on this edge will be created for dimension index calculation. These ghost cons will be created # by copying the cons on an edge to a new relative location (0 0 10.0). This z displacement will # be taken into account while the points distances are calculated. set 2Edges [list [lindex $edgeList 0] [lindex $edgeList 1] ] set updatedEdges {} set zDisplace 0.0 foreach conEdge $2Edges { if { [llength $conEdge] > 1 } { set zDisplacement 10.0 gg::conCopyBegin $conEdge gg::xformTranslate { 0 0 10.0 } set conEdgeCopy [gg::conCopyEnd] set conNumCopy [llength $conEdgeCopy] for { set ii 1 } { $ii < $conNumCopy } { incr ii 1 } { gg::conJoin [lindex $conEdgeCopy 0] [lindex $conEdgeCopy $ii] } set conEdge [lindex $conEdgeCopy 0] lappend updatedEdges $conEdge } else { lappend updatedEdges $conEdge } } set conEdge_1 [lindex $updatedEdges 0] set conEdge_2 [lindex $updatedEdges 1] # Make sure these two edges aligned with max1 and max2 direction. if { [gg::conDim $conEdge_1] != $max1 } { set temp $conEdge_1 set conEdge_1 $conEdge_2 set conEdge_2 $temp } # Use the scale factor (s1, s2) to get the normalized arc length corresponding to # the 4 points indices in the above diagram. set lengthEdge_1 [gg::conGetLength $conEdge_1] set lengthEdge_2 [gg::conGetLength $conEdge_2] set normArc_11 [ expr ( 1.0-[lindex $oScaleFac 0] ) / 2.0 ] set normArc_12 [ expr ( 1.0-$normArc_11 ) ] set normArc_21 [ expr ( 1.0-[lindex $oScaleFac 1] ) / 2.0 ] set normArc_22 [ expr ( 1.0-$normArc_21 ) ] # Obtain the xyz coordinates of the 4 target points. Note the z coordinates of the target # points will be modified if multi-con edges are copied. set pt11_target [gg::conGetPt $conEdge_1 -arc $normArc_11] set pt12_target [gg::conGetPt $conEdge_1 -arc $normArc_12] set pt21_target [gg::conGetPt $conEdge_2 -arc $normArc_21] set pt22_target [gg::conGetPt $conEdge_2 -arc $normArc_22] set [lindex pt11_target 2] [expr [lindex pt11_target 2] - $zDisplace] set [lindex pt12_target 2] [expr [lindex pt12_target 2] - $zDisplace] set [lindex pt21_target 2] [expr [lindex pt21_target 2] - $zDisplace] set [lindex pt22_target 2] [expr [lindex pt22_target 2] - $zDisplace] set tol [gg::tolGP] # corner1_Pts is the candidate points on one edge. set corner1_Pts {} set corner2_Pts {} # Compare the target point with each interior grid points on these two edges. # If a point satisfies any of the following rules, it will be added into the corner_Pts list. # # 1. The distance between this point and the target point is within the grid point tolerance. # 2. The target point is between this point and the neighboring point. for { set ii 2 } { $ii < [ gg::conDim $conEdge_1 ] } { incr ii 1 } { set pt [ gg::conGetPt $conEdge_1 $ii ] set ptp1 [gg::conGetPt $conEdge_1 [expr $ii + 1 ]] set spacing [GetDist $pt $ptp1] if { [ expr [GetDist $pt $pt11_target] ] < $tol || [ expr [GetDist $pt $pt12_target] ] < $tol \ || [ expr [GetDist $pt11_target $pt] ]< $spacing || [ expr [GetDist $pt12_target $pt] ]< $spacing } { lappend corner1_Pts $ii } } for { set ii 2 } { $ii < [ gg::conDim $conEdge_2 ] } { incr ii 1 } { set pt [ gg::conGetPt $conEdge_2 $ii ] set ptp1 [gg::conGetPt $conEdge_2 [expr $ii + 1 ]] set spacing [GetDist $pt $ptp1] if { [ expr [GetDist $pt $pt21_target] ] < $tol || [ expr [GetDist $pt $pt22_target] ] < $tol \ || [ expr [GetDist $pt21_target $pt] ]< $spacing || [ expr [GetDist $pt22_target $pt] ]< $spacing } { lappend corner2_Pts $ii } } # Note that the number of the candidate points can be over 2 if two target points happen to # be sitting between two grid points respectively. So only the first and last elements of this # corner1_Pt list will be picked. set ogrid_i [lindex $corner1_Pts 0] set ogrid_j [lindex $corner2_Pts 0] set ind1_min $ogrid_i set ind1_max [lindex $corner1_Pts [expr [llength $corner1_Pts] -1 ]] set ind2_min $ogrid_j set ind2_max [lindex $corner2_Pts [expr [llength $corner2_Pts] -1 ]] # Obtain the dimension index for the third direction when ALL is applied. if { $dir == "ALL" } { set kSpacing {} set kLength 0.0 set corner3_Pts {} set kPts {} for { set ii 1 } { $ii < $ind3_max } { incr ii 1 } { set pt [gg::blkGetPt $blk "1 1 $ii"] set pt_kp1 [gg::blkGetPt $blk "1 1 [expr $ii+1]"] lappend kPts $pt set incr [GetDist $pt $pt_kp1] set kLength [expr $kLength + $incr] lappend kSpacing $incr } set targetLength_1 [expr $kLength *(1.0-[lindex $oScaleFac 2]) / 2.0] set targetLength_2 [expr $kLength - $targetLength_1 ] set testLength 0.0 for { set ii 1 } { $ii < $ind3_max } { incr ii 1 } { set testLength [expr $testLength + [lindex $kSpacing [expr $ii-1]]] if { [expr abs( $targetLength_1 - $testLength )] < $tol || [expr abs( $targetLength_2 - $testLength )] < $tol || [expr abs( $testLength - $targetLength_1)] < [lindex $kSpacing [expr $ii-1]] || [expr abs( $testLength - $targetLength_2)] < [lindex $kSpacing [expr $ii-1]] } { lappend corner3_Pts $ii } } set ogrid_k [lindex $corner3_Pts 0] if { $ogrid_k == 1 } { set ogrid_k 2 } set ind3_min $ogrid_k set ind3_max [lindex $corner3_Pts [expr [llength $corner3_Pts]-1]] } if { $Propagate == 1 && $dir != "ALL" } { set locatorH_prop [list $ind1_min $ind1_max $ind2_min $ind2_max] } set HLocation [list $ind1_min $ind1_max $ind2_min $ind2_max $ind3_min $ind3_max] return $HLocation } # Replace the old guessing scheme below which requires domain joining if multi-dom # butterfly faces occurs. That is not reliable when the topology gets complicated. proc HDomLocator { blk dir max1 max2 ind3_min ind3_max faceID } { global oScaleFac Propagate locatorH_prop Preview set tol [gg::tolGP] set propagateBlks [getPropagatedBlockList $blk $dir] set propBlks {} foreach blkDir $propagateBlks { lappend propBlks [lindex $blkDir 0] } # For propagate mode only. If H location is already obtained for the first block in # the propagating block list, the old location information will be returned. # This method saves tremendous time if the topology change will be propagated through # many blocks. if { $Propagate == 1 && [llength $locatorH_prop] > 1 && $dir != "ALL" && \ [lsearch $locatorH_prop $blk] > 3 } { # Skip the H calculation if it is already calculated for one block among this # propagating set. Return the first four elements of the list as the location. return [lrange $locatorH_prop 0 3] } # # Improve the performance by simlifying the method of obtaining the ogrid_i/j/k. # The old method above has to go through lots of iterations to decide the cooresponding ijk # index for the H region. Moreover, its guessing scheme is based on the normalized dimention # so the H region location highly depends on the connector distribution. # # Determine the 2 indices (J and K) of H domain given one (I) of butterfly faces. # # index3 index4 # Jmax o---?-------?---o o---------------o # | | | | # | | | | # | | | | # | | | | # index2 ? o-------o | | o-------o | # | | | | | | | | # | | | | | | | | # | | | | | | | | # index1 ? o-------o | | o-------o | # | | | | # | | | | # | | | | # Jmin=1 o---------------o Kmin=1 o---------------o Kmax # # Imin butterfly face Imax butterfly face # # Obtain the grid points, index 1~4, and use their JK indices to locate the H region. set ogrid_k 2 # Case study: max1 VS ind1_min and ind1_max; max2 VS ind2_min and ind2_max. # # Direction: I J K # ogrid_i loop (1,max1_i,1) (max1_i,1,1) (max1_i,1,1) # blkGetIJK indice (max1_i,1,1) (max1_i,1,1) (max1_i,1,1) # ogrid_j loop (1,1,max2_i) (1,1,max2_i) (1,max2_i,1) # blkGetIJK indice (1,max2_i,1) (1,max2_i,1) (1,max2_i,1) # set iSpacing {} set iLength 0.0 set corner1_Pts {} set iPts {} for { set ii 1 } { $ii < $max1 } { incr ii 1 } { set pt [gg::blkGetPt $blk [blkGetIJK $dir $ii 1 1] ] set pt_ip1 [gg::blkGetPt $blk [blkGetIJK $dir [expr $ii+1] 1 1] ] lappend iPts $pt set incr [GetDist $pt $pt_ip1] set iLength [expr $iLength + $incr] lappend iSpacing $incr } set targetLength_1 [expr $iLength *(1.0-[lindex $oScaleFac 0]) / 2.0] set targetLength_2 [expr $iLength - $targetLength_1 ] set testLength 0.0 for { set ii 1 } { $ii < $max1 } { incr ii 1 } { set testLength [expr $testLength + [lindex $iSpacing [expr $ii-1]]] if { [expr abs( $targetLength_1 - $testLength )] < $tol || [expr abs( $targetLength_2 - $testLength )] < $tol || [expr abs( $testLength - $targetLength_1)] < [lindex $iSpacing [expr $ii-1]] || [expr abs( $testLength - $targetLength_2)] < [lindex $iSpacing [expr $ii-1]] } { lappend corner1_Pts [expr $ii+1] } } set ogrid_i [lindex $corner1_Pts 0] if { $ogrid_i == 1 } { set ogrid_i 2 } set ind1_min $ogrid_i set ind1_max [lindex $corner1_Pts [expr [llength $corner1_Pts]-1]] if { $ind1_max == $max1 } { set ind1_max [expr $max1-1] } set jSpacing {} set jLength 0.0 set corner2_Pts {} set jPts {} for { set ii 1 } { $ii < $max2 } { incr ii 1 } { set pt [gg::blkGetPt $blk [blkGetIJK $dir 1 $ii 1] ] set pt_jp1 [gg::blkGetPt $blk [blkGetIJK $dir 1 [expr $ii+1] 1] ] lappend jPts $pt set incr [GetDist $pt $pt_jp1] set jLength [expr $jLength + $incr] lappend jSpacing $incr } set targetLength_1 [expr $jLength *(1.0-[lindex $oScaleFac 1]) / 2.0] set targetLength_2 [expr $jLength - $targetLength_1 ] set testLength 0.0 for { set ii 1 } { $ii < $max2 } { incr ii 1 } { set testLength [expr $testLength + [lindex $jSpacing [expr $ii-1]]] if { [expr abs( $targetLength_1 - $testLength )] < $tol || [expr abs( $targetLength_2 - $testLength )] < $tol || [expr abs( $testLength - $targetLength_1)] < [lindex $jSpacing [expr $ii-1]] || [expr abs( $testLength - $targetLength_2)] < [lindex $jSpacing [expr $ii-1]] } { lappend corner2_Pts [expr $ii+1] } } set ogrid_j [lindex $corner2_Pts 0] if { $ogrid_j == 1 } { set ogrid_j 2 } set ind2_min $ogrid_j set ind2_max [lindex $corner2_Pts [expr [llength $corner2_Pts]-1]] if { $ind2_max == $max2 } { set ind2_max [expr $max2-1] } # Obtain the dimension index for the third direction when ALL is applied. if { $dir == "ALL" } { set kSpacing {} set kLength 0.0 set corner3_Pts {} set kPts {} for { set ii 1 } { $ii < $ind3_max } { incr ii 1 } { set pt [gg::blkGetPt $blk "1 1 $ii"] set pt_kp1 [gg::blkGetPt $blk "1 1 [expr $ii+1]"] lappend kPts $pt set incr [GetDist $pt $pt_kp1] set kLength [expr $kLength + $incr] lappend kSpacing $incr } set targetLength_1 [expr $kLength *(1.0-[lindex $oScaleFac 2]) / 2.0] set targetLength_2 [expr $kLength - $targetLength_1 ] set testLength 0.0 for { set ii 1 } { $ii < $ind3_max } { incr ii 1 } { set testLength [expr $testLength + [lindex $kSpacing [expr $ii-1]]] if { [expr abs( $targetLength_1 - $testLength )] < $tol || [expr abs( $targetLength_2 - $testLength )] < $tol || [expr abs( $testLength - $targetLength_1)] < [lindex $kSpacing [expr $ii-1]] || [expr abs( $testLength - $targetLength_2)] < [lindex $kSpacing [expr $ii-1]] } { lappend corner3_Pts [expr $ii+1] } } set ogrid_k [lindex $corner3_Pts 0] if { $ogrid_k == 1 } { set ogrid_k 2 } set ind3_min $ogrid_k set ind3_max [lindex $corner3_Pts [expr [llength $corner3_Pts]-1]] } # Please note this list should show the corresponding block. Otherwise, the H locator # will be the same even when multiple propagating cases are selected. if { $Propagate == 1 && $dir != "ALL" } { set locatorH_prop [list $ind1_min $ind1_max $ind2_min $ind2_max] set locatorH_prop [concat $locatorH_prop $propBlks] } set HLocation [list $ind1_min $ind1_max $ind2_min $ind2_max $ind3_min $ind3_max] return $HLocation } ######################################################################################################## proc blkMakeBflyConnectors { blk dir var {temp 0}} { global oFraction oDimension Propagate global oScaleFac scriptDir # Warning if oScaleFac component is larger than 1.0. set oScale_1 [lindex $oScaleFac 0] set oScale_2 [lindex $oScaleFac 1] set oScale_3 [lindex $oScaleFac 2] if { $oScale_1 > 1.0 || $oScale_2 > 1.0 || $oScale_3 > 1.0 || $oScale_1 < 0.0 || \ $oScale_2 < 0.0 || $oScale_3 < 0.0 } { ErrorMsg "Invalid scaling factor input!" return } # Skip the H dimension index calculation if propagate is applied to adjacent blocks. #global ind1_min ind1_max ind2_min ind2_max upvar $var con gg::blkReport $blk blkInfo STRUCTURE if { $blkInfo(type) != "STRUCTURED" } { return 0 } set id [lindex $blkInfo(dimensions) 0] set jd [lindex $blkInfo(dimensions) 1] set kd [lindex $blkInfo(dimensions) 2] set ind3_min 1 if {$dir == "I"} { set max1 $jd set max2 $kd set ind3_max $id set faceID 0 } elseif {$dir == "J"} { set max1 $id set max2 $kd set ind3_max $jd set faceID 2 } elseif {$dir == "K"} { set max1 $id set max2 $jd set ind3_max $kd set faceID 4 } else { set max1 $id set max2 $jd set ind3_max $kd set faceID 4 } # Move the H domain locator out of this procedure so that it can be skipped if Propagate # is applied. set ind3_beg $ind3_min set ind3_end $ind3_max set HLocationData [HDomLocator $blk $dir $max1 $max2 $ind3_min $ind3_max $faceID] set ind1_min [lindex $HLocationData 0] set ind1_max [lindex $HLocationData 1] set ind2_min [lindex $HLocationData 2] set ind2_max [lindex $HLocationData 3] if { $dir == "ALL" } { set ind3_min [lindex $HLocationData 4] set ind3_max [lindex $HLocationData 5] } #-- Create the ind2_min conn on ind3_min face set ind3 $ind3_min set ind2 $ind2_min gg::conBegin gg::segBegin -type 3D_LINE for {set ind1 $ind1_min} {$ind1 <= $ind1_max} {incr ind1} { if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $blk $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} con(ind2_min,ind3_min) ] { set con(ind2_min,ind3_min) [getConnectorByEndPoints [gg::blkGetPt $blk [blkGetIJK $dir $ind1_min $ind2 $ind3]] $pt] } #-- Create the ind2_max conn on ind3_min face set ind3 $ind3_min set ind2 $ind2_max gg::conBegin gg::segBegin -type 3D_LINE for {set ind1 $ind1_min} {$ind1 <= $ind1_max} {incr ind1} { if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $blk $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} con(ind2_max,ind3_min) ] { set con(ind2_max,ind3_min) [getConnectorByEndPoints [gg::blkGetPt $blk [blkGetIJK $dir $ind1_min $ind2 $ind3]] $pt] } #-- Create the ind1_min conn on ind3_min face set ind3 $ind3_min set ind1 $ind1_min gg::conBegin gg::segBegin -type 3D_LINE for {set ind2 $ind2_min} {$ind2 <= $ind2_max} {incr ind2} { if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $blk $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} con(ind1_min,ind3_min) ] { set con(ind1_min,ind3_min) [getConnectorByEndPoints [gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2_min $ind3]] $pt] } #-- Create the ind1_max conn on ind3_min face set ind3 $ind3_min set ind1 $ind1_max gg::conBegin gg::segBegin -type 3D_LINE for {set ind2 $ind2_min} {$ind2 <= $ind2_max} {incr ind2} { if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $blk $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} con(ind1_max,ind3_min) ] { set con(ind1_max,ind3_min) [getConnectorByEndPoints [gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2_min $ind3]] $pt] } #-- Create the ind2_min conn on ind3_max face set ind3 $ind3_max set ind2 $ind2_min gg::conBegin gg::segBegin -type 3D_LINE for {set ind1 $ind1_min} {$ind1 <= $ind1_max} {incr ind1} { if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $blk $pt return 0 } gg::segAddControlPt $pt } gg::segEnd ################################################################################### if [ catch {gg::conEnd} con(ind2_min,ind3_max) ] { set con(ind2_min,ind3_max) [getConnectorByEndPoints [gg::blkGetPt $blk [blkGetIJK $dir $ind1_min $ind2 $ind3]] $pt] } #-- Create the ind2_max conn on ind3_max face set ind3 $ind3_max set ind2 $ind2_max gg::conBegin gg::segBegin -type 3D_LINE for {set ind1 $ind1_min} {$ind1 <= $ind1_max} {incr ind1} { if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $blk $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} con(ind2_max,ind3_max) ] { set con(ind2_max,ind3_max) [getConnectorByEndPoints [gg::blkGetPt $blk [blkGetIJK $dir $ind1_min $ind2 $ind3]] $pt] } #-- Create the ind1_min conn on ind3_max face set ind3 $ind3_max set ind1 $ind1_min gg::conBegin gg::segBegin -type 3D_LINE for {set ind2 $ind2_min} {$ind2 <= $ind2_max} {incr ind2} { if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $blk $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} con(ind1_min,ind3_max) ] { set con(ind1_min,ind3_max) [getConnectorByEndPoints [gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2_min $ind3]] $pt] } #-- Create the ind1_max conn on ind3_max face set ind3 $ind3_max set ind1 $ind1_max gg::conBegin gg::segBegin -type 3D_LINE for {set ind2 $ind2_min} {$ind2 <= $ind2_max} {incr ind2} { if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $blk $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} con(ind1_max,ind3_max) ] { set con(ind1_max,ind3_max) [getConnectorByEndPoints [gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2_min $ind3]] $pt] } #-- Create the ind2_min conn on ind1_min face set ind1 $ind1_min set ind2 $ind2_min gg::conBegin gg::segBegin -type 3D_LINE for {set ind3 $ind3_min} {$ind3 <= $ind3_max} {incr ind3} { if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $blk $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} con(ind2_min,ind1_min) ] { set con(ind2_min,ind1_min) [getConnectorByEndPoints [gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3_min]] $pt] } #-- Create the ind2_max conn on ind1_min face set ind1 $ind1_min set ind2 $ind2_max gg::conBegin gg::segBegin -type 3D_LINE for {set ind3 $ind3_min} {$ind3 <= $ind3_max} {incr ind3} { if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $blk $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} con(ind2_max,ind1_min) ] { set con(ind2_max,ind1_min) [getConnectorByEndPoints [gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3_min]] $pt] # ConFailed $blk $con(ind2_max,ind1_min) # return 0 } #-- Create the ind2_min conn on ind1_max face set ind1 $ind1_max set ind2 $ind2_min gg::conBegin gg::segBegin -type 3D_LINE for {set ind3 $ind3_min} {$ind3 <= $ind3_max} {incr ind3} { if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $blk $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} con(ind2_min,ind1_max) ] { set con(ind2_min,ind1_max) [getConnectorByEndPoints [gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3_min]] $pt] } #-- Create the ind2_max conn on ind1_max face set ind1 $ind1_max set ind2 $ind2_max gg::conBegin gg::segBegin -type 3D_LINE for {set ind3 $ind3_min} {$ind3 <= $ind3_max} {incr ind3} { if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $blk $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} con(ind2_max,ind1_max) ] { set con(ind2_max,ind1_max) [getConnectorByEndPoints [gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3_min]] $pt] } #-- Create the corner1 conn on ind3_min face set ind3 $ind3_beg set ind1 1 set ind2 1 if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt1] { DomPtFailed $blk $pt1 return 0 } set ind3 $ind3_min set ind1 $ind1_min set ind2 $ind2_min if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt2] { DomPtFailed $blk $pt2 return 0 } gg::conBegin gg::segBegin -type 3D_LINE gg::segAddControlPt $pt1 gg::segAddControlPt $pt2 gg::segEnd if [ catch {gg::conEnd} con(corner1,ind3_min) ] { set con(corner1,ind3_min) [getConnectorByEndPoints $pt1 $pt2] } #-- Create the corner2 conn on ind3_min face set ind3 $ind3_beg set ind1 $max1 set ind2 1 if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt1] { DomPtFailed $blk $pt1 return 0 } set ind3 $ind3_min set ind1 $ind1_max set ind2 $ind2_min if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt2] { DomPtFailed $blk $pt2 return 0 } gg::conBegin gg::segBegin -type 3D_LINE gg::segAddControlPt $pt1 gg::segAddControlPt $pt2 gg::segEnd if [ catch {gg::conEnd} con(corner2,ind3_min) ] { set con(corner2,ind3_min) [getConnectorByEndPoints $pt1 $pt2] } #-- Create the corner3 conn on ind3_min face set ind3 $ind3_beg set ind1 $max1 set ind2 $max2 if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt1] { DomPtFailed $blk $pt1 return 0 } set ind3 $ind3_min set ind1 $ind1_max set ind2 $ind2_max if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt2] { DomPtFailed $blk $pt2 return 0 } gg::conBegin gg::segBegin -type 3D_LINE gg::segAddControlPt $pt1 gg::segAddControlPt $pt2 gg::segEnd if [ catch {gg::conEnd} con(corner3,ind3_min) ] { set con(corner3,ind3_min) [getConnectorByEndPoints $pt1 $pt2] } #-- Create the corner4 conn on ind3_min face set ind3 $ind3_beg set ind1 1 set ind2 $max2 if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt1] { DomPtFailed $blk $pt1 return 0 } set ind3 $ind3_min set ind1 $ind1_min set ind2 $ind2_max if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt2] { DomPtFailed $blk $pt2 return 0 } gg::conBegin gg::segBegin -type 3D_LINE gg::segAddControlPt $pt1 gg::segAddControlPt $pt2 gg::segEnd if [ catch {gg::conEnd} con(corner4,ind3_min) ] { set con(corner4,ind3_min) [getConnectorByEndPoints $pt1 $pt2] } #-- Create the corner1 conn on ind3_max face set ind3 $ind3_end set ind1 1 set ind2 1 if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt1] { DomPtFailed $blk $pt1 return 0 } set ind3 $ind3_max set ind1 $ind1_min set ind2 $ind2_min if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt2] { DomPtFailed $blk $pt2 return 0 } gg::conBegin gg::segBegin -type 3D_LINE gg::segAddControlPt $pt1 gg::segAddControlPt $pt2 gg::segEnd if [ catch {gg::conEnd} con(corner1,ind3_max) ] { set con(corner1,ind3_max) [getConnectorByEndPoints $pt1 $pt2] } #-- Create the corner2 conn on ind3_max face set ind3 $ind3_end set ind1 $max1 set ind2 1 if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt1] { DomPtFailed $blk $pt1 return 0 } set ind3 $ind3_max set ind1 $ind1_max set ind2 $ind2_min if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt2] { DomPtFailed $blk $pt2 return 0 } gg::conBegin gg::segBegin -type 3D_LINE gg::segAddControlPt $pt1 gg::segAddControlPt $pt2 gg::segEnd if [ catch {gg::conEnd} con(corner2,ind3_max) ] { set con(corner2,ind3_max) [getConnectorByEndPoints $pt1 $pt2] } #-- Create the corner3 conn on ind3_max face set ind3 $ind3_end set ind1 $max1 set ind2 $max2 if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt1] { DomPtFailed $blk $pt1 return 0 } set ind3 $ind3_max set ind1 $ind1_max set ind2 $ind2_max if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt2] { DomPtFailed $blk $pt2 return 0 } gg::conBegin gg::segBegin -type 3D_LINE gg::segAddControlPt $pt1 gg::segAddControlPt $pt2 gg::segEnd if [ catch {gg::conEnd} con(corner3,ind3_max) ] { set con(corner3,ind3_max) [getConnectorByEndPoints $pt1 $pt2] } #-- Create the corner4 conn on ind3_max face set ind3 $ind3_end set ind1 1 set ind2 $max2 if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt1] { DomPtFailed $blk $pt1 return 0 } set ind3 $ind3_max set ind1 $ind1_min set ind2 $ind2_max if [catch {gg::blkGetPt $blk [blkGetIJK $dir $ind1 $ind2 $ind3]} pt2] { DomPtFailed $blk $pt2 return 0 } gg::conBegin gg::segBegin -type 3D_LINE gg::segAddControlPt $pt1 gg::segAddControlPt $pt2 gg::segEnd if [ catch {gg::conEnd} con(corner4,ind3_max) ] { set con(corner4,ind3_max) [getConnectorByEndPoints $pt1 $pt2] } return 1 } proc getConnectorByEndPoints { pt1 pt2 } { set tol [gg::tolNode] foreach con [gg::conGetAll] { set pta [gg::conGetPt $con -arc 0] set ptb [gg::conGetPt $con -arc 1] set dist_1a [GetDist $pt1 $pta] set dist_1b [GetDist $pt1 $ptb] set dist_2a [GetDist $pt2 $pta] set dist_2b [GetDist $pt2 $ptb] if { ($dist_1a < $tol && $dist_2b < $tol) || ($dist_1b < $tol && $dist_2a < $tol) } { return $con } } puts "error: No connector found ($pt1, $pt2)" abort } proc getDomainByCorners { pt1 pt2 pt3 pt4 } { foreach dom [gg::domGetAll] { set pt {} gg::domReport $dom dInfo STRUCTURE lappend pt [gg::domGetPt $dom "1 1"] lappend pt [gg::domGetPt $dom "[lindex $dInfo(dimensions) 0] 1"] lappend pt [gg::domGetPt $dom "1 [lindex $dInfo(dimensions) 1]"] lappend pt [gg::domGetPt $dom $dInfo(dimensions)] if { [lsearch $pt $pt1]!=-1 && [lsearch $pt $pt2]!=-1 && [lsearch $pt $pt3]!=-1 && [lsearch $pt $pt4]!=-1 } { return $dom } } puts "error: No domain found ($pt1, $pt2, $pt3, $pt4)" abort } proc domMakeBflyDomains { dom } { # Read in the plot 3D file of the structured domain on this face for projection. global butterflyDBFile global oFraction oDimension set splitEdges 1 gg::domReport $dom domInfo "STRUCTURE" if { $domInfo(type) != "STRUCTURED" } { return 0 } set id [lindex $domInfo(dimensions) 0] set jd [lindex $domInfo(dimensions) 1] #-- Create connectors domMakeBflyConnectors $dom con 0 gg::conDim "$con(2,0) $con(2,1)" $id gg::conDim "$con(0,2) $con(1,2)" $jd gg::conDim "$con(0,0) $con(0,1) $con(1,0) $con(1,1)" $oDimension #-- Center domain # H region domain gg::domBegin -type STRUCTURED gg::edgeBegin gg::edgeAddCon $con(2,0) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(1,2) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(2,1) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(0,2) gg::edgeEnd gg::domEnd #-- Ogrid domain 1 set edge1 [lindex [gg::domGetEdge $dom 1] 0] gg::domBegin -type STRUCTURED gg::edgeBegin foreach cn $edge1 { gg::edgeAddCon $cn } gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(1,0) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(2,0) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(0,0) gg::edgeEnd set doms(2,0) [gg::domEnd] set num_in_edge [llength $edge1] if {$splitEdges && $num_in_edge > 1} { #-- split opposing con set opcon $con(2,0) incr num_in_edge -1 for {set ii 0} {$ii < $num_in_edge} {incr ii} { set cn [lindex $edge1 $ii] set i [gg::conDim $cn] set pt [gg::conGetPt $opcon $i] set opcon [gg::conSplit $opcon $pt] } } #-- Ogrid domain 2 set edge1 [lindex [gg::domGetEdge $dom 2] 0] gg::domBegin -type STRUCTURED gg::edgeBegin foreach cn $edge1 { gg::edgeAddCon $cn } gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(1,1) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(1,2) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(1,0) gg::edgeEnd set doms(1,2) [gg::domEnd] set num_in_edge [llength $edge1] if {$splitEdges && $num_in_edge > 1} { #-- split opposing con set opcon $con(1,2) incr num_in_edge -1 for {set ii 0} {$ii < $num_in_edge} {incr ii} { set cn [lindex $edge1 $ii] set i [gg::conDim $cn] set pt [gg::conGetPt $opcon $i] set opcon [gg::conSplit $opcon $pt] } } #-- Ogrid domain 3 set edge1 [lindex [gg::domGetEdge $dom 3] 0] gg::domBegin -type STRUCTURED gg::edgeBegin foreach cn $edge1 { gg::edgeAddCon $cn } gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(0,1) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(2,1) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(1,1) gg::edgeEnd set doms(2,1) [gg::domEnd] set num_in_edge [llength $edge1] if {$splitEdges && $num_in_edge > 1} { #-- split opposing con set opcon $con(j_max) incr num_in_edge -1 for {set ii $num_in_edge} {$ii > 0} {incr ii -1} { set cn [lindex $edge1 $ii] set i [gg::conDim $cn] set pt [gg::conGetPt $opcon $i] set opcon [gg::conSplit $opcon $pt] } } #-- Ogrid domain 4 set edge1 [lindex [gg::domGetEdge $dom 4] 0] gg::domBegin -type STRUCTURED gg::edgeBegin foreach cn $edge1 { gg::edgeAddCon $cn } gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(0,0) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(0,2) gg::edgeEnd gg::edgeBegin gg::edgeAddCon $con(0,1) gg::edgeEnd set doms(0,2) [gg::domEnd] set num_in_edge [llength $edge1] if {$splitEdges && $num_in_edge > 1} { #-- split opposing con set opcon $con(0,2) incr num_in_edge -1 for {set ii $num_in_edge} {$ii > 0} {incr ii -1} { set cn [lindex $edge1 $ii] set i [gg::conDim $cn] set pt [gg::conGetPt $opcon $i] set opcon [gg::conSplit $opcon $pt] } } gg::domDisp $dom -style OFF return 1 } ##################################################################### # PROC: dom2BflyCons # Make a butterfly con topology given 1 structured domain # proc domMakeBflyConnectors { dom var {temp 0} } { global oFraction oDimension upvar $var conlist gg::domReport $dom domInfo STRUCTURE set id [lindex $domInfo(dimensions) 0] set jd [lindex $domInfo(dimensions) 1] set id2 [expr $id/2] set jd2 [expr $jd/2] set dist(i,tot) 0.0 set dist(i,1) 0.0 for {set ii 2} {$ii <= $id} {incr ii} { set im1 [expr $ii-1] set pt1 [gg::domGetPt $dom "$im1 $jd2" ] set pt2 [gg::domGetPt $dom "$ii $jd2" ] set dist(i,$ii) [expr $dist(i,$im1)+[GetDist $pt1 $pt2]] set dist(i,tot) $dist(i,$ii) } set dist(j,tot) 0.0 set dist(j,1) 0.0 for {set ii 2} {$ii <= $jd} {incr ii} { set im1 [expr $ii-1] set pt1 [gg::domGetPt $dom "$id2 $im1" ] set pt2 [gg::domGetPt $dom "$id2 $ii" ] set dist(j,$ii) [expr $dist(j,$im1)+[GetDist $pt1 $pt2]] set dist(j,tot) $dist(j,$ii) } if { $dist(i,tot) < $dist(j,tot) } { set dist_target [expr $dist(i,tot)*$oFraction] } else { set dist_target [expr $dist(j,tot)*$oFraction] } for {set ii 2} {$ii <= $id} {incr ii} { if { $dist(i,$ii) > $dist_target } { set d1 [expr $dist_target - $dist(i,[expr $ii-1])] set d2 [expr $dist(i,$ii) - $dist_target] if { $d1 < $d2 } { set ogrid_i [expr $ii-1] } else { set ogrid_i $ii } break } } for {set ii 2} {$ii <= $jd} {incr ii} { if { $dist(j,$ii) > $dist_target } { set d1 [expr $dist_target - $dist(j,[expr $ii-1])] set d2 [expr $dist(j,$ii) - $dist_target] if { $d1 < $d2 } { set ogrid_j [expr $ii-1] } else { set ogrid_j $ii } break } } if {$ogrid_i > $id2} { set ogrid_i $id2 } if {$ogrid_i < 2 } { set ogrid_i 2 } if {$ogrid_j > $jd2} { set ogrid_j $jd2 } if {$ogrid_j < 2 } { set ogrid_j 2 } set i_min $ogrid_i set i_max [expr $id-$ogrid_i+1] set j_min $ogrid_j set j_max [expr $jd-$ogrid_j+1] #-- Create the j_min conn set j $j_min set con_dbs "" gg::conBegin gg::segBegin -type 3D_LINE for {set i $i_min} {$i <= $i_max} {incr i} { if [catch {gg::domGetPt $dom "$i $j"} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $dom $pt return 0 } if [catch {gg::domGetPt $dom -db "$i $j"} dbpt] { #-- point not on DB } else { #-- point on DB - dbpt = u,v,s set srf [lindex $dbpt 2] set ind [lsearch $con_dbs $srf] if { $ind < 0 } { lappend con_dbs $srf } } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} conlist(2,0) ] { ConFailed $dom $conlist(2,0) return 0 } #-- Create the j_max conn set j $j_max gg::conBegin gg::segBegin -type 3D_LINE for {set i $i_min} {$i <= $i_max} {incr i} { if [catch {gg::domGetPt $dom "$i $j"} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $dom $pt return 0 } gg::segAddControlPt $pt } gg::segEnd set conlist(2,1) [gg::conEnd] #-- Create the i_min conn set i $i_min gg::conBegin gg::segBegin -type 3D_LINE for {set j $j_min} {$j <= $j_max} {incr j} { if [catch {gg::domGetPt $dom "$i $j"} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $dom $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} conlist(0,2) ] { ConFailed $dom $conlist(0,2) return 0 } #-- Create the i_max conn set i $i_max gg::conBegin gg::segBegin -type 3D_LINE for {set j $j_min} {$j <= $j_max} {incr j} { if [catch {gg::domGetPt $dom "$i $j"} pt] { gg::segEnd -nosave gg::conEnd -nosave DomPtFailed $dom $pt return 0 } gg::segAddControlPt $pt } gg::segEnd if [ catch {gg::conEnd} conlist(1,2) ] { ConFailed $dom $conlist(1,2) return 0 } #-- Create the corner1 conn set i 1 set j 1 if [catch {gg::domGetPt $dom "$i $j"} pt1] { DomPtFailed $dom $pt1 return 0 } set i $i_min set j $j_min if [catch {gg::domGetPt $dom "$i $j"} pt2] { DomPtFailed $dom $pt2 return 0 } gg::conBegin gg::segBegin -type 3D_LINE gg::segAddControlPt $pt1 gg::segAddControlPt $pt2 gg::segEnd if [ catch {gg::conEnd} conlist(0,0) ] { ConFailed $dom $conlist(0,0) return 0 } #-- Create the corner2 conn set i $id set j 1 if [catch {gg::domGetPt $dom "$i $j"} pt1] { DomPtFailed $dom $pt1 return 0 } set i $i_max set j $j_min if [catch {gg::domGetPt $dom "$i $j"} pt2] { DomPtFailed $dom $pt2 return 0 } gg::conBegin gg::segBegin -type 3D_LINE gg::segAddControlPt $pt1 gg::segAddControlPt $pt2 gg::segEnd if [ catch {gg::conEnd} conlist(1,0) ] { ConFailed $dom $conlist(1,0) return 0 } #-- Create the corner3 conn set i $id set j $jd if [catch {gg::domGetPt $dom "$i $j"} pt1] { DomPtFailed $dom $pt1 return 0 } set i $i_max set j $j_max if [catch {gg::domGetPt $dom "$i $j"} pt2] { DomPtFailed $dom $pt2 return 0 } gg::conBegin gg::segBegin -type 3D_LINE gg::segAddControlPt $pt1 gg::segAddControlPt $pt2 gg::segEnd if [ catch {gg::conEnd} conlist(1,1) ] { ConFailed $dom $conlist(1,1) return 0 } #-- Create the corner4 conn set i 1 set j $jd if [catch {gg::domGetPt $dom "$i $j"} pt1] { DomPtFailed $dom $pt1 return 0 } set i $i_min set j $j_max if [catch {gg::domGetPt $dom "$i $j"} pt2] { DomPtFailed $dom $pt2 return 0 } gg::conBegin gg::segBegin -type 3D_LINE gg::segAddControlPt $pt1 gg::segAddControlPt $pt2 gg::segEnd if [ catch {gg::conEnd} conlist(0,1) ] { ConFailed $dom $conlist(0,1) return 0 } return 1 } proc buildLists { } { global Structured_Blocks Structured_Domains Original_Connectors structuredBlkList set Original_Connectors [gg::conGetAll] set Structured_Domains {} foreach dom [ gg::domGetAll ] { gg::domReport $dom data STRUCTURE if { $data(type) == "STRUCTURED" } { lappend Structured_Domains $dom } } set Structured_Blocks {} set structuredBlkList {} foreach blk [gg::blkGetAll] { gg::blkReport $blk data STRUCTURE if { [string compare $data(type) STRUCTURED] == 0 } { lappend Structured_Blocks $blk lappend structuredBlkList "[gg::blkName $blk]" } } } buildLists global all_doms all_doms_style all_doms_density selected_doms set all_doms [gg::domGetAll] set all_doms_style {} set all_doms_density {} foreach dom $all_doms { lappend all_doms_style [gg::domDisp $dom -style] lappend all_doms_density [gg::domDisp $dom -density] gg::domDisp $dom -style OFF } set Selected_Domains {} set Selected_Blocks {} #CLEANUP CODE proc restoreOriginal {} { global all_doms all_doms_style all_doms_density for {set i 0} {$i < [llength $all_doms]} {incr i} { catch { gg::domDisp [lindex $all_doms $i] -style [lindex $all_doms_style $i] -norefresh } } } ##################################################################### # PROC: UpdateDisplay # Force the Gridgen viewer window to refresh # proc UpdateDisplay {} { gg::dispLight "0 0 0" update } ##################################################################### # PROC: DomSelect # This proc is called everytime a domain is picked # proc DomSelect {} { global Structured_Domains Preview gg::domDisp ALL -style OFF CleanupCons #-- Get the selected domains set sel [.right.top.list curselection] foreach csel $sel { set dom [lindex $Structured_Domains $csel] if { $Preview } { if ![domMakeBflyConnectors $dom con] { CleanupCons 1 break } } else { gg::domDisp $dom -style WIREFRAME } } set dom_selection $sel UpdateDisplay } ##################################################################### # PROC: BlkSelect # This proc is called everytime a block is picked # proc BlkSelect {} { global Structured_Blocks Direction Preview Propagate foreach blk [gg::blkGetAll] { HideBlock $blk } CleanupCons set sel [.right.top.list curselection] foreach csel $sel { set blk [lindex $Structured_Blocks $csel] } } proc updateDispBlks {} { global Preview Propagate Direction Structured_Blocks set sel [.right.top.list curselection] set selBlocks {} foreach csel $sel { set blk [lindex $Structured_Blocks $csel] lappend selBlocks $blk } # Align all selected blocks with the 1st one in the list once Propagate # is applied. if { $Propagate == 1 && $Direction != "ALL" } { gg::blkSpecifyIJK $selBlocks -align_with [lindex $selBlocks 0] } foreach csel $sel { set blk [lindex $Structured_Blocks $csel] set propBlkList [getPropagatedBlockList $blk $Direction] set alignBlkList [lreplace $propBlkList 0 0] set alignBlks {} foreach blkDir $alignBlkList { lappend alignBlks [lindex $blkDir 0] } if { $Preview } { if { $Direction != "ALL" } { if { $Propagate == 0 } { blkMakeBflyConnectors $blk $Direction cons } else { foreach blk_dir $propBlkList { blkMakeBflyConnectors [lindex $blk_dir 0] [lindex $blk_dir 1] cons } } } else { blkMakeBflyConnectors $blk ALL cons } } } UpdateDisplay } ##################################################################### # PROC: HighlightBlock # Highlight a given block # proc HighlightBlock {blk} { set faces [gg::blkGetFace $blk] foreach doms $faces { gg::domDisp $doms -style WIREFRAME } } ##################################################################### # PROC: HideBlock # Hide a given block # proc HideBlock {blk} { set faces [gg::blkGetFace $blk] foreach doms $faces { gg::domDisp $doms -style OFF } } ##################################################################### # PROC: CleanupCons # Cleanup temporary connectors # proc CleanupCons {{force "0"}} { global Original_Connectors set cons [gg::conGetAll] if { [llength $cons] == [llength $Original_Connectors] } { return } foreach con $cons { if { [lsearch $Original_Connectors $con] >= 0 } { continue } if { $force } { gg::conDelete $con -force } else { gg::conDelete $con } } } # Clean up the original interior cons on butterfly faces if multi-dom faces occurs. proc removeMultiDomInteriorCons {} { set allDoms [gg::domGetAll] set goodConList {} foreach dom $allDoms { gg::domReport $dom data REFERENCE foreach con $data(refCons) { set conId [lsearch $goodConList $con] if { $conId >= 0 } { lreplace $goodConList $conId $conId } else { lappend goodConList $con } } } foreach con [gg::conGetAll] { set conId [lsearch $goodConList $con] if { $conId == -1 } { gg::conDelete $con } } } ##################################################################### # PROC: RevertDisplay # Revert the dom display to original values. # proc RevertDisplay {} { global all_doms all_doms_style all_doms_density if { [llength $all_doms] < 1 } { return } #-- Revert dom display foreach dom $all_doms style $all_doms_style density $all_doms_density { catch { gg::domDisp $dom -style $style -density $density } } } ##################################################################### # PROC: quit # Called for a normal exit # proc quit {} { global t scriptDir # Need to restore the old grids if cancel is pressed. gg::conDelete [gg::conGetAll] gg::gridImport [file join $scriptDir "startUpGridFile.gg"] gg::domDisp [gg::domGetAll] -style WIREFRAME exit } ##################################################################### # PROC: abort # Called for a user-initiated abort (no errors) # proc abort {} { CleanupCons 1 quit } ##################################################################### # PROC: ConFailed # Error handling routine for connector creation failures. # proc ConFailed { dom msg } { global selected_doms Structured_Domains set i [lsearch $Structured_Domains $dom] if { $i == -1 } { set name "unknown" } catch {unset selected_doms} set msg "Failed to create connector while processing domain: $name. This is probably due to the creation of a duplicate connector." ErrorMsg $msg } ##################################################################### # PROC: DomPtFailed # Error handling routine for domGetPt failures. # proc DomPtFailed { dom emsg } { global selected_doms str_doms dom_names set i [lsearch $str_doms $dom] if { $i == -1 } { set name "unknown" } else { set name [lindex $dom_names $i] } catch {unset selected_doms} set msg "Failed to get point while processing domain: $name. $emsg" ErrorMsg $msg } ###################################################################### # PROC: ErrorMsg # Error popup message # proc ErrorMsg {msg {title "Error"}} { tk_messageBox -message "$msg" -type ok -icon error -title $title } proc createBflyDBSurf { blk dir } { global butterflyDBFile scriptDir set butterflyDomList {} set butterflyDBFile [file join $scriptDir "butterflyDB.grd"] set butterflyDoms {} set faceList [gg::blkGetFace $blk {IMIN IMAX JMIN JMAX KMIN KMAX}] set domFacImin [lindex $faceList 0] set domFacImax [lindex $faceList 1] set domFacJmin [lindex $faceList 2] set domFacJmax [lindex $faceList 3] set domFacKmin [lindex $faceList 4] set domFacKmax [lindex $faceList 5] set domNumImin [llength $domFacImin] set domNumImax [llength $domFacImax] set domNumJmin [llength $domFacJmin] set domNumJmax [llength $domFacJmax] set domNumKmin [llength $domFacKmin] set domNumKmax [llength $domFacKmax] if { $dir == "I" } { foreach dom $domFacImin { lappend butterflyDoms $dom } foreach dom $domFacImax { lappend butterflyDoms $dom } } elseif { $dir == "J" } { foreach dom $domFacJmin { lappend butterflyDoms $dom } foreach dom $domFacJmax { lappend butterflyDoms $dom } } elseif { $dir == "K" } { foreach dom $domFacKmin { lappend butterflyDoms $dom } foreach dom $domFacKmax { lappend butterflyDoms $dom } } gg::domExport $butterflyDoms $butterflyDBFile -style PLOT3D -format ASCII \ -precision DOUBLE } ###################################################################### # PROC: SwitchMode # This that happen when the mode switches # proc SwitchMode { {dir 0} } { global Mode Selected_Domains Selected_Blocks Propagate Direction global Structured_Blocks if {$Mode == "BLOCKS"} { if { $dir } { set Selected_Blocks [.right.top.list curselection] } else { set Selected_Domains [.right.top.list curselection] } .right.top.list selection clear 0 end .right.top.list configure -listvar structuredBlkList foreach csel $Selected_Blocks { .right.top.list selection set $csel .right.top.list selection set $csel } .left.dir.i configure -state normal .left.dir.j configure -state normal .left.dir.k configure -state normal .left.dir.all configure -state normal if { $Direction == "ALL" } { set Propagate 0 .left.values.propagate configure -state disabled } else { .left.values.propagate configure -state normal } # Disable Propagate if no direction is specified. if { $Direction == "" } { .left.values.propagate configure -state disabled } } else { set Selected_Blocks [.right.top.list curselection] .right.top.list selection clear 0 end .right.top.list configure -listvar Structured_Domains foreach csel $Selected_Domains { .right.top.list selection set $csel } .left.dir.i configure -state disabled .left.dir.j configure -state disabled .left.dir.k configure -state disabled .left.dir.all configure -state disabled .left.values.propagate configure -state disabled set Propagate 0 } Redraw } ###################################################################### # PROC: Redraw # Redraw highlights # proc Redraw {} { global Mode if {$Mode == "BLOCKS" } { BlkSelect # Move the display update part out from the BlkSelect proc to speed up selection. updateDispBlks } else { DomSelect } } proc getDataList { } { global Mode Selected_Domains Selected_Blocks Propagate Direction Structured_Blocks Structured_Domains set t {} if { $Mode == "BLOCKS" } { foreach i [.right.top.list curselection] { lappend t [lindex $Structured_Blocks $i] } } else { foreach i [.right.top.list curselection] { lappend t [lindex $Structured_Domains $i] } } return $t } proc select { } { global Mode Selected_Domains Selected_Blocks Propagate Direction Structured_Blocks Structured_Domains if { $Mode == "BLOCKS" && [llength $Structured_Blocks] <= 0 } { tk_messageBox -title "Error: No Blocks Available" -message "There are no structured blocks in the current grid." -type ok -icon error return } if { $Mode == "DOMS" && [llength $Structured_Domains] <= 0 } { tk_messageBox -title "Error: No Domains Available" -message "There are no structured domains in the current grid." -type ok -icon error return } CleanupCons wm withdraw . if { $Mode == "BLOCKS" } { set tSel [gg::dispPick BLOCK -select [getDataList] -explicit $Structured_Blocks -message \ "Please select blocks for butterfly topology to apply"] .right.top.list selection clear 0 end foreach i $tSel { .right.top.list selection set [lsearch $Structured_Blocks $i] [lsearch $Structured_Blocks $i] } } else { set tSel [gg::dispPick DOMAIN -select [getDataList] -explicit $Structured_Domains -message \ "Please select domains for butterfuly topology to apply"] .right.top.list selection clear 0 end foreach i $tSel { .right.top.list selection set [lsearch $Structured_Domains $i] [lsearch $Structured_Domains $i] } } if {[winfo exists .]} { wm deiconify . } } proc allInList { list1 list2 } { foreach i $list1 { if { [lindex $list2 $i]==-1 } { return 0 } } return 1 } #Function to return face opposite of this one in a block proc getOppositeFace { face block } { foreach f {IMIN IMAX JMIN JMAX KMIN KMAX} { if { [string compare $face [gg::blkGetFace $block $f]]==0 } { switch $f { IMIN { return [gg::blkGetFace $block IMAX] } JMIN { return [gg::blkGetFace $block JMAX] } KMIN { return [gg::blkGetFace $block KMAX] } IMAX { return [gg::blkGetFace $block IMIN] } JMAX { return [gg::blkGetFace $block JMIN] } KMAX { return [gg::blkGetFace $block KMIN] } } } } } proc getNotInList { ilist wlist } { foreach i $wlist { if { [lsearch $ilist $i]==-1 } { return $i } } return ""; } proc getReferencedBlocks { face } { if { [llength [lindex $face 0]]>1 } { gg::domReport [lindex $face 0] cData REFERENCE return $cData(refBlocks) } else { gg::domReport $face cData REFERENCE return $cData(refBlocks) } } proc getPropagatedFaceList { face } { set faceList "$face" set data [getReferencedBlocks $face] set blkList $data foreach blk $data { set cFace [getOppositeFace $face $blk] set faceList "$faceList $cFace" set cData [getReferencedBlocks $cFace] while { [string compare [getNotInList $blkList $cData] ""]!=0 } { set nblk [getNotInList $blkList $cData] set cFace [getOppositeFace $cFace $nblk] set faceList "$faceList $cFace" set blkList "$blkList $nblk" set cData [getReferencedBlocks $cFace] } } return $faceList } proc getParallelDirection { blk1 dirmm blk2 } { set face [gg::blkGetFace $blk1 $dirmm] set retDir "" foreach dir {I J K} { if { [gg::blkGetFace $blk2 ${dir}MIN]==$face || [gg::blkGetFace $blk2 ${dir}MAX]==$face } { set retDir $dir } } # Generate error message when block faces are different in the propagating direction. if { $retDir == "" } { ErrorMsg "Faces of [gg::blkName $blk1] and [gg::blkName $blk2] in the propagating direction\ do not match. This is not supported." quit } else { return $retDir } } proc getAdjacentBlocks { blk dir } { set adjacentBlocks {} if { [llength [lindex [gg::blkGetFace $blk ${dir}MIN] 0]] == 1 } { gg::domReport [lindex [gg::blkGetFace $blk ${dir}MIN] 0] data REFERENCE foreach tblk $data(refBlocks) { if { $tblk != $blk && [string compare [getParallelDirection $blk ${dir}MIN $tblk] ""] != 0 } { lappend adjacentBlocks "$tblk [getParallelDirection $blk ${dir}MIN $tblk]" } } } else { # Allow adjacent blocks to share multi-dom interfaces. set domList [lindex [gg::blkGetFace $blk ${dir}MIN] 0] set referenceBlks {} foreach dom $domList { gg::domReport $dom data REFERENCE foreach tblk $data(refBlocks) { if { [lsearch $referenceBlks $tblk] >= 0 } { set tblkIndex [lsearch $referenceBlks $tblk] lreplace $referenceBlks $tblkIndex $tblkIndex } else { lappend referenceBlks $tblk } } } if { [llength $referenceBlks] == 2 } { foreach tblk $referenceBlks { lappend adjacentBlocks "$tblk [getParallelDirection $blk ${dir}MIN $tblk]" } } elseif { [llength $referenceBlks] == 1 } { ######### } else { ErrorMsg "Block [lindex [gg::blkIdToNum $blk] 0] has more than one adjacent blocks in \ propagating direction $dir. This is not supported." } } if { [llength [lindex [gg::blkGetFace $blk ${dir}MAX] 0]] == 1 } { gg::domReport [lindex [gg::blkGetFace $blk ${dir}MAX] 0] data REFERENCE foreach tblk $data(refBlocks) { if { $tblk != $blk && [lsearch $adjacentBlocks $tblk] == -1 && \ [string compare [getParallelDirection $blk ${dir}MAX $tblk] ""] != 0} { lappend adjacentBlocks "$tblk [getParallelDirection $blk ${dir}MAX $tblk]" } } } else { # Allow adjacent blocks to share multi-dom interfaces. set domList [lindex [gg::blkGetFace $blk ${dir}MAX] 0] set referenceBlks {} foreach dom $domList { gg::domReport $dom data REFERENCE foreach tblk $data(refBlocks) { if { [lsearch $referenceBlks $tblk] >= 0 } { set tblkIndex [lsearch $referenceBlks $tblk] lreplace $referenceBlks $tblkIndex $tblkIndex } else { lappend referenceBlks $tblk } } } if { [llength $referenceBlks] == 2 } { foreach tblk $referenceBlks { lappend adjacentBlocks "$tblk [getParallelDirection $blk ${dir}MAX $tblk]" } } elseif { [llength $referenceBlks] == 1 } { ######### } else { ErrorMsg "Block [lindex [gg::blkIdToNum $blk] 0] has more than one adjacent blocks in \ propagating direction $dir. This is not supported." } } return $adjacentBlocks } proc getPropagatedBlockList { blk dir } { global Propagate # If Propagate checkbox is not checked, the original selected block will be returned immediately. if { $Propagate == 0 } { return $blk } else { lappend blkList "$blk $dir" for { set i 0 } { $i < [llength $blkList] } { incr i } { foreach n [getAdjacentBlocks [lindex [lindex $blkList $i] 0] \ [lindex [lindex $blkList $i] 1]] { if { [lsearch $blkList $n] == -1 } { lappend blkList "$n" } } } return $blkList } } proc getRefedDomains { blks } { gg::blkReport $blks data REFERENCE return $data(refDoms) } proc runJob { blkdom dir prop } { global Structured_Blocks Structured_Domains Clean oScaleFac # Warning if oScaleFac component is larger than 1.0. set oScale_1 [lindex $oScaleFac 0] set oScale_2 [lindex $oScaleFac 1] set oScale_3 [lindex $oScaleFac 2] if { $oScale_1 > 1.0 || $oScale_2 > 1.0 || $oScale_3 > 1.0 || $oScale_1 < 0.0 || \ $oScale_2 < 0.0 || $oScale_3 < 0.0 } { ErrorMsg "Invalid scaling factor input!" return } # global slopeDiscont CleanupCons if { $blkdom == "BLOCKS" } { if { $dir == "ALL" } { if { [llength [.right.top.list curselection]] > 0 } { tk_dialog .diag "Notification" "This process may take a few minutes, please do not attempt to \ close the sript until the operation is completed." "" 0 OK # Using blkList is not robust here. foreach ind [.right.top.list curselection] { set blk [lindex $Structured_Blocks $ind] blkMakeBflyBlocks $blk ALL } } } else { if { [llength [.right.top.list curselection]] > 0 } { tk_dialog .diag "Notification" "This process may take a few minutes, please do not attempt to \ close the script until the operation is completed." "" 0 OK set blkList [list] foreach ind [.right.top.list curselection] { foreach blk [getPropagatedBlockList [lindex $Structured_Blocks $ind] $dir] { lappend blkList [lindex $blk 0] } } set ref [getRefedDomains $blkList] foreach csel [.right.top.list curselection] { set blk [lindex $Structured_Blocks $csel] if { $prop } { lappend blocks [getPropagatedBlockList $blk $dir] } else { lappend blocks [list [list $blk $dir]] } } for { set i 0 } { $i < [llength $blocks] } { incr i } { if { [lsearch $blocks [lindex $blocks $i]] > $i } { set blocks [lreplace $blocks $i $i] set i [expr $i - 1] } } foreach blk $blkList { blkMakeBflyBlocks $blk $dir } for { set i 0 } { $i < [llength $ref] } { incr i } { gg::domReport [lindex $ref $i] data REFERENCE if { [llength $data(refBlocks)] == 0 } { catch { gg::domDelete [lindex $ref $i] } } } } } } else { foreach csel [.right.top.list curselection] { domMakeBflyDomains [lindex $Structured_Domains $csel] } } set Clean 0 } proc multiDomFaceOccurs_old { blkList } { set ret [list] foreach blk $blkList { if { [lsearch $ret "i"] == -1 } { if { [llength [lindex [gg::blkGetFace $blk IMIN] 0]] > 1 \ || [llength [lindex [gg::blkGetFace $blk IMAX] 0]] > 1 } { set ret [lappend $ret "i"] } } if { [lsearch $ret "j"] == -1 } { if { [llength [lindex [gg::blkGetFace $blk JMIN] 0]] > 1 \ || [llength [lindex [gg::blkGetFace $blk JMAX] 0]] > 1 } { set ret [lappend $ret "j"] } } if { [lsearch $ret "k"] == -1 } { if { [llength [lindex [gg::blkGetFace $blk KMIN] 0]] > 1 \ || [llength [lindex [gg::blkGetFace $blk KMAX] 0]] > 1 } { set ret [lappend $ret "k"] } } } return $ret } # Allows the script to apply butterfuly topology change on a multi-domain face. proc multiDomFaceOccurs { blk dir } { if { $dir == "I" } { if { [llength [lindex [gg::blkGetFace $blk IMIN] 0]] > 1 } { joinDomsOnBflyFac [lindex [gg::blkGetFace $blk IMIN] 0] $dir } elseif { [llength [lindex [gg::blkGetFace $blk IMAX] 0]] > 1 } { joinDomsOnBflyFac [lindex [gg::blkGetFace $blk IMAX] 0] $dir } } if { $dir == "J" } { if { [llength [lindex [gg::blkGetFace $blk JMIN] 0]] > 1 } { joinDomsOnBflyFac [lindex [gg::blkGetFace $blk JMIN] 0] $dir } elseif { [llength [lindex [gg::blkGetFace $blk JMAX] 0]] > 1 } { joinDomsOnBflyFac [lindex [gg::blkGetFace $blk JMAX] 0] $dir } } if { $dir == "K" } { if { [llength [lindex [gg::blkGetFace $blk KMIN] 0]] > 1 } { joinDomsOnBflyFac [lindex [gg::blkGetFace $blk KMIN] 0] $dir } elseif { [llength [lindex [gg::blkGetFace $blk KMAX] 0]] > 1 } { joinDomsOnBflyFac [lindex [gg::blkGetFace $blk KMAX] 0] $dir } } } # Join domains on a H topology face where butterfly topology is to be applied. proc joinDomsOnBflyFac { domList dir } { set domNumList {} foreach dom $domList { set domNum [gg::domIdToNum $dom] lappend domNumList [lindex $domNum 0] } set startUpDom [lindex $domList 0] set domList2 [lreplace $domList 0 0] switch [catch { gg::domJoinBegin $startUpDom gg::domJoinAddDom $domList2 gg::domJoinEnd } result] { 1 { ErrorMsg "Domains $domNumList on butterfly face cannot be joined into one single domain!"} } } proc enableDisable { } { global Structured_Blocks Propagate Direction global blkList set sel [.right.top.list curselection] set blkList [list] foreach csel $sel { set blk [lindex $Structured_Blocks $csel] lappend blkList $blk } } proc makeInputField { parent name title variable {width 10} {when ""} {valid ""}} { frame $parent.$name label $parent.$name.lbl$name -text $title entry $parent.$name.ent$name -textvariable $variable -width $width if { [string compare $valid ""]!=0 } { $parent.$name.ent$name configure -validate $when set var "if { $valid==1 } { if { [string compare %V focusout]==0 } { focus %W }; return 0 } else { %W configure -background #FFFFFF; return 1 }" $parent.$name.ent$name configure -validatecommand $var $parent.$name.ent$name configure -invalidcommand { %W configure -background "#FFCCCC" } } pack "$parent.$name.lbl$name" -side left -padx 3 -pady 1 pack "$parent.$name.ent$name" -side right -padx 3 -pady 1 return $parent.$name } proc makeWindow { } { # Save the existing grids just in case. global scriptDir gg::gridExport [file join $scriptDir "startUpGridFile.gg"] puts "INFO: Initial grids are saved into $scriptDir/startUpGridFile.gg" label .title -text "Transform H Topology Block(s) into Butterfly Topology" set font [.title cget -font] .title configure -font [font create -family [font actual $font -family] -weight bold] pack .title -expand 1 -side top pack [frame .hr1 -bd 1 -height 2 -relief sunken] -fill x -pady 2 pack [frame .content] -fill both -side top frame .contents frame .left frame .left.dir -bd 1 -relief solid pack [radiobutton .left.dir.i -text "I" -command { global Direction Duplicate_Direction; \ if { [string compare $Direction $Duplicate_Direction] != 0 } { SwitchMode 1 }; \ set Duplicate_Direction $Direction } -variable Direction -value I] -side left -expand 1 pack [radiobutton .left.dir.j -text "J" -command { global Direction Duplicate_Direction; \ if { [string compare $Direction $Duplicate_Direction] != 0 } { SwitchMode 1 }; \ set Duplicate_Direction $Direction } -variable Direction -value J] -side left -expand 1 pack [radiobutton .left.dir.k -text "K" -command { global Direction Duplicate_Direction; \ if { [string compare $Direction $Duplicate_Direction] != 0 } { SwitchMode 1 }; \ set Duplicate_Direction $Direction } -variable Direction -value K] -side left -expand 1 pack [radiobutton .left.dir.all -text "All" -command { global Direction Duplicate_Direction; \ if { [string compare $Direction $Duplicate_Direction] != 0 } { SwitchMode 1 }; \ set Duplicate_Direction $Direction } -variable Direction -value ALL] -side left -expand 1 pack .left.dir -fill x -padx 2 -pady 2 -expand 1 frame .left.values -bd 1 -relief solid # Allow user to input scaling factor in 2 dimensions for adjusting H region's length and width. pack [makeInputField .left.values dist "H Region 3D Scaler (0,1.0):" oScaleFac] -fill x -padx 2 -pady 4 pack [makeInputField .left.values pts "Grid Points on Ogrid Ribs:" oDimension] -fill x -padx 2 -pady 4 checkbutton .left.values.propagate -text "Propagate Topology" -variable Propagate -command {Redraw} button .left.values.preview -text "Preview Topology" -command {global locatorH_prop; Redraw; \ set locatorH_prop {}} pack .left.values -fill x -padx 2 -pady 2 -expand 1 pack .left.values.propagate -padx 2 -pady 2 pack .left.values.preview -padx 2 -pady 2 pack .left -in .contents -side right -fill y frame .right -relief solid # Change the position and the text of select block button. This command is not neccary # when the selection is already made in the GUI list. pack [button .right.select -text "Click to select interactively" -command select] -side top \ -pady 8 -padx 1 pack [frame .right.top] -side bottom pack [scrollbar .right.top.scroll -command ".right.top.list yview" -takefocus 0] -side right -fill y pack [listbox .right.top.list -yscrollcommand ".right.top.scroll set" -selectmode multiple \ -exportselection false -takefocus 0] -fill both -side right bind .right.top.list <> { BlkSelect } pack .right -in .contents -side left -fill y pack .contents -padx 10 -pady 10 frame .left.buttons -relief solid pack [button .left.buttons.cancel -text "Abort" -command { CleanupCons; restoreOriginal; \ abort }] -padx 2 -pady 1 -side right pack [button .left.buttons.ok -text "OK" -command { global Mode Direction Propagate; \ runJob $Mode $Direction $Propagate; restoreOriginal; CleanupCons; \ removeMultiDomInteriorCons; exit }] -padx 2 -pady 1 -side right pack [button .left.buttons.apply -text "Run" -command { global Mode Direction Propagate \ locatorH_prop; \ runJob $Mode $Direction $Propagate; buildLists; .right.top.list selection clear 0 end; \ set locatorH_prop {}; removeMultiDomInteriorCons; set Propagate 0}] -padx 4 -pady 1 -side right pack .left.buttons -fill x -padx 2 -pady 2 if {![catch {pwiLogoCreate .buttons.logo 1} b]} { $b configure -bd 0 -relief flat pack $b -side left -padx 5 } bind . { global Clean; if { $Clean } { CleanupCons; restoreOriginal; abort } } ::tk::PlaceWindow . widget wm title . "Create Butterfly Topology" } makeWindow SwitchMode update idletasks gg::tkLoop # # DISCLAIMER: # TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, POINTWISE DISCLAIMS # ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED # TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE, WITH REGARD TO THIS SCRIPT. TO THE MAXIMUM EXTENT PERMITTED # BY APPLICABLE LAW, IN NO EVENT SHALL POINTWISE BE LIABLE TO ANY PARTY # FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES # WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF # BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE # USE OF OR INABILITY TO USE THIS SCRIPT EVEN IF POINTWISE HAS BEEN # ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND REGARDLESS OF THE # FAULT OR NEGLIGENCE OF POINTWISE. #