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

Source Code for Module PyFoam.Applications.Decomposer

  1  #  ICE Revision: $Id: Decomposer.py 9973 2009-02-05 12:47:31Z 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   
 17  from CommonMultiRegion import CommonMultiRegion 
 18  from CommonStandardOutput import CommonStandardOutput 
 19  from CommonServer import CommonServer 
 20   
 21  from os import path,system 
 22  import sys,string 
 23   
24 -class Decomposer(PyFoamApplication, 25 CommonStandardOutput, 26 CommonServer, 27 CommonMultiRegion):
28 - def __init__(self,args=None):
29 description=""" 30 Generates a decomposeParDict for a case and runs the decompose-Utility on that case 31 """ 32 PyFoamApplication.__init__(self, 33 args=args, 34 description=description, 35 usage="%prog [options] <case> <procnr>", 36 interspersed=True, 37 nr=2)
38 39 decomposeChoices=["metis","simple","hierarchical","manual"] 40
41 - def addOptions(self):
42 spec=OptionGroup(self.parser, 43 "Decomposition Specification", 44 "How the case should be decomposed") 45 spec.add_option("--method", 46 type="choice", 47 default="metis", 48 dest="method", 49 action="store", 50 choices=self.decomposeChoices, 51 help="The method used for decomposing (Choices: "+string.join(self.decomposeChoices,", ")+") Default: %default") 52 53 spec.add_option("--n", 54 dest="n", 55 action="store", 56 default=None, 57 help="Number of subdivisions in coordinate directions. A python list or tuple (for simple and hierarchical)") 58 59 spec.add_option("--delta", 60 dest="delta", 61 action="store", 62 type="float", 63 default=None, 64 help="Cell skew factor (for simple and hierarchical)") 65 66 spec.add_option("--order", 67 dest="order", 68 action="store", 69 default=None, 70 help="Order of decomposition (for hierarchical)") 71 72 spec.add_option("--processorWeights", 73 dest="processorWeights", 74 action="store", 75 default=None, 76 help="The weights of the processors. A python list. Used for metis") 77 78 spec.add_option("--dataFile", 79 dest="dataFile", 80 action="store", 81 default=None, 82 help="File with the allocations. (for manual)") 83 self.parser.add_option_group(spec) 84 85 behave=OptionGroup(self.parser, 86 "Decomposition behaviour", 87 "How the program should behave during decomposition") 88 behave.add_option("--test", 89 dest="test", 90 action="store_true", 91 default=False, 92 help="Just print the resulting dictionary") 93 94 behave.add_option("--clear", 95 dest="clear", 96 action="store_true", 97 default=False, 98 help="Clear the case of previous processor directories") 99 100 behave.add_option("--no-decompose", 101 dest="doDecompose", 102 action="store_false", 103 default=True, 104 help="Don't run the decomposer (only writes the dictionary") 105 106 behave.add_option("--decomposer", 107 dest="decomposer", 108 action="store", 109 default="decomposePar", 110 help="The decompose Utility that should be used") 111 self.parser.add_option_group(behave) 112 113 CommonMultiRegion.addOptions(self) 114 CommonStandardOutput.addOptions(self) 115 CommonServer.addOptions(self,False)
116
117 - def run(self):
118 if self.opts.keeppseudo and (not self.opts.regions and self.opts.region==None): 119 warning("Option --keep-pseudocases only makes sense for multi-region-cases") 120 121 nr=int(self.parser.getArgs()[1]) 122 if nr<2: 123 error("Number of processors",nr,"too small (at least 2)") 124 125 case=self.parser.getArgs()[0] 126 method=self.opts.method 127 128 result={} 129 result["numberOfSubdomains"]=nr 130 result["method"]=method 131 132 coeff={} 133 result[method+"Coeffs"]=coeff 134 135 if method=="metis": 136 if self.opts.processorWeights!=None: 137 weigh=eval(self.opts.processorWeights) 138 if nr!=len(weigh): 139 error("Number of processors",nr,"and length of",weigh,"differ") 140 coeff["processorWeights"]=weigh 141 elif method=="manual": 142 if self.opts.dataFile==None: 143 error("Missing required option dataFile") 144 else: 145 coeff["dataFile"]="\""+self.opts.dataFile+"\"" 146 elif method=="simple" or method=="hierarchical": 147 if self.opts.n==None or self.opts.delta==None: 148 error("Missing required option n or delta") 149 n=eval(self.opts.n) 150 if len(n)!=3: 151 error("Needs to be three elements, not",n) 152 if nr!=n[0]*n[1]*n[2]: 153 error("Subdomains",n,"inconsistent with processor number",nr) 154 coeff["n"]="(%d %d %d)" % (n[0],n[1],n[2]) 155 156 coeff["delta"]=float(self.opts.delta) 157 if method=="hierarchical": 158 if self.opts.order==None: 159 error("Missing reuired option order") 160 if len(self.opts.order)!=3: 161 error("Order needs to be three characters") 162 coeff["order"]=self.opts.order 163 else: 164 error("Method",method,"not yet implementes") 165 166 gen=FoamFileGenerator(result) 167 168 if self.opts.test: 169 print str(gen) 170 sys.exit(-1) 171 else: 172 f=open(path.join(case,"system","decomposeParDict"),"w") 173 writeDictionaryHeader(f) 174 f.write(str(gen)) 175 f.close() 176 177 if self.opts.clear: 178 system("rm -rf "+path.join(case,"processor*")) 179 180 if self.opts.doDecompose: 181 regionNames=[self.opts.region] 182 regions=None 183 184 if self.opts.regions or self.opts.region!=None: 185 print "Building Pseudocases" 186 sol=SolutionDirectory(case) 187 regions=RegionCases(sol,clean=True) 188 189 if self.opts.regions: 190 regionNames=sol.getRegions() 191 192 for theRegion in regionNames: 193 theCase=path.normpath(case) 194 if theRegion!=None: 195 theCase+="."+theRegion 196 197 if oldApp(): 198 argv=[self.opts.decomposer,".",theCase] 199 else: 200 argv=[self.opts.decomposer,"-case",theCase] 201 202 self.setLogname(default="Decomposer",useApplication=False) 203 204 run=UtilityRunner(argv=argv, 205 silent=self.opts.progress, 206 logname=self.opts.logname, 207 server=self.opts.server, 208 noLog=self.opts.noLog) 209 run.start() 210 211 if theRegion!=None: 212 print "Syncing into master case" 213 regions.resync(theRegion) 214 215 if regions!=None: 216 if not self.opts.keeppseudo: 217 print "Removing pseudo-regions" 218 regions.cleanAll() 219 else: 220 for r in sol.getRegions(): 221 if r not in regionNames: 222 regions.clean(r)
223