/[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 885 by gross, Wed Nov 1 09:05:51 2006 UTC
# Line 1  Line 1 
1  # $Id$  # $Id$
2    
3    """
4    Environment for implementing models in escript
5    
6    @var __author__: name of author
7    @var __copyright__: copyrights
8    @var __license__: licence agreement
9    @var __url__: url entry point on documentation
10    @var __version__: version
11    @var __date__: date of the version
12    """
13    
14    __author__="Lutz Gross, l.gross@uq.edu.au"
15    __copyright__="""  Copyright (c) 2006 by ACcESS MNRF
16                        http://www.access.edu.au
17                    Primary Business: Queensland, Australia"""
18    __license__="""Licensed under the Open Software License version 3.0
19                 http://www.opensource.org/licenses/osl-3.0.php"""
20    __url__="http://www.iservo.edu.au/esys"
21    __version__="$Revision$"
22    __date__="$Date$"
23    
24    
25  from types import StringType,IntType,FloatType,BooleanType,ListType,DictType  from types import StringType,IntType,FloatType,BooleanType,ListType,DictType
26  from sys import stdout  from sys import stdout
27    import numarray
28    import operator
29  import itertools  import itertools
30  # import modellib  temporarily removed!!!  # import modellib  temporarily removed!!!
31    
# Line 15  from xml.dom import minidom Line 39  from xml.dom import minidom
39    
40  def dataNode(document, tagName, data):  def dataNode(document, tagName, data):
41      """      """
42      dataNodes are the building blocks of the xml documents constructed in      C{dataNode}s are the building blocks of the xml documents constructed in
43      this module. document is the current xml document, tagName is the      this module.  
44      associated xml tag, and data is the values in the tag.      
45        @param document: the current xml document
46        @param tagName: the associated xml tag
47        @param data: the values in the tag
48      """      """
49      t = document.createTextNode(str(data))      t = document.createTextNode(str(data))
50      n = document.createElement(tagName)      n = document.createElement(tagName)
# Line 57  def registerLink(obj_id, l): Line 84  def registerLink(obj_id, l):
84    
85  def parse(xml):  def parse(xml):
86      """      """
87      Generic parse method for EsysXML. Without this, Links don't work.      Generic parse method for EsysXML.  Without this, Links don't work.
88      """      """
89      global LinkRegistry, LinkableObjectRegistry      global LinkRegistry, LinkableObjectRegistry
90      LinkRegistry = []      LinkRegistry = []
# Line 70  def parse(xml): Line 97  def parse(xml):
97    
98      return sim      return sim
99    
100    def importName(modulename, name):
101        """ Import a named object from a module in the context of this function,
102            which means you should use fully qualified module paths.
103            
104            Return None on failure.
105    
106            This function from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52241
107        """
108        module = __import__(modulename, globals(), locals(), [name])
109            
110        try:
111            return vars(module)[name]
112        except KeyError:
113            raise ImportError("Could not import %s from %s" % (name, modulename))
114    
115  def getComponent(doc):  def getComponent(doc):
116      """      """
117      Used to get components of Simualtions, Models.      Used to get components of Simualtions, Models.
# Line 81  def getComponent(doc): Line 123  def getComponent(doc):
123                  if node.getAttribute("type") == 'Simulation':                  if node.getAttribute("type") == 'Simulation':
124                      return Simulation.fromDom(node)                      return Simulation.fromDom(node)
125              if node.tagName == 'Model':              if node.tagName == 'Model':
126                  model_type = node.getAttribute("type")                  if (node.getAttribute("module")):
127                  model_subclasses = Model.__subclasses__()                      model_module = node.getAttribute("module")
128                  for model in model_subclasses:                      model_type = node.getAttribute("type")
129                      if model_type == model.__name__:                      return importName(model_module, model_type).fromDom(node)
130                          return Model.fromDom(node)                  else:
131                        model_type = node.getAttribute("type")
132                        model_subclasses = Model.__subclasses__()
133                        for model in model_subclasses:
134                            if model_type == model.__name__:
135                                return Model.fromDom(node)
136              if node.tagName == 'ParameterSet':              if node.tagName == 'ParameterSet':
137                  parameter_type = node.getAttribute("type")                  parameter_type = node.getAttribute("type")
138                  return ParameterSet.fromDom(node)                  return ParameterSet.fromDom(node)
# Line 97  def getComponent(doc): Line 144  def getComponent(doc):
144    
145  class Link:  class Link:
146      """      """
147      a Link makes an attribute of an object callable:      A Link makes an attribute of an object callable::
148    
149            o.object()            o.object()
150            o.a=8            o.a=8
151            l=Link(o,"a")            l=Link(o,"a")
# Line 106  class Link: Line 154  class Link:
154            
155      def __init__(self,target,attribute=None):      def __init__(self,target,attribute=None):
156          """          """
157          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
158          establised to this attribute of the target.  Otherwise the attribute is          establised to this attribute of the target.  Otherwise the attribute is
159          undefined.          undefined.
160          """          """
# Line 116  class Link: Line 164  class Link:
164            
165      def setAttributeName(self,attribute):      def setAttributeName(self,attribute):
166          """          """
167          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
168          target object must have the attribute with name attribute.          target object must have the attribute with name attribute.
169          """          """
170          if attribute and self.target:          if attribute and self.target:
# Line 130  class Link: Line 178  class Link:
178            
179      def hasDefinedAttributeName(self):      def hasDefinedAttributeName(self):
180          """          """
181          returns true if an attribute name is set          Returns true if an attribute name is set.
182          """          """
183          return self.attribute != None          return self.attribute != None
184            
185      def __repr__(self):      def __repr__(self):
186          """          """
187          returns a string representation of the link          Returns a string representation of the link.
188          """          """
189          if self.hasDefinedAttributeName():          if self.hasDefinedAttributeName():
190              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 193  class Link:
193            
194      def __call__(self,name=None):      def __call__(self,name=None):
195          """          """
196          returns the value of the attribute of the target object. If the          Returns the value of the attribute of the target object. If the
197          atrribute is callable then the return value of the call is returned.          atrribute is callable then the return value of the call is returned.
198          """          """
199          if name:          if name:
# Line 160  class Link: Line 208  class Link:
208    
209      def toDom(self, document, node):      def toDom(self, document, node):
210          """          """
211          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
212          document      current XML document.
213          """          """
214          link = document.createElement('Link')          link = document.createElement('Link')
215          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 231  class Link:
231            
232      def writeXML(self,ostream=stdout):      def writeXML(self,ostream=stdout):
233          """          """
234          writes an XML representation of self to the output stream ostream.          Writes an XML representation of self to the output stream ostream.
235          If ostream is nor present the standart output stream is used.  If          If ostream is nor present the standart output stream is used.  If
236          esysheader==True the esys XML header is written          esysheader==True the esys XML header is written
237          """          """
# Line 196  class Link: Line 244  class Link:
244  class LinkableObject(object):  class LinkableObject(object):
245      """      """
246      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
247      via a Link object. For instance      via a Link object. For instance::
248                        
249             p = LinkableObject()             p = LinkableObject()
250             p.x = Link(o,"name")             p.x = Link(o,"name")
251             print p.x             print p.x
252            
253      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}.
254    
255      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
256        C{o}.  
257    
258      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
259      value of the call.      the return value of the call.
260      """      """
261        
262      number_sequence = itertools.count(100)      number_sequence = itertools.count(100)
263            
264      def __init__(self, debug=False):      def __init__(self, debug=False):
265          """ initializes LinkableObject so that we can operate on Links """          """
266        Initializes LinkableObject so that we can operate on Links
267        """
268          self.debug = debug          self.debug = debug
269          self.__linked_attributes={}          self.__linked_attributes={}
270          self.id = self.number_sequence.next()          self.id = self.number_sequence.next()
271            registerLinkableObject(self.id, self)
272    
273      def trace(self, msg):      def trace(self, msg):
274          """ If debugging is on, print the message, otherwise do nothing          """
275        If debugging is on, print the message, otherwise do nothing
276          """          """
277          if self.debug:          if self.debug:
278              print "%s: %s"%(str(self),msg)              print "%s: %s"%(str(self),msg)
279            
280      def __getattr__(self,name):      def __getattr__(self,name):
281          """returns the value of attribute name. If the value is a Link object the          """
282          object is called and the return value is returned."""      Returns the value of attribute name. If the value is a Link object the
283            object is called and the return value is returned.
284        """
285          out = self.getAttributeObject(name)          out = self.getAttributeObject(name)
286          if isinstance(out,Link):          if isinstance(out,Link):
287              return out()              return out()
# Line 234  class LinkableObject(object): Line 289  class LinkableObject(object):
289              return out              return out
290            
291      def getAttributeObject(self,name):      def getAttributeObject(self,name):
292          """return the object stored for attribute name."""          """
293        Return the object stored for attribute name.
294        """
295    
296          if self.__dict__.has_key(name):          if self.__dict__.has_key(name):
297              return self.__dict__[name]              return self.__dict__[name]
# Line 248  class LinkableObject(object): Line 305  class LinkableObject(object):
305          raise AttributeError,"No attribute %s."%name          raise AttributeError,"No attribute %s."%name
306            
307      def hasAttribute(self,name):      def hasAttribute(self,name):
308          """returns True if self as attribute name"""          """
309        Returns True if self as attribute name.
310        """
311          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)
312    
313      def __setattr__(self,name,value):      def __setattr__(self,name,value):
314          """sets the value for attribute name. If value is a Link the target          """
315          attribute is set to name if no attribute has been specified."""      Sets the value for attribute name. If value is a Link the target
316            attribute is set to name if no attribute has been specified.
317        """
318    
319          if self.__dict__.has_key(name):          if self.__dict__.has_key(name):
320              del self.__dict__[name]              del self.__dict__[name]
# Line 269  class LinkableObject(object): Line 329  class LinkableObject(object):
329              self.__dict__[name] = value              self.__dict__[name] = value
330            
331      def __delattr__(self,name):      def __delattr__(self,name):
332          """removes the attribute name."""          """
333        Removes the attribute name.
334        """
335    
336          if self.__linked_attributes.has_key[name]:          if self.__linked_attributes.has_key[name]:
337              del self.__linked_attributes[name]              del self.__linked_attributes[name]
# Line 292  class _ParameterIterator: Line 354  class _ParameterIterator:
354          return self          return self
355    
356  class ParameterSet(LinkableObject):  class ParameterSet(LinkableObject):
357      """a class which allows to emphazise attributes to be written and read to XML      """
358        A class which allows to emphazise attributes to be written and read to XML
359                
360         Leaves of  an ESySParameters objects can be      Leaves of an ESySParameters object can be:
361            
362              a real number       - a real number
363              a integer number       - a integer number
364              a string       - a string
365              a boolean value       - a boolean value
366              a ParameterSet object       - a ParameterSet object
367              a Simulation object       - a Simulation object
368              a Model object       - a Model object
369              any other object (not considered by writeESySXML and writeXML)       - a numarray object
370                 - a list of booleans
371             Example how to create an ESySParameters object:          - any other object (not considered by writeESySXML and writeXML)
372            
373                   p11=ParameterSet(gamma1=1.,gamma2=2.,gamma3=3.)      Example how to create an ESySParameters object::
374                   p1=ParameterSet(dim=2,tol_v=0.001,output_file="/tmp/u.%3.3d.dx",runFlag=True,parm11=p11)      
375                   parm=ParameterSet(parm1=p1,parm2=ParameterSet(alpha=Link(p11,"gamma1")))          p11=ParameterSet(gamma1=1.,gamma2=2.,gamma3=3.)
376                p1=ParameterSet(dim=2,tol_v=0.001,output_file="/tmp/u.%3.3d.dx",runFlag=True,parm11=p11)
377             This can be accessed as          parm=ParameterSet(parm1=p1,parm2=ParameterSet(alpha=Link(p11,"gamma1")))
378            
379                   parm.parm1.gamma=0.      This can be accessed as::
380                   parm.parm1.dim=2      
381                   parm.parm1.tol_v=0.001      parm.parm1.gamma=0.
382                   parm.parm1.output_file="/tmp/u.%3.3d.dx"          parm.parm1.dim=2
383                   parm.parm1.runFlag=True          parm.parm1.tol_v=0.001
384                   parm.parm1.parm11.gamma1=1.          parm.parm1.output_file="/tmp/u.%3.3d.dx"
385                   parm.parm1.parm11.gamma2=2.          parm.parm1.runFlag=True
386                   parm.parm1.parm11.gamma3=3.          parm.parm1.parm11.gamma1=1.
387                   parm.parm2.alpha=1. (value of parm.parm1.parm11.gamma1)          parm.parm1.parm11.gamma2=2.
388                        parm.parm1.parm11.gamma3=3.
389            parm.parm2.alpha=1. (value of parm.parm1.parm11.gamma1)
390      """      """
391      def __init__(self, parameters=[], **kwargs):      def __init__(self, parameters=[], **kwargs):
392          """creates a ParameterSet with parameters parameters"""          """
393        Creates a ParameterSet with parameters parameters.
394        """
395          LinkableObject.__init__(self, **kwargs)          LinkableObject.__init__(self, **kwargs)
396          self.parameters = set()          self.parameters = set()
397          self.declareParameters(parameters)          self.declareParameters(parameters)
# Line 335  class ParameterSet(LinkableObject): Line 401  class ParameterSet(LinkableObject):
401                              [(p, getattr(self, p, None)) for p in self.parameters])                              [(p, getattr(self, p, None)) for p in self.parameters])
402            
403      def declareParameter(self,**parameters):      def declareParameter(self,**parameters):
404          """declares a new parameter(s) and its (their) inital value."""          """
405        Declares a new parameter(s) and its (their) initial value.
406        """
407          self.declareParameters(parameters)          self.declareParameters(parameters)
408            
409      def declareParameters(self,parameters):      def declareParameters(self,parameters):
410          """declares a set of parameters. parameters can be a list, a dictonary or a ParameterSet."""          """
411        Declares a set of parameters. parameters can be a list, a dictionary
412        or a ParameterSet.
413        """
414          if isinstance(parameters,ListType):          if isinstance(parameters,ListType):
415              parameters = zip(parameters, itertools.repeat(None))              parameters = zip(parameters, itertools.repeat(None))
416          if isinstance(parameters,DictType):          if isinstance(parameters,DictType):
# Line 352  class ParameterSet(LinkableObject): Line 423  class ParameterSet(LinkableObject):
423              self.trace("parameter %s has been declared."%prm)              self.trace("parameter %s has been declared."%prm)
424    
425      def releaseParameters(self,name):      def releaseParameters(self,name):
426          """removes parameter name from the paramameters"""          """
427        Removes parameter name from the paramameters.
428        """
429          if self.isParameter(name):          if self.isParameter(name):
430              self.parameters.remove(name)              self.parameters.remove(name)
431              self.trace("parameter %s has been removed."%name)              self.trace("parameter %s has been removed."%name)
432            
433      def __iter__(self):      def __iter__(self):
434          """creates an iterator over the parameter and their values"""          """
435        Creates an iterator over the parameter and their values.
436        """
437          return _ParameterIterator(self)          return _ParameterIterator(self)
438            
439      def showParameters(self):      def showParameters(self):
440          """returns a descrition of the parameters"""                  """
441        Returns a descrition of the parameters.
442        """        
443          out="{"          out="{"
444          notfirst=False          notfirst=False
445          for i,v in self:          for i,v in self:
# Line 375  class ParameterSet(LinkableObject): Line 452  class ParameterSet(LinkableObject):
452          return out+"}"          return out+"}"
453            
454      def __delattr__(self,name):      def __delattr__(self,name):
455          """removes the attribute name."""          """
456        Removes the attribute name.
457        """
458          LinkableObject.__delattr__(self,name)          LinkableObject.__delattr__(self,name)
459          try:          try:
460              self.releaseParameter(name)              self.releaseParameter(name)
# Line 383  class ParameterSet(LinkableObject): Line 462  class ParameterSet(LinkableObject):
462              pass              pass
463    
464      def toDom(self, document, node):      def toDom(self, document, node):
465          """ toDom method of ParameterSet class """          """
466        C{toDom} method of ParameterSet class.
467        """
468          pset = document.createElement('ParameterSet')          pset = document.createElement('ParameterSet')
469          node.appendChild(pset)          node.appendChild(pset)
470          self._parametersToDom(document, pset)          self._parametersToDom(document, pset)
471    
472      def _parametersToDom(self, document, node):      def _parametersToDom(self, document, node):
473          node.setAttribute ('id', str(self.id))          node.setAttribute('id', str(self.id))
474            node.setIdAttribute("id")
475          for name,value in self:          for name,value in self:
476              param = document.createElement('Parameter')              param = document.createElement('Parameter')
477              param.setAttribute('type', value.__class__.__name__)              param.setAttribute('type', value.__class__.__name__)
# Line 398  class ParameterSet(LinkableObject): Line 480  class ParameterSet(LinkableObject):
480    
481              val = document.createElement('Value')              val = document.createElement('Value')
482    
483              if isinstance(value,ParameterSet):              if isinstance(value,(ParameterSet,Link,DataSource)):
484                  value.toDom(document, val)                  value.toDom(document, val)
485                  param.appendChild(val)                  param.appendChild(val)
486              elif isinstance(value, Link):              elif isinstance(value, numarray.NumArray):
487                  value.toDom(document, val)                  shape = value.getshape()
488                    if isinstance(shape, tuple):
489                        size = reduce(operator.mul, shape)
490                        shape = ' '.join(map(str, shape))
491                    else:
492                        size = shape
493                        shape = str(shape)
494    
495                    arraytype = value.type()
496                    numarrayElement = document.createElement('NumArray')
497                    numarrayElement.appendChild(dataNode(document, 'ArrayType', str(arraytype)))
498                    numarrayElement.appendChild(dataNode(document, 'Shape', shape))
499                    numarrayElement.appendChild(dataNode(document, 'Data', ' '.join(
500                        [str(x) for x in numarray.reshape(value, size)])))
501                    val.appendChild(numarrayElement)
502                  param.appendChild(val)                  param.appendChild(val)
503              elif isinstance(value,StringType):              elif isinstance (value, list):
504                  param.appendChild(dataNode(document, 'Value', value))                  param.appendChild(dataNode(document, 'Value', ' '.join(
505                        [str(x) for x in value])
506                    ))
507              else:              else:
508                  param.appendChild(dataNode(document, 'Value', str(value)))                  param.appendChild(dataNode(document, 'Value', str(value)))
509    
# Line 416  class ParameterSet(LinkableObject): Line 514  class ParameterSet(LinkableObject):
514          # Define a host of helper functions to assist us.          # Define a host of helper functions to assist us.
515          def _children(node):          def _children(node):
516              """              """
517              Remove the empty nodes from the children of this node              Remove the empty nodes from the children of this node.
518              """              """
519              return [x for x in node.childNodes              ret = []
520                      if not isinstance(x, minidom.Text) or x.nodeValue.strip()]              for x in node.childNodes:
521                    if isinstance(x, minidom.Text):
522                        if x.nodeValue.strip():
523                            ret.append(x)
524                    else:
525                        ret.append(x)
526                return ret
527    
528          def _floatfromValue(doc):          def _floatfromValue(doc):
529              return float(doc.nodeValue.strip())              return float(doc.nodeValue.strip())
# Line 431  class ParameterSet(LinkableObject): Line 535  class ParameterSet(LinkableObject):
535              return int(doc.nodeValue.strip())              return int(doc.nodeValue.strip())
536    
537          def _boolfromValue(doc):          def _boolfromValue(doc):
538              return bool(doc.nodeValue.strip())              return _boolfromstring(doc.nodeValue.strip())
539          
540            def _nonefromValue(doc):
541                return None
542    
543            def _numarrayfromValue(doc):
544                for node in _children(doc):
545                    if node.tagName == 'ArrayType':
546                        arraytype = node.firstChild.nodeValue.strip()
547                    if node.tagName == 'Shape':
548                        shape = node.firstChild.nodeValue.strip()
549                        shape = [int(x) for x in shape.split()]
550                    if node.tagName == 'Data':
551                        data = node.firstChild.nodeValue.strip()
552                        data = [float(x) for x in data.split()]
553                return numarray.reshape(numarray.array(data, type=getattr(numarray, arraytype)),
554                                        shape)
555          
556            def _listfromValue(doc):
557                return [_boolfromstring(x) for x in doc.nodeValue.split()]
558    
559    
560            def _boolfromstring(s):
561                if s == 'True':
562                    return True
563                else:
564                    return False
565          # 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
566          ptypemap = {"Simulation": Simulation.fromDom,          ptypemap = {"Simulation": Simulation.fromDom,
567                      "Model":Model.fromDom,                      "Model":Model.fromDom,
568                      "ParameterSet":ParameterSet.fromDom,                      "ParameterSet":ParameterSet.fromDom,
569                      "Link":Link.fromDom,                      "Link":Link.fromDom,
570                        "DataSource":DataSource.fromDom,
571                      "float":_floatfromValue,                      "float":_floatfromValue,
572                      "int":_intfromValue,                      "int":_intfromValue,
573                      "str":_stringfromValue,                      "str":_stringfromValue,
574                      "bool":_boolfromValue                      "bool":_boolfromValue,
575                        "list":_listfromValue,
576                        "NumArray":_numarrayfromValue,
577                        "NoneType":_nonefromValue,
578                      }                      }
579    
580  #        print doc.toxml()  #        print doc.toxml()
# Line 458  class ParameterSet(LinkableObject): Line 591  class ParameterSet(LinkableObject):
591    
592                  if childnode.tagName == "Value":                  if childnode.tagName == "Value":
593                      nodes = _children(childnode)                      nodes = _children(childnode)
594                    #    if ptype == 'NumArray':
595                     #       pvalue = _numarrayfromValue(nodes)
596                     #   else:
597                      pvalue = ptypemap[ptype](nodes[0])                      pvalue = ptypemap[ptype](nodes[0])
598    
599              parameters[pname] = pvalue              parameters[pname] = pvalue
# Line 471  class ParameterSet(LinkableObject): Line 607  class ParameterSet(LinkableObject):
607      fromDom = classmethod(fromDom)      fromDom = classmethod(fromDom)
608            
609      def writeXML(self,ostream=stdout):      def writeXML(self,ostream=stdout):
610          """writes the object as an XML object into an output stream"""          """
611        Writes the object as an XML object into an output stream.
612        """
613          # ParameterSet(d) with d[Name]=Value          # ParameterSet(d) with d[Name]=Value
614          document, node = esysDoc()          document, node = esysDoc()
615          self.toDom(document, node)          self.toDom(document, node)
# Line 479  class ParameterSet(LinkableObject): Line 617  class ParameterSet(LinkableObject):
617    
618  class Model(ParameterSet):  class Model(ParameterSet):
619      """      """
620        A Model object represents a processess marching over time until a
621      A Model object represents a processess marching over time      finalizing condition is fullfilled. At each time step an iterative
622      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
623      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:  
624    
625            doInitialization()            doInitialization()
626            while not finalize():            while not finalize():
# Line 493  class Model(ParameterSet): Line 630  class Model(ParameterSet):
630                 doStepPostprocessing(dt)                 doStepPostprocessing(dt)
631            doFinalization()            doFinalization()
632    
633            where doInitialization,finalize, getSafeTimeStepSize, doStepPreprocessing, terminateIteration, doStepPostprocessing, doFinalization      where C{doInitialization}, C{finalize}, C{getSafeTimeStepSize},
634            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},
635            the subclass implementinf a Model.      C{doFinalization} are methods of the particular instance of a Model. The
636        default implementations of these methods have to be overwritten by the
637        subclass implementing a Model.
638      """      """
639    
640      UNDEF_DT=1.e300      UNDEF_DT=1.e300
641    
642      def __init__(self,parameters=[],**kwarg):      def __init__(self,parameters=[],**kwarg):
643          """creates a model          """
644        Creates a model.
645    
646              Just calls the parent constructor.          Just calls the parent constructor.
647          """          """
648          ParameterSet.__init__(self, parameters=parameters,**kwarg)          ParameterSet.__init__(self, parameters=parameters,**kwarg)
649    
# Line 512  class Model(ParameterSet): Line 651  class Model(ParameterSet):
651         return "<%s %d>"%(self.__class__,id(self))         return "<%s %d>"%(self.__class__,id(self))
652    
653      def toDom(self, document, node):      def toDom(self, document, node):
654          """ toDom method of Model class """          """
655        C{toDom} method of Model class
656        """
657          pset = document.createElement('Model')          pset = document.createElement('Model')
658          pset.setAttribute('type', self.__class__.__name__)          pset.setAttribute('type', self.__class__.__name__)
659            if not self.__class__.__module__.startswith('esys.escript'):
660                pset.setAttribute('module', self.__class__.__module__)
661          node.appendChild(pset)          node.appendChild(pset)
662          self._parametersToDom(document, pset)          self._parametersToDom(document, pset)
663    
664      def doInitialization(self):      def doInitialization(self):
665          """initializes the time stepping scheme. This function may be overwritten."""          """
666        Initializes the time stepping scheme.  
667        
668        This function may be overwritten.
669        """
670          pass          pass
671            
672      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
673          """returns a time step size which can safely be used.          """
674             dt gives the previously used step size.      Returns a time step size which can safely be used.
675             This function may be overwritten."""  
676            C{dt} gives the previously used step size.
677    
678            This function may be overwritten.
679        """
680          return self.UNDEF_DT          return self.UNDEF_DT
681            
682      def finalize(self):      def finalize(self):
683          """returns False if the time stepping is finalized. This function may be          """
684          overwritten."""      Returns False if the time stepping is finalized.
685        
686        This function may be overwritten.
687        """
688          return False          return False
689                
690      def doFinalization(self):      def doFinalization(self):
691          """finalizes the time stepping. This function may be overwritten."""          """
692        Finalizes the time stepping.
693        
694        This function may be overwritten.
695        """
696          pass          pass
697            
698      def doStepPreprocessing(self,dt):      def doStepPreprocessing(self,dt):
699          """sets up a time step of step size dt. This function may be overwritten."""          """
700        Sets up a time step of step size dt.
701        
702        This function may be overwritten.
703        """
704          pass          pass
705            
706      def doStep(self,dt):      def doStep(self,dt):
707          """executes an iteration step at a time step.          """
708             dt is the currently used time step size.      Executes an iteration step at a time step.
709             This function may be overwritten."""  
710            C{dt} is the currently used time step size.
711    
712            This function may be overwritten.
713        """
714          pass          pass
715            
716      def terminateIteration(self):      def terminateIteration(self):
717          """returns True if iteration on a time step is terminated."""          """
718        Returns True if iteration on a time step is terminated.
719        """
720          return True          return True
721                
722      def doStepPostprocessing(self,dt):      def doStepPostprocessing(self,dt):
723          """finalalizes the time step.          """
724             dt is the currently used time step size.      Finalalizes the time step.
725             This function may be overwritten."""  
726            dt is the currently used time step size.
727    
728            This function may be overwritten.
729        """
730          pass          pass
731            
732      def writeXML(self, ostream=stdout):      def writeXML(self, ostream=stdout):
# Line 562  class Model(ParameterSet): Line 734  class Model(ParameterSet):
734          self.toDom(document, node)          self.toDom(document, node)
735          ostream.write(document.toprettyxml())          ostream.write(document.toprettyxml())
736            
       
737    
738  class Simulation(Model):  class Simulation(Model):
739      """      """
740            A Simulation object is special Model which runs a sequence of Models.      A Simulation object is special Model which runs a sequence of Models.
741    
742            The methods doInitialization,finalize, getSafeTimeStepSize, doStepPreprocessing,      The methods C{doInitialization}, C{finalize}, C{getSafeTimeStepSize},
743            terminateIteration, doStepPostprocessing, doFinalization      C{doStepPreprocessing}, C{terminateIteration}, C{doStepPostprocessing},
744            are executing the corresponding methods of the models in the simulation.      C{doFinalization} are executing the corresponding methods of the models in
745                  the simulation.
746      """      """
747            
748      FAILED_TIME_STEPS_MAX=20      FAILED_TIME_STEPS_MAX=20
749      MAX_ITER_STEPS=50      MAX_ITER_STEPS=50
750        MAX_CHANGE_OF_DT=2.
751            
752      def __init__(self, models=[], **kwargs):      def __init__(self, models=[], **kwargs):
753          """initiates a simulation from a list of models. """          """
754        Initiates a simulation from a list of models.
755        """
756          Model.__init__(self, **kwargs)          Model.__init__(self, **kwargs)
757          self.__models=[]          self.__models=[]
758            
759          for i in range(len(models)):          for i in range(len(models)):
760              self[i] = models[i]              self[i] = models[i]
761                
762    
763      def __repr__(self):      def __repr__(self):
764          """          """
765          returns a string representation of the Simulation          Returns a string representation of the Simulation.
766          """          """
767          return "<Simulation %r>" % self.__models          return "<Simulation %r>" % self.__models
768    
769      def __str__(self):      def __str__(self):
770          """          """
771          returning Simulation as a string          Returning Simulation as a string.
772          """          """
773          return "<Simulation %d>"%id(self)          return "<Simulation %d>"%id(self)
774            
775      def iterModels(self):      def iterModels(self):
776          """returns an iterator over the models"""          """
777        Returns an iterator over the models.
778        """
779          return self.__models          return self.__models
780            
781      def __getitem__(self,i):      def __getitem__(self,i):
782          """returns the i-th model"""          """
783        Returns the i-th model.
784        """
785          return self.__models[i]          return self.__models[i]
786            
787      def __setitem__(self,i,value):      def __setitem__(self,i,value):
788          """sets the i-th model"""          """
789        Sets the i-th model.
790        """
791          if not isinstance(value,Model):          if not isinstance(value,Model):
792              raise ValueError("assigned value is not a Model")              raise ValueError,"assigned value is not a Model but instance of %s"%(value.__class__.__name__,)
793          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)):
794                self.__models.append(None)
795          self.__models[i]=value          self.__models[i]=value
796            
797      def __len__(self):      def __len__(self):
798          """returns the number of models"""          """
799        Returns the number of models.
800        """
801          return len(self.__models)          return len(self.__models)
802    
803      def toDom(self, document, node):      def toDom(self, document, node):
804          """ toDom method of Simulation class """          """
805        C{toDom} method of Simulation class.
806        """
807          simulation = document.createElement('Simulation')          simulation = document.createElement('Simulation')
808          simulation.setAttribute('type', self.__class__.__name__)          simulation.setAttribute('type', self.__class__.__name__)
809    
# Line 632  class Simulation(Model): Line 818  class Simulation(Model):
818          node.appendChild(simulation)          node.appendChild(simulation)
819    
820      def writeXML(self,ostream=stdout):      def writeXML(self,ostream=stdout):
821          """writes the object as an XML object into an output stream"""          """
822        Writes the object as an XML object into an output stream.
823        """
824          document, rootnode = esysDoc()          document, rootnode = esysDoc()
825          self.toDom(document, rootnode)          self.toDom(document, rootnode)
826            targetsList = document.getElementsByTagName('Target')
827            
828            for element in targetsList:
829                targetId = int(element.firstChild.nodeValue.strip())
830                if document.getElementById(str(targetId)):
831                    continue
832                targetObj = LinkableObjectRegistry[targetId]
833                targetObj.toDom(document, rootnode)
834          ostream.write(document.toprettyxml())          ostream.write(document.toprettyxml())
835            
836      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
837          """returns a time step size which can safely be used by all models.          """
838             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.
839    
840            This is the minimum over the time step sizes of all models.
841        """
842          out=min([o.getSafeTimeStepSize(dt) for o in self.iterModels()])          out=min([o.getSafeTimeStepSize(dt) for o in self.iterModels()])
843          print "%s: safe step size is %e."%(str(self),out)          #print "%s: safe step size is %e."%(str(self),out)
844          return out          return out
845            
846      def doInitialization(self):      def doInitialization(self):
847          """initializes all models """          """
848        Initializes all models.
849        """
850          self.n=0          self.n=0
851          self.tn=0.          self.tn=0.
852          for o in self.iterModels():          for o in self.iterModels():
853              o.doInitialization()              o.doInitialization()
854            
855      def finalize(self):      def finalize(self):
856          """returns True if any of the models is to be finalized"""          """
857        Returns True if any of the models is to be finalized.
858        """
859          return any([o.finalize() for o in self.iterModels()])          return any([o.finalize() for o in self.iterModels()])
860                
861      def doFinalization(self):      def doFinalization(self):
862          """finalalizes the time stepping for all models."""          """
863        Finalalizes the time stepping for all models.
864        """
865          for i in self.iterModels(): i.doFinalization()          for i in self.iterModels(): i.doFinalization()
866          self.trace("end of time integation.")          self.trace("end of time integation.")
867            
868      def doStepPreprocessing(self,dt):      def doStepPreprocessing(self,dt):
869          """initializes the time step for all models."""          """
870        Initializes the time step for all models.
871        """
872          for o in self.iterModels():          for o in self.iterModels():
873              o.doStepPreprocessing(dt)              o.doStepPreprocessing(dt)
874            
875      def terminateIteration(self):      def terminateIteration(self):
876          """returns True if all iterations for all models are terminated."""          """
877        Returns True if all iterations for all models are terminated.
878        """
879          out=all([o.terminateIteration() for o in self.iterModels()])          out=all([o.terminateIteration() for o in self.iterModels()])
880          return out          return out
881                
882      def doStepPostprocessing(self,dt):      def doStepPostprocessing(self,dt):
883          """finalalizes the iteration process for all models."""          """
884        Finalalizes the iteration process for all models.
885        """
886          for o in self.iterModels():          for o in self.iterModels():
887              o.doStepPostprocessing(dt)              o.doStepPostprocessing(dt)
888          self.n+=1          self.n+=1
# Line 679  class Simulation(Model): Line 890  class Simulation(Model):
890            
891      def doStep(self,dt):      def doStep(self,dt):
892          """          """
893               executes the iteration step at a time step for all model:      Executes the iteration step at a time step for all model::
894    
895                    self.doStepPreprocessing(dt)              self.doStepPreprocessing(dt)
896                    while not self.terminateIteration(): for all models: self.doStep(dt)              while not self.terminateIteration():
897                    self.doStepPostprocessing(dt)              for all models:
898                self.doStep(dt)
899                    self.doStepPostprocessing(dt)
900          """          """
901          self.iter=0          self.iter=0
902          while not self.terminateIteration():          while not self.terminateIteration():
# Line 697  class Simulation(Model): Line 909  class Simulation(Model):
909    
910      def run(self,check_point=None):      def run(self,check_point=None):
911          """          """
912        Run the simulation by performing essentially::
            run the simulation by performing essentially  
913            
914                 self.doInitialization()          self.doInitialization()
915                 while not self.finalize():          while not self.finalize():
916                    dt=self.getSafeTimeStepSize()              dt=self.getSafeTimeStepSize()
917                    self.doStep(dt)              self.doStep(dt)
918                    if n%check_point==0: self.writeXML()              if n%check_point==0:
919                 self.doFinalization()              self.writeXML()
920            self.doFinalization()
921             If one of the models in throws a FailedTimeStepError exception a new time step size is  
922             computed through getSafeTimeStepSize() and the time step is repeated.          If one of the models in throws a C{FailedTimeStepError} exception a
923        new time step size is computed through getSafeTimeStepSize() and the
924        time step is repeated.
925        
926             If one of the models in throws a IterationDivergenceError exception the time step size          If one of the models in throws a C{IterationDivergenceError}
927             is halved and the time step is repeated.      exception the time step size is halved and the time step is repeated.
   
            In both cases the time integration is given up after Simulation.FAILED_TIME_STEPS_MAX  
            attempts.  
928    
929                In both cases the time integration is given up after
930        C{Simulation.FAILED_TIME_STEPS_MAX} attempts.
931          """          """
932          dt=self.UNDEF_DT          dt=self.UNDEF_DT
933          self.doInitialization()          self.doInitialization()
934          while not self.finalize():          while not self.finalize():
935              step_fail_counter=0              step_fail_counter=0
936              iteration_fail_counter=0              iteration_fail_counter=0
937              dt_new=self.getSafeTimeStepSize(dt)              if self.n==0:
938                    dt_new=self.getSafeTimeStepSize(dt)
939                else:
940                    dt_new=min(max(self.getSafeTimeStepSize(dt),dt/self.MAX_CHANGE_OF_DT),dt*self.MAX_CHANGE_OF_DT)
941              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.n+1,self.tn+dt_new,dt_new))
942              end_of_step=False              end_of_step=False
943              while not end_of_step:              while not end_of_step:
944                 end_of_step=True                 end_of_step=True
945                 if not dt_new>0:                 if not dt_new>0:
946                    raise NonPositiveStepSizeError("non-positive step size in step %d",self.n+1)                    raise NonPositiveStepSizeError("non-positive step size in step %d"%(self.n+1))
947                 try:                 try:
948                    self.doStepPreprocessing(dt_new)                    self.doStepPreprocessing(dt_new)
949                    self.doStep(dt_new)                    self.doStep(dt_new)
# Line 739  class Simulation(Model): Line 953  class Simulation(Model):
953                    end_of_step=False                    end_of_step=False
954                    iteration_fail_counter+=1                    iteration_fail_counter+=1
955                    if iteration_fail_counter>self.FAILED_TIME_STEPS_MAX:                    if iteration_fail_counter>self.FAILED_TIME_STEPS_MAX:
956                             raise SimulationBreakDownError("reduction of time step to achieve convergence failed.")                             raise SimulationBreakDownError("reduction of time step to achieve convergence failed after %s steps."%self.FAILED_TIME_STEPS_MAX)
957                    self.trace("iteration fails. time step is repeated with new step size.")                    self.trace("Iteration failed. Time step is repeated with new step size %s."%dt_new)
958                 except FailedTimeStepError:                 except FailedTimeStepError:
959                    dt_new=self.getSafeTimeStepSize(dt)                    dt_new=self.getSafeTimeStepSize(dt)
960                    end_of_step=False                    end_of_step=False
961                    step_fail_counter+=1                    step_fail_counter+=1
962                    self.trace("time step is repeated.")                    self.trace("Time step is repeated with new time step size %s."%dt_new)
963                    if step_fail_counter>self.FAILED_TIME_STEPS_MAX:                    if step_fail_counter>self.FAILED_TIME_STEPS_MAX:
964                          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)
965              dt=dt_new              dt=dt_new
966              if not check_point==None:              if not check_point==None:
967                  if n%check_point==0:                  if n%check_point==0:
# Line 770  class Simulation(Model): Line 984  class Simulation(Model):
984    
985  class IterationDivergenceError(Exception):  class IterationDivergenceError(Exception):
986      """      """
987         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
988         but there is a chance taht a smaller step could help to reach convergence.      process at a time step.
989    
990        But there is a chance that a smaller step could help to reach convergence.
991      """      """
992      pass      pass
993    
994  class FailedTimeStepError(Exception):  class FailedTimeStepError(Exception):
995      """excpetion which is thrown if the time step fails because of a step size that have been choosen to be too large"""      """
996        Exception which is thrown if the time step fails because of a step
997        size that have been choosen to be too large.
998        """
999      pass      pass
1000    
1001  class SimulationBreakDownError(Exception):  class SimulationBreakDownError(Exception):
1002      """excpetion which is thrown if the simulation does not manage to progress in time."""      """
1003        Exception which is thrown if the simulation does not manage to
1004        progress in time.
1005        """
1006      pass      pass
1007    
1008  class NonPositiveStepSizeError(Exception):  class NonPositiveStepSizeError(Exception):
1009      """excpetion which is thrown if the step size is not positive"""      """
1010        Exception which is thrown if the step size is not positive.
1011        """
1012      pass      pass
1013    
1014    class DataSource(object):
1015        """
1016        Class for handling data sources, including local and remote files. This class is under development.
1017        """
1018    
1019        def __init__(self, uri="file.ext", fileformat="unknown"):
1020            self.uri = uri
1021            self.fileformat = fileformat
1022    
1023        def toDom(self, document, node):
1024            """
1025            C{toDom} method of DataSource. Creates a DataSource node and appends it to the
1026        current XML document.
1027            """
1028            ds = document.createElement('DataSource')
1029            ds.appendChild(dataNode(document, 'URI', self.uri))
1030            ds.appendChild(dataNode(document, 'FileFormat', self.fileformat))
1031            node.appendChild(ds)
1032    
1033        def fromDom(cls, doc):
1034            uri= doc.getElementsByTagName("URI")[0].firstChild.nodeValue.strip()
1035            fileformat= doc.getElementsByTagName("FileFormat")[0].firstChild.nodeValue.strip()
1036            ds = cls(uri, fileformat)
1037            return ds
1038    
1039        def getLocalFileName(self):
1040            return self.uri
1041    
1042        fromDom = classmethod(fromDom)
1043        
1044    # vim: expandtab shiftwidth=4:

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

  ViewVC Help
Powered by ViewVC 1.1.26