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