Package PyFoam :: Package Execution :: Module BasicRunner
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.Execution.BasicRunner

  1  """Run a OpenFOAM command""" 
  2   
  3  import sys 
  4  import string 
  5  from os import path 
  6   
  7  from FoamThread import FoamThread 
  8  from PyFoam.Infrastructure.FoamServer import FoamServer 
  9  from PyFoam.Infrastructure.Logging import foamLogger 
 10  from PyFoam.RunDictionary.SolutionDirectory import SolutionDirectory 
 11  from PyFoam.Execution.ParallelExecution import LAMMachine 
 12  from PyFoam.RunDictionary.ParameterFile import ParameterFile 
 13   
14 -class BasicRunner(object):
15 """Base class for the running of commands 16 17 When the command is run the output is copied to a LogFile and 18 (optionally) standard-out 19 20 The argument list assumes for the first three elements the 21 OpenFOAM-convention: 22 23 <cmd> <dir> <case> 24 25 The directory name for outputs is therefor created from <dir> and 26 <case> 27 28 Provides some handle-methods that are to be overloaded for 29 additional functionality""" 30
31 - def __init__(self,argv=None,silent=False,logname="PyFoam",lam=None,server=False):
32 """@param argv: list with the tokens that are the command line 33 if not set the standard command line is used 34 @param silent: if True no output is sent to stdout 35 @param logname: name of the logfile 36 @param lam: Information about a parallel run 37 @param server: Whether or not to start the network-server 38 @type lam: PyFoam.Execution.ParallelExecution.LAMMachine""" 39 40 if argv==None: 41 self.argv=sys.argv[1:] 42 else: 43 self.argv=argv 44 self.dir=path.join(self.argv[1],self.argv[2]) 45 if self.argv[2][-1]==path.sep: 46 self.argv[2]=self.argv[2][:-1] 47 48 self.silent=silent 49 self.lam=lam 50 self.origArgv=self.argv 51 52 if self.lam!=None: 53 self.argv=lam.buildMPIrun(self.argv) 54 self.cmd=string.join(self.argv," ") 55 foamLogger().info("Starting: "+self.cmd+" in "+path.abspath(path.curdir)) 56 self.logFile=path.join(self.dir,logname+".logfile") 57 58 self.fatalError=False 59 self.warnings=0 60 self.started=False 61 62 self.run=FoamThread(self.cmd) 63 64 self.server=None 65 if server: 66 self.server=FoamServer(run=self.run,master=self) 67 self.server.setDaemon(True) 68 self.server.start() 69 70 self.createTime=None 71 self.nowTime=None 72 73 self.stopMe=False
74
75 - def start(self):
76 """starts the command and stays with it till the end""" 77 78 self.started=True 79 fh=open(self.logFile,"w") 80 81 self.startHandle() 82 83 check=BasicRunnerCheck() 84 85 self.run.start() 86 87 while self.run.check(): 88 try: 89 self.run.read() 90 if not self.run.check(): 91 break 92 93 line=self.run.getLine() 94 95 tmp=check.getTime(line) 96 if tmp!=None: 97 self.nowTime=tmp 98 if self.createTime==None: 99 # necessary because interFoam reports no creation time 100 self.createTime=tmp 101 102 tmp=check.getCreateTime(line) 103 if tmp!=None: 104 self.createTime=tmp 105 106 if not self.silent: 107 print line 108 109 if line.find("FOAM FATAL ERROR")>=0 or line.find("FOAM FATAL IO ERROR")>=0: 110 self.fatalError=True 111 112 if self.fatalError and line!="": 113 foamLogger().error(line) 114 115 if line.find("FOAM Warning")>=0: 116 self.warnings+=1 117 118 if self.server!=None: 119 self.server._insertLine(line) 120 121 self.lineHandle(line) 122 123 fh.write(line+"\n") 124 fh.flush() 125 except KeyboardInterrupt,e: 126 foamLogger().warning("Keyboard Interrupt") 127 self.run.interrupt() 128 129 self.stopHandle() 130 131 fh.close() 132 133 if self.server!=None: 134 self.server.deregister() 135 136 foamLogger().info("Finished")
137
138 - def runOK(self):
139 """checks whether the run was successful""" 140 if self.started: 141 return not self.fatalError 142 else: 143 return False
144
145 - def startHandle(self):
146 """to be called before the program is started""" 147 pass
148
149 - def stopGracefully(self):
150 """Tells the runner to stop at the next convenient time""" 151 if not self.stopMe: 152 self.stopMe=True 153 self.controlDict=ParameterFile(path.join(self.dir,"system","controlDict"),backup=True) 154 dt=self.controlDict.readParameter("deltaT") 155 self.controlDict.replaceParameter("stopAt","nextWrite") 156 self.controlDict.replaceParameter("writeInterval",dt) 157 print "Stopping run at next write"
158
159 - def stopHandle(self):
160 """called after the program has stopped""" 161 if self.stopMe: 162 self.controlDict.restore()
163
164 - def lineHandle(self,line):
165 """called every time a new line is read""" 166 pass
167
168 - def logName(self):
169 """Get the name of the logfiles""" 170 return self.logFile
171
172 - def getSolutionDirectory(self,archive=None):
173 """@return: The directory of the case 174 @rtype: PyFoam.RunDictionary.SolutionDirectory 175 @param archive: Name of the directory for archiving results""" 176 177 return SolutionDirectory(self.dir,archive=archive)
178 179 import re 180
181 -class BasicRunnerCheck(object):
182 """A small class that does primitve checking for BasicRunner 183 Duplicates other efforts, but ....""" 184 185 floatRegExp="[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?" 186
187 - def __init__(self):
188 self.timeExpr=re.compile("^Time = (%f%)$".replace("%f%",self.floatRegExp)) 189 self.createExpr=re.compile("^Create mesh for time = (%f%)$".replace("%f%",self.floatRegExp))
190
191 - def getTime(self,line):
192 """Does this line contain time information?""" 193 m=self.timeExpr.match(line) 194 if m: 195 return float(m.group(1)) 196 else: 197 return None
198
199 - def getCreateTime(self,line):
200 """Does this line contain mesh time information?""" 201 m=self.createExpr.match(line) 202 if m: 203 return float(m.group(1)) 204 else: 205 return None
206