Package PyFoam :: Package Applications :: Module PrepareCase
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.Applications.PrepareCase

  1  """ 
  2  Application-class that implements pyFoamPrepareCase.py 
  3  """ 
  4  from optparse import OptionGroup 
  5   
  6  from .PyFoamApplication import PyFoamApplication 
  7   
  8  from PyFoam.RunDictionary.SolutionDirectory import SolutionDirectory 
  9  from PyFoam.Basics.Utilities import rmtree,copytree,execute,remove 
 10  from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile,WriteParameterFile 
 11  from PyFoam.Basics.TemplateFile import TemplateFile 
 12  from PyFoam.Execution.BasicRunner import BasicRunner 
 13   
 14  from PyFoam.FoamInformation import foamFork,foamVersion 
 15   
 16  from .CommonTemplateFormat import CommonTemplateFormat 
 17  from .CommonTemplateBehaviour import CommonTemplateBehaviour 
 18   
 19  from PyFoam.ThirdParty.six import print_,iteritems 
 20   
 21  from PyFoam import configuration 
 22   
 23  from os import path,listdir,mkdir 
 24  from shutil import copymode,copy 
 25   
26 -class PrepareCase(PyFoamApplication, 27 CommonTemplateBehaviour, 28 CommonTemplateFormat):
29 30 parameterOutFile="PyFoamPrepareCaseParameters" 31
32 - def __init__(self, 33 args=None, 34 exactNr=True, 35 interspersed=True, 36 usage="%prog <caseDirectory>", 37 examples=None, 38 nr=1, 39 description=None, 40 **kwargs):
41 self.defaultMeshCreate=configuration().get("PrepareCase","MeshCreateScript") 42 self.defaultCaseSetup=configuration().get("PrepareCase","CaseSetupScript") 43 44 description2="""\ 45 Prepares a case for running. This is intended to be the replacement for 46 boiler-plate scripts. The steps done are 47 48 1. Clear old data from the case (including processor directories) 49 50 2. if a folder 0.org is present remove the 0 folder too 51 52 3. go through all folders and for every found file with the extension .template 53 do template expansion using the pyratemp-engine (automatically create variables 54 casePath and caseName) 55 56 4. create a mesh (either by using a script or if a blockMeshDict is present by 57 running blockMesh. If none of these is present assume that there is a valid mesh 58 present) 59 60 5. copy every foo.org that is found to to foo (recursively if directory) 61 62 6. do template-expansion for every file with the extension .postTemplate 63 64 7. execute another preparation script 65 66 The used parameters are written to a file 'PyFoamPrepareCaseParameters' and are used by other utilities 67 """ 68 examples2="""\ 69 %prog . --paramter-file=parameters.base 70 71 Prepare the current case with the parameters list in parameters.base 72 73 %prog . --paramter-file=parameters.base --values-string="{'visco':1e-3}" 74 75 Changes the value of the parameter visco 76 77 %prog . --no-mesh-create 78 79 Skip the mesh creation phase 80 """ 81 PyFoamApplication.__init__(self, 82 args=args, 83 description=description if description else description2, 84 usage=usage, 85 examples=examples if examples else examples2, 86 interspersed=interspersed, 87 nr=nr, 88 exactNr=exactNr, 89 **kwargs)
90
91 - def addOptions(self):
92 output=OptionGroup(self.parser, 93 "Output", 94 "What information should be given") 95 self.parser.add_option_group(output) 96 output.add_option("--fatal", 97 action="store_true", 98 dest="fatal", 99 default=False, 100 help="If non-cases are specified the program should abort") 101 output.add_option("--no-complain", 102 action="store_true", 103 dest="noComplain", 104 default=False, 105 help="Don't complain about non-case-files") 106 output.add_option("--quiet", 107 action="store_false", 108 dest="verbose", 109 default=True, 110 help="Do not report what is being done") 111 output.add_option("--no-write-parameters", 112 action="store_false", 113 dest="writeParameters", 114 default=True, 115 help="Usually a file '"+self.parameterOutFile+"' with a dictionary of the used parameters is written to the case directory. ") 116 117 extensions=OptionGroup(self.parser, 118 "Extensions", 119 "File extensions that are used in actions") 120 self.parser.add_option_group(extensions) 121 extensions.add_option("--template-extension", 122 action="store", 123 dest="templateExt", 124 default=".template", 125 help="Extension for template files. Default: %default") 126 extensions.add_option("--post-template-extension", 127 action="store", 128 dest="postTemplateExt", 129 default=".postTemplate", 130 help="Extension for post-template files. Default: %default") 131 extensions.add_option("--original-extension", 132 action="store", 133 dest="originalExt", 134 default=".org", 135 help="Extension for files and directories that are copied. Default: %default") 136 137 inputs=OptionGroup(self.parser, 138 "Inputs", 139 "Inputs for the templating process") 140 self.parser.add_option_group(inputs) 141 142 inputs.add_option("--parameter-file", 143 action="append", 144 default=[], 145 dest="valuesDicts", 146 help="Name of a dictionary-file in OpenFOAM-format. Can be specified more than once. Values in later files override old values") 147 inputs.add_option("--values-string", 148 action="append", 149 default=[], 150 dest="values", 151 help="String with the values that are to be inserted into the template as a dictionaty in Python-format. Can be specified more than once and overrides values from the parameter-files") 152 153 special=OptionGroup(self.parser, 154 "Special files and directories", 155 "Files and directories that get special treatment") 156 self.parser.add_option_group(special) 157 158 special.add_option("--directories-to-clean", 159 action="append", 160 default=["0"], 161 dest="cleanDirectories", 162 help="Directory from which templates are cleaned (to avoid problems with decomposePar). Can be specified more than once. Default: %default") 163 special.add_option("--overload-directory", 164 action="append", 165 default=[], 166 dest="overloadDirs", 167 help="Before starting the preparation process load files from this directory recursively into this case. Caution: existing files will be overwritten. Can be specified more than once. Directories are then copied in the specified order") 168 169 CommonTemplateFormat.addOptions(self) 170 CommonTemplateBehaviour.addOptions(self) 171 172 stages=OptionGroup(self.parser, 173 "Stages", 174 "Which steps should be executed") 175 self.parser.add_option_group(stages) 176 177 stages.add_option("--only-variables", 178 action="store_true", 179 dest="onlyVariables", 180 default=False, 181 help="Do nothing. Only read the variables") 182 183 stages.add_option("--no-clear", 184 action="store_false", 185 dest="doClear", 186 default=True, 187 help="Do not clear the case") 188 189 stages.add_option("--no-templates", 190 action="store_false", 191 dest="doTemplates", 192 default=True, 193 help="Do not rework the templates") 194 195 stages.add_option("--no-mesh-create", 196 action="store_false", 197 dest="doMeshCreate", 198 default=True, 199 help="Do not execute a script to create a mesh") 200 201 stages.add_option("--no-copy", 202 action="store_false", 203 dest="doCopy", 204 default=True, 205 help="Do not copy original directories") 206 207 stages.add_option("--no-post-templates", 208 action="store_false", 209 dest="doPostTemplates", 210 default=True, 211 help="Do not rework the post-templates") 212 213 stages.add_option("--no-case-setup", 214 action="store_false", 215 dest="doCaseSetup", 216 default=True, 217 help="Do not execute a script to set initial conditions etc") 218 219 stages.add_option("--no-template-clean", 220 action="store_false", 221 dest="doTemplateClean", 222 default=True, 223 help="Do not clean template files from 0-directory") 224 225 scripts=OptionGroup(self.parser, 226 "Scripts", 227 "Specification of scripts to be executed") 228 self.parser.add_option_group(scripts) 229 230 scripts.add_option("--mesh-create-script", 231 action="store", 232 dest="meshCreateScript", 233 default=None, 234 help="Script that is executed after the template expansion to create the mesh. If not specified then the utility looks for "+self.defaultMeshCreate+" and executes this. If this is also not found blockMesh is executed if a blockMeshDict is found") 235 scripts.add_option("--case-setup-script", 236 action="store", 237 dest="caseSetupScript", 238 default=None, 239 help="Script that is executed after the original files have been copied to set initial conditions or similar. If not specified then the utility looks for "+self.defaultCaseSetup+" and executes this.")
240
241 - def copyOriginals(self,startDir):
242 """Go recursivly through directories and copy foo.org to foo""" 243 if self.opts.verbose: 244 print_("Looking for originals in",startDir) 245 for f in listdir(startDir): 246 if f[0]==".": 247 if self.opts.verbose: 248 print_("Skipping",f) 249 continue 250 src=path.join(startDir,f) 251 if path.splitext(f)[1]==self.opts.originalExt: 252 dst=path.join(startDir,path.splitext(f)[0]) 253 if path.exists(dst): 254 if self.opts.verbose: 255 print_("Replacing",dst,"with",src) 256 rmtree(dst) 257 else: 258 if self.opts.verbose: 259 print_("Copying",src,"to",dst) 260 copytree(src,dst,force=True) 261 elif path.isdir(src): 262 self.copyOriginals(src)
263
264 - def cleanExtension(self, 265 startDir, 266 ext):
267 """Go recursivly through directories and remove all files that have a specific extension""" 268 if self.opts.verbose: 269 print_("Looking for extension",ext,"in",startDir) 270 for f in listdir(startDir): 271 if f[0]==".": 272 if self.opts.verbose: 273 print_("Skipping",f) 274 continue 275 src=path.join(startDir,f) 276 if path.splitext(f)[1]==ext and not path.isdir(src): 277 if self.opts.verbose: 278 print_("Removing",src) 279 remove(src) 280 elif path.isdir(src): 281 self.cleanExtension(src,ext)
282
283 - def searchAndReplaceTemplates(self, 284 startDir, 285 values, 286 templateExt):
287 """Go through the directory recursively and replate foo.template with 288 foo after inserting the values""" 289 if self.opts.verbose: 290 print_("Looking for templates with extension",templateExt,"in ",startDir) 291 for f in listdir(startDir): 292 if f[0]==".": 293 if self.opts.verbose: 294 print_("Skipping",f) 295 continue 296 if path.isdir(path.join(startDir,f)): 297 self.searchAndReplaceTemplates( 298 path.join(startDir,f), 299 values, 300 templateExt) 301 elif path.splitext(f)[1]==templateExt: 302 fName=path.join(startDir,path.splitext(f)[0]) 303 if self.opts.verbose: 304 print_("Found template for",fName) 305 t=TemplateFile(name=fName+templateExt, 306 tolerantRender=self.opts.tolerantRender, 307 allowExec=self.opts.allowExec, 308 expressionDelimiter=self.opts.expressionDelimiter, 309 assignmentDebug=self.pickAssignmentDebug(fName), 310 assignmentLineStart=self.opts.assignmentLineStart) 311 t.writeToFile(fName,values) 312 copymode(fName+templateExt,fName)
313
314 - def overloadDir(self,here,there):
315 """Copy files recursively. Overwrite local copies if they exist""" 316 for f in listdir(there): 317 fSrc=path.join(there,f) 318 fDst=path.join(here,f) 319 if path.isdir(fSrc): 320 if not path.exists(fDst): 321 if self.opts.verbose: 322 print_("Creating directory",fDst) 323 mkdir(fDst) 324 elif not path.isdir(fDst): 325 self.error("Destination path",fDst,"exists, but is no directory") 326 self.overloadDir(fDst,fSrc) 327 elif path.isfile(fSrc): 328 if path.exists(fDst): 329 if not path.isfile(fDst): 330 self.error("Desination",fDst,"exists but is no file") 331 if self.opts.verbose: 332 print_("Copying",fSrc,"to",fDst) 333 copy(fSrc,fDst) 334 else: 335 self.errr("Source file",fSrc,"is neither file nor directory")
336
337 - def run(self):
338 cName=self.parser.getArgs()[0] 339 if self.checkCase(cName,fatal=self.opts.fatal,verbose=not self.opts.noComplain): 340 self.addLocalConfig(cName) 341 sol=SolutionDirectory(cName,archive=None,paraviewLink=False) 342 self.prepare(sol,cName=cName)
343
344 - def prepare(self,sol,cName=None,overrideParameters=None):
345 if cName==None: 346 cName=sol.name 347 348 if self.opts.onlyVariables: 349 self.opts.verbose=True 350 351 vals={} 352 vals["casePath"]='"'+path.abspath(cName)+'"' 353 vals["caseName"]='"'+path.basename(path.abspath(cName))+'"' 354 vals["foamVersion"]=foamVersion() 355 vals["foamFork"]=foamFork() 356 357 if self.opts.verbose: 358 print_("Looking for template values",cName) 359 for f in self.opts.valuesDicts: 360 if self.opts.verbose: 361 print_("Reading values from",f) 362 vals.update(ParsedParameterFile(f, 363 noHeader=True, 364 doMacroExpansion=True).getValueDict()) 365 for v in self.opts.values: 366 if self.opts.verbose: 367 print_("Updating values",v) 368 vals.update(eval(v)) 369 370 if overrideParameters: 371 vals.update(overrideParameters) 372 373 if self.opts.verbose and len(vals)>0: 374 print_("\nUsed values\n") 375 nameLen=max(len("Name"), 376 max(*[len(k) for k in vals.keys()])) 377 format="%%%ds - %%s" % nameLen 378 print_(format % ("Name","Value")) 379 print_("-"*40) 380 for k,v in sorted(iteritems(vals)): 381 print_(format % (k,v)) 382 print_("") 383 elif self.opts.verbose: 384 print_("\nNo values specified\n") 385 386 if self.opts.onlyVariables: 387 return 388 389 if self.opts.doClear: 390 if self.opts.verbose: 391 print_("Clearing",cName) 392 sol.clear(processor=True, 393 pyfoam=True, 394 vtk=True, 395 removeAnalyzed=True, 396 keepParallel=False, 397 clearHistory=False, 398 clearParameters=True, 399 additional=["postProcessing"]) 400 401 if self.opts.writeParameters: 402 fName=path.join(cName,self.parameterOutFile) 403 if self.opts.verbose: 404 print_("Writing parameters to",fName) 405 with WriteParameterFile(fName,noHeader=True) as w: 406 w.content.update(vals,toString=True) 407 w["foamVersion"]=vals["foamVersion"] 408 w.writeFile() 409 410 self.addToCaseLog(cName) 411 412 for over in self.opts.overloadDirs: 413 if self.opts.verbose: 414 print_("Overloading files from",over) 415 self.overloadDir(sol.name,over) 416 417 zeroOrig=path.join(sol.name,"0.org") 418 419 hasOrig=path.exists(zeroOrig) 420 if not hasOrig: 421 if self.opts.verbose: 422 print_("Not going to clean '0'") 423 self.opts.cleanDirectories.remove("0") 424 425 if self.opts.doCopy: 426 if hasOrig: 427 if self.opts.verbose: 428 print_("Found 0.org. Clearing 0") 429 zeroDir=path.join(sol.name,"0") 430 if path.exists(zeroDir): 431 rmtree(zeroDir) 432 elif self.opts.verbose: 433 print_("No 0-directory") 434 435 if self.opts.verbose: 436 print_("") 437 438 if self.opts.doTemplates: 439 self.searchAndReplaceTemplates(sol.name, 440 vals, 441 self.opts.templateExt) 442 443 if self.opts.verbose: 444 print_("") 445 446 if self.opts.doMeshCreate: 447 if self.opts.meshCreateScript: 448 scriptName=path.join(sol.name,self.opts.meshCreateScript) 449 if not path.exists(scriptName): 450 self.error("Script",scriptName,"does not exist") 451 elif path.exists(path.join(sol.name,self.defaultMeshCreate)): 452 scriptName=path.join(sol.name,self.defaultMeshCreate) 453 else: 454 scriptName=None 455 456 if scriptName: 457 if self.opts.verbose: 458 print_("Executing",scriptName,"for mesh creation") 459 if self.opts.verbose: 460 echo="Mesh: " 461 else: 462 echo=None 463 result="".join(execute([scriptName],workdir=sol.name,echo=echo)) 464 open(scriptName+".log","w").write(result) 465 else: 466 if self.opts.verbose: 467 print_("No script for mesh creation found. Looking for 'blockMeshDict'") 468 if sol.blockMesh()!="": 469 if self.opts.verbose: 470 print_(sol.blockMesh(),"found. Executing 'blockMesh'") 471 bm=BasicRunner(argv=["blockMesh","-case",sol.name]) 472 bm.start() 473 if not bm.runOK(): 474 self.error("Problem with blockMesh") 475 if self.opts.verbose: 476 print_("") 477 478 if self.opts.doCopy: 479 self.copyOriginals(sol.name) 480 481 if self.opts.verbose: 482 print_("") 483 484 if self.opts.doPostTemplates: 485 self.searchAndReplaceTemplates(sol.name, 486 vals, 487 self.opts.postTemplateExt) 488 489 if self.opts.verbose: 490 print_("") 491 492 if self.opts.doCaseSetup: 493 if self.opts.caseSetupScript: 494 scriptName=path.join(sol.name,self.opts.caseSetupScript) 495 if not path.exists(scriptName): 496 self.error("Script",scriptName,"does not exist") 497 elif path.exists(path.join(sol.name,self.defaultCaseSetup)): 498 scriptName=path.join(sol.name,self.defaultCaseSetup) 499 else: 500 scriptName=None 501 502 if scriptName: 503 if self.opts.verbose: 504 print_("Executing",scriptName,"for case setup") 505 if self.opts.verbose: 506 echo="Case:" 507 else: 508 echo=None 509 result="".join(execute([scriptName],workdir=sol.name,echo=echo)) 510 open(scriptName+".log","w").write(result) 511 else: 512 if self.opts.verbose: 513 print_("No script for case-setup found. Nothing done") 514 if self.opts.verbose: 515 print_("") 516 517 if self.opts.doTemplateClean: 518 if self.opts.verbose: 519 print_("Clearing templates") 520 for d in self.opts.cleanDirectories: 521 for e in [self.opts.templateExt,self.opts.postTemplateExt]: 522 self.cleanExtension(path.join(sol.name,d),e) 523 if self.opts.verbose: 524 print_("") 525 526 if self.opts.verbose: 527 print_("Case setup finished")
528