/[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

trunk/esys2/escript/py_src/modelframe.py revision 147 by jgs, Fri Aug 12 01:45:47 2005 UTC trunk/escript/py_src/modelframe.py revision 614 by elspeth, Wed Mar 22 01:37:07 2006 UTC
# Line 1  Line 1 
1  # $Id$  # $Id$
2    
3    __copyright__="""  Copyright (c) 2006 by ACcESS MNRF
4                        http://www.access.edu.au
5                    Primary Business: Queensland, Australia"""
6    __license__="""Licensed under the Open Software License version 3.0
7                 http://www.opensource.org/licenses/osl-3.0.php"""
8    
9  from types import StringType,IntType,FloatType,BooleanType,ListType,DictType  from types import StringType,IntType,FloatType,BooleanType,ListType,DictType
10  from sys import stdout  from sys import stdout
11  import itertools  import itertools
# Line 15  from xml.dom import minidom Line 21  from xml.dom import minidom
21    
22  def dataNode(document, tagName, data):  def dataNode(document, tagName, data):
23      """      """
24      dataNodes are the building blocks of the xml documents constructed in      C{dataNode}s are the building blocks of the xml documents constructed in
25      this module. document is the current xml document, tagName is the      this module.  
26      associated xml tag, and data is the values in the tag.      
27        @param document: the current xml document
28        @param tagName: the associated xml tag
29        @param data: the values in the tag
30      """      """
31      t = document.createTextNode(str(data))      t = document.createTextNode(str(data))
32      n = document.createElement(tagName)      n = document.createElement(tagName)
# Line 57  def registerLink(obj_id, l): Line 66  def registerLink(obj_id, l):
66    
67  def parse(xml):  def parse(xml):
68      """      """
69      Generic parse method for EsysXML. Without this, Links don't work.      Generic parse method for EsysXML.  Without this, Links don't work.
70      """      """
71      global LinkRegistry, LinkableObjectRegistry      global LinkRegistry, LinkableObjectRegistry
72      LinkRegistry = []      LinkRegistry = []
# Line 70  def parse(xml): Line 79  def parse(xml):
79    
80      return sim      return sim
81    
82    def importName(modulename, name):
83        """ Import a named object from a module in the context of this function,
84            which means you should use fully qualified module paths.
85            
86            Return None on failure.
87    
88            This function from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52241
89        """
90        module = __import__(modulename, globals(), locals(), [name])
91            
92        try:
93            return vars(module)[name]
94        except KeyError:
95            raise ImportError("Could not import %s from %s" % (name, modulename))
96    
97  def getComponent(doc):  def getComponent(doc):
98      """      """
99      Used to get components of Simualtions, Models.      Used to get components of Simualtions, Models.
# Line 81  def getComponent(doc): Line 105  def getComponent(doc):
105                  if node.getAttribute("type") == 'Simulation':                  if node.getAttribute("type") == 'Simulation':
106                      return Simulation.fromDom(node)                      return Simulation.fromDom(node)
107              if node.tagName == 'Model':              if node.tagName == 'Model':
108                  model_type = node.getAttribute("type")                  if (node.getAttribute("module")):
109                  model_subclasses = Model.__subclasses__()                      model_module = node.getAttribute("module")
110                  for model in model_subclasses:                      model_type = node.getAttribute("type")
111                      if model_type == model.__name__:                      return importName(model_module, model_type).fromDom(node)
112                          return Model.fromDom(node)                  else:
113                        model_type = node.getAttribute("type")
114                        model_subclasses = Model.__subclasses__()
115                        for model in model_subclasses:
116                            if model_type == model.__name__:
117                                return Model.fromDom(node)
118              if node.tagName == 'ParameterSet':              if node.tagName == 'ParameterSet':
119                  parameter_type = node.getAttribute("type")                  parameter_type = node.getAttribute("type")
120                  return ParameterSet.fromDom(node)                  return ParameterSet.fromDom(node)
# Line 97  def getComponent(doc): Line 126  def getComponent(doc):
126    
127  class Link:  class Link:
128      """      """
129      a Link makes an attribute of an object callable:      A Link makes an attribute of an object callable::
130    
131            o.object()            o.object()
132            o.a=8            o.a=8
133            l=Link(o,"a")            l=Link(o,"a")
# Line 106  class Link: Line 136  class Link:
136            
137      def __init__(self,target,attribute=None):      def __init__(self,target,attribute=None):
138          """          """
139          creates a link to the object target. If attribute is given, the link is          Creates a link to the object target. If attribute is given, the link is
140          establised to this attribute of the target.  Otherwise the attribute is          establised to this attribute of the target.  Otherwise the attribute is
141          undefined.          undefined.
142          """          """
# Line 116  class Link: Line 146  class Link:
146            
147      def setAttributeName(self,attribute):      def setAttributeName(self,attribute):
148          """          """
149          set a new attribute name to be collected from the target object. The          Set a new attribute name to be collected from the target object. The
150          target object must have the attribute with name attribute.          target object must have the attribute with name attribute.
151          """          """
152          if attribute and self.target:          if attribute and self.target:
# Line 130  class Link: Line 160  class Link:
160            
161      def hasDefinedAttributeName(self):      def hasDefinedAttributeName(self):
162          """          """
163          returns true if an attribute name is set          Returns true if an attribute name is set.
164          """          """
165          return self.attribute != None          return self.attribute != None
166            
167      def __repr__(self):      def __repr__(self):
168          """          """
169          returns a string representation of the link          Returns a string representation of the link.
170          """          """
171          if self.hasDefinedAttributeName():          if self.hasDefinedAttributeName():
172              return "<Link to attribute %s of %s>" % (self.attribute, self.target)              return "<Link to attribute %s of %s>" % (self.attribute, self.target)
# Line 145  class Link: Line 175  class Link:
175            
176      def __call__(self,name=None):      def __call__(self,name=None):
177          """          """
178          returns the value of the attribute of the target object. If the          Returns the value of the attribute of the target object. If the
179          atrribute is callable then the return value of the call is returned.          atrribute is callable then the return value of the call is returned.
180          """          """
181          if name:          if name:
# Line 160  class Link: Line 190  class Link:
190    
191      def toDom(self, document, node):      def toDom(self, document, node):
192          """          """
193          toDom method of Link. Creates a Link node and appends it to the current XML          C{toDom} method of Link. Creates a Link node and appends it to the
194          document      current XML document.
195          """          """
196          link = document.createElement('Link')          link = document.createElement('Link')
197          assert (self.target != None), ("Target was none, name was %r" % self.attribute)          assert (self.target != None), ("Target was none, name was %r" % self.attribute)
# Line 183  class Link: Line 213  class Link:
213            
214      def writeXML(self,ostream=stdout):      def writeXML(self,ostream=stdout):
215          """          """
216          writes an XML representation of self to the output stream ostream.          Writes an XML representation of self to the output stream ostream.
217          If ostream is nor present the standart output stream is used.  If          If ostream is nor present the standart output stream is used.  If
218          esysheader==True the esys XML header is written          esysheader==True the esys XML header is written
219          """          """
# Line 196  class Link: Line 226  class Link:
226  class LinkableObject(object):  class LinkableObject(object):
227      """      """
228      An object that allows to link its attributes to attributes of other objects      An object that allows to link its attributes to attributes of other objects
229      via a Link object. For instance      via a Link object. For instance::
230                        
231             p = LinkableObject()             p = LinkableObject()
232             p.x = Link(o,"name")             p.x = Link(o,"name")
233             print p.x             print p.x
234            
235      links attribute x of p to the attribute name of object o.      links attribute C{x} of C{p} to the attribute name of object C{o}.
236    
237      p.x will contain the current value of attribute name of object o.        C{p.x} will contain the current value of attribute C{name} of object
238        C{o}.  
239    
240      If the value of getattr(o, "name") is callable, p.x will rturn the return      If the value of C{getattr(o, "name")} is callable, C{p.x} will return
241      value of the call.      the return value of the call.
242      """      """
243        
244      number_sequence = itertools.count(100)      number_sequence = itertools.count(100)
245            
246      def __init__(self, debug=False):      def __init__(self, debug=False):
247          """ initializes LinkableObject so that we can operate on Links """          """
248        Initializes LinkableObject so that we can operate on Links
249        """
250          self.debug = debug          self.debug = debug
251          self.__linked_attributes={}          self.__linked_attributes={}
252          self.id = self.number_sequence.next()          self.id = self.number_sequence.next()
253            registerLinkableObject(self.id, self)
254    
255      def trace(self, msg):      def trace(self, msg):
256          """ If debugging is on, print the message, otherwise do nothing          """
257        If debugging is on, print the message, otherwise do nothing
258          """          """
259          if self.debug:          if self.debug:
260              print "%s: %s"%(str(self),msg)              print "%s: %s"%(str(self),msg)
261            
262      def __getattr__(self,name):      def __getattr__(self,name):
263          """returns the value of attribute name. If the value is a Link object the          """
264          object is called and the return value is returned."""      Returns the value of attribute name. If the value is a Link object the
265            object is called and the return value is returned.
266        """
267          out = self.getAttributeObject(name)          out = self.getAttributeObject(name)
268          if isinstance(out,Link):          if isinstance(out,Link):
269              return out()              return out()
# Line 234  class LinkableObject(object): Line 271  class LinkableObject(object):
271              return out              return out
272            
273      def getAttributeObject(self,name):      def getAttributeObject(self,name):
274          """return the object stored for attribute name."""          """
275        Return the object stored for attribute name.
276        """
277    
278          if self.__dict__.has_key(name):          if self.__dict__.has_key(name):
279              return self.__dict__[name]              return self.__dict__[name]
# Line 248  class LinkableObject(object): Line 287  class LinkableObject(object):
287          raise AttributeError,"No attribute %s."%name          raise AttributeError,"No attribute %s."%name
288            
289      def hasAttribute(self,name):      def hasAttribute(self,name):
290          """returns True if self as attribute name"""          """
291        Returns True if self as attribute name.
292        """
293          return self.__dict__.has_key(name) or self.__linked_attributes.has_key(name) or  self.__class__.__dict__.has_key(name)          return self.__dict__.has_key(name) or self.__linked_attributes.has_key(name) or  self.__class__.__dict__.has_key(name)
294    
295      def __setattr__(self,name,value):      def __setattr__(self,name,value):
296          """sets the value for attribute name. If value is a Link the target          """
297          attribute is set to name if no attribute has been specified."""      Sets the value for attribute name. If value is a Link the target
298            attribute is set to name if no attribute has been specified.
299        """
300    
301          if self.__dict__.has_key(name):          if self.__dict__.has_key(name):
302              del self.__dict__[name]              del self.__dict__[name]
# Line 269  class LinkableObject(object): Line 311  class LinkableObject(object):
311              self.__dict__[name] = value              self.__dict__[name] = value
312            
313      def __delattr__(self,name):      def __delattr__(self,name):
314          """removes the attribute name."""          """
315        Removes the attribute name.
316        """
317    
318          if self.__linked_attributes.has_key[name]:          if self.__linked_attributes.has_key[name]:
319              del self.__linked_attributes[name]              del self.__linked_attributes[name]
# Line 292  class _ParameterIterator: Line 336  class _ParameterIterator:
336          return self          return self
337    
338  class ParameterSet(LinkableObject):  class ParameterSet(LinkableObject):
339      """a class which allows to emphazise attributes to be written and read to XML      """
340        A class which allows to emphazise attributes to be written and read to XML
341                
342         Leaves of  an ESySParameters objects can be      Leaves of an ESySParameters object can be:
343            
344              a real number       - a real number
345              a integer number       - a integer number
346              a string       - a string
347              a boolean value       - a boolean value
348              a ParameterSet object       - a ParameterSet object
349              a Simulation object       - a Simulation object
350              a Model object       - a Model object
351              any other object (not considered by writeESySXML and writeXML)       - any other object (not considered by writeESySXML and writeXML)
352            
353             Example how to create an ESySParameters object:      Example how to create an ESySParameters object::
354            
355                   p11=ParameterSet(gamma1=1.,gamma2=2.,gamma3=3.)          p11=ParameterSet(gamma1=1.,gamma2=2.,gamma3=3.)
356                   p1=ParameterSet(dim=2,tol_v=0.001,output_file="/tmp/u.%3.3d.dx",runFlag=True,parm11=p11)          p1=ParameterSet(dim=2,tol_v=0.001,output_file="/tmp/u.%3.3d.dx",runFlag=True,parm11=p11)
357                   parm=ParameterSet(parm1=p1,parm2=ParameterSet(alpha=Link(p11,"gamma1")))          parm=ParameterSet(parm1=p1,parm2=ParameterSet(alpha=Link(p11,"gamma1")))
358            
359             This can be accessed as      This can be accessed as::
360            
361                   parm.parm1.gamma=0.      parm.parm1.gamma=0.
362                   parm.parm1.dim=2          parm.parm1.dim=2
363                   parm.parm1.tol_v=0.001          parm.parm1.tol_v=0.001
364                   parm.parm1.output_file="/tmp/u.%3.3d.dx"          parm.parm1.output_file="/tmp/u.%3.3d.dx"
365                   parm.parm1.runFlag=True          parm.parm1.runFlag=True
366                   parm.parm1.parm11.gamma1=1.          parm.parm1.parm11.gamma1=1.
367                   parm.parm1.parm11.gamma2=2.          parm.parm1.parm11.gamma2=2.
368                   parm.parm1.parm11.gamma3=3.          parm.parm1.parm11.gamma3=3.
369                   parm.parm2.alpha=1. (value of parm.parm1.parm11.gamma1)          parm.parm2.alpha=1. (value of parm.parm1.parm11.gamma1)
               
370      """      """
371      def __init__(self, parameters=[], **kwargs):      def __init__(self, parameters=[], **kwargs):
372          """creates a ParameterSet with parameters parameters"""          """
373        Creates a ParameterSet with parameters parameters.
374        """
375          LinkableObject.__init__(self, **kwargs)          LinkableObject.__init__(self, **kwargs)
376          self.parameters = set()          self.parameters = set()
377          self.declareParameters(parameters)          self.declareParameters(parameters)
# Line 335  class ParameterSet(LinkableObject): Line 381  class ParameterSet(LinkableObject):
381                              [(p, getattr(self, p, None)) for p in self.parameters])                              [(p, getattr(self, p, None)) for p in self.parameters])
382            
383      def declareParameter(self,**parameters):      def declareParameter(self,**parameters):
384          """declares a new parameter(s) and its (their) inital value."""          """
385        Declares a new parameter(s) and its (their) initial value.
386        """
387          self.declareParameters(parameters)          self.declareParameters(parameters)
388            
389      def declareParameters(self,parameters):      def declareParameters(self,parameters):
390          """declares a set of parameters. parameters can be a list, a dictonary or a ParameterSet."""          """
391        Declares a set of parameters. parameters can be a list, a dictionary
392        or a ParameterSet.
393        """
394          if isinstance(parameters,ListType):          if isinstance(parameters,ListType):
395              parameters = zip(parameters, itertools.repeat(None))              parameters = zip(parameters, itertools.repeat(None))
396          if isinstance(parameters,DictType):          if isinstance(parameters,DictType):
# Line 352  class ParameterSet(LinkableObject): Line 403  class ParameterSet(LinkableObject):
403              self.trace("parameter %s has been declared."%prm)              self.trace("parameter %s has been declared."%prm)
404    
405      def releaseParameters(self,name):      def releaseParameters(self,name):
406          """removes parameter name from the paramameters"""          """
407        Removes parameter name from the paramameters.
408        """
409          if self.isParameter(name):          if self.isParameter(name):
410              self.parameters.remove(name)              self.parameters.remove(name)
411              self.trace("parameter %s has been removed."%name)              self.trace("parameter %s has been removed."%name)
412            
413      def __iter__(self):      def __iter__(self):
414          """creates an iterator over the parameter and their values"""          """
415        Creates an iterator over the parameter and their values.
416        """
417          return _ParameterIterator(self)          return _ParameterIterator(self)
418            
419      def showParameters(self):      def showParameters(self):
420          """returns a descrition of the parameters"""                  """
421        Returns a descrition of the parameters.
422        """        
423          out="{"          out="{"
424          notfirst=False          notfirst=False
425          for i,v in self:          for i,v in self:
# Line 375  class ParameterSet(LinkableObject): Line 432  class ParameterSet(LinkableObject):
432          return out+"}"          return out+"}"
433            
434      def __delattr__(self,name):      def __delattr__(self,name):
435          """removes the attribute name."""          """
436        Removes the attribute name.
437        """
438          LinkableObject.__delattr__(self,name)          LinkableObject.__delattr__(self,name)
439          try:          try:
440              self.releaseParameter(name)              self.releaseParameter(name)
# Line 383  class ParameterSet(LinkableObject): Line 442  class ParameterSet(LinkableObject):
442              pass              pass
443    
444      def toDom(self, document, node):      def toDom(self, document, node):
445          """ toDom method of ParameterSet class """          """
446        C{toDom} method of ParameterSet class.
447        """
448          pset = document.createElement('ParameterSet')          pset = document.createElement('ParameterSet')
449          node.appendChild(pset)          node.appendChild(pset)
450          self._parametersToDom(document, pset)          self._parametersToDom(document, pset)
451    
452      def _parametersToDom(self, document, node):      def _parametersToDom(self, document, node):
453          node.setAttribute ('id', str(self.id))          node.setAttribute('id', str(self.id))
454            node.setIdAttribute("id")
455          for name,value in self:          for name,value in self:
456              param = document.createElement('Parameter')              param = document.createElement('Parameter')
457              param.setAttribute('type', value.__class__.__name__)              param.setAttribute('type', value.__class__.__name__)
# Line 416  class ParameterSet(LinkableObject): Line 478  class ParameterSet(LinkableObject):
478          # Define a host of helper functions to assist us.          # Define a host of helper functions to assist us.
479          def _children(node):          def _children(node):
480              """              """
481              Remove the empty nodes from the children of this node              Remove the empty nodes from the children of this node.
482              """              """
483              return [x for x in node.childNodes              return [x for x in node.childNodes
484                      if not isinstance(x, minidom.Text) or x.nodeValue.strip()]                      if not isinstance(x, minidom.Text) or x.nodeValue.strip()]
# Line 432  class ParameterSet(LinkableObject): Line 494  class ParameterSet(LinkableObject):
494    
495          def _boolfromValue(doc):          def _boolfromValue(doc):
496              return bool(doc.nodeValue.strip())              return bool(doc.nodeValue.strip())
497    
498            def _nonefromValue(doc):
499                return None
500                
501          # Mapping from text types in the xml to methods used to process trees of that type          # Mapping from text types in the xml to methods used to process trees of that type
502          ptypemap = {"Simulation": Simulation.fromDom,          ptypemap = {"Simulation": Simulation.fromDom,
# Line 441  class ParameterSet(LinkableObject): Line 506  class ParameterSet(LinkableObject):
506                      "float":_floatfromValue,                      "float":_floatfromValue,
507                      "int":_intfromValue,                      "int":_intfromValue,
508                      "str":_stringfromValue,                      "str":_stringfromValue,
509                      "bool":_boolfromValue                      "bool":_boolfromValue,
510                        "NoneType":_nonefromValue
511                      }                      }
512    
513  #        print doc.toxml()  #        print doc.toxml()
# Line 471  class ParameterSet(LinkableObject): Line 537  class ParameterSet(LinkableObject):
537      fromDom = classmethod(fromDom)      fromDom = classmethod(fromDom)
538            
539      def writeXML(self,ostream=stdout):      def writeXML(self,ostream=stdout):
540          """writes the object as an XML object into an output stream"""          """
541        Writes the object as an XML object into an output stream.
542        """
543          # ParameterSet(d) with d[Name]=Value          # ParameterSet(d) with d[Name]=Value
544          document, node = esysDoc()          document, node = esysDoc()
545          self.toDom(document, node)          self.toDom(document, node)
# Line 479  class ParameterSet(LinkableObject): Line 547  class ParameterSet(LinkableObject):
547    
548  class Model(ParameterSet):  class Model(ParameterSet):
549      """      """
550        A Model object represents a processess marching over time until a
551      A Model object represents a processess marching over time      finalizing condition is fullfilled. At each time step an iterative
552      until a finalizing condition is fullfilled. At each time step an iterative      process can be performed and the time step size can be controlled. A
553      process can be performed and the time step size can be controlled. A Model has      Model has the following work flow::
     the following work flow:  
554    
555            doInitialization()            doInitialization()
556            while not finalize():            while not finalize():
# Line 493  class Model(ParameterSet): Line 560  class Model(ParameterSet):
560                 doStepPostprocessing(dt)                 doStepPostprocessing(dt)
561            doFinalization()            doFinalization()
562    
563            where doInitialization,finalize, getSafeTimeStepSize, doStepPreprocessing, terminateIteration, doStepPostprocessing, doFinalization      where C{doInitialization}, C{finalize}, C{getSafeTimeStepSize},
564            are methods of the particular instance of a Model. The default implementations of these methods have to be overwritten by      C{doStepPreprocessing}, C{terminateIteration}, C{doStepPostprocessing},
565            the subclass implementinf a Model.      C{doFinalization} are methods of the particular instance of a Model. The
566        default implementations of these methods have to be overwritten by the
567        subclass implementing a Model.
568      """      """
569    
570      UNDEF_DT=1.e300      UNDEF_DT=1.e300
571    
572      def __init__(self,parameters=[],**kwarg):      def __init__(self,parameters=[],**kwarg):
573          """creates a model          """
574        Creates a model.
575    
576              Just calls the parent constructor.          Just calls the parent constructor.
577          """          """
578          ParameterSet.__init__(self, parameters=parameters,**kwarg)          ParameterSet.__init__(self, parameters=parameters,**kwarg)
579    
# Line 512  class Model(ParameterSet): Line 581  class Model(ParameterSet):
581         return "<%s %d>"%(self.__class__,id(self))         return "<%s %d>"%(self.__class__,id(self))
582    
583      def toDom(self, document, node):      def toDom(self, document, node):
584          """ toDom method of Model class """          """
585        C{toDom} method of Model class
586        """
587          pset = document.createElement('Model')          pset = document.createElement('Model')
588          pset.setAttribute('type', self.__class__.__name__)          pset.setAttribute('type', self.__class__.__name__)
589            if not self.__class__.__module__.startswith('esys.escript'):
590                pset.setAttribute('module', self.__class__.__module__)
591          node.appendChild(pset)          node.appendChild(pset)
592          self._parametersToDom(document, pset)          self._parametersToDom(document, pset)
593    
594      def doInitialization(self):      def doInitialization(self):
595          """initializes the time stepping scheme. This function may be overwritten."""          """
596        Initializes the time stepping scheme.  
597        
598        This function may be overwritten.
599        """
600          pass          pass
601            
602      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
603          """returns a time step size which can safely be used.          """
604             dt gives the previously used step size.      Returns a time step size which can safely be used.
605             This function may be overwritten."""  
606            C{dt} gives the previously used step size.
607    
608            This function may be overwritten.
609        """
610          return self.UNDEF_DT          return self.UNDEF_DT
611            
612      def finalize(self):      def finalize(self):
613          """returns False if the time stepping is finalized. This function may be          """
614          overwritten."""      Returns False if the time stepping is finalized.
615        
616        This function may be overwritten.
617        """
618          return False          return False
619                
620      def doFinalization(self):      def doFinalization(self):
621          """finalizes the time stepping. This function may be overwritten."""          """
622        Finalizes the time stepping.
623        
624        This function may be overwritten.
625        """
626          pass          pass
627            
628      def doStepPreprocessing(self,dt):      def doStepPreprocessing(self,dt):
629          """sets up a time step of step size dt. This function may be overwritten."""          """
630        Sets up a time step of step size dt.
631        
632        This function may be overwritten.
633        """
634          pass          pass
635            
636      def doStep(self,dt):      def doStep(self,dt):
637          """executes an iteration step at a time step.          """
638             dt is the currently used time step size.      Executes an iteration step at a time step.
639             This function may be overwritten."""  
640            C{dt} is the currently used time step size.
641    
642            This function may be overwritten.
643        """
644          pass          pass
645            
646      def terminateIteration(self):      def terminateIteration(self):
647          """returns True if iteration on a time step is terminated."""          """
648        Returns True if iteration on a time step is terminated.
649        """
650          return True          return True
651                
652      def doStepPostprocessing(self,dt):      def doStepPostprocessing(self,dt):
653          """finalalizes the time step.          """
654             dt is the currently used time step size.      Finalalizes the time step.
655             This function may be overwritten."""  
656            dt is the currently used time step size.
657    
658            This function may be overwritten.
659        """
660          pass          pass
661            
662      def writeXML(self, ostream=stdout):      def writeXML(self, ostream=stdout):
# Line 562  class Model(ParameterSet): Line 664  class Model(ParameterSet):
664          self.toDom(document, node)          self.toDom(document, node)
665          ostream.write(document.toprettyxml())          ostream.write(document.toprettyxml())
666            
       
667    
668  class Simulation(Model):  class Simulation(Model):
669      """      """
670            A Simulation object is special Model which runs a sequence of Models.      A Simulation object is special Model which runs a sequence of Models.
671    
672            The methods doInitialization,finalize, getSafeTimeStepSize, doStepPreprocessing,      The methods C{doInitialization}, C{finalize}, C{getSafeTimeStepSize},
673            terminateIteration, doStepPostprocessing, doFinalization      C{doStepPreprocessing}, C{terminateIteration}, C{doStepPostprocessing},
674            are executing the corresponding methods of the models in the simulation.      C{doFinalization} are executing the corresponding methods of the models in
675                  the simulation.
676      """      """
677            
678      FAILED_TIME_STEPS_MAX=20      FAILED_TIME_STEPS_MAX=20
679      MAX_ITER_STEPS=50      MAX_ITER_STEPS=50
680            
681      def __init__(self, models=[], **kwargs):      def __init__(self, models=[], **kwargs):
682          """initiates a simulation from a list of models. """          """
683        Initiates a simulation from a list of models.
684        """
685          Model.__init__(self, **kwargs)          Model.__init__(self, **kwargs)
686          self.__models=[]          self.__models=[]
687            
688          for i in range(len(models)):          for i in range(len(models)):
689              self[i] = models[i]              self[i] = models[i]
690                
691    
692      def __repr__(self):      def __repr__(self):
693          """          """
694          returns a string representation of the Simulation          Returns a string representation of the Simulation.
695          """          """
696          return "<Simulation %r>" % self.__models          return "<Simulation %r>" % self.__models
697    
698      def __str__(self):      def __str__(self):
699          """          """
700          returning Simulation as a string          Returning Simulation as a string.
701          """          """
702          return "<Simulation %d>"%id(self)          return "<Simulation %d>"%id(self)
703            
704      def iterModels(self):      def iterModels(self):
705          """returns an iterator over the models"""          """
706        Returns an iterator over the models.
707        """
708          return self.__models          return self.__models
709            
710      def __getitem__(self,i):      def __getitem__(self,i):
711          """returns the i-th model"""          """
712        Returns the i-th model.
713        """
714          return self.__models[i]          return self.__models[i]
715            
716      def __setitem__(self,i,value):      def __setitem__(self,i,value):
717          """sets the i-th model"""          """
718        Sets the i-th model.
719        """
720          if not isinstance(value,Model):          if not isinstance(value,Model):
721              raise ValueError("assigned value is not a Model")              raise ValueError("assigned value is not a Model, Model was:", i, " an instance of: ", value.__class__.__name__)
722          for j in range(max(i-len(self.__models)+1,0)): self.__models.append(None)          for j in range(max(i-len(self.__models)+1,0)):
723                self.__models.append(None)
724          self.__models[i]=value          self.__models[i]=value
725            
726      def __len__(self):      def __len__(self):
727          """returns the number of models"""          """
728        Returns the number of models.
729        """
730          return len(self.__models)          return len(self.__models)
731    
732      def toDom(self, document, node):      def toDom(self, document, node):
733          """ toDom method of Simulation class """          """
734        C{toDom} method of Simulation class.
735        """
736          simulation = document.createElement('Simulation')          simulation = document.createElement('Simulation')
737          simulation.setAttribute('type', self.__class__.__name__)          simulation.setAttribute('type', self.__class__.__name__)
738    
# Line 632  class Simulation(Model): Line 747  class Simulation(Model):
747          node.appendChild(simulation)          node.appendChild(simulation)
748    
749      def writeXML(self,ostream=stdout):      def writeXML(self,ostream=stdout):
750          """writes the object as an XML object into an output stream"""          """
751        Writes the object as an XML object into an output stream.
752        """
753          document, rootnode = esysDoc()          document, rootnode = esysDoc()
754          self.toDom(document, rootnode)          self.toDom(document, rootnode)
755            targetsList = document.getElementsByTagName('Target')
756            
757            for element in targetsList:
758                targetId = int(element.firstChild.nodeValue.strip())
759                if document.getElementById(str(targetId)):
760                    continue
761                targetObj = LinkableObjectRegistry[targetId]
762                targetObj.toDom(document, rootnode)
763          ostream.write(document.toprettyxml())          ostream.write(document.toprettyxml())
764            
765      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
766          """returns a time step size which can safely be used by all models.          """
767             This is the minimum over the time step sizes of all models."""      Returns a time step size which can safely be used by all models.
768    
769            This is the minimum over the time step sizes of all models.
770        """
771          out=min([o.getSafeTimeStepSize(dt) for o in self.iterModels()])          out=min([o.getSafeTimeStepSize(dt) for o in self.iterModels()])
772          print "%s: safe step size is %e."%(str(self),out)          #print "%s: safe step size is %e."%(str(self),out)
773          return out          return out
774            
775      def doInitialization(self):      def doInitialization(self):
776          """initializes all models """          """
777        Initializes all models.
778        """
779          self.n=0          self.n=0
780          self.tn=0.          self.tn=0.
781          for o in self.iterModels():          for o in self.iterModels():
782              o.doInitialization()              o.doInitialization()
783            
784      def finalize(self):      def finalize(self):
785          """returns True if any of the models is to be finalized"""          """
786        Returns True if any of the models is to be finalized.
787        """
788          return any([o.finalize() for o in self.iterModels()])          return any([o.finalize() for o in self.iterModels()])
789                
790      def doFinalization(self):      def doFinalization(self):
791          """finalalizes the time stepping for all models."""          """
792        Finalalizes the time stepping for all models.
793        """
794          for i in self.iterModels(): i.doFinalization()          for i in self.iterModels(): i.doFinalization()
795          self.trace("end of time integation.")          self.trace("end of time integation.")
796            
797      def doStepPreprocessing(self,dt):      def doStepPreprocessing(self,dt):
798          """initializes the time step for all models."""          """
799        Initializes the time step for all models.
800        """
801          for o in self.iterModels():          for o in self.iterModels():
802              o.doStepPreprocessing(dt)              o.doStepPreprocessing(dt)
803            
804      def terminateIteration(self):      def terminateIteration(self):
805          """returns True if all iterations for all models are terminated."""          """
806        Returns True if all iterations for all models are terminated.
807        """
808          out=all([o.terminateIteration() for o in self.iterModels()])          out=all([o.terminateIteration() for o in self.iterModels()])
809          return out          return out
810                
811      def doStepPostprocessing(self,dt):      def doStepPostprocessing(self,dt):
812          """finalalizes the iteration process for all models."""          """
813        Finalalizes the iteration process for all models.
814        """
815          for o in self.iterModels():          for o in self.iterModels():
816              o.doStepPostprocessing(dt)              o.doStepPostprocessing(dt)
817          self.n+=1          self.n+=1
# Line 679  class Simulation(Model): Line 819  class Simulation(Model):
819            
820      def doStep(self,dt):      def doStep(self,dt):
821          """          """
822               executes the iteration step at a time step for all model:      Executes the iteration step at a time step for all model::
823    
824                    self.doStepPreprocessing(dt)              self.doStepPreprocessing(dt)
825                    while not self.terminateIteration(): for all models: self.doStep(dt)              while not self.terminateIteration():
826                    self.doStepPostprocessing(dt)              for all models:
827                self.doStep(dt)
828                    self.doStepPostprocessing(dt)
829          """          """
830          self.iter=0          self.iter=0
831          while not self.terminateIteration():          while not self.terminateIteration():
# Line 697  class Simulation(Model): Line 838  class Simulation(Model):
838    
839      def run(self,check_point=None):      def run(self,check_point=None):
840          """          """
841        Run the simulation by performing essentially::
            run the simulation by performing essentially  
842            
843                 self.doInitialization()          self.doInitialization()
844                 while not self.finalize():          while not self.finalize():
845                    dt=self.getSafeTimeStepSize()              dt=self.getSafeTimeStepSize()
846                    self.doStep(dt)              self.doStep(dt)
847                    if n%check_point==0: self.writeXML()              if n%check_point==0:
848                 self.doFinalization()              self.writeXML()
849            self.doFinalization()
850             If one of the models in throws a FailedTimeStepError exception a new time step size is  
851             computed through getSafeTimeStepSize() and the time step is repeated.          If one of the models in throws a C{FailedTimeStepError} exception a
852        new time step size is computed through getSafeTimeStepSize() and the
853        time step is repeated.
854        
855             If one of the models in throws a IterationDivergenceError exception the time step size          If one of the models in throws a C{IterationDivergenceError}
856             is halved and the time step is repeated.      exception the time step size is halved and the time step is repeated.
857    
858             In both cases the time integration is given up after Simulation.FAILED_TIME_STEPS_MAX          In both cases the time integration is given up after
859             attempts.      C{Simulation.FAILED_TIME_STEPS_MAX} attempts.
   
       
860          """          """
861          dt=self.UNDEF_DT          dt=self.UNDEF_DT
862          self.doInitialization()          self.doInitialization()
# Line 770  class Simulation(Model): Line 910  class Simulation(Model):
910    
911  class IterationDivergenceError(Exception):  class IterationDivergenceError(Exception):
912      """      """
913         excpetion which is thrown if there is no convergence of the iteration process at a time step      Exception which is thrown if there is no convergence of the iteration
914         but there is a chance taht a smaller step could help to reach convergence.      process at a time step.
915    
916        But there is a chance that a smaller step could help to reach convergence.
917      """      """
918      pass      pass
919    
920  class FailedTimeStepError(Exception):  class FailedTimeStepError(Exception):
921      """excpetion which is thrown if the time step fails because of a step size that have been choosen to be too large"""      """
922        Exception which is thrown if the time step fails because of a step
923        size that have been choosen to be too large.
924        """
925      pass      pass
926    
927  class SimulationBreakDownError(Exception):  class SimulationBreakDownError(Exception):
928      """excpetion which is thrown if the simulation does not manage to progress in time."""      """
929        Exception which is thrown if the simulation does not manage to
930        progress in time.
931        """
932      pass      pass
933    
934  class NonPositiveStepSizeError(Exception):  class NonPositiveStepSizeError(Exception):
935      """excpetion which is thrown if the step size is not positive"""      """
936        Exception which is thrown if the step size is not positive.
937        """
938      pass      pass
939    
940    # vim: expandtab shiftwidth=4:

Legend:
Removed from v.147  
changed lines
  Added in v.614

  ViewVC Help
Powered by ViewVC 1.1.26