1 # Copyright (C) 2014-2022 EDF R&D
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 import sys, math, copy, subprocess
24 CWD = subprocess.getoutput('pwd')
27 from MacObject import *
28 import Config, GenFunctions
30 def CompositeBox (X0 , Y0 , DX , DY , **args ) :
32 if args.__contains__('groups') :
33 GroupNames = args['groups']
34 else : GroupNames = [None, None, None, None]
35 # Create a full Box just to inherit, globally, the mesh parameters of bounding objects
36 MacObject('CompBoxF',[(X0,Y0),(DX,DY)],['auto'],publish=0)
38 # Save the existing number of segments on each direction
39 ExistingSegments = Config.ListObj[-1].DirectionalMeshParams
41 # Sort the connection list for the full Box
42 ObjIDLists = SortObjLists(Config.Connections[-1],X0 , Y0 , DX , DY )
45 print("ObjIDLists: ", ObjIDLists)
50 if not(args.__contains__('recursive')) : Config.Count = 0
51 print("Config.Count : ", Config.Count)
52 Config.Criterion = GetCriterion(ObjIDLists)
53 for index, ObjList in enumerate(ObjIDLists) :
54 if not (ObjList[0] == -1 or Config.Count >= Config.Criterion):
55 if len(ObjList)>1 : flag = 1
58 ToLook0 = [2,2,0,0][index]
59 ToLook1 = [3,2,1,0][index]
60 CommonSide = FindCommonSide(Config.ListObj[ObjID].DirBoundaries(ToLook1),[X0-DX/2.,X0+DX/2.,Y0-DY/2.,Y0+DY/2.][ToLook0:ToLook0+2])
61 ToLook2 = [1,0,3,2][index]
62 RealSegments.append(Config.ListObj[ObjID].DirectionalMeshParams[ToLook2]*IntLen(CommonSide)/IntLen(Config.ListObj[ObjID].DirBoundaries(ToLook1)))
63 Direction.append(ToLook0/2)
65 if flag and Config.Count < Config.Criterion:
67 if abs(CommonSide[0] - (Y0-DY/2.))<1e-7 : SouthGR = GroupNames[0]
69 if abs(CommonSide[1] - (Y0+DY/2.))<1e-7 : NorthGR = GroupNames[1]
71 CompositeBox (X0, CommonSide[0]+IntLen(CommonSide)/2., DX,IntLen(CommonSide), recursive=1, groups = [SouthGR,NorthGR]+GroupNames[2:4])
73 if abs(CommonSide[0] - (X0-DX/2.))<1e-7 : EastGR = GroupNames[2]
75 if abs(CommonSide[1] - (X0+DX/2.))<1e-7 : WestGR = GroupNames[3]
77 CompositeBox (CommonSide[0]+IntLen(CommonSide)/2., Y0, IntLen(CommonSide),DY, recursive=1, groups = GroupNames[0:2]+[EastGR,WestGR])
79 if Config.Count >= Config.Criterion :
81 if flag == 0 and Config.Count < Config.Criterion:
82 #print "Dir : ", Direction
83 #print "RealSegments : ", RealSegments
85 #Xind = Direction.index(0)
86 #Yind = Direction.index(1)
87 #MacObject('CompBoxF',[(X0,Y0),(DX,DY)] ,[(RealSegments[Xind],RealSegments[Yind])], groups = GroupNames)
88 MacObject('CompBoxF',[(X0,Y0),(DX,DY)] ,['auto'], groups = GroupNames)
93 def FindCommonSide (Int1, Int2) :
94 if abs(min(Int1[1],Int2[1])-max(Int1[0],Int2[0])) < 1e-5: return [0,0]
95 else : return [max(Int1[0],Int2[0]), min(Int1[1],Int2[1])]
97 def IntLen (Interval) :
98 return abs(Interval[1]-Interval[0])
100 def RemoveLastObj() :
101 Config.ListObj = Config.ListObj[:-1]
102 Config.Connections = Config.Connections[:-1]
104 def GetCriterion (ObjListIDs):
105 return max(Config.Criterion, max(len(ObjListIDs[0]),len(ObjListIDs[1]))*max(len(ObjListIDs[2]),len(ObjListIDs[3])))
107 def SortObjLists (List,X0,Y0,DX,DY) :
109 This function sorts the list of neighbouring objects on each side, according to their intersection
110 with the object being created. From South to North and from East to West
113 # First find the directions where no neighbour exists
114 # Important : Here we assume that exactly two directions have no neighbours !!!
115 # Should we change this to allow a more general case ????
116 dummy = IndexMultiOcc(List,(-1,))
118 # dummy[0] is either 0, meaning there is no neighbour on X- (West)
119 # or 1, meaning there is no neighbour on X+ (East)
120 # Similarly dummy[1] can be either 2 or 3 (South and North respectively)
121 # In order to get back to the formalism of groups (SNWE)
122 # => we do the following to define Sense of no neighbours and then the Direction list
123 # is calculated as to include uniquely the directions where we DO have neighbours
125 # This adds a second direction where neighbours are not regarded, it is either 0 or 2
126 dummy.append(2*(dummy[0]+2<4))
127 print("Careful, you have neighbours on 3 or more sides of the box, we will not check if on two parallel sides the boxes are compatible !!!")
128 if len(dummy) == 2 or len(dummy) == 1 :
129 # Sense contains : Vertical then Horizontal
130 Sense = [dummy[1]%2,dummy[0]]
131 DirList = [[1,0][dummy[0]],[3,2][dummy[1]%2]]
132 for index,Direction in enumerate(DirList) :
133 ObjList = List[Direction]
135 ToLook0 = [2,2,0,0][Direction]
136 ToLook1 = [3,2,1,0][Direction]
137 for index1,ObjID in enumerate(ObjList) :
138 RankMin.append([-1.,1.][Sense[index]] * FindCommonSide(Config.ListObj[ObjID].DirBoundaries(ToLook1),[X0-DX/2.,X0+DX/2.,Y0-DY/2.,Y0+DY/2.][ToLook0:ToLook0+2])[Sense[index]])
139 Output[Direction] = SortList(ObjList,RankMin)
141 elif len(dummy) == 3 :
142 # We find the direction where we do have neighbours and then we sort the object list along it
144 Direction = [ i not in dummy for i in range(4) ].index(True)
145 ObjList = List[Direction]
147 ToLook0 = [2,2,0,0][Direction]
148 ToLook1 = [3,2,1,0][Direction]
149 for index1,ObjID in enumerate(ObjList) :
150 RankMin.append([-1.,1.][Sense] * FindCommonSide(Config.ListObj[ObjID].DirBoundaries(ToLook1),[X0-DX/2.,X0+DX/2.,Y0-DY/2.,Y0+DY/2.][ToLook0:ToLook0+2])[Sense])
151 Output[Direction] = SortList(ObjList,RankMin)
153 print ("Error : the composite box being created has no neighbours, how on earth do you want us to inherit its mesh parameters!!!")
158 def IndexMultiOcc (Array,Element) :
160 This functions returns the occurrences indices of Element in Array.
161 As opposed to Array.index(Element) method, this allows determining
162 multiple entries rather than just the first one!
165 try : Array.index(Element)
166 except ValueError : print("No more occurrences")
167 else : Output.append(Array.index(Element))
169 if not(Output == []) and len(Array) > 1 :
170 for index, ArrElem in enumerate(Array[Output[0]+1:]) :
171 if ArrElem == Element : Output.append(index+Output[0]+1)
175 def SortList (ValList, CritList):
177 SortedCritList = sorted(copy.copy(CritList))
178 for i in range(0,len(ValList)):
179 index = CritList.index(SortedCritList[i])
180 Output.append(ValList[index])