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

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

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

revision 874 by elspeth, Tue Oct 17 12:06:11 2006 UTC revision 920 by gross, Thu Jan 4 00:00:40 2007 UTC
# Line 27  from sys import stdout Line 27  from sys import stdout
27  import numarray  import numarray
28  import operator  import operator
29  import itertools  import itertools
 # 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 37  except NameError: Line 36  except NameError:
36    
37  from xml.dom import minidom  from xml.dom import minidom
38    
 def dataNode(document, tagName, data):  
     """  
     C{dataNode}s are the building blocks of the xml documents constructed in  
     this module.    
       
     @param document: the current xml document  
     @param tagName: the associated xml tag  
     @param data: 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 72  def any(seq): Line 49  def any(seq):
49              return True              return True
50      return False      return False
51    
 LinkableObjectRegistry = {}  
   
 def registerLinkableObject(obj_id, o):  
     LinkableObjectRegistry[obj_id] = o  
   
 LinkRegistry = []  
   
 def registerLink(obj_id, l):  
     LinkRegistry.append((obj_id,l))  
   
 def parse(xml):  
     """  
     Generic parse method for EsysXML.  Without this, Links don't work.  
     """  
     global LinkRegistry, LinkableObjectRegistry  
     LinkRegistry = []  
     LinkableObjectRegistry = {}  
   
     doc = minidom.parseString(xml)  
     sim = getComponent(doc.firstChild)  
     for obj_id, link in LinkRegistry:  
         link.target = LinkableObjectRegistry[obj_id]  
   
     return sim  
   
52  def importName(modulename, name):  def importName(modulename, name):
53      """ Import a named object from a module in the context of this function,      """ Import a named object from a module in the context of this function,
54          which means you should use fully qualified module paths.          which means you should use fully qualified module paths.
           
55          Return None on failure.          Return None on failure.
56    
57          This function from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52241          This function from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52241
# Line 112  def importName(modulename, name): Line 63  def importName(modulename, name):
63      except KeyError:      except KeyError:
64          raise ImportError("Could not import %s from %s" % (name, modulename))          raise ImportError("Could not import %s from %s" % (name, modulename))
65    
66  def getComponent(doc):  class ESySXMLParser(object):
     """  
     Used to get components of Simualtions, Models.  
67      """      """
68      for node in doc.childNodes:      parser for ESysXML file
69                """
70          if isinstance(node, minidom.Element):      def __init__(self,xml, debug=False):
71              if node.tagName == 'Simulation':        self.__dom = minidom.parseString(xml)
72                  if node.getAttribute("type") == 'Simulation':        self.__linkable_object_registry= {}
73                      return Simulation.fromDom(node)        self.__link_registry=  []
74              if node.tagName == 'Model':        self.__esys=self.__dom.firstChild
75                  if (node.getAttribute("module")):        self.debug=debug
76                      model_module = node.getAttribute("module")    
77                      model_type = node.getAttribute("type")      def getClassPath(self, node):
78                      return importName(model_module, model_type).fromDom(node)          type = node.getAttribute("type")
79                  else:          if (node.getAttribute("module")):
80                      model_type = node.getAttribute("type")              module = node.getAttribute("module")
81                      model_subclasses = Model.__subclasses__()              return importName(module, type)
82                      for model in model_subclasses:          else:
83                          if model_type == model.__name__:              return importName("__main__", type)
                             return Model.fromDom(node)  
             if node.tagName == 'ParameterSet':  
                 parameter_type = node.getAttribute("type")  
                 return ParameterSet.fromDom(node)  
             raise "Invalid simulation type, %r" % node.getAttribute("type")  
           
84    
85      raise ValueError("No Simulation Found")      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    class ESySXMLCreator(object):
138        """
139        creates an XML Dom representation
140        """
141        def __init__(self):
142           self.__dom=minidom.Document()
143           self.__esys =self.__dom.createElement('ESys')
144           self.__dom.appendChild(self.__esys)
145           self.__linkable_object_registry={}
146           self.__number_sequence = itertools.count(100)
147        def getRoot(self):
148           return self.__esys
149        def createElement(self,name):
150          return self.__dom.createElement(name)
151        def createTextNode(self,name):
152          return self.__dom.createTextNode(name)
153        def getElementById(self,name):
154          return self.__dom.getElementById(name)
155        def createDataNode(self, tagName, data):
156              """
157              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::
# Line 161  class Link: Line 213  class Link:
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          """          """
# Line 206  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          C{toDom} method of Link. Creates a Link node and appends it to the          C{toDom} method of Link. Creates a Link node and appends it to the
270      current XML 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
# Line 259  class LinkableObject(object): Line 305  class LinkableObject(object):
305      the return 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          """          """
311      Initializes LinkableObject so that we can operate on Links      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()          
         registerLinkableObject(self.id, self)  
   
316      def trace(self, msg):      def trace(self, msg):
317          """          """
318      If debugging is on, print the message, otherwise do nothing      If debugging is on, print the message, otherwise do nothing
# Line 397  class ParameterSet(LinkableObject): Line 440  class ParameterSet(LinkableObject):
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          """          """
# Line 461  class ParameterSet(LinkableObject): Line 503  class ParameterSet(LinkableObject):
503          except:          except:
504              pass              pass
505    
506      def toDom(self, document, node):      def toDom(self, esysxml, node):
507          """          """
508      C{toDom} method of ParameterSet class.      C{toDom} method of Model class
509      """      """
510          pset = document.createElement('ParameterSet')          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))  
         node.setIdAttribute("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,Link)):              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, numarray.NumArray):              elif isinstance(value, numarray.NumArray):
543                  shape = value.getshape()                  shape = value.getshape()
# Line 493  class ParameterSet(LinkableObject): Line 549  class ParameterSet(LinkableObject):
549                      shape = str(shape)                      shape = str(shape)
550    
551                  arraytype = value.type()                  arraytype = value.type()
552                  numarrayElement = document.createElement('NumArray')                  if isinstance(arraytype, numarray.BooleanType):
553                  numarrayElement.appendChild(dataNode(document, 'ArrayType', str(arraytype)))                        arraytype_str="Bool"
554                  numarrayElement.appendChild(dataNode(document, 'Shape', shape))                  elif isinstance(arraytype, numarray.IntegralType):
555                  numarrayElement.appendChild(dataNode(document, 'Data', ' '.join(                        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)])))                      [str(x) for x in numarray.reshape(value, size)])))
567                  val.appendChild(numarrayElement)                  val.appendChild(numarrayElement)
568                  param.appendChild(val)                  param.appendChild(val)
569              elif isinstance (value, list):              elif isinstance(value, list):
570                  param.appendChild(dataNode(document, 'Value', ' '.join(                  param.appendChild(esysxml.createDataNode('Value', ' '.join([str(x) for x in value]) ))
571                      [str(x) for x in value])              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              """              """
# Line 525  class ParameterSet(LinkableObject): Line 590  class ParameterSet(LinkableObject):
590                      ret.append(x)                      ret.append(x)
591              return ret              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 _boolfromstring(doc.nodeValue.strip())              return _boolfromstring(node.nodeValue.strip())
604    
605          def _nonefromValue(doc):          def _nonefromValue(esysxml, node):
606              return None              return None
607    
608          def _numarrayfromValue(doc):          def _numarrayfromValue(esysxml, node):
609              for node in _children(doc):              for node in _children(node):
610                  if node.tagName == 'ArrayType':                  if node.tagName == 'ArrayType':
611                      arraytype = node.firstChild.nodeValue.strip()                      arraytype = node.firstChild.nodeValue.strip()
612                  if node.tagName == 'Shape':                  if node.tagName == 'Shape':
# Line 553  class ParameterSet(LinkableObject): Line 618  class ParameterSet(LinkableObject):
618              return numarray.reshape(numarray.array(data, type=getattr(numarray, arraytype)),              return numarray.reshape(numarray.array(data, type=getattr(numarray, arraytype)),
619                                      shape)                                      shape)
620                
621          def _listfromValue(doc):          def _listfromValue(esysxml, node):
622              return [_boolfromstring(x) for x in doc.nodeValue.split()]              return [x for x in node.nodeValue.split()]
   
623    
624          def _boolfromstring(s):          def _boolfromstring(s):
625              if s == 'True':              if s == 'True':
# Line 567  class ParameterSet(LinkableObject): Line 631  class ParameterSet(LinkableObject):
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,
# Line 576  class ParameterSet(LinkableObject): Line 641  class ParameterSet(LinkableObject):
641                      "NoneType":_nonefromValue,                      "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                  #    if ptype == 'NumArray':                      pvalue = ptypemap[ptype](esysxml, nodes[0])
                  #       pvalue = _numarrayfromValue(nodes)  
                  #   else:  
                     pvalue = ptypemap[ptype](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)
668        
669      def writeXML(self,ostream=stdout):      def writeXML(self,ostream=stdout):
670          """          """
671      Writes the object as an XML object into an output stream.      Writes the object as an XML object into an output stream.
672      """      """
673          # ParameterSet(d) with d[Name]=Value          esysxml=ESySXMLCreator()
674          document, node = esysDoc()          self.toDom(esysxml, esysxml.getRoot())
675          self.toDom(document, node)          ostream.write(esysxml.toprettyxml())
676          ostream.write(document.toprettyxml())      
   
677  class Model(ParameterSet):  class Model(ParameterSet):
678      """      """
679      A Model object represents a processess marching over time until a      A Model object represents a processess marching over time until a
680      finalizing condition is fullfilled. At each time step an iterative      finalizing condition is fullfilled. At each time step an iterative
681      process can be performed and the time step size can be controlled. A      process can be performed and the time step size can be controlled. A
682      Model has the following work flow::      Model has the following work flow::
683              
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 638  class Model(ParameterSet): Line 700  class Model(ParameterSet):
700    
701      UNDEF_DT=1.e300      UNDEF_DT=1.e300
702    
703      def __init__(self,parameters=[],**kwarg):      def __init__(self,parameters=[],**kwargs):
704          """          """
705      Creates a model.      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):  
         """  
     C{toDom} method of Model class  
     """  
         pset = document.createElement('Model')  
         pset.setAttribute('type', self.__class__.__name__)  
         if not self.__class__.__module__.startswith('esys.escript'):  
             pset.setAttribute('module', self.__class__.__module__)  
         node.appendChild(pset)  
         self._parametersToDom(document, pset)  
714    
715      def doInitialization(self):      def doInitialization(self):
716          """          """
# Line 667  class Model(ParameterSet): Line 719  class Model(ParameterSet):
719      This function may be overwritten.      This function may be overwritten.
720      """      """
721          pass          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
743            
744      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
745          """          """
# Line 717  class Model(ParameterSet): Line 790  class Model(ParameterSet):
790      Returns True if iteration on a time step is terminated.      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          """          """
797      Finalalizes the time step.      finalises the time step.
798    
799          dt is the currently used time step size.          dt is the currently used time step size.
800    
801          This function may be overwritten.          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.
# Line 752  class Simulation(Model): Line 831  class Simulation(Model):
831          """          """
832      Initiates a simulation from a list of models.      Initiates a simulation from a list of models.
833      """      """
834          Model.__init__(self, **kwargs)          super(Simulation, self).__init__(**kwargs)
835          self.__models=[]          self.__models=[]
836                    
837          for i in range(len(models)):          for i in range(len(models)):
# Line 799  class Simulation(Model): Line 878  class Simulation(Model):
878      """      """
879          return len(self.__models)          return len(self.__models)
880    
     def toDom(self, document, node):  
         """  
     C{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)  
         targetsList = document.getElementsByTagName('Target')  
           
         for element in targetsList:  
             targetId = int(element.firstChild.nodeValue.strip())  
             if document.getElementById(str(targetId)):  
                 continue  
             targetObj = LinkableObjectRegistry[targetId]  
             targetObj.toDom(document, rootnode)  
         ostream.write(document.toprettyxml())  
881            
882      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
883          """          """
# Line 839  class Simulation(Model): Line 886  class Simulation(Model):
886          This is the minimum over the time step sizes of all models.          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):
# Line 849  class Simulation(Model): Line 895  class Simulation(Model):
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          """          """
922      Returns True if any of the models is to be finalized.      Returns True if any of the models is to be finalized.
# Line 859  class Simulation(Model): Line 925  class Simulation(Model):
925                
926      def doFinalization(self):      def doFinalization(self):
927          """          """
928      Finalalizes the time stepping for all models.      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.")
# Line 877  class Simulation(Model): Line 943  class Simulation(Model):
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          """          """
956      Finalalizes the iteration process for all models.      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)
# Line 911  class Simulation(Model): Line 984  class Simulation(Model):
984      Run the simulation by performing essentially::      Run the simulation by performing essentially::
985            
986          self.doInitialization()          self.doInitialization()
987                while not self.terminateInitialIteration(): self.doInitialStep()
988                self.doInitialPostprocessing()
989          while not self.finalize():          while not self.finalize():
990              dt=self.getSafeTimeStepSize()              dt=self.getSafeTimeStepSize()
991              self.doStep(dt)              self.doStep(dt)
# Line 928  class Simulation(Model): Line 1003  class Simulation(Model):
1003          In both cases the time integration is given up after          In both cases the time integration is given up after
1004      C{Simulation.FAILED_TIME_STEPS_MAX} attempts.      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
# Line 968  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          return cls(sims)  
1063        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      """      """
# Line 1010  class NonPositiveStepSizeError(Exception Line 1110  class NonPositiveStepSizeError(Exception
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:  # vim: expandtab shiftwidth=4:

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

  ViewVC Help
Powered by ViewVC 1.1.26