Source code for PyFoam.Applications.RestartRunner

#  ICE Revision: $Id$
"""
Application class that implements pyFoamRestartRunner
"""

from .PyFoamApplication import PyFoamApplication

from PyFoam.Execution.AnalyzedRunner import AnalyzedRunner
from PyFoam.Execution.BasicRunner import calcLogname,findRestartFiles
from PyFoam.LogAnalysis.BoundingLogAnalyzer import BoundingLogAnalyzer
from PyFoam.RunDictionary.SolutionDirectory import SolutionDirectory
from PyFoam.RunDictionary.RegionCases import RegionCases
from PyFoam.RunDictionary.ParameterFile import ParameterFile

from PyFoam.Error import warning

from .CommonPlotLines import CommonPlotLines
from .CommonReportUsage import CommonReportUsage
from .CommonReportRunnerData import CommonReportRunnerData
from .CommonWriteAllTrigger import CommonWriteAllTrigger
from .CommonLibFunctionTrigger import CommonLibFunctionTrigger
from .CommonStandardOutput import CommonStandardOutput
from .CommonParallel import CommonParallel
from .CommonServer import CommonServer
from .CommonVCSCommit import CommonVCSCommit
from .CommonPrePostHooks import CommonPrePostHooks
from .CommonBlink1 import CommonBlink1

from .CursesApplicationWrapper import CWindowAnalyzed

from PyFoam.ThirdParty.six import print_

from optparse import OptionGroup

[docs]class RestartRunner(PyFoamApplication, CommonPlotLines, CommonWriteAllTrigger, CommonLibFunctionTrigger, CommonReportUsage, CommonReportRunnerData, CommonParallel, CommonServer, CommonStandardOutput, CommonVCSCommit, CommonPrePostHooks, CommonBlink1): CWindowType=CWindowAnalyzed def __init__(self, args=None, **kwargs): description="""\ Runs an OpenFOAM solver repeatedly by restarting it from the last time-step written by the previous run. Stops if the solver either - reached the end time, - did not write a new time-step during the last restart - took less than a certain number of time-steps - a number of predefined restarts is used Purpose of this utility is to run cases where sometimes the solver fails for reasons that have nothing to do with the physics but runs fine after a restart """ CommonPlotLines.__init__(self) PyFoamApplication.__init__(self, exactNr=False, args=args, description=description, findLocalConfigurationFile=self.localConfigFromCasename, **kwargs)
[docs] def addOptions(self): CommonReportUsage.addOptions(self) CommonReportRunnerData.addOptions(self) CommonStandardOutput.addOptions(self) CommonParallel.addOptions(self) CommonPlotLines.addOptions(self) CommonWriteAllTrigger.addOptions(self) CommonLibFunctionTrigger.addOptions(self) CommonServer.addOptions(self) CommonVCSCommit.addOptions(self) CommonPrePostHooks.addOptions(self) CommonBlink1.addOptions(self) restart=OptionGroup(self.parser, "Restart", "Controlling how often restarting is actually done") self.parser.add_option_group(restart) restart.add_option("--maximum-number-of-restarts", action="store", type="int", dest="maximumRestarts", default=99, help="If the number of restarts is exceeded then the whole operation will stop. Default: %default") restart.add_option("--minimum-number-of-steps", action="store", type="int", dest="minimumSteps", default=5, help="If the number of steps is smaller then this a restart is not considered. Default: %default")
[docs] def run(self): casePath=self.parser.casePath() self.checkCase(casePath) # self.addLocalConfig(casePath) self.addToCaseLog(casePath,"Starting") self.prepareHooks() self.processPlotLineOptions(autoPath=casePath) lam=self.getParallel(SolutionDirectory(casePath,archive=None)) isParallel=lam is not None self.lastWrittenTime=None sol=SolutionDirectory(casePath,archive=None,parallel=isParallel) ctrlDict=ParameterFile(sol.controlDict(),backup=False) if ctrlDict.readParameter("startFrom")!="latestTime": self.error("In",casePath,"the value of 'startFrom' is not 'latestTime' (required for this script)") args=self.replaceAutoInArgs(self.parser.getArgs()) def checkRestart(data=None): lastTimeName=sol.getLast() lastTime=float(lastTimeName) ctrlDict=ParameterFile(sol.controlDict(),backup=False) endTime=float(ctrlDict.readParameter("endTime")) if abs(endTime-lastTime)/endTime<1e-5: return "Reached endTime {}".format(endTime) logfile=calcLogname(self.opts.logname,args) isRestart,restartnr,restartName,lastlog=findRestartFiles(logfile,sol) # TODO: look into the logfile if self.lastWrittenTime is not None: if self.lastWrittenTime==lastTimeName: return "Last restart didn't improve on {}. Further restarts make no sense".format(lastTime) self.lastWrittenTime=lastTimeName if data: if "stepNr" in data and data["stepNr"]<self.opts.minimumSteps: return "Only {} steps done while {} are required".format( data["stepNr"], self.opts.minimumSteps ) redo=True reason=checkRestart() if reason is not None: self.warning("Not starting:",reason) redo=False self.checkAndCommit(sol) self.initBlink() startNr=0 self.setLogname() while redo: startNr+=1 print_() print_("Starting restart nr",startNr,"on case",casePath) print_() self.addToCaseLog(casePath,"Restart nr",startNr,"started") run=AnalyzedRunner(BoundingLogAnalyzer(progress=self.opts.progress, doFiles=self.opts.writeFiles, singleFile=self.opts.singleDataFilesOnly, doTimelines=True), silent=self.opts.progress or self.opts.silent, splitThres=self.opts.splitDataPointsThreshold if self.opts.doSplitDataPoints else None, split_fraction_unchanged=self.opts.split_fraction_unchanged, argv=args, server=self.opts.server, lam=lam, logname=self.opts.logname, compressLog=self.opts.compress, logTail=self.opts.logTail, noLog=self.opts.noLog, remark=self.opts.remark, parameters=self.getRunParameters(), echoCommandLine=self.opts.echoCommandPrefix, jobId=self.opts.jobId) run.createPlots(customRegexp=self.lines_, splitThres=self.opts.splitDataPointsThreshold if self.opts.doSplitDataPoints else None, split_fraction_unchanged=self.opts.split_fraction_unchanged, writeFiles=self.opts.writeFiles) if self.cursesWindow: self.cursesWindow.setAnalyzer(run.analyzer) self.cursesWindow.setRunner(run) run.analyzer.addTimeListener(self.cursesWindow) self.addWriteAllTrigger(run,SolutionDirectory(casePath,archive=None)) self.addLibFunctionTrigger(run,SolutionDirectory(casePath,archive=None)) self.runPreHooks() if self.blink1: run.addTicker(lambda: self.blink1.ticToc()) run.start() if run.data["keyboardInterrupt"]: print_() self.warning("Not restarting because of keyboard interrupt") redo=False self.setData({startNr:run.data}) self.runPostHooks() self.reportUsage(run) self.reportRunnerData(run) self.addToCaseLog(casePath,"Restart nr",startNr,"ended") reason=checkRestart(data=run.data) if reason is not None: print_() self.warning("Not starting:",reason) self.addToCaseLog(casePath,"Stopping because of",reason) redo=False if startNr>=self.opts.maximumRestarts: print_() self.warning("Maximum number",self.opts.maximumRestarts, "restarts reached") self.addToCaseLog(casePath,"Stopping because maximum number", self.opts.maximumRestarts,"of restarts reached") redo=False self.stopBlink() self.addToCaseLog(casePath,"Ended") print_() print_("Ended after",startNr,"restarts") print_()
# Should work with Python3 and Python2