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 """@param argv: list with the tokens that are the command line
54 if not set the standard command line is used
55 @param silent: if True no output is sent to stdout
56 @param logname: name of the logfile
57 @param lam: Information about a parallel run
58 @param server: Whether or not to start the network-server
59 @type lam: PyFoam.Execution.ParallelExecution.LAMMachine"""
60
61 if sys.version_info < (2,3):
62
63 if server:
64 warning("Can not start server-process because Python-Version is too old")
65 server=False
66
67 if argv==None:
68 self.argv=sys.argv[1:]
69 else:
70 self.argv=argv
71
72 if oldApp():
73 self.dir=path.join(self.argv[1],self.argv[2])
74 if self.argv[2][-1]==path.sep:
75 self.argv[2]=self.argv[2][:-1]
76 else:
77 self.dir=path.curdir
78 if "-case" in self.argv:
79 self.dir=self.argv[self.argv.index("-case")+1]
80
81 if logname==None:
82 logname="PyFoam."+path.basename(argv[0])
83
84 try:
85 sol=self.getSolutionDirectory()
86 except OSError,e:
87 error("Solution directory",self.dir,"does not exist. No use running. Problem:",e)
88
89 self.silent=silent
90 self.lam=lam
91 self.origArgv=self.argv
92
93 if self.lam!=None:
94 self.argv=lam.buildMPIrun(self.argv)
95 self.cmd=string.join(self.argv," ")
96 foamLogger().info("Starting: "+self.cmd+" in "+path.abspath(path.curdir))
97 self.logFile=path.join(self.dir,logname+".logfile")
98
99 self.fatalError=False
100 self.fatalFPE=False
101 self.fatalStackdump=False
102
103 self.warnings=0
104 self.started=False
105
106 self.isRestarted=False
107 if restart:
108 self.controlDict=ParameterFile(path.join(self.dir,"system","controlDict"),backup=True)
109 self.controlDict.replaceParameter("startFrom","latestTime")
110 self.isRestarted=True
111 else:
112 self.controlDict=None
113
114 self.run=FoamThread(self.cmd,self)
115
116 self.server=None
117 if server:
118 self.server=FoamServer(run=self.run,master=self)
119 self.server.setDaemon(True)
120 self.server.start()
121 try:
122 IP,PID,Port=self.server.info()
123 f=open(path.join(self.dir,"PyFoamServer.info"),"w")
124 print >>f,IP,PID,Port
125 f.close()
126 except AttributeError:
127 warning("There seems to be a problem with starting the server:",self.server,"with attributes",dir(self.server))
128 self.server=None
129
130 self.createTime=None
131 self.nowTime=None
132
133 self.stopMe=False
134 self.writeRequested=False
135
136 self.endTriggers=[]
137
216
218 """checks whether the run was successful"""
219 if self.started:
220 return not self.fatalError and not self.fatalFPE and not self.fatalStackdump
221 else:
222 return False
223
225 """to be called before the program is started"""
226 pass
227
229 """Tells the runner to stop at the next convenient time"""
230 if not self.stopMe:
231 self.stopMe=True
232 if not self.isRestarted:
233 self.controlDict=ParameterFile(path.join(self.dir,"system","controlDict"),backup=True)
234 self.controlDict.replaceParameter("stopAt","writeNow")
235 warning("Stopping run at next write")
236
246
248 """called after the program has stopped"""
249 if self.stopMe or self.isRestarted:
250 self.controlDict.restore()
251
253 """called every time a new line is read"""
254 pass
255
257 """Get the name of the logfiles"""
258 return self.logFile
259
261 """@return: The directory of the case
262 @rtype: PyFoam.RunDictionary.SolutionDirectory
263 @param archive: Name of the directory for archiving results"""
264
265 return SolutionDirectory(self.dir,archive=archive)
266
268 """@param f: A function that is to be executed at the end of the simulation"""
269 self.endTriggers.append(f)
270
271 import re
272
274 """A small class that does primitve checking for BasicRunner
275 Duplicates other efforts, but ...."""
276
277 floatRegExp="[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?"
278
280 self.timeExpr=re.compile("^Time = (%f%)$".replace("%f%",self.floatRegExp))
281 self.createExpr=re.compile("^Create mesh for time = (%f%)$".replace("%f%",self.floatRegExp))
282
284 """Does this line contain time information?"""
285 m=self.timeExpr.match(line)
286 if m:
287 return float(m.group(1))
288 else:
289 return None
290
292 """Does this line contain mesh time information?"""
293 m=self.createExpr.match(line)
294 if m:
295 return float(m.group(1))
296 else:
297 return None
298
300 """Was the controlDict reread?"""
301 if line.find("Reading object controlDict from file"):
302 return True
303 else:
304 return False
305