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

Source Code for Module PyFoam.Applications.Decomposer

  1  #  ICE Revision: $Id: /local/openfoam/Python/PyFoam/PyFoam/Applications/Decomposer.py 6624 2010-05-27T22:52:22.964263Z bgschaid  $  
  2  """ 
  3  Class that implements pyFoamDecompose 
  4  """ 
  5   
  6  from optparse import OptionGroup 
  7   
  8  from PyFoamApplication import PyFoamApplication 
  9  from PyFoam.Basics.FoamFileGenerator import FoamFileGenerator 
 10  from PyFoam.Error import error 
 11  from PyFoam.Basics.Utilities import writeDictionaryHeader 
 12  from PyFoam.Execution.UtilityRunner import UtilityRunner 
 13  from PyFoam.RunDictionary.SolutionDirectory import SolutionDirectory 
 14  from PyFoam.RunDictionary.RegionCases import RegionCases 
 15  from PyFoam.FoamInformation import oldAppConvention as oldApp 
 16  from PyFoam.FoamInformation import foamVersion 
 17   
 18  from CommonMultiRegion import CommonMultiRegion 
 19  from CommonStandardOutput import CommonStandardOutput 
 20  from CommonServer import CommonServer 
 21   
 22  from os import path,system,listdir,symlink 
 23  import sys,string 
 24   
25 -class Decomposer(PyFoamApplication, 26 CommonStandardOutput, 27 CommonServer, 28 CommonMultiRegion):
29 - def __init__(self,args=None):
30 description=""" 31 Generates a decomposeParDict for a case and runs the decompose-Utility on that case 32 """ 33 PyFoamApplication.__init__(self, 34 args=args, 35 description=description, 36 usage="%prog [options] <case> <procnr>", 37 interspersed=True, 38 nr=2)
39 40 decomposeChoices=["metis","simple","hierarchical","manual"] 41 defaultMethod="metis" 42
43 - def addOptions(self):
44 if foamVersion()>=(1,6): 45 self.defaultMethod="scotch" 46 self.decomposeChoices+=[self.defaultMethod] 47 48 spec=OptionGroup(self.parser, 49 "Decomposition Specification", 50 "How the case should be decomposed") 51 spec.add_option("--method", 52 type="choice", 53 default=self.defaultMethod, 54 dest="method", 55 action="store", 56 choices=self.decomposeChoices, 57 help="The method used for decomposing (Choices: "+string.join(self.decomposeChoices,", ")+") Default: %default") 58 59 spec.add_option("--n", 60 dest="n", 61 action="store", 62 default=None, 63 help="Number of subdivisions in coordinate directions. A python list or tuple (for simple and hierarchical)") 64 65 spec.add_option("--delta", 66 dest="delta", 67 action="store", 68 type="float", 69 default=None, 70 help="Cell skew factor (for simple and hierarchical)") 71 72 spec.add_option("--order", 73 dest="order", 74 action="store", 75 default=None, 76 help="Order of decomposition (for hierarchical)") 77 78 spec.add_option("--processorWeights", 79 dest="processorWeights", 80 action="store", 81 default=None, 82 help="The weights of the processors. A python list. Used for metis") 83 84 spec.add_option("--globalFaceZones", 85 dest="globalFaceZones", 86 action="store", 87 default=None, 88 help="Global face zones. A python string. Used for the GGI interface. Ex: '(GGI_Z1 GGI_Z2)'") 89 90 spec.add_option("--dataFile", 91 dest="dataFile", 92 action="store", 93 default=None, 94 help="File with the allocations. (for manual)") 95 self.parser.add_option_group(spec) 96 97 behave=OptionGroup(self.parser, 98 "Decomposition behaviour", 99 "How the program should behave during decomposition") 100 behave.add_option("--test", 101 dest="test", 102 action="store_true", 103 default=False, 104 help="Just print the resulting dictionary") 105 106 behave.add_option("--clear", 107 dest="clear", 108 action="store_true", 109 default=False, 110 help="Clear the case of previous processor directories") 111 112 behave.add_option("--no-decompose", 113 dest="doDecompose", 114 action="store_false", 115 default=True, 116 help="Don't run the decomposer (only writes the dictionary") 117 118 behave.add_option("--decomposer", 119 dest="decomposer", 120 action="store", 121 default="decomposePar", 122 help="The decompose Utility that should be used") 123 self.parser.add_option_group(behave) 124 125 work=OptionGroup(self.parser, 126 "Additional work", 127 "What else should be done in addition to decomposing") 128 work.add_option("--constant-link", 129 dest="doConstantLinks", 130 action="store_true", 131 default=False, 132 help="Add links to the contents of the constant directory to the constant directories of the processor-directories") 133 self.parser.add_option_group(work) 134 135 CommonMultiRegion.addOptions(self) 136 CommonStandardOutput.addOptions(self) 137 CommonServer.addOptions(self,False)
138
139 - def run(self):
140 if self.opts.keeppseudo and (not self.opts.regions and self.opts.region==None): 141 warning("Option --keep-pseudocases only makes sense for multi-region-cases") 142 143 nr=int(self.parser.getArgs()[1]) 144 if nr<2: 145 error("Number of processors",nr,"too small (at least 2)") 146 147 case=path.abspath(self.parser.getArgs()[0]) 148 method=self.opts.method 149 150 result={} 151 result["numberOfSubdomains"]=nr 152 result["method"]=method 153 154 coeff={} 155 result[method+"Coeffs"]=coeff 156 157 if self.opts.globalFaceZones!=None: 158 fZones=eval(self.opts.globalFaceZones) 159 result["globalFaceZones"]=fZones 160 161 if method=="metis" or method=="scotch": 162 if self.opts.processorWeights!=None: 163 weigh=eval(self.opts.processorWeights) 164 if nr!=len(weigh): 165 error("Number of processors",nr,"and length of",weigh,"differ") 166 coeff["processorWeights"]=weigh 167 elif method=="manual": 168 if self.opts.dataFile==None: 169 error("Missing required option dataFile") 170 else: 171 coeff["dataFile"]="\""+self.opts.dataFile+"\"" 172 elif method=="simple" or method=="hierarchical": 173 if self.opts.n==None or self.opts.delta==None: 174 error("Missing required option n or delta") 175 n=eval(self.opts.n) 176 if len(n)!=3: 177 error("Needs to be three elements, not",n) 178 if nr!=n[0]*n[1]*n[2]: 179 error("Subdomains",n,"inconsistent with processor number",nr) 180 coeff["n"]="(%d %d %d)" % (n[0],n[1],n[2]) 181 182 coeff["delta"]=float(self.opts.delta) 183 if method=="hierarchical": 184 if self.opts.order==None: 185 error("Missing reuired option order") 186 if len(self.opts.order)!=3: 187 error("Order needs to be three characters") 188 coeff["order"]=self.opts.order 189 else: 190 error("Method",method,"not yet implementes") 191 192 gen=FoamFileGenerator(result) 193 194 if self.opts.test: 195 print str(gen) 196 sys.exit(-1) 197 else: 198 f=open(path.join(case,"system","decomposeParDict"),"w") 199 writeDictionaryHeader(f) 200 f.write(str(gen)) 201 f.close() 202 203 if self.opts.clear: 204 system("rm -rf "+path.join(case,"processor*")) 205 206 if self.opts.doDecompose: 207 regionNames=[self.opts.region] 208 regions=None 209 210 if self.opts.regions or self.opts.region!=None: 211 print "Building Pseudocases" 212 sol=SolutionDirectory(case) 213 regions=RegionCases(sol,clean=True,processorDirs=False) 214 215 if self.opts.regions: 216 regionNames=sol.getRegions() 217 218 for theRegion in regionNames: 219 theCase=path.normpath(case) 220 if theRegion!=None: 221 theCase+="."+theRegion 222 223 if oldApp(): 224 argv=[self.opts.decomposer,".",theCase] 225 else: 226 argv=[self.opts.decomposer,"-case",theCase] 227 228 self.setLogname(default="Decomposer",useApplication=False) 229 230 run=UtilityRunner(argv=argv, 231 silent=self.opts.progress, 232 logname=self.opts.logname, 233 compressLog=self.opts.compress, 234 server=self.opts.server, 235 noLog=self.opts.noLog, 236 jobId=self.opts.jobId) 237 run.start() 238 239 if theRegion!=None: 240 print "Syncing into master case" 241 regions.resync(theRegion) 242 243 if regions!=None: 244 if not self.opts.keeppseudo: 245 print "Removing pseudo-regions" 246 regions.cleanAll() 247 else: 248 for r in sol.getRegions(): 249 if r not in regionNames: 250 regions.clean(r) 251 252 if self.opts.doConstantLinks: 253 print "Adding symlinks in the constant directories" 254 constPath=path.join(case,"constant") 255 for f in listdir(constPath): 256 srcExpr=path.join(path.pardir,path.pardir,"constant",f) 257 for p in range(nr): 258 dest=path.join(case,"processor%d"%p,"constant",f) 259 if not path.exists(dest): 260 symlink(srcExpr,dest) 261 262 self.addToCaseLog(case)
263