1
2 """
3 Application class that implements pyFoamRunner
4 """
5
6 from PyFoamApplication import PyFoamApplication
7
8 from PyFoam.FoamInformation import changeFoamVersion
9
10 from PyFoam.Execution.AnalyzedRunner import AnalyzedRunner
11 from PyFoam.LogAnalysis.BoundingLogAnalyzer import BoundingLogAnalyzer
12 from PyFoam.LogAnalysis.RegExpLineAnalyzer import RegExpLineAnalyzer
13 from PyFoam.RunDictionary.SolutionDirectory import SolutionDirectory
14 from PyFoam.RunDictionary.RegionCases import RegionCases
15
16 from PyFoam.Execution.ParallelExecution import LAMMachine
17
18 from PyFoam.Error import warning,error
19
20 from os import path
21
22 -class Runner(PyFoamApplication):
24 description="""
25 Runs an OpenFoam solver. Needs the usual 3 arguments (<solver>
26 <directory> <case>) and passes them on (plus additional arguments).
27 Output is sent to stdout and a logfile inside the case directory
28 (PyFoamSolver.logfile) The Directory PyFoamSolver.analyzed contains
29 this information: a) Residuals and other information of the linear
30 solvers b Execution time c) continuity information d) bounding of
31 variables
32 """
33
34 PyFoamApplication.__init__(self,args=args,description=description)
35
37 self.parser.add_option("--procnr",
38 type="int",
39 dest="procnr",
40 default=None,
41 help="The number of processors the run should be started on")
42 self.parser.add_option("--machinefile",
43 dest="machinefile",
44 default=None,
45 help="The machinefile that specifies the parallel machine")
46 self.parser.add_option("--clear-case",
47 action="store_true",
48 default=False,
49 dest="clearCase",
50 help="Clear all timesteps except for the first before running")
51 self.parser.add_option("--restart",
52 action="store_true",
53 default=False,
54 dest="restart",
55 help="Restart the simulation from the last time-step")
56
57 self.parser.add_option("--progress",
58 action="store_true",
59 default=False,
60 dest="progress",
61 help="Only prints the progress of the simulation, but swallows all the other output")
62 self.parser.add_option("--foamVersion",
63 dest="foamVersion",
64 default=None,
65 help="Change the OpenFOAM-version that is to be used")
66 self.parser.add_option("--logname",
67 dest="logname",
68 default="PyFoamSolve",
69 help="Name of the logfile")
70
71 self.parser.add_option("--all-regions",
72 action="store_true",
73 default=False,
74 dest="regions",
75 help="Executes the command for all available regions (builds a pseudo-case for each region)")
76
77 self.parser.add_option("--region",
78 dest="region",
79 default=None,
80 help="Executes the command for a region (builds a pseudo-case for that region)")
81
82 self.parser.add_option("--keep-pseudocases",
83 action="store_true",
84 default=False,
85 dest="keeppseudo",
86 help="Keep the pseudo-cases that were built for a multi-region case")
87 self.parser.add_option("--report-usage",
88 action="store_true",
89 default=False,
90 dest="reportUsage",
91 help="After the execution the maximum memory usage is printed to the screen")
92
93 self.parser.add_option("--custom-regexp",
94 action="append",
95 default=None,
96 dest="customRegex",
97 help="Add a custom regular expression to be plotted (can be used more than once)")
98
99 self.parser.add_option("--regexp-file",
100 action="store",
101 default=None,
102 dest="regexpFile",
103 help="A file with regulare expressions that are treated like the expressions given with --custom-regexp")
104
105 self.parser.add_option("--no-auto-customRegexp",
106 action="store_false",
107 default=True,
108 dest="autoCustom",
109 help="Do not automatically load the expressions from the file customRegexp")
110
112 """Adds the lines from a file to the custom regular expressions
113 @param fName: The name of the file"""
114 f=open(fName)
115
116 for l in f.readlines():
117 l=l.strip()
118 if len(l)==0:
119 continue
120 if l[0]=='"' and l[-1]=='"':
121 l=l[1:-1]
122 if len(l)>0:
123 if self.opts.customRegex==None:
124 self.opts.customRegex=[]
125 self.opts.customRegex.append(l)
126 f.close()
127
129 if self.opts.keeppseudo and (not self.opts.regions and self.opts.region==None):
130 warning("Option --keep-pseudocases only makes sense for multi-region-cases")
131 regionNames=[self.opts.region]
132 regions=None
133
134 if self.opts.regions or self.opts.region!=None:
135 print "Building Pseudocases"
136 sol=SolutionDirectory(self.parser.getArgs()[2],archive=None)
137 regions=RegionCases(sol,clean=True)
138
139 if self.opts.regions:
140 regionNames=sol.getRegions()
141
142 if self.opts.foamVersion!=None:
143 changeFoamVersion(self.opts.foamVersion)
144
145 if self.opts.regexpFile!=None:
146 self.addFileRegexps(self.opts.regexpFile)
147
148 if self.opts.autoCustom:
149 autoFile=path.join(self.parser.getArgs()[1],self.parser.getArgs()[2],"customRegexp")
150 if path.exists(autoFile):
151 print " Reading regular expressions from",autoFile
152 self.addFileRegexps(autoFile)
153
154 if self.opts.clearCase:
155 print "Clearing out old timesteps ...."
156
157 cName=self.parser.getArgs()[2]
158 sol=SolutionDirectory(cName,archive=None)
159 sol.clearResults()
160
161 lam=None
162 if self.opts.procnr!=None or self.opts.machinefile!=None:
163 lam=LAMMachine(machines=self.opts.machinefile,nr=self.opts.procnr)
164
165 for theRegion in regionNames:
166 args=self.parser.getArgs()[:]
167 if theRegion!=None:
168 args[2]+="."+theRegion
169
170 run=AnalyzedRunner(BoundingLogAnalyzer(progress=self.opts.progress),silent=self.opts.progress,argv=args,server=True,lam=lam,restart=self.opts.restart,logname=self.opts.logname)
171
172 if self.opts.customRegex!=None:
173 for i in range(len(self.opts.customRegex)):
174 name="Custom%02d" % i
175 run.addAnalyzer(name,RegExpLineAnalyzer(name.lower(),self.opts.customRegex[i],doTimelines=False,doFiles=True))
176
177 run.start()
178
179 if self.opts.reportUsage:
180 print "\n Used Memory: ",run.run.usedMemory(),"MB"
181
182 if theRegion!=None:
183 print "Syncing into master case"
184 regions.resync(theRegion)
185
186
187 if regions!=None:
188 if not self.opts.keeppseudo:
189 print "Removing pseudo-regions"
190 regions.cleanAll()
191 else:
192 for r in sol.getRegions():
193 if r not in regionNames:
194 regions.clean(r)
195