1
2 """Run a OpenFOAM command"""
3
4 import sys
5 import string
6 from os import path
7 from threading import Timer
8
9 from PyFoam.FoamInformation import oldAppConvention as oldApp
10
11 if not 'curdir' in dir(path) or not 'sep' in dir(path):
12 print "Warning: Inserting symbols into os.path (Python-Version<2.3)"
13 path.curdir='.'
14 path.sep ='/'
15
16 from FoamThread import FoamThread
17 from PyFoam.Infrastructure.FoamServer import FoamServer
18 from PyFoam.Infrastructure.Logging import foamLogger
19 from PyFoam.RunDictionary.SolutionDirectory import SolutionDirectory
20 from PyFoam.RunDictionary.ParameterFile import ParameterFile
21 from PyFoam.Error import warning,error
22 from PyFoam import configuration as config
23
25 """Timed function to avoid time-stamp-problems"""
26 warning("Restoring the controlDict")
27 ctrl.restore()
28
30 """Base class for the running of commands
31
32 When the command is run the output is copied to a LogFile and
33 (optionally) standard-out
34
35 The argument list assumes for the first three elements the
36 OpenFOAM-convention:
37
38 <cmd> <dir> <case>
39
40 The directory name for outputs is therefor created from <dir> and
41 <case>
42
43 Provides some handle-methods that are to be overloaded for
44 additional functionality"""
45
46 - def __init__(self,
47 argv=None,
48 silent=False,
49 logname=None,
50 lam=None,
51 server=False,
52 restart=False,
53 noLog=False):
54 """@param argv: list with the tokens that are the command line
55 if not set the standard command line is used
56 @param silent: if True no output is sent to stdout
57 @param logname: name of the logfile
58 @param lam: Information about a parallel run
59 @param server: Whether or not to start the network-server
60 @type lam: PyFoam.Execution.ParallelExecution.LAMMachine
61 @param noLog: Don't output a log file"""
62
63 if sys.version_info < (2,3):
64
65 if server:
66 warning("Can not start server-process because Python-Version is too old")
67 server=False
68
69 if argv==None:
70 self.argv=sys.argv[1:]
71 else:
72 self.argv=argv
73
74 if oldApp():
75 self.dir=path.join(self.argv[1],self.argv[2])
76 if self.argv[2][-1]==path.sep:
77 self.argv[2]=self.argv[2][:-1]
78 else:
79 self.dir=path.curdir
80 if "-case" in self.argv:
81 self.dir=self.argv[self.argv.index("-case")+1]
82
83 if logname==None:
84 logname="PyFoam."+path.basename(argv[0])
85
86 try:
87 sol=self.getSolutionDirectory()
88 except OSError,e:
89 error("Solution directory",self.dir,"does not exist. No use running. Problem:",e)
90
91 self.silent=silent
92 self.lam=lam
93 self.origArgv=self.argv
94
95 if self.lam!=None:
96 self.argv=lam.buildMPIrun(self.argv)
97 self.cmd=string.join(self.argv," ")
98 foamLogger().info("Starting: "+self.cmd+" in "+path.abspath(path.curdir))
99 self.logFile=path.join(self.dir,logname+".logfile")
100 self.noLog=noLog
101
102 self.fatalError=False
103 self.fatalFPE=False
104 self.fatalStackdump=False
105
106 self.warnings=0
107 self.started=False
108
109 self.isRestarted=False
110 if restart:
111 self.controlDict=ParameterFile(path.join(self.dir,"system","controlDict"),backup=True)
112 self.controlDict.replaceParameter("startFrom","latestTime")
113 self.isRestarted=True
114 else:
115 self.controlDict=None
116
117 self.run=FoamThread(self.cmd,self)
118
119 self.server=None
120 if server:
121 self.server=FoamServer(run=self.run,master=self)
122 self.server.setDaemon(True)
123 self.server.start()
124 try:
125 IP,PID,Port=self.server.info()
126 f=open(path.join(self.dir,"PyFoamServer.info"),"w")
127 print >>f,IP,PID,Port
128 f.close()
129 except AttributeError:
130 warning("There seems to be a problem with starting the server:",self.server,"with attributes",dir(self.server))
131 self.server=None
132
133 self.createTime=None
134 self.nowTime=None
135
136 self.stopMe=False
137 self.writeRequested=False
138
139 self.endTriggers=[]
140
223
225 """checks whether the run was successful"""
226 if self.started:
227 return not self.fatalError and not self.fatalFPE and not self.fatalStackdump
228 else:
229 return False
230
232 """to be called before the program is started"""
233 pass
234
236 """Tells the runner to stop at the next convenient time"""
237 if not self.stopMe:
238 self.stopMe=True
239 if not self.isRestarted:
240 self.controlDict=ParameterFile(path.join(self.dir,"system","controlDict"),backup=True)
241 self.controlDict.replaceParameter("stopAt","writeNow")
242 warning("Stopping run at next write")
243
253
255 """called after the program has stopped"""
256 if self.stopMe or self.isRestarted:
257 self.controlDict.restore()
258
260 """called every time a new line is read"""
261 pass
262
264 """Get the name of the logfiles"""
265 return self.logFile
266
268 """@return: The directory of the case
269 @rtype: PyFoam.RunDictionary.SolutionDirectory
270 @param archive: Name of the directory for archiving results"""
271
272 return SolutionDirectory(self.dir,archive=archive)
273
275 """@param f: A function that is to be executed at the end of the simulation"""
276 self.endTriggers.append(f)
277
278 import re
279
281 """A small class that does primitve checking for BasicRunner
282 Duplicates other efforts, but ...."""
283
284 floatRegExp="[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?"
285
287 self.timeExpr=re.compile("^Time = (%f%)$".replace("%f%",self.floatRegExp))
288 self.createExpr=re.compile("^Create mesh for time = (%f%)$".replace("%f%",self.floatRegExp))
289
291 """Does this line contain time information?"""
292 m=self.timeExpr.match(line)
293 if m:
294 return float(m.group(1))
295 else:
296 return None
297
299 """Does this line contain mesh time information?"""
300 m=self.createExpr.match(line)
301 if m:
302 return float(m.group(1))
303 else:
304 return None
305
307 """Was the controlDict reread?"""
308 if line.find("Reading object controlDict from file"):
309 return True
310 else:
311 return False
312