Package PyFoam :: Package Site :: Module InitGgiInterface
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.Site.InitGgiInterface

  1  """ 
  2  Application-class that implements pyFoamInitGgiInterface.py 
  3   
  4  Inititialize various ggi interface attributes in the 
  5  constant/polymesh/boundary file, and in the time directories. 
  6   
  7  Backups of the boundary file is created. 
  8   
  9  Generate companion scripts for initializing the ggi zone faceSets. 
 10   
 11  Modify the decomposeParDict file for the new ggi zones names. 
 12   
 13  Author: 
 14    Martin Beaudoin, Hydro-Quebec, 2012.  All rights reserved 
 15   
 16  """ 
 17   
 18  import sys, fnmatch, re 
 19  from os import path, listdir, chmod 
 20  from stat import * 
 21   
 22  from PyFoam.Applications.PyFoamApplication import PyFoamApplication 
 23  from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile 
 24  from PyFoam.ThirdParty.six import print_ 
 25  from PyFoam.RunDictionary.TimeDirectory import TimeDirectory 
 26  from PyFoam.Basics.BasicFile import BasicFile 
 27   
28 -class InitGgiInterface(PyFoamApplication):
29 - def __init__(self,args=None):
30 description=""" 31 Init GGI boundary condition parameters in boundary file. 32 Init GGI boundary fields in time directories. 33 Generate faceSet scripts for ggi zones. 34 Modify GGI zones information in decomposeParDict file. 35 """ 36 PyFoamApplication.__init__(self, 37 args=args, 38 description=description, 39 usage="%prog <caseDirectory> ggi_MasterPatchName ggi_ShadowPatchName", 40 interspersed=True, 41 changeVersion=False, 42 nr=3)
43
44 - def addOptions(self):
45 self.parser.add_option("--type", 46 action="store", 47 dest="ggiType", 48 default='ggi', 49 help='ggi type: ggi | cyclicGgi | overlapGgi') 50 self.parser.add_option("--patchZoneName", 51 action="store", 52 dest="patchZoneName", 53 default=None, 54 help='Name of the zone for the GGI patch') 55 self.parser.add_option("--bridgeOverlapFlag", 56 action="store", 57 dest="bridgeOverlapFlag", 58 default=None, 59 help='bridgeOverlap flag (on/off)') 60 self.parser.add_option("--rotationAxis", 61 action="store", 62 dest="rotationAxis", 63 default=None, 64 help='rotation axis for cyclicGgi or overlapGgi') 65 self.parser.add_option("--rotationAngle", 66 action="store", 67 dest="rotationAngle", 68 default=None, 69 help='rotation axis angle for cyclicGgi. Accept Python math expressions like 360.0/17.0') 70 self.parser.add_option("--separationOffset", 71 action="store", 72 dest="separationOffset", 73 default=None, 74 help='separation offset for cyclicGgi') 75 self.parser.add_option("--nCopies", 76 action="store", 77 dest="nCopies", 78 default=None, 79 help='number of copies for overlapGgi') 80 self.parser.add_option("--timeDirs", 81 action="store", 82 dest="timeDirs", 83 default=None, 84 help='time directories for modifying the ggi boundaryfields. Accept expressions like "[0-9]*", "0", etc.') 85 86 self.parser.add_option("--genFaceSetForGgiZonesScriptName", 87 action="store", 88 dest="genFaceSetForGgiZonesScriptName", 89 default="genFaceSetForGgiZones.setSet", 90 help='setSet batch file for generating faceSets for GGI zones. Default: genFaceSetForGgiZones.setSet') 91 92 self.parser.add_option("--initGgiZonesScriptName", 93 action="store", 94 dest="initGgiZonesScriptName", 95 default="initGgiZones.sh", 96 help='script name for initializing the GGI zone faceSets. Default: initGgiZones.sh') 97 98 self.parser.add_option("--test", 99 action="store_true", 100 default=False, 101 dest="test", 102 help="Only print the new boundary file")
103
104 - def createGGIPatch(self, patch, patchName, ggiType):
105 description="""\ 106 Create a default definition for a ggi patch, and replace 107 the current definition 108 """ 109 print_("Replacing definition of patch: ", patchName, ":", patch) 110 newPatch={ 111 'type' : ggiType, 112 'nFaces' : patch["nFaces"], 113 'startFace' : patch["startFace"], 114 'shadowPatch' : 'unknown', 115 'zone' : patchName+'Zone', 116 'bridgeOverlap' : 'true', 117 'rotationAxis' : '(0 0 1)', 118 'rotationAngle' : '0.0', 119 'separationOffset' : '(0 0 0)' 120 } 121 return newPatch
122
123 - def modifyGGIPatchDefinition(self, patch, patchName, shadowName, ggiType, rotationAngle):
124 description="""\ 125 Modify the definition of a ggi patch 126 """ 127 print_(" Modifying ggi boundary definition in constant/polyMesh/boundary for patch", patchName) 128 129 patch["type"]=ggiType 130 131 patch["shadowPatch"]=shadowName 132 133 if self.parser.getOptions().patchZoneName!=None: 134 patch["zone"]=self.parser.getOptions().patchZoneName 135 else: 136 patch["zone"]=patchName+'Zone' 137 138 if self.parser.getOptions().bridgeOverlapFlag!=None: 139 patch["bridgeOverlap"]=self.parser.getOptions().bridgeOverlapFlag 140 141 if ggiType=="cyclicGgi": 142 if self.parser.getOptions().rotationAxis!=None: 143 patch["rotationAxis"]=self.parser.getOptions().rotationAxis 144 145 # Use the rotationAngle value passed as a parameter. 146 # The calling function will change the sign for the slave ggi patch 147 if self.parser.getOptions().rotationAngle!=None: 148 patch["rotationAngle"]=rotationAngle 149 150 if self.parser.getOptions().separationOffset!=None: 151 patch["separationOffset"]=self.parser.getOptions().separationOffset 152 153 if ggiType=="overlapGgi": 154 if self.parser.getOptions().rotationAxis!=None: 155 patch["rotationAxis"]=self.parser.getOptions().rotationAxis 156 157 if self.parser.getOptions().nCopies!=None: 158 patch["nCopies"]=self.parser.getOptions().nCopies
159 160
161 - def modifyGGIPatchDefinitionInTimeDirs(self, caseDir, patchName, ggiType, timeDirs):
162 description="""\ 163 Modify the definition of a ggi patch in the time directories 164 """ 165 regex = fnmatch.translate(timeDirs) 166 167 reobj = re.compile(regex) 168 169 for timeDir in listdir(caseDir): 170 if reobj.match(timeDir): 171 print_(" Modifying ggi boundaryFields in timeDir", timeDir, "for patch", patchName) 172 173 td=TimeDirectory(caseDir, timeDir, yieldParsedFiles=True) 174 175 for f in td: 176 print_(" Modifying field", f.name) 177 f["boundaryField"][patchName]["type"]=ggiType 178 f.writeFile()
179 180
181 - def generateCompanionFiles(self, caseDir, boundary):
182 description="""\ 183 Generate a setSet batch file based on the zone info specified in the ggi interfaces definition. 184 Generate a bash file for invoking setSet and setsToZones 185 Update GGI zone infoprmation in decomposeParDict 186 """ 187 # Default file: genFaceSetForGgiZones.setSet 188 bfGenFaceSets = BasicFile(path.join(caseDir, self.parser.getOptions().genFaceSetForGgiZonesScriptName)) 189 190 print_(" Updating file ", bfGenFaceSets.name, " for generating GGI zones faceSet using the setSet command") 191 192 bnd=boundary.content 193 194 if type(bnd)!=list: 195 self.error("Problem with boundary file (not a list)") 196 197 # Memorize list of GGI zones for later processing 198 listOfGgiZones = [] 199 200 for index in range(0, len(bnd), 2): 201 patchName = bnd[index] 202 indexDefPatch=index+1 203 if bnd[indexDefPatch]["type"]=='ggi' or bnd[indexDefPatch]["type"]=='cyclicGgi' or bnd[indexDefPatch]["type"]=='overlapGgi': 204 bfGenFaceSets.writeLine([ "faceSet " + bnd[indexDefPatch]["zone"] + " new patchToFace "+ patchName ]) 205 listOfGgiZones.append(bnd[indexDefPatch]["zone"]) 206 207 bfGenFaceSets.writeLine([ "quit" ]) 208 bfGenFaceSets.close() 209 210 # Default file: initGgiZones.sh 211 bfInitGgiZones = BasicFile(path.join(caseDir, self.parser.getOptions().initGgiZonesScriptName)) 212 213 print_(" Updating file ", bfInitGgiZones.name, " for inititalizing GGI zones") 214 215 bfInitGgiZones.writeLine([ "#!/bin/bash" ]) 216 bfInitGgiZones.writeLine([ "setSet -batch " + self.parser.getOptions().genFaceSetForGgiZonesScriptName ]) 217 bfInitGgiZones.writeLine([ "setsToZones -noFlipMap" ]) 218 bfInitGgiZones.close() 219 220 # Set execution permissions for this script (755) 221 chmod(bfInitGgiZones.name, S_IRWXU|S_IRGRP|S_IXGRP|S_IXOTH|S_IROTH) 222 223 # DecomposeParDict 224 decomposeParDictPath=path.join(caseDir,"system","decomposeParDict") 225 if path.exists(decomposeParDictPath): 226 print_(" Updating file ", decomposeParDictPath, " for GGI zones") 227 decomposeParDict=ParsedParameterFile(decomposeParDictPath,debug=False,backup=True) 228 dcp=decomposeParDict.content 229 dcp["globalFaceZones"]="(\n " + '\n '.join(list(listOfGgiZones)) + "\n)" 230 decomposeParDict.writeFile()
231
232 - def run(self):
233 caseDir=self.parser.getArgs()[0] 234 masterbName=self.parser.getArgs()[1] 235 shadowbName=self.parser.getArgs()[2] 236 237 boundary=ParsedParameterFile(path.join(".",caseDir,"constant","polyMesh","boundary"),debug=False,boundaryDict=True,backup=True) 238 239 bnd=boundary.content 240 241 if type(bnd)!=list: 242 self.error("Problem with boundary file (not a list)") 243 244 masterFound=False 245 shadowFound=False 246 updateTimeDirs=False 247 248 timeDirs="0" 249 if self.parser.getOptions().timeDirs!=None: 250 timeDirs=self.parser.getOptions().timeDirs 251 updateTimeDirs=True 252 253 ggiType=self.parser.getOptions().ggiType 254 255 rotationAngle=0.0 256 if self.parser.getOptions().rotationAngle!=None: 257 rotationAngle=float(eval(self.parser.getOptions().rotationAngle)) 258 259 for index in range(len(bnd)): 260 indexDefPatch=index+1 261 262 if bnd[index]==masterbName: 263 masterFound=True 264 if bnd[indexDefPatch]["type"]!=ggiType: 265 bnd[indexDefPatch] = self.createGGIPatch(bnd[indexDefPatch], masterbName, ggiType) 266 267 self.modifyGGIPatchDefinition(bnd[indexDefPatch], masterbName, shadowbName, ggiType, rotationAngle) 268 269 if updateTimeDirs: 270 self.modifyGGIPatchDefinitionInTimeDirs(caseDir, masterbName, ggiType, timeDirs) 271 272 elif bnd[index]==shadowbName: 273 shadowFound=True 274 if bnd[indexDefPatch]["type"]!=ggiType: 275 bnd[indexDefPatch] = self.createGGIPatch(bnd[indexDefPatch], shadowbName, ggiType) 276 self.modifyGGIPatchDefinition(bnd[indexDefPatch], shadowbName, masterbName, ggiType, -rotationAngle) 277 278 if updateTimeDirs: 279 self.modifyGGIPatchDefinitionInTimeDirs(caseDir, shadowbName, ggiType, timeDirs) 280 281 if masterFound and shadowFound: 282 break; 283 284 if not masterFound: 285 self.error("Boundary patch",masterbName,"not found in",bnd[::2]) 286 287 if not shadowFound: 288 self.error("Boundary patch",shadowbName,"not found in",bnd[::2]) 289 290 if self.parser.getOptions().test: 291 print_(boundary) 292 else: 293 boundary.writeFile() 294 295 # Write companion files 296 self.generateCompanionFiles(caseDir, boundary)
297