/[escript]/trunk/escript/py_src/modelframe.py
ViewVC logotype

Diff of /trunk/escript/py_src/modelframe.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 926 by gross, Fri Jan 12 06:31:37 2007 UTC revision 1042 by gross, Mon Mar 19 03:50:34 2007 UTC
# Line 27  from sys import stdout Line 27  from sys import stdout
27  import numarray  import numarray
28  import operator  import operator
29  import itertools  import itertools
30    import time
31    import os
32    
33  # import the 'set' module if it's not defined (python2.3/2.4 difference)  # import the 'set' module if it's not defined (python2.3/2.4 difference)
34  try:  try:
# Line 71  class ESySXMLParser(object): Line 73  class ESySXMLParser(object):
73        self.__dom = minidom.parseString(xml)        self.__dom = minidom.parseString(xml)
74        self.__linkable_object_registry= {}        self.__linkable_object_registry= {}
75        self.__link_registry=  []        self.__link_registry=  []
76        self.__esys=self.__dom.firstChild        self.__esys=self.__dom.getElementsByTagName('ESys')[0]
77        self.debug=debug        self.debug=debug
78        
79      def getClassPath(self, node):      def getClassPath(self, node):
# Line 214  class Link: Line 216  class Link:
216          self.attribute = None          self.attribute = None
217          self.setAttributeName(attribute)          self.setAttributeName(attribute)
218    
219        def getTarget(self):
220            """
221            returns the target
222            """
223            return self.target
224      def getAttributeName(self):      def getAttributeName(self):
225          """          """
226          returns the name of the attribute the link is pointing to          returns the name of the attribute the link is pointing to
# Line 462  class ParameterSet(LinkableObject): Line 469  class ParameterSet(LinkableObject):
469              setattr(self,prm,value)              setattr(self,prm,value)
470              self.parameters.add(prm)              self.parameters.add(prm)
471    
             self.trace("parameter %s has been declared."%prm)  
   
472      def releaseParameters(self,name):      def releaseParameters(self,name):
473          """          """
474      Removes parameter name from the paramameters.      Removes parameter name from the paramameters.
# Line 471  class ParameterSet(LinkableObject): Line 476  class ParameterSet(LinkableObject):
476          if self.isParameter(name):          if self.isParameter(name):
477              self.parameters.remove(name)              self.parameters.remove(name)
478              self.trace("parameter %s has been removed."%name)              self.trace("parameter %s has been removed."%name)
479    
480        def checkLinkTargets(self, models, hash):
481            """
482            returns a set of tuples ("<self>(<name>)", <target model>) if the parameter <name> is linked to model <target model>
483            but <target model> is not in the list models. If the a parameter is linked to another parameter set which is not in the hash list
484            the parameter set is checked for its models. hash gives the call history.
485            """
486            out=set()
487            for name, value in self:
488                if isinstance(value, Link):
489                   m=value.getTarget()
490                   if isinstance(m, Model):
491                       if not m in models: out.add( (str(self)+"("+name+")",m) )
492                   elif isinstance(m, ParameterSet) and not m in hash:
493                         out|=set( [ (str(self)+"("+name+")."+f[0],f[1]) for f in m.checkLinkTargets(models, hash+[ self ] ) ] )
494            return out
495            
496      def __iter__(self):      def __iter__(self):
497          """          """
# Line 522  class ParameterSet(LinkableObject): Line 543  class ParameterSet(LinkableObject):
543                  for i in value:                  for i in value:
544                      if isinstance(i, bool):                      if isinstance(i, bool):
545                          elem_type = max(elem_type,0)                          elem_type = max(elem_type,0)
546                      if isinstance(i, int) and not isinstance(i, bool):                      elif isinstance(i, int):
547                          elem_type = max(elem_type,1)                          elem_type = max(elem_type,1)
548                      if isinstance(i, float):                      elif isinstance(i, float):
549                          elem_type = max(elem_type,2)                          elem_type = max(elem_type,2)
550                  if elem_type == 0: value = numarray.array(value,numarray.Bool)                  if elem_type == 0: value = numarray.array(value,numarray.Bool)
551                  if elem_type == 1: value = numarray.array(value,numarray.Int)                  if elem_type == 1: value = numarray.array(value,numarray.Int)
# Line 582  class ParameterSet(LinkableObject): Line 603  class ParameterSet(LinkableObject):
603                      dic.appendChild(i)                      dic.appendChild(i)
604                   param.appendChild(dic)                   param.appendChild(dic)
605              else:              else:
                 print value  
606                  raise ValueError("cannot serialize %s type to XML."%str(value.__class__))                  raise ValueError("cannot serialize %s type to XML."%str(value.__class__))
607    
608              node.appendChild(param)              node.appendChild(param)
# Line 671  class ParameterSet(LinkableObject): Line 691  class ParameterSet(LinkableObject):
691              parameters[pname] = pvalue              parameters[pname] = pvalue
692    
693          # Create the instance of ParameterSet          # Create the instance of ParameterSet
694          o = cls(debug=esysxml.debug)          try:
695               o = cls(debug=esysxml.debug)
696            except TypeError, inst:
697               print inst.args[0]
698               if inst.args[0]=="__init__() got an unexpected keyword argument 'debug'":
699                  raise TypeError("The Model class %s __init__ needs to have argument 'debug'.")
700               else:
701                  raise inst
702          o.declareParameters(parameters)          o.declareParameters(parameters)
703          esysxml.registerLinkableObject(o, node)          esysxml.registerLinkableObject(o, node)
704          return o          return o
# Line 724  class Model(ParameterSet): Line 751  class Model(ParameterSet):
751         return "<%s %d>"%(self.__class__.__name__,id(self))         return "<%s %d>"%(self.__class__.__name__,id(self))
752    
753    
754        def setUp(self):
755            """
756            Sets up the model.
757    
758            This function may be overwritten.
759            """
760            pass
761    
762      def doInitialization(self):      def doInitialization(self):
763          """          """
764      Initializes the time stepping scheme.        Initializes the time stepping scheme. This method is not called in case of a restart.
765            
766      This function may be overwritten.      This function may be overwritten.
767      """      """
768          pass          pass
769      def doInitialStep(self):      def doInitialStep(self):
770          """          """
771      performs an iteration step in the initialization phase      performs an iteration step in the initialization phase. This method is not called in case of a restart.
772    
773      This function may be overwritten.      This function may be overwritten.
774      """      """
# Line 741  class Model(ParameterSet): Line 776  class Model(ParameterSet):
776    
777      def terminateInitialIteration(self):      def terminateInitialIteration(self):
778          """          """
779      Returns True if iteration at the inital phase is terminated.      Returns True if iteration at the inital phase is terminated.
780      """      """
781          return True          return True
782    
783      def doInitialPostprocessing(self):      def doInitialPostprocessing(self):
784          """          """
785      finalises the initialization iteration process      finalises the initialization iteration process. This method is not called in case of a restart.
786    
787      This function may be overwritten.      This function may be overwritten.
788      """      """
# Line 844  class Simulation(Model): Line 879  class Simulation(Model):
879      Initiates a simulation from a list of models.      Initiates a simulation from a list of models.
880      """      """
881          super(Simulation, self).__init__(**kwargs)          super(Simulation, self).__init__(**kwargs)
882            self.declareParameter(time=0.,
883                                  time_step=0,
884                                  dt = self.UNDEF_DT)
885            for m in models:
886                if not isinstance(m, Model):
887                     raise TypeError("%s is not a subclass of Model."%m)
888          self.__models=[]          self.__models=[]
           
889          for i in range(len(models)):          for i in range(len(models)):
890              self[i] = models[i]              self[i] = models[i]
891                            
# Line 890  class Simulation(Model): Line 930  class Simulation(Model):
930      """      """
931          return len(self.__models)          return len(self.__models)
932    
933        def getAllModels(self):
934            """
935            returns a list of all models used in the Simulation including subsimulations
936            """
937            out=[]
938            for m in self.iterModels():
939                if isinstance(m, Simulation):
940                   out+=m.getAllModels()
941                else:
942                   out.append(m)
943            return list(set(out))
944    
945        def checkModels(self, models, hash):
946            """
947            returns a list of (model,parameter, target model ) if the the parameter of model
948            is linking to the target_model which is not in list of models.
949            """
950            out=self.checkLinkTargets(models, hash + [self])
951            for m in self.iterModels():
952                if isinstance(m, Simulation):
953                     out|=m.checkModels(models, hash)
954                else:
955                     out|=m.checkLinkTargets(models, hash + [self])
956            return set( [ (str(self)+"."+f[0],f[1]) for f in out ] )
957    
958            
959      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
960          """          """
# Line 899  class Simulation(Model): Line 964  class Simulation(Model):
964      """      """
965          out=min([o.getSafeTimeStepSize(dt) for o in self.iterModels()])          out=min([o.getSafeTimeStepSize(dt) for o in self.iterModels()])
966          return out          return out
967    
968        def setUp(self):
969            """
970            performs the setup for all models
971            """
972            for o in self.iterModels():
973                 o.setUp()
974            
975      def doInitialization(self):      def doInitialization(self):
976          """          """
977      Initializes all models.      Initializes all models.
978      """      """
         self.n=0  
         self.tn=0.  
979          for o in self.iterModels():          for o in self.iterModels():
980               o.doInitialization()               o.doInitialization()
981      def doInitialStep(self):      def doInitialStep(self):
# Line 969  class Simulation(Model): Line 1039  class Simulation(Model):
1039      """      """
1040          for o in self.iterModels():          for o in self.iterModels():
1041              o.doStepPostprocessing(dt)              o.doStepPostprocessing(dt)
1042          self.n+=1          self.time_step+=1
1043          self.tn+=dt          self.time+=dt
1044            self.dt=dt
1045            
1046      def doStep(self,dt):      def doStep(self,dt):
1047          """          """
# Line 984  class Simulation(Model): Line 1055  class Simulation(Model):
1055          """          """
1056          self.iter=0          self.iter=0
1057          while not self.terminateIteration():          while not self.terminateIteration():
1058              if self.iter==0: self.trace("iteration at %d-th time step %e starts"%(self.n+1,self.tn+dt))              if self.iter==0: self.trace("iteration at %d-th time step %e starts"%(self.time_step+1,self.time+dt))
1059              self.iter+=1              self.iter+=1
1060              self.trace("iteration step %d"%(self.iter))              self.trace("iteration step %d"%(self.iter))
1061              for o in self.iterModels():              for o in self.iterModels():
1062                    o.doStep(dt)                    o.doStep(dt)
1063          if self.iter>0: self.trace("iteration at %d-th time step %e finalized."%(self.n+1,self.tn+dt))          if self.iter>0: self.trace("iteration at %d-th time step %e finalized."%(self.time_step+1,self.time+dt))
1064    
1065      def run(self,check_point=None):      def run(self,check_pointing=None):
1066          """          """
1067      Run the simulation by performing essentially::      Run the simulation by performing essentially::
1068            
1069          self.doInitialization()              self.setUp()
1070              while not self.terminateInitialIteration(): self.doInitialStep()              if not restart:
1071              self.doInitialPostprocessing()              self.doInitialization()
1072                    while not self.terminateInitialIteration(): self.doInitialStep()
1073                    self.doInitialPostprocessing()
1074          while not self.finalize():          while not self.finalize():
1075              dt=self.getSafeTimeStepSize()              dt=self.getSafeTimeStepSize()
1076              self.doStep(dt)                  self.doStepPreprocessing(dt_new)
1077              if n%check_point==0:                  self.doStep(dt_new)
1078              self.writeXML()                  self.doStepPostprocessing(dt_new)
1079          self.doFinalization()          self.doFinalization()
1080    
1081          If one of the models in throws a C{FailedTimeStepError} exception a          If one of the models in throws a C{FailedTimeStepError} exception a
# Line 1015  class Simulation(Model): Line 1088  class Simulation(Model):
1088          In both cases the time integration is given up after          In both cases the time integration is given up after
1089      C{Simulation.FAILED_TIME_STEPS_MAX} attempts.      C{Simulation.FAILED_TIME_STEPS_MAX} attempts.
1090          """          """
1091          self.doInitialization()          # check the completness of the models:
1092          self.doInitialStep()          # first a list of all the models involved in the simulation including subsimulations:
1093          self.doInitialPostprocessing()          #
1094          dt=self.UNDEF_DT          missing=self.checkModels(self.getAllModels(), [])
1095            if len(missing)>0:
1096                msg=""
1097                for l in missing:
1098                     msg+="\n\t"+str(l[1])+" at "+l[0]
1099                raise MissingLink("link targets missing in the Simulation: %s"%msg)
1100            #==============================
1101            self.setUp()
1102            if self.time_step < 1:
1103               self.doInitialization()
1104               self.doInitialStep()
1105               self.doInitialPostprocessing()
1106          while not self.finalize():          while not self.finalize():
1107              step_fail_counter=0              step_fail_counter=0
1108              iteration_fail_counter=0              iteration_fail_counter=0
1109              if self.n==0:              if self.time_step==0:
1110                  dt_new=self.getSafeTimeStepSize(dt)                  dt_new=self.getSafeTimeStepSize(self.dt)
1111              else:              else:
1112                  dt_new=min(max(self.getSafeTimeStepSize(dt),dt/self.MAX_CHANGE_OF_DT),dt*self.MAX_CHANGE_OF_DT)                  dt_new=min(max(self.getSafeTimeStepSize(self.dt),self.dt/self.MAX_CHANGE_OF_DT),self.dt*self.MAX_CHANGE_OF_DT)
1113              self.trace("%d. time step %e (step size %e.)" % (self.n+1,self.tn+dt_new,dt_new))              self.trace("%d. time step %e (step size %e.)" % (self.time_step+1,self.time+dt_new,dt_new))
1114              end_of_step=False              end_of_step=False
1115              while not end_of_step:              while not end_of_step:
1116                 end_of_step=True                 end_of_step=True
1117                 if not dt_new>0:                 if not dt_new>0:
1118                    raise NonPositiveStepSizeError("non-positive step size in step %d"%(self.n+1))                    raise NonPositiveStepSizeError("non-positive step size in step %d"%(self.time_step+1))
1119                 try:                 try:
1120                    self.doStepPreprocessing(dt_new)                    self.doStepPreprocessing(dt_new)
1121                    self.doStep(dt_new)                    self.doStep(dt_new)
# Line 1044  class Simulation(Model): Line 1128  class Simulation(Model):
1128                             raise SimulationBreakDownError("reduction of time step to achieve convergence failed after %s steps."%self.FAILED_TIME_STEPS_MAX)                             raise SimulationBreakDownError("reduction of time step to achieve convergence failed after %s steps."%self.FAILED_TIME_STEPS_MAX)
1129                    self.trace("Iteration failed. Time step is repeated with new step size %s."%dt_new)                    self.trace("Iteration failed. Time step is repeated with new step size %s."%dt_new)
1130                 except FailedTimeStepError:                 except FailedTimeStepError:
1131                    dt_new=self.getSafeTimeStepSize(dt)                    dt_new=self.getSafeTimeStepSize(self.dt)
1132                    end_of_step=False                    end_of_step=False
1133                    step_fail_counter+=1                    step_fail_counter+=1
1134                    self.trace("Time step is repeated with new time step size %s."%dt_new)                    self.trace("Time step is repeated with new time step size %s."%dt_new)
1135                    if step_fail_counter>self.FAILED_TIME_STEPS_MAX:                    if step_fail_counter>self.FAILED_TIME_STEPS_MAX:
1136                          raise SimulationBreakDownError("Time integration is given up after %d attempts."%step_fail_counter)                          raise SimulationBreakDownError("Time integration is given up after %d attempts."%step_fail_counter)
1137              dt=dt_new              if not check_pointing==None:
1138              if not check_point==None:                 if check_pointing.doDump():
                 if n%check_point==0:  
1139                      self.trace("check point is created.")                      self.trace("check point is created.")
1140                      self.writeXML()                      self.writeXML()
1141          self.doFinalization()          self.doFinalization()
# Line 1078  class Simulation(Model): Line 1161  class Simulation(Model):
1161              if isinstance(n, minidom.Text):              if isinstance(n, minidom.Text):
1162                  continue                  continue
1163              sims.append(esysxml.getComponent(n))              sims.append(esysxml.getComponent(n))
1164          sims.sort(cmp=_comp)          sims.sort(_comp)
1165          sim=cls([s[1] for s in sims], debug=esysxml.debug)          sim=cls([s[1] for s in sims], debug=esysxml.debug)
1166          esysxml.registerLinkableObject(sim, node)          esysxml.registerLinkableObject(sim, node)
1167          return sim          return sim
# Line 1122  class NonPositiveStepSizeError(Exception Line 1205  class NonPositiveStepSizeError(Exception
1205      """      """
1206      pass      pass
1207    
1208    class MissingLink(Exception):
1209        """
1210        Exception thrown when a link is missing
1211        """
1212        pass
1213    
1214  class DataSource(object):  class DataSource(object):
1215      """      """
1216      Class for handling data sources, including local and remote files. This class is under development.      Class for handling data sources, including local and remote files. This class is under development.
# Line 1151  class DataSource(object): Line 1240  class DataSource(object):
1240          return self.uri          return self.uri
1241    
1242      fromDom = classmethod(fromDom)      fromDom = classmethod(fromDom)
1243        
1244    class RestartManager(object):
1245         """
1246         A restart manager which does two things: it decides when restart files have created (when doDump returns true) and
1247         manages directories for restart files. The method getNewDumper creates a new directory and returns its name.
1248        
1249         This restart manager will decide to dump restart files if every dump_step calls of doDump or
1250         if more than dump_time since the last dump has elapsed. The restart manager controls two directories for dumping restart data, namely
1251         for the current and previous dump. This way the previous dump can be used for restart in the case the current dump failed.
1252    
1253         @cvar SEC: unit of seconds, for instance for 5*RestartManager.SEC to define 5 seconds.
1254         @cvar MIN: unit of minutes, for instance for 5*RestartManager.MIN to define 5 minutes.
1255         @cvar H: unit of hours, for instance for 5*RestartManager.H to define 5 hours.
1256         @cvar D: unit of days, for instance for 5*RestartManager.D to define 5 days.
1257         """
1258         SEC=1.
1259         MIN=60.
1260         H=360.
1261         D=8640.
1262         def __init__(self,dump_time=1080., dump_step=None, dumper=None):
1263             """
1264             initializes the RestartManager.
1265    
1266             @param dump_time: defines the minimum time interval in SEC between to dumps. If None, time is not used as criterion.
1267             @param dump_step: defines the number of calls of doDump between to dump events. If None, the call counter is not used as criterion.
1268             @param dumper: defines the directory for dumping restart files. Additionally the directories dumper+"_bkp" and dumper+"_bkp2" are used.
1269                            if the directory does not exist it is created. If dumper is not present a unique directory within the current
1270                            working directory is used.
1271             """
1272             self.__dump_step=dump_time
1273             self.__dump_time=dump_step
1274             self.__counter=0
1275             self.__saveMarker()
1276             if dumper == None:
1277                self.__dumper="restart"+str(os.getpid())
1278             else:
1279                self.__dumper=dumper
1280             self.__dumper_bkp=self.__dumper+"_bkp"
1281             self.__dumper_bkp2=self.__dumper+"_bkp2"
1282             self.__current_dumper=None
1283         def __saveMarker(self):
1284             self.__last_restart_time=time.time()
1285             self.__last_restart_counter=self.__counter
1286         def getCurrentDumper(self):
1287             """
1288             returns the name of the currently used dumper
1289             """
1290             return self.__current_dumper
1291         def doDump(self):
1292            """
1293            returns true the restart should be dumped. use C{getNewDumper} to get the directory name to be used.
1294            """
1295            if self.__dump_step == None:
1296               if self.__dump_step == None:
1297                  out = False
1298               else:
1299                  out = (self.__dump_step + self.__last_restart_counter) <= self.__counter
1300            else:
1301               if dump_step == None:
1302                  out = (self.__last_restart_time + self.__dump_time) <= time.time()
1303               else:
1304                  out =    ( (self.__dump_step + self.__last_restart_counter) <= self.__counter)  \
1305                        or ( (self.__last_restart_time + self.__dump_time) <= time.time() )
1306            if out: self.__saveMarker()
1307            self__counter+=1
1308         def getNewDumper(self):
1309           """
1310           creates a new directory to be used for dumping and returns its name.
1311           """
1312           if os.access(self.__dumper_bkp,os.F_OK):
1313              if os.access(self.__dumper_bkp2, os.F_OK):
1314                 raise RunTimeError("please remove %s."%self.__dumper_bkp2)
1315              try:
1316                 os.rename(self.__dumper_bkp, self.__dumper_bkp2)
1317              except:
1318                 self.__current_dumper=self.__dumper
1319                 raise RunTimeError("renaming back-up directory %s failed. Use %s for restart."%(self.__dumper_bkp,self.__dumper))
1320           if os.access(self.__dumper,os.F_OK):
1321              if os.access(self.__dumper_bkp, os.F_OK):
1322                 raise RunTimeError("please remove %s."%self.__dumper_bkp)
1323              try:
1324                 os.rename(self.__dumper, self.__dumper_bkp)
1325              except:
1326                 self.__current_dumper=self.__dumper_bkp2
1327                 raise RunTimeError("moving directory %s to back-up failed. Use %s for restart."%(self.__dumper,self.__dumper_bkp2))
1328           try:
1329              os.mkdir(self.__dumper)
1330           except:
1331              self.__current_dumper=self.__dumper_bkp
1332              raise RunTimeError("creating a new restart directory %s failed. Use %s for restart."%(self.__dumper,self.__dumper_bkp))
1333           if os.access(self.__dumper_bkp2, os.F_OK): os.rmdir(self.__dumper_bkp2)
1334           return self.getCurrentDumper()
1335            
1336        
1337  # vim: expandtab shiftwidth=4:  # vim: expandtab shiftwidth=4:

Legend:
Removed from v.926  
changed lines
  Added in v.1042

  ViewVC Help
Powered by ViewVC 1.1.26