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

Source Code for Module PyFoam.Applications.CaseBuilderBackend

  1  """ 
  2  Represents the actual CaseBuilder-File and other things that have to do with the Casebuilder 
  3  """ 
  4   
  5  from xml.dom.minidom import parse 
  6  import xml.dom 
  7  from os import path 
  8  import os 
  9  import shutil 
 10  import glob 
 11   
 12  from PyFoam.Error import error 
 13  from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile 
 14  from PyFoam.Execution.BasicRunner import BasicRunner 
 15  from PyFoam.FoamInformation import oldAppConvention as oldApp 
 16  from CreateBoundaryPatches import CreateBoundaryPatches 
 17  from PyFoam import configuration as config 
 18   
19 -class CaseBuilderDescriptionList(object):
20 """Gets a list of the case-builder files found in the current path"""
21 - def __init__(self):
22 dirList=config().get("CaseBuilder","descriptionpath") 23 self.list=[] 24 for d in dirList: 25 for f in glob.glob(path.join(d,"*.pfcb")): 26 nm=path.basename(f) 27 cb=CaseBuilderFile(f) 28 self.list.append((nm,f,cb.name(),cb.description()))
29
30 - def __iter__(self):
31 for f in self.list: 32 yield f
33
34 - def __len__(self):
35 return len(self.list)
36
37 - def __getitem__(self,i):
38 return self.list[i]
39
40 -class CaseBuilderFile(object):
41 """ 42 This class reads an XML-file that describes how to build a case 43 and gives information about the case and if asked to builds the actual case 44 """ 45
46 - def __init__(self,fName):
47 """@param fName: the XML-file that describes how to build the case""" 48 49 dom=parse(fName) 50 self.doc=dom.documentElement 51 52 if self.doc.tagName!='casebuilder': 53 error("Wrong root-element",self.doc.tagName,"Expected: 'casebuilder'")
54
55 - def name(self):
56 return self.doc.getAttribute("name")
57
58 - def description(self):
59 return self.doc.getAttribute("description")
60
61 - def helpText(self):
62 ht=self.getSingleElement(self.doc,"helptext",optional=True) 63 if ht: 64 return ht.firstChild.nodeValue 65 else: 66 return "<No help text>"
67
68 - def argTree(self):
69 return self.getSingleElement(self.doc,"arguments")
70
71 - def varTree(self):
72 return self.getSingleElement(self.doc,"variables",optional=True)
73
74 - def filesTree(self):
75 return self.getSingleElement(self.doc,"files")
76
77 - def boundaryTree(self):
78 return self.getSingleElement(self.filesTree(),"boundaries")
79
80 - def fieldTree(self):
81 return self.getSingleElement(self.filesTree(),"fieldfiles")
82
83 - def parameterTree(self):
84 return self.getSingleElement(self.filesTree(),"parameterfiles")
85
86 - def templatePath(self):
87 return self.expandVars(self.doc.getAttribute("template"))
88
89 - def initialDir(self):
90 tmp=self.doc.getAttribute("initialdir") 91 if tmp=="": 92 tmp="0" 93 return tmp
94
95 - def expandVars(self,orig,keys=None):
96 orig=path.expanduser(orig) 97 orig=path.expandvars(orig) 98 if keys!=None: 99 orig=orig % keys 100 return orig
101
102 - def boundaries(self):
103 bounds=[] 104 105 for a in self.boundaryTree().getElementsByTagName("boundary"): 106 bounds.append(a.getAttribute("name")) 107 108 return bounds
109
110 - def boundaryPatterns(self):
111 bounds=[] 112 113 for a in self.boundaryTree().getElementsByTagName("boundary"): 114 bounds.append((a.getAttribute("name"),a.getAttribute("pattern"))) 115 116 return bounds
117
118 - def boundaryPatternDict(self):
119 res={} 120 for nm,pat in self.boundaryPatterns(): 121 res[nm]=pat 122 return res
123
124 - def boundaryDescriptions(self):
125 bounds={} 126 127 for a in self.boundaryTree().getElementsByTagName("boundary"): 128 bounds[a.getAttribute("name")]=a.getAttribute("description") 129 130 return bounds
131
132 - def argumentGroups(self):
133 args=[] 134 135 for a in self.argTree().getElementsByTagName("argumentgroup"): 136 args.append(a.getAttribute("name")) 137 138 return args
139
140 - def argumentGroupDescription(self):
141 args={} 142 143 for a in self.argTree().getElementsByTagName("argumentgroup"): 144 args[a.getAttribute("name")]=a.getAttribute("description") 145 146 return args
147
148 - def arguments(self):
149 args=[] 150 151 for a in self.argTree().getElementsByTagName("arg"): 152 args.append(a.getAttribute("name")) 153 154 return args
155
156 - def groupArguments(self,name=None):
157 """Returns a list with the arguments belongin to a specific group 158 @param name: Name of the group. If none is given, then all the arguments 159 belonging to no group are returned""" 160 161 result=[] 162 163 for c in self.argTree().childNodes: 164 if "tagName" in dir(c): 165 if c.tagName=="arg" and name==None: 166 result.append(c.getAttribute("name")) 167 elif c.tagName=="argumentgroup": 168 if c.getAttribute("name")==name: 169 for e in c.getElementsByTagName("arg"): 170 result.append(e.getAttribute("name")) 171 172 return result
173
174 - def argumentDescriptions(self):
175 args={} 176 177 for a in self.argTree().getElementsByTagName("arg"): 178 args[a.getAttribute("name")]=a.getAttribute("description") 179 180 return args
181
182 - def argumentDefaults(self):
183 args={} 184 185 for a in self.argTree().getElementsByTagName("arg"): 186 args[a.getAttribute("name")]=a.getAttribute("default") 187 188 return args
189
190 - def getSingleElement(self,parent,name,optional=False):
191 """Get an element and check that it is the only one 192 @param parent: the parent element 193 @param name: The name of the element""" 194 195 tmp=parent.getElementsByTagName(name) 196 if len(tmp)<1: 197 if optional: 198 return None 199 else: 200 error("Element",name,"does not exist") 201 if len(tmp)>1: 202 error("More than one element",name,"does exist") 203 return tmp[0]
204
205 - def makeBC(self,node,args):
206 result="'type':'"+node.getAttribute("type")+"'" 207 para=self.expandVars(node.getAttribute("parameters"),args) 208 if para!="": 209 result+=","+para 210 return "{"+result+"}"
211
212 - def verifyArguments(self,args):
213 """Validate the arguments with the provided code (if it exists)""" 214 totalMsg="" 215 for a in self.argTree().getElementsByTagName("arg"): 216 msg=None 217 nm=a.getAttribute("name") 218 verify=self.getSingleElement(a,"verify",optional=True) 219 if verify: 220 valid=self.getSingleElement(verify,"validator",optional=True) 221 script=self.getSingleElement(verify,"script",optional=True) 222 if valid and script: 223 error("Variable",nm,"has script and validator. Only one of them supported") 224 elif valid: 225 typ=valid.getAttribute("type") 226 arg=args[nm] 227 isNumeric=False 228 if typ=="float": 229 isNumeric=True 230 try: 231 tmp=float(arg) 232 except ValueError: 233 msg="Not a floating point number" 234 elif typ=="integer": 235 isNumeric=True 236 try: 237 tmp=int(arg) 238 except ValueError: 239 msg="Not an integer number" 240 elif typ=="file": 241 if not path.exists(arg): 242 msg="File "+arg+" does not exist" 243 else: 244 error("No validator implemented for type",typ,"in variable",nm) 245 if isNumeric and not msg: 246 if valid.hasAttribute("min"): 247 if float(arg)<float(valid.getAttribute("min")): 248 msg="Must be bigger than "+valid.getAttribute("min") 249 if valid.hasAttribute("max"): 250 if float(arg)>float(valid.getAttribute("max")): 251 msg="Must be smaller than "+valid.getAttribute("max") 252 253 elif script: 254 if script.getAttribute("plugin")!="python": 255 error("Only plugin-type 'python' is supported for variable",nm) 256 code=script.firstChild.nodeValue 257 arg=args[nm] 258 exec code 259 if msg: 260 totalMsg+=nm+": "+msg+" " 261 262 if totalMsg=="": 263 totalMsg=None 264 265 return totalMsg
266
267 - def calculateVariables(self,_args_):
268 """Add derived variables to the argument dictionary""" 269 270 for _a_ in _args_: 271 exec "%s = '%s'" % (_a_,_args_[_a_]) 272 273 if self.varTree(): 274 for _a_ in self.varTree().getElementsByTagName("var"): 275 _nm_=_a_.getAttribute("name") 276 if _nm_ in ["_args_","_a_","_nm_"]: 277 error("Variable",_nm_,"is needed for this routine to work") 278 279 if len(_a_.firstChild.nodeValue)>0: 280 exec _a_.firstChild.nodeValue 281 exec "_args_['"+_nm_+"']=str("+_nm_+")" 282 283 return _args_
284
285 - def buildCase(self,cName,args):
286 """Builds the case 287 @param cName: The name of the case directory 288 @param args: The arguments (as a dictionary)""" 289 290 args=self.calculateVariables(args) 291 292 os.mkdir(cName) 293 294 for d in self.parameterTree().getElementsByTagName("directory"): 295 dName=path.join(cName,d.getAttribute("name")) 296 if not path.isdir(dName): 297 os.mkdir(dName) 298 sName=path.join(self.templatePath(),d.getAttribute("name")) 299 for f in d.getElementsByTagName("file"): 300 dFile=path.join(dName,f.getAttribute("name")) 301 shutil.copy(path.join(sName,f.getAttribute("name")),dFile) 302 if len(f.getElementsByTagName("parameter"))>0: 303 pf=ParsedParameterFile(dFile) 304 for p in f.getElementsByTagName("parameter"): 305 pName=p.getAttribute("name") 306 pValue=self.expandVars(p.getAttribute("value"),args) 307 exec "pf"+pName+"="+pValue 308 pf.writeFile() 309 310 prep=self.getSingleElement(self.doc,"meshpreparation") 311 util=self.getSingleElement(prep,"utility",optional=True) 312 copy=self.getSingleElement(prep,"copy",optional=True) 313 314 if util and copy: 315 error("Copy and utilitiy mesh preparation specified") 316 elif util: 317 app=util.getAttribute("command") 318 arg=self.expandVars(util.getAttribute("arguments"),args) 319 argv=[app,"-case",cName]+arg.split() 320 if oldApp(): 321 argv[1]="." 322 run=BasicRunner(argv=argv,silent=True,logname="CaseBuilder.prepareMesh."+app) 323 run.start() 324 if not run.runOK(): 325 error(app,"failed. Check the logs") 326 elif copy: 327 source=self.expandVars(copy.getAttribute("template"),args) 328 time=self.expandVars(copy.getAttribute("time"),args) 329 if time=="": 330 time="constant" 331 shutil.copytree(path.join(source,time,"polyMesh"), 332 path.join(cName,"constant","polyMesh")) 333 else: 334 error("Neither copy nor utilitiy mesh preparation specified") 335 336 dName=path.join(cName,self.initialDir()) 337 if not path.isdir(dName): 338 os.mkdir(dName) 339 sName=path.join(self.templatePath(),self.initialDir()) 340 for f in self.fieldTree().getElementsByTagName("field"): 341 dFile=path.join(dName,f.getAttribute("name")) 342 shutil.copy(path.join(sName,f.getAttribute("name")),dFile) 343 default=self.makeBC(self.getSingleElement(f,"defaultbc"),args) 344 345 CreateBoundaryPatches(args=["--fix-types", 346 "--overwrite", 347 "--clear", 348 "--default="+default, 349 dFile]) 350 bcDict={} 351 bounds=self.boundaries() 352 for b in f.getElementsByTagName("bc"): 353 nm=b.getAttribute("name") 354 if nm not in bounds: 355 error("Boundary",nm,"not in list",bounds,"for field",f.getAttribute("name")) 356 bcDict[nm]=b 357 358 for name,pattern in self.boundaryPatterns(): 359 if name in bcDict: 360 default=self.makeBC(bcDict[name],args) 361 CreateBoundaryPatches(args=["--filter="+pattern, 362 "--overwrite", 363 "--default="+default, 364 dFile]) 365 366 ic=self.expandVars(self.getSingleElement(f,"ic").getAttribute("value"),args) 367 pf=ParsedParameterFile(dFile) 368 pf["internalField"]="uniform "+ic 369 pf.writeFile()
370