/[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 920 by gross, Thu Jan 4 00:00:40 2007 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
 # import modellib  temporarily removed!!!  
30    
31  # import the 'set' module if it's not defined (python2.3/2.4 difference)  # import the 'set' module if it's not defined (python2.3/2.4 difference)
32  try:  try:
# Line 13  except NameError: Line 36  except NameError:
36    
37  from xml.dom import minidom  from xml.dom import minidom
38    
 def dataNode(document, tagName, data):  
     """  
     dataNodes are the building blocks of the xml documents constructed in  
     this module. document is the current xml document, tagName is the  
     associated xml tag, and data is the values in the tag.  
     """  
     t = document.createTextNode(str(data))  
     n = document.createElement(tagName)  
     n.appendChild(t)  
     return n  
   
 def esysDoc():  
     """  
     Global method for creating an instance of an EsysXML document.  
     """  
     doc = minidom.Document()  
     esys = doc.createElement('ESys')  
     doc.appendChild(esys)  
     return doc, esys  
39    
40  def all(seq):  def all(seq):
41      for x in seq:      for x in seq:
# Line 45  def any(seq): Line 49  def any(seq):
49              return True              return True
50      return False      return False
51    
52  LinkableObjectRegistry = {}  def importName(modulename, name):
53        """ Import a named object from a module in the context of this function,
54  def registerLinkableObject(obj_id, o):          which means you should use fully qualified module paths.
55      LinkableObjectRegistry[obj_id] = o          Return None on failure.
56    
57  LinkRegistry = []          This function from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52241
58        """
59  def registerLink(obj_id, l):      module = __import__(modulename, globals(), locals(), [name])
60      LinkRegistry.append((obj_id,l))          
61        try:
62            return vars(module)[name]
63        except KeyError:
64            raise ImportError("Could not import %s from %s" % (name, modulename))
65    
66  def parse(xml):  class ESySXMLParser(object):
67      """      """
68      Generic parse method for EsysXML. Without this, Links don't work.      parser for ESysXML file
69      """      """
70      global LinkRegistry, LinkableObjectRegistry      def __init__(self,xml, debug=False):
71      LinkRegistry = []        self.__dom = minidom.parseString(xml)
72      LinkableObjectRegistry = {}        self.__linkable_object_registry= {}
73          self.__link_registry=  []
74      doc = minidom.parseString(xml)        self.__esys=self.__dom.firstChild
75      sim = getComponent(doc.firstChild)        self.debug=debug
76      for obj_id, link in LinkRegistry:    
77          link.target = LinkableObjectRegistry[obj_id]      def getClassPath(self, node):
78            type = node.getAttribute("type")
79            if (node.getAttribute("module")):
80                module = node.getAttribute("module")
81                return importName(module, type)
82            else:
83                return importName("__main__", type)
84    
85      return sim      def setLinks(self):
86            for obj_id, link in self.__link_registry:
87                link.target = self.__linkable_object_registry[obj_id]
88    
89        def parse(self):
90           """
91           parser method for EsysXML and returns the list of generating ParameterSets
92           """
93           found=[]
94           for node in self.__esys.childNodes:
95               if isinstance(node, minidom.Element):
96                   if node.tagName == 'Simulation':
97                            found.append(Simulation.fromDom(self, node))
98                   elif node.tagName == 'Model':
99                            found.append(self.getClassPath(node).fromDom(self, node))
100                   elif node.tagName == 'ParameterSet':
101                            found.append(self.getClassPath(node).fromDom(self, node))
102                   else:
103                      raise "Invalid type, %r" % node.getAttribute("type")
104           self.setLinks()
105           return found
106    
107        def registerLink(self,obj_id, link):
108            self.__link_registry.append((int(obj_id),link))
109    
110        def registerLinkableObject(self,obj, node):
111            id_str=node.getAttribute('id').strip()
112            if len(id_str)>0:
113               id=int(id_str)
114               if self.__linkable_object_registry.has_key(id):
115                   raise ValueError("Object id %s already exists."%id)
116               else:
117                   self.__linkable_object_registry[id]=obj
118    
119        def getComponent(self, node):
120           """
121           returns a single component + rank from a simulation
122           parser method for EsysXML and returns the list of generating ParameterSets
123           """
124           rank  = int(node.getAttribute("rank"))
125           for n in node.childNodes:
126               if isinstance(n, minidom.Element):
127                   if n.tagName == 'Simulation':
128                            return (rank, Simulation.fromDom(self, n))
129                   elif n.tagName == 'Model':
130                            return (rank, self.getClassPath(n).fromDom(self, n))
131                   elif n.tagName == 'ParameterSet':
132                            return (rank, self.getClassPath(n).fromDom(self, n))
133                   else:
134                     raise ValueError("illegal component type %s"%n.tagName)
135           raise ValueError("cannot resolve Component")
136    
137  def getComponent(doc):  class ESySXMLCreator(object):
     """  
     Used to get components of Simualtions, Models.  
138      """      """
139      for node in doc.childNodes:      creates an XML Dom representation
140                """
141          if isinstance(node, minidom.Element):      def __init__(self):
142              if node.tagName == 'Simulation':         self.__dom=minidom.Document()
143                  if node.getAttribute("type") == 'Simulation':         self.__esys =self.__dom.createElement('ESys')
144                      return Simulation.fromDom(node)         self.__dom.appendChild(self.__esys)
145              if node.tagName == 'Model':         self.__linkable_object_registry={}
146                  model_type = node.getAttribute("type")         self.__number_sequence = itertools.count(100)
147                  model_subclasses = Model.__subclasses__()      def getRoot(self):
148                  for model in model_subclasses:         return self.__esys
149                      if model_type == model.__name__:      def createElement(self,name):
150                          return Model.fromDom(node)        return self.__dom.createElement(name)
151              if node.tagName == 'ParameterSet':      def createTextNode(self,name):
152                  parameter_type = node.getAttribute("type")        return self.__dom.createTextNode(name)
153                  return ParameterSet.fromDom(node)      def getElementById(self,name):
154              raise "Invalid simulation type, %r" % node.getAttribute("type")        return self.__dom.getElementById(name)
155                def createDataNode(self, tagName, data):
156              """
157      raise ValueError("No Simulation Found")            C{createDataNode}s are the building blocks of the xml documents constructed in
158                          this module.  
159        
160              @param tagName: the associated xml tag
161              @param data: the values in the tag
162              """
163              n = self.createElement(tagName)
164              n.appendChild(self.createTextNode(str(data)))
165              return n
166        def getLinkableObjectId(self, obj):
167            for id, o in self.__linkable_object_registry.items():
168                if o == obj: return id
169            id =self.__number_sequence.next()
170            self.__linkable_object_registry[id]=obj
171            return id
172            
173        def registerLinkableObject(self, obj, node):
174            """
175            returns a unique object id for object obj
176            """
177            id=self.getLinkableObjectId(obj)
178            node.setAttribute('id',str(id))
179            node.setIdAttribute("id")
180    
181        def includeTargets(self):
182            target_written=True
183            while target_written:
184                targetsList =self.__dom.getElementsByTagName('Target')
185                target_written=False
186                for element in targetsList:
187                   targetId = int(element.firstChild.nodeValue.strip())
188                   if self.getElementById(str(targetId)): continue
189                   targetObj = self.__linkable_object_registry[targetId]
190                   targetObj.toDom(self, self.__esys)
191                   target_written=True
192    
193        def toprettyxml(self):
194            self.includeTargets()
195            return self.__dom.toprettyxml()
196    
197  class Link:  class Link:
198      """      """
199      a Link makes an attribute of an object callable:      A Link makes an attribute of an object callable::
200    
201            o.object()            o.object()
202            o.a=8            o.a=8
203            l=Link(o,"a")            l=Link(o,"a")
# Line 106  class Link: Line 206  class Link:
206            
207      def __init__(self,target,attribute=None):      def __init__(self,target,attribute=None):
208          """          """
209          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
210          establised to this attribute of the target.  Otherwise the attribute is          establised to this attribute of the target.  Otherwise the attribute is
211          undefined.          undefined.
212          """          """
213          self.target = target          self.target = target
214          self.attribute = None          self.attribute = None
215          self.setAttributeName(attribute)          self.setAttributeName(attribute)
216    
217        def getAttributeName(self):
218            """
219            returns the name of the attribute the link is pointing to
220            """
221            return self.attribute
222            
223      def setAttributeName(self,attribute):      def setAttributeName(self,attribute):
224          """          """
225          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
226          target object must have the attribute with name attribute.          target object must have the attribute with name attribute.
227          """          """
228          if attribute and self.target:          if attribute and self.target:
# Line 130  class Link: Line 236  class Link:
236            
237      def hasDefinedAttributeName(self):      def hasDefinedAttributeName(self):
238          """          """
239          returns true if an attribute name is set          Returns true if an attribute name is set.
240          """          """
241          return self.attribute != None          return self.attribute != None
242            
243      def __repr__(self):      def __repr__(self):
244          """          """
245          returns a string representation of the link          Returns a string representation of the link.
246          """          """
247          if self.hasDefinedAttributeName():          if self.hasDefinedAttributeName():
248              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 251  class Link:
251            
252      def __call__(self,name=None):      def __call__(self,name=None):
253          """          """
254          returns the value of the attribute of the target object. If the          Returns the value of the attribute of the target object. If the
255          atrribute is callable then the return value of the call is returned.          atrribute is callable then the return value of the call is returned.
256          """          """
257          if name:          if name:
# Line 158  class Link: Line 264  class Link:
264          else:          else:
265              return out              return out
266    
267      def toDom(self, document, node):      def toDom(self, esysxml, node):
268          """          """
269          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
270          document      current XML esysxml.
271          """          """
272          link = document.createElement('Link')          link = esysxml.createElement('Link')
273          assert (self.target != None), ("Target was none, name was %r" % self.attribute)          assert (self.target != None), ("Target was none, name was %r" % self.attribute)
274          link.appendChild(dataNode(document, 'Target', self.target.id))          link.appendChild(esysxml.createDataNode('Target', esysxml.getLinkableObjectId(self.target)))
275          # this use of id will not work for purposes of being able to retrieve the intended          # this use of id will not work for purposes of being able to retrieve the intended
276          # target from the xml later. I need a better unique identifier.          # target from the xml later. I need a better unique identifier.
277          assert self.attribute, "You can't xmlify a Link without a target attribute"          assert self.attribute, "You can't xmlify a Link without a target attribute"
278          link.appendChild(dataNode(document, 'Attribute', self.attribute))          link.appendChild(esysxml.createDataNode('Attribute', self.attribute))
279          node.appendChild(link)          node.appendChild(link)
280    
281      def fromDom(cls, doc):      def fromDom(cls, esysxml, node):
282          targetid = doc.getElementsByTagName("Target")[0].firstChild.nodeValue.strip()          targetid = int(node.getElementsByTagName("Target")[0].firstChild.nodeValue.strip())
283          attribute = doc.getElementsByTagName("Attribute")[0].firstChild.nodeValue.strip()          attribute =str(node.getElementsByTagName("Attribute")[0].firstChild.nodeValue.strip())
284          l = cls(None, attribute)          l = cls(None, attribute)
285          registerLink(targetid, l)          esysxml.registerLink(targetid, l)
286          return l          return l
287    
288      fromDom = classmethod(fromDom)      fromDom = classmethod(fromDom)
289            
     def writeXML(self,ostream=stdout):  
         """  
         writes an XML representation of self to the output stream ostream.  
         If ostream is nor present the standart output stream is used.  If  
         esysheader==True the esys XML header is written  
         """  
         print 'I got to the Link writeXML method'  
         document, rootnode = esysDoc()  
         self.toDom(document, rootnode)  
   
         ostream.write(document.toprettyxml())  
   
290  class LinkableObject(object):  class LinkableObject(object):
291      """      """
292      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
293      via a Link object. For instance      via a Link object. For instance::
294                        
295             p = LinkableObject()             p = LinkableObject()
296             p.x = Link(o,"name")             p.x = Link(o,"name")
297             print p.x             print p.x
298            
299      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}.
300    
301      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
302        C{o}.  
303    
304      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
305      value of the call.      the return value of the call.
306      """      """
307        
     number_sequence = itertools.count(100)  
308            
309      def __init__(self, debug=False):      def __init__(self, id = None, debug=False):
310          """ initializes LinkableObject so that we can operate on Links """          """
311        Initializes LinkableObject so that we can operate on Links
312        """
313          self.debug = debug          self.debug = debug
314          self.__linked_attributes={}          self.__linked_attributes={}
315          self.id = self.number_sequence.next()          
   
316      def trace(self, msg):      def trace(self, msg):
317          """ If debugging is on, print the message, otherwise do nothing          """
318        If debugging is on, print the message, otherwise do nothing
319          """          """
320          if self.debug:          if self.debug:
321              print "%s: %s"%(str(self),msg)              print "%s: %s"%(str(self),msg)
322            
323      def __getattr__(self,name):      def __getattr__(self,name):
324          """returns the value of attribute name. If the value is a Link object the          """
325          object is called and the return value is returned."""      Returns the value of attribute name. If the value is a Link object the
326            object is called and the return value is returned.
327        """
328          out = self.getAttributeObject(name)          out = self.getAttributeObject(name)
329          if isinstance(out,Link):          if isinstance(out,Link):
330              return out()              return out()
# Line 234  class LinkableObject(object): Line 332  class LinkableObject(object):
332              return out              return out
333            
334      def getAttributeObject(self,name):      def getAttributeObject(self,name):
335          """return the object stored for attribute name."""          """
336        Return the object stored for attribute name.
337        """
338    
339          if self.__dict__.has_key(name):          if self.__dict__.has_key(name):
340              return self.__dict__[name]              return self.__dict__[name]
# Line 248  class LinkableObject(object): Line 348  class LinkableObject(object):
348          raise AttributeError,"No attribute %s."%name          raise AttributeError,"No attribute %s."%name
349            
350      def hasAttribute(self,name):      def hasAttribute(self,name):
351          """returns True if self as attribute name"""          """
352        Returns True if self as attribute name.
353        """
354          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)
355    
356      def __setattr__(self,name,value):      def __setattr__(self,name,value):
357          """sets the value for attribute name. If value is a Link the target          """
358          attribute is set to name if no attribute has been specified."""      Sets the value for attribute name. If value is a Link the target
359            attribute is set to name if no attribute has been specified.
360        """
361    
362          if self.__dict__.has_key(name):          if self.__dict__.has_key(name):
363              del self.__dict__[name]              del self.__dict__[name]
# Line 269  class LinkableObject(object): Line 372  class LinkableObject(object):
372              self.__dict__[name] = value              self.__dict__[name] = value
373            
374      def __delattr__(self,name):      def __delattr__(self,name):
375          """removes the attribute name."""          """
376        Removes the attribute name.
377        """
378    
379          if self.__linked_attributes.has_key[name]:          if self.__linked_attributes.has_key[name]:
380              del self.__linked_attributes[name]              del self.__linked_attributes[name]
# Line 292  class _ParameterIterator: Line 397  class _ParameterIterator:
397          return self          return self
398    
399  class ParameterSet(LinkableObject):  class ParameterSet(LinkableObject):
400      """a class which allows to emphazise attributes to be written and read to XML      """
401        A class which allows to emphazise attributes to be written and read to XML
402                
403         Leaves of  an ESySParameters objects can be      Leaves of an ESySParameters object can be:
404            
405              a real number       - a real number
406              a integer number       - a integer number
407              a string       - a string
408              a boolean value       - a boolean value
409              a ParameterSet object       - a ParameterSet object
410              a Simulation object       - a Simulation object
411              a Model object       - a Model object
412              any other object (not considered by writeESySXML and writeXML)       - a numarray object
413                 - a list of booleans
414             Example how to create an ESySParameters object:          - any other object (not considered by writeESySXML and writeXML)
415            
416                   p11=ParameterSet(gamma1=1.,gamma2=2.,gamma3=3.)      Example how to create an ESySParameters object::
417                   p1=ParameterSet(dim=2,tol_v=0.001,output_file="/tmp/u.%3.3d.dx",runFlag=True,parm11=p11)      
418                   parm=ParameterSet(parm1=p1,parm2=ParameterSet(alpha=Link(p11,"gamma1")))          p11=ParameterSet(gamma1=1.,gamma2=2.,gamma3=3.)
419                p1=ParameterSet(dim=2,tol_v=0.001,output_file="/tmp/u.%3.3d.dx",runFlag=True,parm11=p11)
420             This can be accessed as          parm=ParameterSet(parm1=p1,parm2=ParameterSet(alpha=Link(p11,"gamma1")))
421            
422                   parm.parm1.gamma=0.      This can be accessed as::
423                   parm.parm1.dim=2      
424                   parm.parm1.tol_v=0.001      parm.parm1.gamma=0.
425                   parm.parm1.output_file="/tmp/u.%3.3d.dx"          parm.parm1.dim=2
426                   parm.parm1.runFlag=True          parm.parm1.tol_v=0.001
427                   parm.parm1.parm11.gamma1=1.          parm.parm1.output_file="/tmp/u.%3.3d.dx"
428                   parm.parm1.parm11.gamma2=2.          parm.parm1.runFlag=True
429                   parm.parm1.parm11.gamma3=3.          parm.parm1.parm11.gamma1=1.
430                   parm.parm2.alpha=1. (value of parm.parm1.parm11.gamma1)          parm.parm1.parm11.gamma2=2.
431                        parm.parm1.parm11.gamma3=3.
432            parm.parm2.alpha=1. (value of parm.parm1.parm11.gamma1)
433      """      """
434      def __init__(self, parameters=[], **kwargs):      def __init__(self, parameters=[], **kwargs):
435          """creates a ParameterSet with parameters parameters"""          """
436        Creates a ParameterSet with parameters parameters.
437        """
438          LinkableObject.__init__(self, **kwargs)          LinkableObject.__init__(self, **kwargs)
439          self.parameters = set()          self.parameters = set()
440          self.declareParameters(parameters)          self.declareParameters(parameters)
441    
442      def __repr__(self):      def __repr__(self):
443          return "<%s %r>" % (self.__class__.__name__,          return "<%s %d>"%(self.__class__.__name__,id(self))
                             [(p, getattr(self, p, None)) for p in self.parameters])  
444            
445      def declareParameter(self,**parameters):      def declareParameter(self,**parameters):
446          """declares a new parameter(s) and its (their) inital value."""          """
447        Declares a new parameter(s) and its (their) initial value.
448        """
449          self.declareParameters(parameters)          self.declareParameters(parameters)
450            
451      def declareParameters(self,parameters):      def declareParameters(self,parameters):
452          """declares a set of parameters. parameters can be a list, a dictonary or a ParameterSet."""          """
453        Declares a set of parameters. parameters can be a list, a dictionary
454        or a ParameterSet.
455        """
456          if isinstance(parameters,ListType):          if isinstance(parameters,ListType):
457              parameters = zip(parameters, itertools.repeat(None))              parameters = zip(parameters, itertools.repeat(None))
458          if isinstance(parameters,DictType):          if isinstance(parameters,DictType):
# Line 352  class ParameterSet(LinkableObject): Line 465  class ParameterSet(LinkableObject):
465              self.trace("parameter %s has been declared."%prm)              self.trace("parameter %s has been declared."%prm)
466    
467      def releaseParameters(self,name):      def releaseParameters(self,name):
468          """removes parameter name from the paramameters"""          """
469        Removes parameter name from the paramameters.
470        """
471          if self.isParameter(name):          if self.isParameter(name):
472              self.parameters.remove(name)              self.parameters.remove(name)
473              self.trace("parameter %s has been removed."%name)              self.trace("parameter %s has been removed."%name)
474            
475      def __iter__(self):      def __iter__(self):
476          """creates an iterator over the parameter and their values"""          """
477        Creates an iterator over the parameter and their values.
478        """
479          return _ParameterIterator(self)          return _ParameterIterator(self)
480            
481      def showParameters(self):      def showParameters(self):
482          """returns a descrition of the parameters"""                  """
483        Returns a descrition of the parameters.
484        """        
485          out="{"          out="{"
486          notfirst=False          notfirst=False
487          for i,v in self:          for i,v in self:
# Line 375  class ParameterSet(LinkableObject): Line 494  class ParameterSet(LinkableObject):
494          return out+"}"          return out+"}"
495            
496      def __delattr__(self,name):      def __delattr__(self,name):
497          """removes the attribute name."""          """
498        Removes the attribute name.
499        """
500          LinkableObject.__delattr__(self,name)          LinkableObject.__delattr__(self,name)
501          try:          try:
502              self.releaseParameter(name)              self.releaseParameter(name)
503          except:          except:
504              pass              pass
505    
506      def toDom(self, document, node):      def toDom(self, esysxml, node):
507          """ toDom method of ParameterSet class """          """
508          pset = document.createElement('ParameterSet')      C{toDom} method of Model class
509        """
510            pset = esysxml.createElement('ParameterSet')
511            pset.setAttribute('type', self.__class__.__name__)
512            pset.setAttribute('module', self.__class__.__module__)
513            esysxml.registerLinkableObject(self, pset)
514            self._parametersToDom(esysxml, pset)
515          node.appendChild(pset)          node.appendChild(pset)
         self._parametersToDom(document, pset)  
516    
517      def _parametersToDom(self, document, node):      def _parametersToDom(self, esysxml, node):
         node.setAttribute ('id', str(self.id))  
518          for name,value in self:          for name,value in self:
519              param = document.createElement('Parameter')              # convert list to numarray when possible:
520              param.setAttribute('type', value.__class__.__name__)              if isinstance (value, list):
521                    elem_type=-1
522                    for i in value:
523                        if isinstance(i, bool):
524                            elem_type = max(elem_type,0)
525                        if isinstance(i, int) and not isinstance(i, bool):
526                            elem_type = max(elem_type,1)
527                        if isinstance(i, float):
528                            elem_type = max(elem_type,2)
529                    if elem_type == 0: value = numarray.array(value,numarray.Bool)
530                    if elem_type == 1: value = numarray.array(value,numarray.Int)
531                    if elem_type == 2: value = numarray.array(value,numarray.Float)
532    
533              param.appendChild(dataNode(document, 'Name', name))              param = esysxml.createElement('Parameter')
534                param.setAttribute('type', value.__class__.__name__)
535    
536              val = document.createElement('Value')              param.appendChild(esysxml.createDataNode('Name', name))
537    
538              if isinstance(value,ParameterSet):              val = esysxml.createElement('Value')
539                  value.toDom(document, val)              if isinstance(value,(ParameterSet,Link,DataSource)):
540                    value.toDom(esysxml, val)
541                  param.appendChild(val)                  param.appendChild(val)
542              elif isinstance(value, Link):              elif isinstance(value, numarray.NumArray):
543                  value.toDom(document, val)                  shape = value.getshape()
544                    if isinstance(shape, tuple):
545                        size = reduce(operator.mul, shape)
546                        shape = ' '.join(map(str, shape))
547                    else:
548                        size = shape
549                        shape = str(shape)
550    
551                    arraytype = value.type()
552                    if isinstance(arraytype, numarray.BooleanType):
553                          arraytype_str="Bool"
554                    elif isinstance(arraytype, numarray.IntegralType):
555                          arraytype_str="Int"
556                    elif isinstance(arraytype, numarray.FloatingType):
557                          arraytype_str="Float"
558                    elif isinstance(arraytype, numarray.ComplexType):
559                          arraytype_str="Complex"
560                    else:
561                          arraytype_str=str(arraytype)
562                    numarrayElement = esysxml.createElement('NumArray')
563                    numarrayElement.appendChild(esysxml.createDataNode('ArrayType', arraytype_str))
564                    numarrayElement.appendChild(esysxml.createDataNode('Shape', shape))
565                    numarrayElement.appendChild(esysxml.createDataNode('Data', ' '.join(
566                        [str(x) for x in numarray.reshape(value, size)])))
567                    val.appendChild(numarrayElement)
568                  param.appendChild(val)                  param.appendChild(val)
569              elif isinstance(value,StringType):              elif isinstance(value, list):
570                  param.appendChild(dataNode(document, 'Value', value))                  param.appendChild(esysxml.createDataNode('Value', ' '.join([str(x) for x in value]) ))
571                elif isinstance(value, (str, bool, int, float, type(None))):
572                    param.appendChild(esysxml.createDataNode('Value', str(value)))
573              else:              else:
574                  param.appendChild(dataNode(document, 'Value', str(value)))                  raise ValueError("cannot serialize %s type to XML."%str(value.__class__))
575    
576              node.appendChild(param)              node.appendChild(param)
577    
578      def fromDom(cls, doc):      def fromDom(cls, esysxml, node):
   
579          # Define a host of helper functions to assist us.          # Define a host of helper functions to assist us.
580          def _children(node):          def _children(node):
581              """              """
582              Remove the empty nodes from the children of this node              Remove the empty nodes from the children of this node.
583              """              """
584              return [x for x in node.childNodes              ret = []
585                      if not isinstance(x, minidom.Text) or x.nodeValue.strip()]              for x in node.childNodes:
586                    if isinstance(x, minidom.Text):
587                        if x.nodeValue.strip():
588                            ret.append(x)
589                    else:
590                        ret.append(x)
591                return ret
592    
593          def _floatfromValue(doc):          def _floatfromValue(esysxml, node):
594              return float(doc.nodeValue.strip())              return float(node.nodeValue.strip())
595    
596          def _stringfromValue(doc):          def _stringfromValue(esysxml, node):
597              return str(doc.nodeValue.strip())              return str(node.nodeValue.strip())
598                
599          def _intfromValue(doc):          def _intfromValue(esysxml, node):
600              return int(doc.nodeValue.strip())              return int(node.nodeValue.strip())
601    
602          def _boolfromValue(doc):          def _boolfromValue(esysxml, node):
603              return bool(doc.nodeValue.strip())              return _boolfromstring(node.nodeValue.strip())
604          
605            def _nonefromValue(esysxml, node):
606                return None
607    
608            def _numarrayfromValue(esysxml, node):
609                for node in _children(node):
610                    if node.tagName == 'ArrayType':
611                        arraytype = node.firstChild.nodeValue.strip()
612                    if node.tagName == 'Shape':
613                        shape = node.firstChild.nodeValue.strip()
614                        shape = [int(x) for x in shape.split()]
615                    if node.tagName == 'Data':
616                        data = node.firstChild.nodeValue.strip()
617                        data = [float(x) for x in data.split()]
618                return numarray.reshape(numarray.array(data, type=getattr(numarray, arraytype)),
619                                        shape)
620          
621            def _listfromValue(esysxml, node):
622                return [x for x in node.nodeValue.split()]
623    
624            def _boolfromstring(s):
625                if s == 'True':
626                    return True
627                else:
628                    return False
629          # 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
630          ptypemap = {"Simulation": Simulation.fromDom,          ptypemap = {"Simulation": Simulation.fromDom,
631                      "Model":Model.fromDom,                      "Model":Model.fromDom,
632                      "ParameterSet":ParameterSet.fromDom,                      "ParameterSet":ParameterSet.fromDom,
633                      "Link":Link.fromDom,                      "Link":Link.fromDom,
634                        "DataSource":DataSource.fromDom,
635                      "float":_floatfromValue,                      "float":_floatfromValue,
636                      "int":_intfromValue,                      "int":_intfromValue,
637                      "str":_stringfromValue,                      "str":_stringfromValue,
638                      "bool":_boolfromValue                      "bool":_boolfromValue,
639                        "list":_listfromValue,
640                        "NumArray":_numarrayfromValue,
641                        "NoneType":_nonefromValue,
642                      }                      }
643    
 #        print doc.toxml()  
   
644          parameters = {}          parameters = {}
645          for node in _children(doc):          for n in _children(node):
646              ptype = node.getAttribute("type")              ptype = n.getAttribute("type")
647                if not ptypemap.has_key(ptype):
648                   raise KeyError("cannot handle parameter type %s."%ptype)
649    
650              pname = pvalue = None              pname = pvalue = None
651              for childnode in _children(node):              for childnode in _children(n):
   
652                  if childnode.tagName == "Name":                  if childnode.tagName == "Name":
653                      pname = childnode.firstChild.nodeValue.strip()                      pname = childnode.firstChild.nodeValue.strip()
654    
655                  if childnode.tagName == "Value":                  if childnode.tagName == "Value":
656                      nodes = _children(childnode)                      nodes = _children(childnode)
657                      pvalue = ptypemap[ptype](nodes[0])                      pvalue = ptypemap[ptype](esysxml, nodes[0])
658    
659              parameters[pname] = pvalue              parameters[pname] = pvalue
660    
661          # Create the instance of ParameterSet          # Create the instance of ParameterSet
662          o = cls()          o = cls(debug=esysxml.debug)
663          o.declareParameters(parameters)          o.declareParameters(parameters)
664          registerLinkableObject(doc.getAttribute("id"), o)          esysxml.registerLinkableObject(o, node)
665          return o          return o
666            
667      fromDom = classmethod(fromDom)      fromDom = classmethod(fromDom)
       
     def writeXML(self,ostream=stdout):  
         """writes the object as an XML object into an output stream"""  
         # ParameterSet(d) with d[Name]=Value  
         document, node = esysDoc()  
         self.toDom(document, node)  
         ostream.write(document.toprettyxml())  
668    
669        def writeXML(self,ostream=stdout):
670            """
671        Writes the object as an XML object into an output stream.
672        """
673            esysxml=ESySXMLCreator()
674            self.toDom(esysxml, esysxml.getRoot())
675            ostream.write(esysxml.toprettyxml())
676        
677  class Model(ParameterSet):  class Model(ParameterSet):
678      """      """
679        A Model object represents a processess marching over time until a
680      A Model object represents a processess marching over time      finalizing condition is fullfilled. At each time step an iterative
681      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
682      process can be performed and the time step size can be controlled. A Model has      Model has the following work flow::
683      the following work flow:            
   
684            doInitialization()            doInitialization()
685              while not terminateInitialIteration(): doInitializationiStep()
686              doInitialPostprocessing()
687            while not finalize():            while not finalize():
688                 dt=getSafeTimeStepSize(dt)                 dt=getSafeTimeStepSize(dt)
689                 doStepPreprocessing(dt)                 doStepPreprocessing(dt)
# Line 493  class Model(ParameterSet): Line 691  class Model(ParameterSet):
691                 doStepPostprocessing(dt)                 doStepPostprocessing(dt)
692            doFinalization()            doFinalization()
693    
694            where doInitialization,finalize, getSafeTimeStepSize, doStepPreprocessing, terminateIteration, doStepPostprocessing, doFinalization      where C{doInitialization}, C{finalize}, C{getSafeTimeStepSize},
695            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},
696            the subclass implementinf a Model.      C{doFinalization} are methods of the particular instance of a Model. The
697        default implementations of these methods have to be overwritten by the
698        subclass implementing a Model.
699      """      """
700    
701      UNDEF_DT=1.e300      UNDEF_DT=1.e300
702    
703      def __init__(self,parameters=[],**kwarg):      def __init__(self,parameters=[],**kwargs):
704          """creates a model          """
705        Creates a model.
706    
707              Just calls the parent constructor.          Just calls the parent constructor.
708          """          """
709          ParameterSet.__init__(self, parameters=parameters,**kwarg)          ParameterSet.__init__(self, parameters=parameters,**kwargs)
710    
711      def __str__(self):      def __str__(self):
712         return "<%s %d>"%(self.__class__,id(self))         return "<%s %d>"%(self.__class__.__name__,id(self))
713    
     def toDom(self, document, node):  
         """ toDom method of Model class """  
         pset = document.createElement('Model')  
         pset.setAttribute('type', self.__class__.__name__)  
         node.appendChild(pset)  
         self._parametersToDom(document, pset)  
714    
715      def doInitialization(self):      def doInitialization(self):
716          """initializes the time stepping scheme. This function may be overwritten."""          """
717        Initializes the time stepping scheme.  
718        
719        This function may be overwritten.
720        """
721            pass
722        def doInitialStep(self):
723            """
724        performs an iteration step in the initialization phase
725    
726        This function may be overwritten.
727        """
728            pass
729    
730        def terminateInitialIteration(self):
731            """
732        Returns True if iteration at the inital phase is terminated.
733        """
734            return True
735    
736        def doInitialPostprocessing(self):
737            """
738        finalises the initialization iteration process
739    
740        This function may be overwritten.
741        """
742          pass          pass
743            
744      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
745          """returns a time step size which can safely be used.          """
746             dt gives the previously used step size.      Returns a time step size which can safely be used.
747             This function may be overwritten."""  
748            C{dt} gives the previously used step size.
749    
750            This function may be overwritten.
751        """
752          return self.UNDEF_DT          return self.UNDEF_DT
753            
754      def finalize(self):      def finalize(self):
755          """returns False if the time stepping is finalized. This function may be          """
756          overwritten."""      Returns False if the time stepping is finalized.
757        
758        This function may be overwritten.
759        """
760          return False          return False
761                
762      def doFinalization(self):      def doFinalization(self):
763          """finalizes the time stepping. This function may be overwritten."""          """
764        Finalizes the time stepping.
765        
766        This function may be overwritten.
767        """
768          pass          pass
769            
770      def doStepPreprocessing(self,dt):      def doStepPreprocessing(self,dt):
771          """sets up a time step of step size dt. This function may be overwritten."""          """
772        Sets up a time step of step size dt.
773        
774        This function may be overwritten.
775        """
776          pass          pass
777            
778      def doStep(self,dt):      def doStep(self,dt):
779          """executes an iteration step at a time step.          """
780             dt is the currently used time step size.      Executes an iteration step at a time step.
781             This function may be overwritten."""  
782            C{dt} is the currently used time step size.
783    
784            This function may be overwritten.
785        """
786          pass          pass
787            
788      def terminateIteration(self):      def terminateIteration(self):
789          """returns True if iteration on a time step is terminated."""          """
790        Returns True if iteration on a time step is terminated.
791        """
792          return True          return True
793    
794                
795      def doStepPostprocessing(self,dt):      def doStepPostprocessing(self,dt):
796          """finalalizes the time step.          """
797             dt is the currently used time step size.      finalises the time step.
798             This function may be overwritten."""  
799            dt is the currently used time step size.
800    
801            This function may be overwritten.
802        """
803          pass          pass
       
     def writeXML(self, ostream=stdout):  
         document, node = esysDoc()  
         self.toDom(document, node)  
         ostream.write(document.toprettyxml())  
       
       
804    
805        def toDom(self, esysxml, node):
806            """
807        C{toDom} method of Model class
808        """
809            pset = esysxml.createElement('Model')
810            pset.setAttribute('type', self.__class__.__name__)
811            pset.setAttribute('module', self.__class__.__module__)
812            esysxml.registerLinkableObject(self, pset)
813            node.appendChild(pset)
814            self._parametersToDom(esysxml, pset)
815        
816  class Simulation(Model):  class Simulation(Model):
817      """      """
818            A Simulation object is special Model which runs a sequence of Models.      A Simulation object is special Model which runs a sequence of Models.
819    
820            The methods doInitialization,finalize, getSafeTimeStepSize, doStepPreprocessing,      The methods C{doInitialization}, C{finalize}, C{getSafeTimeStepSize},
821            terminateIteration, doStepPostprocessing, doFinalization      C{doStepPreprocessing}, C{terminateIteration}, C{doStepPostprocessing},
822            are executing the corresponding methods of the models in the simulation.      C{doFinalization} are executing the corresponding methods of the models in
823                  the simulation.
824      """      """
825            
826      FAILED_TIME_STEPS_MAX=20      FAILED_TIME_STEPS_MAX=20
827      MAX_ITER_STEPS=50      MAX_ITER_STEPS=50
828        MAX_CHANGE_OF_DT=2.
829            
830      def __init__(self, models=[], **kwargs):      def __init__(self, models=[], **kwargs):
831          """initiates a simulation from a list of models. """          """
832          Model.__init__(self, **kwargs)      Initiates a simulation from a list of models.
833        """
834            super(Simulation, self).__init__(**kwargs)
835          self.__models=[]          self.__models=[]
836            
837          for i in range(len(models)):          for i in range(len(models)):
838              self[i] = models[i]              self[i] = models[i]
839                
840    
841      def __repr__(self):      def __repr__(self):
842          """          """
843          returns a string representation of the Simulation          Returns a string representation of the Simulation.
844          """          """
845          return "<Simulation %r>" % self.__models          return "<Simulation %r>" % self.__models
846    
847      def __str__(self):      def __str__(self):
848          """          """
849          returning Simulation as a string          Returning Simulation as a string.
850          """          """
851          return "<Simulation %d>"%id(self)          return "<Simulation %d>"%id(self)
852            
853      def iterModels(self):      def iterModels(self):
854          """returns an iterator over the models"""          """
855        Returns an iterator over the models.
856        """
857          return self.__models          return self.__models
858            
859      def __getitem__(self,i):      def __getitem__(self,i):
860          """returns the i-th model"""          """
861        Returns the i-th model.
862        """
863          return self.__models[i]          return self.__models[i]
864            
865      def __setitem__(self,i,value):      def __setitem__(self,i,value):
866          """sets the i-th model"""          """
867        Sets the i-th model.
868        """
869          if not isinstance(value,Model):          if not isinstance(value,Model):
870              raise ValueError("assigned value is not a Model")              raise ValueError,"assigned value is not a Model but instance of %s"%(value.__class__.__name__,)
871          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)):
872                self.__models.append(None)
873          self.__models[i]=value          self.__models[i]=value
874            
875      def __len__(self):      def __len__(self):
876          """returns the number of models"""          """
877        Returns the number of models.
878        """
879          return len(self.__models)          return len(self.__models)
880    
     def toDom(self, document, node):  
         """ toDom method of Simulation class """  
         simulation = document.createElement('Simulation')  
         simulation.setAttribute('type', self.__class__.__name__)  
   
         for rank, sim in enumerate(self.iterModels()):  
             component = document.createElement('Component')  
             component.setAttribute('rank', str(rank))  
   
             sim.toDom(document, component)  
   
             simulation.appendChild(component)  
   
         node.appendChild(simulation)  
   
     def writeXML(self,ostream=stdout):  
         """writes the object as an XML object into an output stream"""  
         document, rootnode = esysDoc()  
         self.toDom(document, rootnode)  
         ostream.write(document.toprettyxml())  
881            
882      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
883          """returns a time step size which can safely be used by all models.          """
884             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.
885    
886            This is the minimum over the time step sizes of all models.
887        """
888          out=min([o.getSafeTimeStepSize(dt) for o in self.iterModels()])          out=min([o.getSafeTimeStepSize(dt) for o in self.iterModels()])
         print "%s: safe step size is %e."%(str(self),out)  
889          return out          return out
890            
891      def doInitialization(self):      def doInitialization(self):
892          """initializes all models """          """
893        Initializes all models.
894        """
895          self.n=0          self.n=0
896          self.tn=0.          self.tn=0.
897          for o in self.iterModels():          for o in self.iterModels():
898              o.doInitialization()               o.doInitialization()
899            def doInitialStep(self):
900            """
901        performs an iteration step in the initialization step for all models
902        """
903            iter=0
904            while not self.terminateInitialIteration():
905                if iter==0: self.trace("iteration for initialization starts")
906                iter+=1
907                self.trace("iteration step %d"%(iter))
908                for o in self.iterModels():
909                     o.doInitialStep()
910                if iter>self.MAX_ITER_STEPS:
911                     raise IterationDivergenceError("initial iteration did not converge after %s steps."%iter)
912            self.trace("Initialization finalized after %s iteration steps."%iter)
913    
914        def doInitialPostprocessing(self):
915            """
916        finalises the initialization iteration process for all models.
917        """
918            for o in self.iterModels():
919                o.doInitialPostprocessing()
920      def finalize(self):      def finalize(self):
921          """returns True if any of the models is to be finalized"""          """
922        Returns True if any of the models is to be finalized.
923        """
924          return any([o.finalize() for o in self.iterModels()])          return any([o.finalize() for o in self.iterModels()])
925                
926      def doFinalization(self):      def doFinalization(self):
927          """finalalizes the time stepping for all models."""          """
928        finalises the time stepping for all models.
929        """
930          for i in self.iterModels(): i.doFinalization()          for i in self.iterModels(): i.doFinalization()
931          self.trace("end of time integation.")          self.trace("end of time integation.")
932            
933      def doStepPreprocessing(self,dt):      def doStepPreprocessing(self,dt):
934          """initializes the time step for all models."""          """
935        Initializes the time step for all models.
936        """
937          for o in self.iterModels():          for o in self.iterModels():
938              o.doStepPreprocessing(dt)              o.doStepPreprocessing(dt)
939            
940      def terminateIteration(self):      def terminateIteration(self):
941          """returns True if all iterations for all models are terminated."""          """
942        Returns True if all iterations for all models are terminated.
943        """
944          out=all([o.terminateIteration() for o in self.iterModels()])          out=all([o.terminateIteration() for o in self.iterModels()])
945          return out          return out
946    
947        def terminateInitialIteration(self):
948            """
949        Returns True if all initial iterations for all models are terminated.
950        """
951            out=all([o.terminateInitialIteration() for o in self.iterModels()])
952            return out
953                
954      def doStepPostprocessing(self,dt):      def doStepPostprocessing(self,dt):
955          """finalalizes the iteration process for all models."""          """
956        finalises the iteration process for all models.
957        """
958          for o in self.iterModels():          for o in self.iterModels():
959              o.doStepPostprocessing(dt)              o.doStepPostprocessing(dt)
960          self.n+=1          self.n+=1
# Line 679  class Simulation(Model): Line 962  class Simulation(Model):
962            
963      def doStep(self,dt):      def doStep(self,dt):
964          """          """
965               executes the iteration step at a time step for all model:      Executes the iteration step at a time step for all model::
966    
967                    self.doStepPreprocessing(dt)              self.doStepPreprocessing(dt)
968                    while not self.terminateIteration(): for all models: self.doStep(dt)              while not self.terminateIteration():
969                    self.doStepPostprocessing(dt)              for all models:
970                self.doStep(dt)
971                    self.doStepPostprocessing(dt)
972          """          """
973          self.iter=0          self.iter=0
974          while not self.terminateIteration():          while not self.terminateIteration():
# Line 697  class Simulation(Model): Line 981  class Simulation(Model):
981    
982      def run(self,check_point=None):      def run(self,check_point=None):
983          """          """
984        Run the simulation by performing essentially::
            run the simulation by performing essentially  
985            
986                 self.doInitialization()          self.doInitialization()
987                 while not self.finalize():              while not self.terminateInitialIteration(): self.doInitialStep()
988                    dt=self.getSafeTimeStepSize()              self.doInitialPostprocessing()
989                    self.doStep(dt)          while not self.finalize():
990                    if n%check_point==0: self.writeXML()              dt=self.getSafeTimeStepSize()
991                 self.doFinalization()              self.doStep(dt)
992                if n%check_point==0:
993             If one of the models in throws a FailedTimeStepError exception a new time step size is              self.writeXML()
994             computed through getSafeTimeStepSize() and the time step is repeated.          self.doFinalization()
995    
996            If one of the models in throws a C{FailedTimeStepError} exception a
997        new time step size is computed through getSafeTimeStepSize() and the
998        time step is repeated.
999        
1000             If one of the models in throws a IterationDivergenceError exception the time step size          If one of the models in throws a C{IterationDivergenceError}
1001             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.  
1002    
1003                In both cases the time integration is given up after
1004        C{Simulation.FAILED_TIME_STEPS_MAX} attempts.
1005          """          """
         dt=self.UNDEF_DT  
1006          self.doInitialization()          self.doInitialization()
1007            self.doInitialStep()
1008            self.doInitialPostprocessing()
1009            dt=self.UNDEF_DT
1010          while not self.finalize():          while not self.finalize():
1011              step_fail_counter=0              step_fail_counter=0
1012              iteration_fail_counter=0              iteration_fail_counter=0
1013              dt_new=self.getSafeTimeStepSize(dt)              if self.n==0:
1014                    dt_new=self.getSafeTimeStepSize(dt)
1015                else:
1016                    dt_new=min(max(self.getSafeTimeStepSize(dt),dt/self.MAX_CHANGE_OF_DT),dt*self.MAX_CHANGE_OF_DT)
1017              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))
1018              end_of_step=False              end_of_step=False
1019              while not end_of_step:              while not end_of_step:
1020                 end_of_step=True                 end_of_step=True
1021                 if not dt_new>0:                 if not dt_new>0:
1022                    raise NonPositiveStepSizeError("non-positive step size in step %d",self.n+1)                    raise NonPositiveStepSizeError("non-positive step size in step %d"%(self.n+1))
1023                 try:                 try:
1024                    self.doStepPreprocessing(dt_new)                    self.doStepPreprocessing(dt_new)
1025                    self.doStep(dt_new)                    self.doStep(dt_new)
# Line 739  class Simulation(Model): Line 1029  class Simulation(Model):
1029                    end_of_step=False                    end_of_step=False
1030                    iteration_fail_counter+=1                    iteration_fail_counter+=1
1031                    if iteration_fail_counter>self.FAILED_TIME_STEPS_MAX:                    if iteration_fail_counter>self.FAILED_TIME_STEPS_MAX:
1032                             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)
1033                    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)
1034                 except FailedTimeStepError:                 except FailedTimeStepError:
1035                    dt_new=self.getSafeTimeStepSize(dt)                    dt_new=self.getSafeTimeStepSize(dt)
1036                    end_of_step=False                    end_of_step=False
1037                    step_fail_counter+=1                    step_fail_counter+=1
1038                    self.trace("time step is repeated.")                    self.trace("Time step is repeated with new time step size %s."%dt_new)
1039                    if step_fail_counter>self.FAILED_TIME_STEPS_MAX:                    if step_fail_counter>self.FAILED_TIME_STEPS_MAX:
1040                          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)
1041              dt=dt_new              dt=dt_new
1042              if not check_point==None:              if not check_point==None:
1043                  if n%check_point==0:                  if n%check_point==0:
# Line 755  class Simulation(Model): Line 1045  class Simulation(Model):
1045                      self.writeXML()                      self.writeXML()
1046          self.doFinalization()          self.doFinalization()
1047    
     def fromDom(cls, doc):  
         sims = []  
         for node in doc.childNodes:  
             if isinstance(node, minidom.Text):  
                 continue  
1048    
1049              sims.append(getComponent(node))      def toDom(self, esysxml, node):
1050            """
1051        C{toDom} method of Simulation class.
1052        """
1053            simulation = esysxml.createElement('Simulation')
1054            esysxml.registerLinkableObject(self, simulation)
1055            for rank, sim in enumerate(self.iterModels()):
1056                component = esysxml.createElement('Component')
1057                component.setAttribute('rank', str(rank))
1058                sim.toDom(esysxml, component)
1059                simulation.appendChild(component)
1060            node.appendChild(simulation)
1061    
1062    
1063          return cls(sims)      def fromDom(cls, esysxml, node):
1064            sims = []
1065            for n in node.childNodes:
1066                if isinstance(n, minidom.Text):
1067                    continue
1068                sims.append(esysxml.getComponent(n))
1069            sims.sort(cmp=_comp)
1070            sim=cls([s[1] for s in sims], debug=esysxml.debug)
1071            esysxml.registerLinkableObject(sim, node)
1072            return sim
1073    
1074      fromDom = classmethod(fromDom)      fromDom = classmethod(fromDom)
1075    
1076    def _comp(a,b):
1077        if a[0]<a[1]:
1078          return 1
1079        elif a[0]>a[1]:
1080          return -1
1081        else:
1082          return 0
1083    
1084  class IterationDivergenceError(Exception):  class IterationDivergenceError(Exception):
1085      """      """
1086         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
1087         but there is a chance taht a smaller step could help to reach convergence.      process at a time step.
1088    
1089        But there is a chance that a smaller step could help to reach convergence.
1090      """      """
1091      pass      pass
1092    
1093  class FailedTimeStepError(Exception):  class FailedTimeStepError(Exception):
1094      """excpetion which is thrown if the time step fails because of a step size that have been choosen to be too large"""      """
1095        Exception which is thrown if the time step fails because of a step
1096        size that have been choosen to be too large.
1097        """
1098      pass      pass
1099    
1100  class SimulationBreakDownError(Exception):  class SimulationBreakDownError(Exception):
1101      """excpetion which is thrown if the simulation does not manage to progress in time."""      """
1102        Exception which is thrown if the simulation does not manage to
1103        progress in time.
1104        """
1105      pass      pass
1106    
1107  class NonPositiveStepSizeError(Exception):  class NonPositiveStepSizeError(Exception):
1108      """excpetion which is thrown if the step size is not positive"""      """
1109        Exception which is thrown if the step size is not positive.
1110        """
1111      pass      pass
1112    
1113    class DataSource(object):
1114        """
1115        Class for handling data sources, including local and remote files. This class is under development.
1116        """
1117    
1118        def __init__(self, uri="file.ext", fileformat="unknown"):
1119            self.uri = uri
1120            self.fileformat = fileformat
1121    
1122        def toDom(self, esysxml, node):
1123            """
1124            C{toDom} method of DataSource. Creates a DataSource node and appends it to the
1125        current XML esysxml.
1126            """
1127            ds = esysxml.createElement('DataSource')
1128            ds.appendChild(esysxml.createDataNode('URI', self.uri))
1129            ds.appendChild(esysxml.createDataNode('FileFormat', self.fileformat))
1130            node.appendChild(ds)
1131    
1132        def fromDom(cls, esysxml, node):
1133            uri= str(node.getElementsByTagName("URI")[0].firstChild.nodeValue.strip())
1134            fileformat= str(node.getElementsByTagName("FileFormat")[0].firstChild.nodeValue.strip())
1135            ds = cls(uri, fileformat)
1136            return ds
1137    
1138        def getLocalFileName(self):
1139            return self.uri
1140    
1141        fromDom = classmethod(fromDom)
1142        
1143    # vim: expandtab shiftwidth=4:

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

  ViewVC Help
Powered by ViewVC 1.1.26