1
2 """
3 Class that implements pyFoamPlotRunner
4 """
5
6 from PyFoamApplication import PyFoamApplication
7
8 from PyFoam.FoamInformation import changeFoamVersion
9
10 from PyFoam.Execution.GnuplotRunner import GnuplotRunner
11
12 from PyFoam.Execution.ParallelExecution import LAMMachine
13
14 from PyFoam.RunDictionary.SolutionDirectory import SolutionDirectory
15
16 from PyFoam.Error import warning
17
18 from os import path
19
22 description="""
23 runs an OpenFoam solver needs the usual 3 arguments (<solver>
24 <directory> <case>) and passes them on (plus additional arguments).
25 Output is sent to stdout and a logfile inside the case directory
26 (PyFoamSolver.logfile) Information about the residuals is output as
27 graphs
28
29 If the directory contains a file customRegexp this is automatically
30 read and the regular expressions in it are displayed
31 """
32 PyFoamApplication.__init__(self,args=args,description=description)
33
35 self.parser.add_option("--frequency",
36 type="float",
37 dest="frequency",
38 default=1.,
39 help="The frequency with which output should be generated (in seconds)")
40
41 self.parser.add_option("--persist",
42 action="store_true",
43 dest="persist",
44 default=True,
45 help="Gnuplot windows stay after interrupt")
46
47 self.parser.add_option("--non-persist",
48 action="store_false",
49 dest="persist",
50 help="Gnuplot windows close after interrupt")
51
52 self.parser.add_option("--raise",
53 action="store_true",
54 dest="raiseit",
55 help="Raise the Gnuplot windows after every replot")
56
57 self.parser.add_option("--no-default",
58 action="store_true",
59 default=False,
60 dest="nodefault",
61 help="Switch off the default plots (linear, continuity and bound)")
62
63 self.parser.add_option("--no-linear",
64 action="store_false",
65 default=True,
66 dest="linear",
67 help="Don't plot the linear solver convergence")
68
69 self.parser.add_option("--no-continuity",
70 action="store_false",
71 default=True,
72 dest="cont",
73 help="Don't plot the continuity info")
74
75 self.parser.add_option("--no-bound",
76 action="store_false",
77 default=True,
78 dest="bound",
79 help="Don't plot the bounding of variables")
80
81 self.parser.add_option("--with-iterations",
82 action="store_true",
83 default=False,
84 dest="iterations",
85 help="Plot the number of iterations of the linear solver")
86
87 self.parser.add_option("--with-courant",
88 action="store_true",
89 default=False,
90 dest="courant",
91 help="Plot the courant-numbers of the flow")
92
93 self.parser.add_option("--with-execution",
94 action="store_true",
95 default=False,
96 dest="execution",
97 help="Plot the execution time of each time-step")
98
99 self.parser.add_option("--with-deltat",
100 action="store_true",
101 default=False,
102 dest="deltaT",
103 help="'Plot the timestep-size time-step")
104
105 self.parser.add_option("--with-all",
106 action="store_true",
107 default=False,
108 dest="withAll",
109 help="Switch all possible plots on")
110
111 self.parser.add_option("--custom-regexp",
112 action="append",
113 default=None,
114 dest="customRegex",
115 help="Add a custom regular expression to be plotted (can be used more than once)")
116
117 self.parser.add_option("--write-files",
118 action="store_true",
119 default=False,
120 dest="writeFiles",
121 help="Writes the parsed data to files")
122
123 self.parser.add_option("--regexp-file",
124 action="store",
125 default=None,
126 dest="regexpFile",
127 help="A file with regulare expressions that are treated like the expressions given with --custom-regexp")
128
129 self.parser.add_option("--no-auto-customRegexp",
130 action="store_false",
131 default=True,
132 dest="autoCustom",
133 help="Do not automatically load the expressions from the file customRegexp")
134
135 self.parser.add_option("--procnr",
136 type="int",
137 dest="procnr",
138 default=None,
139 help="The number of processors the run should be started on")
140
141 self.parser.add_option("--machinefile",
142 dest="machinefile",
143 default=None,
144 help="The machinefile that specifies the parallel machine")
145
146 self.parser.add_option("--clear-case",
147 action="store_true",
148 default=False,
149 dest="clearCase",
150 help="Clear all timesteps except for the first before running")
151
152 self.parser.add_option("--steady-run",
153 action="store_true",
154 default=False,
155 dest="steady",
156 help="This is a steady run. Stop it after convergence")
157
158 self.parser.add_option("--restart",
159 action="store_true",
160 default=False,
161 dest="restart",
162 help="Restart the simulation from the last time-step")
163
164 self.parser.add_option("--progress",
165 action="store_true",
166 default=False,
167 dest="progress",
168 help="Only prints the progress of the simulation, but swallows all the other output")
169
170 self.parser.add_option("--foamVersion",
171 dest="foamVersion",
172 default=None,
173 help="Change the OpenFOAM-version that is to be used")
174
175 self.parser.add_option("--safe-until",
176 type="float",
177 dest="safeUntil",
178 default=None,
179 help="Sets lower under-relaxation and lower-order convection-schemes for the start of the simulation (only for steady-runs)")
180
181 self.parser.add_option("--safe-relaxation-factor",
182 type="float",
183 dest="safeRelaxation",
184 default=0.5,
185 help="The factor by which the relaxation-factors should be scaled down (when calculating safe)")
186
187 self.parser.add_option("--report-usage",
188 action="store_true",
189 default=False,
190 dest="reportUsage",
191 help="After the execution the maximum memory usage is printed to the screen")
192
193
195 """Adds the lines from a file to the custom regular expressions
196 @param fName: The name of the file"""
197 f=open(fName)
198
199 for l in f.readlines():
200 l=l.strip()
201 if len(l)==0:
202 continue
203 if l[0]=='"' and l[-1]=='"':
204 l=l[1:-1]
205 if len(l)>0:
206 if self.opts.customRegex==None:
207 self.opts.customRegex=[]
208 self.opts.customRegex.append(l)
209 f.close()
210
211
213 if self.opts.foamVersion!=None:
214 changeFoamVersion(self.opts.foamVersion)
215
216 if self.opts.nodefault:
217 self.opts.linear=False
218 self.opts.cont=False
219 self.opts.bound=False
220
221 if self.opts.withAll:
222 self.opts.linear=True
223 self.opts.cont=True
224 self.opts.bound=True
225 self.opts.iterations=True
226 self.opts.courant=True
227 self.opts.execution=True
228 self.opts.deltaT=True
229
230 if self.opts.regexpFile!=None:
231 self.addFileRegexps(self.opts.regexpFile)
232
233 if self.opts.autoCustom:
234 autoFile=path.join(self.parser.getArgs()[1],self.parser.getArgs()[2],"customRegexp")
235 if path.exists(autoFile):
236 print " Reading regular expressions from",autoFile
237 self.addFileRegexps(autoFile)
238
239 cName=self.parser.getArgs()[2]
240 sol=SolutionDirectory(cName,archive=None)
241
242 if self.opts.clearCase:
243 print "Clearing out old timesteps ...."
244 sol.clearResults()
245
246 lam=None
247 if self.opts.procnr!=None or self.opts.machinefile!=None:
248 lam=LAMMachine(machines=self.opts.machinefile,nr=self.opts.procnr)
249
250 run=GnuplotRunner(argv=self.parser.getArgs(),smallestFreq=self.opts.frequency,persist=self.opts.persist,plotLinear=self.opts.linear,plotCont=self.opts.cont,plotBound=self.opts.bound,plotIterations=self.opts.iterations,plotCourant=self.opts.courant,plotExecution=self.opts.execution,plotDeltaT=self.opts.deltaT,customRegexp=self.opts.customRegex,writeFiles=self.opts.writeFiles,server=True,lam=lam,raiseit=self.opts.raiseit,steady=self.opts.steady,progress=self.opts.progress,restart=self.opts.restart)
251
252 if self.opts.safeUntil:
253 if not self.opts.steady:
254 warning("This is an unsteady run. No safe settings set")
255 else:
256 warning("Adding Trigger and resetting to safer start-settings")
257 trig=SafeTrigger(sol,self.opts.safeRelaxation)
258 run.addTrigger(self.opts.safeUntil,trig.resetIt)
259 run.addEndTrigger(trig.resetIt)
260
261 run.start()
262
263 if self.opts.reportUsage:
264 print "\n Used Memory: ",run.run.usedMemory(),"MB"
265
266 import re
267 from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile
268
271 self.solution=ParsedParameterFile(path.join(sol.systemDir(),"fvSolution"),backup=True)
272 self.schemes=ParsedParameterFile(path.join(sol.systemDir(),"fvSchemes"),backup=True)
273
274 self.fresh=True
275
276 try:
277 relax=self.solution["relaxationFactors"]
278 for var in relax:
279 relax[var]*=factor
280
281 cExp=re.compile("div\((.+),(.+)\)")
282 conv=self.schemes["divSchemes"]
283 for nm in conv:
284 if cExp.match(nm) or nm=="default":
285 conv[nm]="Gauss upwind"
286
287 self.solution.writeFile()
288 self.schemes.writeFile()
289 except Exception,e:
290 warning("Restoring defaults")
291 self.solution.restore()
292 self.schemes.restore()
293 raise e
294
296 if self.fresh:
297 warning("Trigger called: Resetting fvSchemes and fvSolution")
298 self.solution.restore()
299 self.schemes.restore()
300 self.fresh=False
301