/[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 939 by gross, Thu Jan 25 04:23:38 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 467  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 476  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 527  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 587  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 676  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 729  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 746  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 849  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:          for m in models:
886              if not isinstance(m, Model):              if not isinstance(m, Model):
887                   raise TypeError("%s is not a subclass of Model."%m)                   raise TypeError("%s is not a subclass of Model."%m)
# Line 909  class Simulation(Model): Line 942  class Simulation(Model):
942                 out.append(m)                 out.append(m)
943          return list(set(out))          return list(set(out))
944    
945      def checkModelLinks(self, models):      def checkModels(self, models, hash):
946          """          """
947          returns a list of (model,parameter, target model ) if the the parameter of model          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.          is linking to the target_model which is not in list of models.
949          """          """
950          out=[]          out=self.checkLinkTargets(models, hash + [self])
951          for m in self.iterModels():          for m in self.iterModels():
952              if isinstance(m, Simulation):              if isinstance(m, Simulation):
953                 out+=[ (m,) + f for f in  m.checkModelLinks(models) ]                   out|=m.checkModels(models, hash)
954              else:              else:
955                for p in m:                   out|=m.checkLinkTargets(models, hash + [self])
956                   if isinstance(p[1], Link):          return set( [ (str(self)+"."+f[0],f[1]) for f in out ] )
                     l_m=p[1].getTarget()  
                     if isinstance(l_m, Model) and not l_m in models: out.append( (m,p[0],l_m) )  
         return out  
957    
958            
959      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
# Line 934  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 1004  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 1019  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 1053  class Simulation(Model): Line 1091  class Simulation(Model):
1091          # check the completness of the models:          # check the completness of the models:
1092          # first a list of all the models involved in the simulation including subsimulations:          # first a list of all the models involved in the simulation including subsimulations:
1093          #          #
1094          missing=self.checkModelLinks(self.getAllModels())          missing=self.checkModels(self.getAllModels(), [])
1095          if len(missing)>0:          if len(missing)>0:
1096              msg=""              msg=""
1097              for l in missing:              for l in missing:
1098                   msg+="\n\t"+str(l[-1])+" at "+str(self)                   msg+="\n\t"+str(l[1])+" at "+l[0]
                  for i in xrange(len(l)-1): msg+="."+str(l[i])  
1099              raise MissingLink("link targets missing in the Simulation: %s"%msg)              raise MissingLink("link targets missing in the Simulation: %s"%msg)
1100          #==============================          #==============================
1101          self.doInitialization()          self.setUp()
1102          self.doInitialStep()          if self.time_step < 1:
1103          self.doInitialPostprocessing()             self.doInitialization()
1104          dt=self.UNDEF_DT             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 1090  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 1124  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 1203  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.939  
changed lines
  Added in v.1042

  ViewVC Help
Powered by ViewVC 1.1.26