1
2 """
3 Class that implements pyFoamDecompose
4 """
5
6 from PyFoamApplication import PyFoamApplication
7 from PyFoam.FoamInformation import changeFoamVersion
8 from PyFoam.Basics.FoamFileGenerator import FoamFileGenerator
9 from PyFoam.Error import error
10 from PyFoam.Basics.Utilities import writeDictionaryHeader
11 from PyFoam.Execution.UtilityRunner import UtilityRunner
12
13 from os import path,system
14 import sys
15
18 description="""
19 Generates a decomposeParDict for a case and runs the decompose-Utility on that case
20 """
21 PyFoamApplication.__init__(self,description=description,usage="%prog [options] <case> <procnr>",interspersed=True,nr=2)
22
24 self.parser.add_option("--method",type="choice",default="metis",dest="method",action="store",
25 choices=["metis","simple","hierarchical","manual"],
26 help="The method used for decomposing")
27
28 self.parser.add_option("--test",dest="test",action="store_true",default=False,
29 help="Just print the resulting dictionary")
30
31 self.parser.add_option("--n",dest="n",action="store",default=None,
32 help="Number of subdivisions in coordinate directions. A python list or tuple (for simple and hierarchical)")
33 self.parser.add_option("--delta",dest="delta",action="store",type="float",default=None,
34 help="Cell skew factor (for simple and hierarchical)")
35 self.parser.add_option("--order",dest="order",action="store",default=None,
36 help="Order of decomposition (for hierarchical)")
37 self.parser.add_option("--processorWeights",dest="processorWeights",action="store",default=None,
38 help="The weights of the processors. A python list. Used for metis")
39 self.parser.add_option("--dataFile",dest="dataFile",action="store",default=None,
40 help="File with the allocations. (for manual)")
41
42 self.parser.add_option("--clear",dest="clear",action="store_true",default=False,
43 help="Clear the case of previous processor directories")
44 self.parser.add_option("--no-decompose",dest="doDecompose",action="store_false",default=True,
45 help="Don't run the decomposer (only writes the dictionary")
46 self.parser.add_option("--decomposer",dest="decomposer",action="store",default="decomposePar",
47 help="The decompose Utility that should be used")
48 self.parser.add_option("--foamVersion",dest="foamVersion",default=None,
49 help="Change the OpenFOAM-version that is to be used")
50
52 if self.opts.foamVersion!=None:
53 changeFoamVersion(self.opts.foamVersion)
54
55 nr=int(self.parser.getArgs()[1])
56 if nr<2:
57 error("Number of processors",nr,"too small (at least 2)")
58
59 case=self.parser.getArgs()[0]
60 method=self.opts.method
61
62 result={}
63 result["numberOfSubdomains"]=nr
64 result["method"]=method
65
66 coeff={}
67 result[method+"Coeffs"]=coeff
68
69 if method=="metis":
70 if self.opts.processorWeights!=None:
71 weigh=eval(self.opts.processorWeights)
72 if nr!=len(weigh):
73 error("Number of processors",nr,"and length of",weigh,"differ")
74 coeff["processorWeights"]=weigh
75 elif method=="manual":
76 if self.opts.dataFile==None:
77 error("Missing required option dataFile")
78 else:
79 coeff["dataFile"]="\""+self.opts.dataFile+"\""
80 elif method=="simple" or method=="hierarchical":
81 if self.opts.n==None or self.opts.delta==None:
82 error("Missing required option n or delta")
83 n=eval(self.opts.n)
84 if len(n)!=3:
85 error("Needs to be three elements, not",n)
86 if nr!=n[0]*n[1]*n[2]:
87 error("Subdomains",n,"inconsistent with processor number",nr)
88 coeff["n"]="(%d %d %d)" % (n[0],n[1],n[2])
89
90 coeff["delta"]=float(self.opts.delta)
91 if method=="hierarchical":
92 if self.opts.order==None:
93 error("Missing reuired option order")
94 if len(self.opts.order)!=3:
95 error("Order needs to be three characters")
96 coeff["order"]=self.opts.order
97 else:
98 error("Method",method,"not yet implementes")
99
100 gen=FoamFileGenerator(result)
101
102 if self.opts.test:
103 print str(gen)
104 sys.exit(-1)
105 else:
106 f=open(path.join(case,"system","decomposeParDict"),"w")
107 writeDictionaryHeader(f)
108 f.write(str(gen))
109 f.close()
110
111 if self.opts.clear:
112 system("rm -rf "+path.join(case,"processor*"))
113
114 if self.opts.doDecompose:
115 run=UtilityRunner(argv=[self.opts.decomposer,".",case],silent=False,server=False)
116 run.start()
117