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

Source Code for Module PyFoam.Execution.BasicRunner

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