/[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 885 by gross, Wed Nov 1 09:05:51 2006 UTC revision 950 by gross, Tue Feb 6 07:01:11 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.getElementsByTagName('ESys')[0]
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 getTarget(self):
218            """
219            returns the target
220            """
221            return self.target
222        def getAttributeName(self):
223            """
224            returns the name of the attribute the link is pointing to
225            """
226            return self.attribute
227            
228      def setAttributeName(self,attribute):      def setAttributeName(self,attribute):
229          """          """
# Line 206  class Link: Line 269  class Link:
269          else:          else:
270              return out              return out
271    
272      def toDom(self, document, node):      def toDom(self, esysxml, node):
273          """          """
274          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
275      current XML document.      current XML esysxml.
276          """          """
277          link = document.createElement('Link')          link = esysxml.createElement('Link')
278          assert (self.target != None), ("Target was none, name was %r" % self.attribute)          assert (self.target != None), ("Target was none, name was %r" % self.attribute)
279          link.appendChild(dataNode(document, 'Target', self.target.id))          link.appendChild(esysxml.createDataNode('Target', esysxml.getLinkableObjectId(self.target)))
280          # 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
281          # target from the xml later. I need a better unique identifier.          # target from the xml later. I need a better unique identifier.
282          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"
283          link.appendChild(dataNode(document, 'Attribute', self.attribute))          link.appendChild(esysxml.createDataNode('Attribute', self.attribute))
284          node.appendChild(link)          node.appendChild(link)
285    
286      def fromDom(cls, doc):      def fromDom(cls, esysxml, node):
287          targetid = doc.getElementsByTagName("Target")[0].firstChild.nodeValue.strip()          targetid = int(node.getElementsByTagName("Target")[0].firstChild.nodeValue.strip())
288          attribute = doc.getElementsByTagName("Attribute")[0].firstChild.nodeValue.strip()          attribute =str(node.getElementsByTagName("Attribute")[0].firstChild.nodeValue.strip())
289          l = cls(None, attribute)          l = cls(None, attribute)
290          registerLink(targetid, l)          esysxml.registerLink(targetid, l)
291          return l          return l
292    
293      fromDom = classmethod(fromDom)      fromDom = classmethod(fromDom)
294            
     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())  
   
295  class LinkableObject(object):  class LinkableObject(object):
296      """      """
297      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 310  class LinkableObject(object):
310      the return value of the call.      the return value of the call.
311      """      """
312        
     number_sequence = itertools.count(100)  
313            
314      def __init__(self, debug=False):      def __init__(self, id = None, debug=False):
315          """          """
316      Initializes LinkableObject so that we can operate on Links      Initializes LinkableObject so that we can operate on Links
317      """      """
318          self.debug = debug          self.debug = debug
319          self.__linked_attributes={}          self.__linked_attributes={}
320          self.id = self.number_sequence.next()          
         registerLinkableObject(self.id, self)  
   
321      def trace(self, msg):      def trace(self, msg):
322          """          """
323      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 445  class ParameterSet(LinkableObject):
445          self.declareParameters(parameters)          self.declareParameters(parameters)
446    
447      def __repr__(self):      def __repr__(self):
448          return "<%s %r>" % (self.__class__.__name__,          return "<%s %d>"%(self.__class__.__name__,id(self))
                             [(p, getattr(self, p, None)) for p in self.parameters])  
449            
450      def declareParameter(self,**parameters):      def declareParameter(self,**parameters):
451          """          """
# Line 429  class ParameterSet(LinkableObject): Line 476  class ParameterSet(LinkableObject):
476          if self.isParameter(name):          if self.isParameter(name):
477              self.parameters.remove(name)              self.parameters.remove(name)
478              self.trace("parameter %s has been removed."%name)              self.trace("parameter %s has been removed."%name)
479    
480        def checkLinkTargets(self, models, hash):
481            """
482            returns a list of (paramter set,parameter, target model ) if the the parameter of model
483            is linking to the target_model which is not in list of models.
484            """
485            out=[]
486            for name, value in self:
487                if isinstance(value, Link):
488                   print str(self), name, value
489                   m=value.getTarget()
490                   if (m,name) in hash:
491                     raise RuntimeError("recursive link: %s"%(hash+[ (m,name) ]))
492                   if isinstance(m, Model) and not m in models: out.append( (self,name,m) )
493                   if isinstance(m, ParameterSet):
494                      try:
495                         out+=m.checkLinkTargets(models, hash+[ (self,name) ] )
496                      except RuntimeError, e:
497                         print str(e), str(self), name
498                         raise e
499            return list(set(out))
500            
501      def __iter__(self):      def __iter__(self):
502          """          """
# Line 461  class ParameterSet(LinkableObject): Line 529  class ParameterSet(LinkableObject):
529          except:          except:
530              pass              pass
531    
532      def toDom(self, document, node):      def toDom(self, esysxml, node):
533          """          """
534      C{toDom} method of ParameterSet class.      C{toDom} method of Model class
535      """      """
536          pset = document.createElement('ParameterSet')          pset = esysxml.createElement('ParameterSet')
537            pset.setAttribute('type', self.__class__.__name__)
538            pset.setAttribute('module', self.__class__.__module__)
539            esysxml.registerLinkableObject(self, pset)
540            self._parametersToDom(esysxml, pset)
541          node.appendChild(pset)          node.appendChild(pset)
         self._parametersToDom(document, pset)  
542    
543      def _parametersToDom(self, document, node):      def _parametersToDom(self, esysxml, node):
         node.setAttribute('id', str(self.id))  
         node.setIdAttribute("id")  
544          for name,value in self:          for name,value in self:
545              param = document.createElement('Parameter')              # convert list to numarray when possible:
546              param.setAttribute('type', value.__class__.__name__)              if isinstance (value, list):
547                    elem_type=-1
548                    for i in value:
549                        if isinstance(i, bool):
550                            elem_type = max(elem_type,0)
551                        if isinstance(i, int) and not isinstance(i, bool):
552                            elem_type = max(elem_type,1)
553                        if isinstance(i, float):
554                            elem_type = max(elem_type,2)
555                    if elem_type == 0: value = numarray.array(value,numarray.Bool)
556                    if elem_type == 1: value = numarray.array(value,numarray.Int)
557                    if elem_type == 2: value = numarray.array(value,numarray.Float)
558    
559              param.appendChild(dataNode(document, 'Name', name))              param = esysxml.createElement('Parameter')
560                param.setAttribute('type', value.__class__.__name__)
561    
562              val = document.createElement('Value')              param.appendChild(esysxml.createDataNode('Name', name))
563    
564                val = esysxml.createElement('Value')
565              if isinstance(value,(ParameterSet,Link,DataSource)):              if isinstance(value,(ParameterSet,Link,DataSource)):
566                  value.toDom(document, val)                  value.toDom(esysxml, val)
567                  param.appendChild(val)                  param.appendChild(val)
568              elif isinstance(value, numarray.NumArray):              elif isinstance(value, numarray.NumArray):
569                  shape = value.getshape()                  shape = value.getshape()
# Line 493  class ParameterSet(LinkableObject): Line 575  class ParameterSet(LinkableObject):
575                      shape = str(shape)                      shape = str(shape)
576    
577                  arraytype = value.type()                  arraytype = value.type()
578                  numarrayElement = document.createElement('NumArray')                  if isinstance(arraytype, numarray.BooleanType):
579                  numarrayElement.appendChild(dataNode(document, 'ArrayType', str(arraytype)))                        arraytype_str="Bool"
580                  numarrayElement.appendChild(dataNode(document, 'Shape', shape))                  elif isinstance(arraytype, numarray.IntegralType):
581                  numarrayElement.appendChild(dataNode(document, 'Data', ' '.join(                        arraytype_str="Int"
582                    elif isinstance(arraytype, numarray.FloatingType):
583                          arraytype_str="Float"
584                    elif isinstance(arraytype, numarray.ComplexType):
585                          arraytype_str="Complex"
586                    else:
587                          arraytype_str=str(arraytype)
588                    numarrayElement = esysxml.createElement('NumArray')
589                    numarrayElement.appendChild(esysxml.createDataNode('ArrayType', arraytype_str))
590                    numarrayElement.appendChild(esysxml.createDataNode('Shape', shape))
591                    numarrayElement.appendChild(esysxml.createDataNode('Data', ' '.join(
592                      [str(x) for x in numarray.reshape(value, size)])))                      [str(x) for x in numarray.reshape(value, size)])))
593                  val.appendChild(numarrayElement)                  val.appendChild(numarrayElement)
594                  param.appendChild(val)                  param.appendChild(val)
595              elif isinstance (value, list):              elif isinstance(value, list):
596                  param.appendChild(dataNode(document, 'Value', ' '.join(                  param.appendChild(esysxml.createDataNode('Value', ' '.join([str(x) for x in value]) ))
597                      [str(x) for x in value])              elif isinstance(value, (str, bool, int, float, type(None))):
598                  ))                  param.appendChild(esysxml.createDataNode('Value', str(value)))
599                elif isinstance(value, dict):
600                     dic = esysxml.createElement('dictionary')
601                     if len(value.keys())>0:
602                         dic.setAttribute('key_type', value.keys()[0].__class__.__name__)
603                         dic.setAttribute('value_type', value[value.keys()[0]].__class__.__name__)
604                     for k,v in value.items():
605                        i=esysxml.createElement('item')
606                        i.appendChild(esysxml.createDataNode('key', k))
607                        i.appendChild(esysxml.createDataNode('value', v))
608                        dic.appendChild(i)
609                     param.appendChild(dic)
610              else:              else:
611                  param.appendChild(dataNode(document, 'Value', str(value)))                  print value
612                    raise ValueError("cannot serialize %s type to XML."%str(value.__class__))
613    
614              node.appendChild(param)              node.appendChild(param)
615    
616      def fromDom(cls, doc):      def fromDom(cls, esysxml, node):
   
617          # Define a host of helper functions to assist us.          # Define a host of helper functions to assist us.
618          def _children(node):          def _children(node):
619              """              """
# Line 525  class ParameterSet(LinkableObject): Line 628  class ParameterSet(LinkableObject):
628                      ret.append(x)                      ret.append(x)
629              return ret              return ret
630    
631          def _floatfromValue(doc):          def _floatfromValue(esysxml, node):
632              return float(doc.nodeValue.strip())              return float(node.nodeValue.strip())
633    
634          def _stringfromValue(doc):          def _stringfromValue(esysxml, node):
635              return str(doc.nodeValue.strip())              return str(node.nodeValue.strip())
636                
637          def _intfromValue(doc):          def _intfromValue(esysxml, node):
638              return int(doc.nodeValue.strip())              return int(node.nodeValue.strip())
639    
640          def _boolfromValue(doc):          def _boolfromValue(esysxml, node):
641              return _boolfromstring(doc.nodeValue.strip())              return _boolfromstring(node.nodeValue.strip())
642    
643          def _nonefromValue(doc):          def _nonefromValue(esysxml, node):
644              return None              return None
645    
646          def _numarrayfromValue(doc):          def _numarrayfromValue(esysxml, node):
647              for node in _children(doc):              for node in _children(node):
648                  if node.tagName == 'ArrayType':                  if node.tagName == 'ArrayType':
649                      arraytype = node.firstChild.nodeValue.strip()                      arraytype = node.firstChild.nodeValue.strip()
650                  if node.tagName == 'Shape':                  if node.tagName == 'Shape':
# Line 553  class ParameterSet(LinkableObject): Line 656  class ParameterSet(LinkableObject):
656              return numarray.reshape(numarray.array(data, type=getattr(numarray, arraytype)),              return numarray.reshape(numarray.array(data, type=getattr(numarray, arraytype)),
657                                      shape)                                      shape)
658                
659          def _listfromValue(doc):          def _listfromValue(esysxml, node):
660              return [_boolfromstring(x) for x in doc.nodeValue.split()]              return [x for x in node.nodeValue.split()]
   
661    
662          def _boolfromstring(s):          def _boolfromstring(s):
663              if s == 'True':              if s == 'True':
# Line 577  class ParameterSet(LinkableObject): Line 679  class ParameterSet(LinkableObject):
679                      "NoneType":_nonefromValue,                      "NoneType":_nonefromValue,
680                      }                      }
681    
 #        print doc.toxml()  
   
682          parameters = {}          parameters = {}
683          for node in _children(doc):          for n in _children(node):
684              ptype = node.getAttribute("type")              ptype = n.getAttribute("type")
685                if not ptypemap.has_key(ptype):
686                   raise KeyError("cannot handle parameter type %s."%ptype)
687    
688              pname = pvalue = None              pname = pvalue = None
689              for childnode in _children(node):              for childnode in _children(n):
   
690                  if childnode.tagName == "Name":                  if childnode.tagName == "Name":
691                      pname = childnode.firstChild.nodeValue.strip()                      pname = childnode.firstChild.nodeValue.strip()
692    
693                  if childnode.tagName == "Value":                  if childnode.tagName == "Value":
694                      nodes = _children(childnode)                      nodes = _children(childnode)
695                  #    if ptype == 'NumArray':                      pvalue = ptypemap[ptype](esysxml, nodes[0])
                  #       pvalue = _numarrayfromValue(nodes)  
                  #   else:  
                     pvalue = ptypemap[ptype](nodes[0])  
696    
697              parameters[pname] = pvalue              parameters[pname] = pvalue
698    
699          # Create the instance of ParameterSet          # Create the instance of ParameterSet
700          o = cls()          o = cls(debug=esysxml.debug)
701          o.declareParameters(parameters)          o.declareParameters(parameters)
702          registerLinkableObject(doc.getAttribute("id"), o)          esysxml.registerLinkableObject(o, node)
703          return o          return o
704            
705      fromDom = classmethod(fromDom)      fromDom = classmethod(fromDom)
706        
707      def writeXML(self,ostream=stdout):      def writeXML(self,ostream=stdout):
708          """          """
709      Writes the object as an XML object into an output stream.      Writes the object as an XML object into an output stream.
710      """      """
711          # ParameterSet(d) with d[Name]=Value          esysxml=ESySXMLCreator()
712          document, node = esysDoc()          self.toDom(esysxml, esysxml.getRoot())
713          self.toDom(document, node)          ostream.write(esysxml.toprettyxml())
714          ostream.write(document.toprettyxml())      
   
715  class Model(ParameterSet):  class Model(ParameterSet):
716      """      """
717      A Model object represents a processess marching over time until a      A Model object represents a processess marching over time until a
718      finalizing condition is fullfilled. At each time step an iterative      finalizing condition is fullfilled. At each time step an iterative
719      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
720      Model has the following work flow::      Model has the following work flow::
721              
722            doInitialization()            doInitialization()
723              while not terminateInitialIteration(): doInitializationiStep()
724              doInitialPostprocessing()
725            while not finalize():            while not finalize():
726                 dt=getSafeTimeStepSize(dt)                 dt=getSafeTimeStepSize(dt)
727                 doStepPreprocessing(dt)                 doStepPreprocessing(dt)
# Line 639  class Model(ParameterSet): Line 738  class Model(ParameterSet):
738    
739      UNDEF_DT=1.e300      UNDEF_DT=1.e300
740    
741      def __init__(self,parameters=[],**kwarg):      def __init__(self,parameters=[],**kwargs):
742          """          """
743      Creates a model.      Creates a model.
744    
745          Just calls the parent constructor.          Just calls the parent constructor.
746          """          """
747          ParameterSet.__init__(self, parameters=parameters,**kwarg)          ParameterSet.__init__(self, parameters=parameters,**kwargs)
748    
749      def __str__(self):      def __str__(self):
750         return "<%s %d>"%(self.__class__,id(self))         return "<%s %d>"%(self.__class__.__name__,id(self))
751    
     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)  
752    
753      def doInitialization(self):      def doInitialization(self):
754          """          """
# Line 668  class Model(ParameterSet): Line 757  class Model(ParameterSet):
757      This function may be overwritten.      This function may be overwritten.
758      """      """
759          pass          pass
760        def doInitialStep(self):
761            """
762        performs an iteration step in the initialization phase
763    
764        This function may be overwritten.
765        """
766            pass
767    
768        def terminateInitialIteration(self):
769            """
770        Returns True if iteration at the inital phase is terminated.
771        """
772            return True
773    
774        def doInitialPostprocessing(self):
775            """
776        finalises the initialization iteration process
777    
778        This function may be overwritten.
779        """
780            pass
781            
782      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
783          """          """
# Line 718  class Model(ParameterSet): Line 828  class Model(ParameterSet):
828      Returns True if iteration on a time step is terminated.      Returns True if iteration on a time step is terminated.
829      """      """
830          return True          return True
831    
832                
833      def doStepPostprocessing(self,dt):      def doStepPostprocessing(self,dt):
834          """          """
835      Finalalizes the time step.      finalises the time step.
836    
837          dt is the currently used time step size.          dt is the currently used time step size.
838    
839          This function may be overwritten.          This function may be overwritten.
840      """      """
841          pass          pass
       
     def writeXML(self, ostream=stdout):  
         document, node = esysDoc()  
         self.toDom(document, node)  
         ostream.write(document.toprettyxml())  
       
842    
843        def toDom(self, esysxml, node):
844            """
845        C{toDom} method of Model class
846        """
847            pset = esysxml.createElement('Model')
848            pset.setAttribute('type', self.__class__.__name__)
849            pset.setAttribute('module', self.__class__.__module__)
850            esysxml.registerLinkableObject(self, pset)
851            node.appendChild(pset)
852            self._parametersToDom(esysxml, pset)
853        
854  class Simulation(Model):  class Simulation(Model):
855      """      """
856      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 753  class Simulation(Model): Line 869  class Simulation(Model):
869          """          """
870      Initiates a simulation from a list of models.      Initiates a simulation from a list of models.
871      """      """
872          Model.__init__(self, **kwargs)          super(Simulation, self).__init__(**kwargs)
873            for m in models:
874                if not isinstance(m, Model):
875                     raise TypeError("%s is not a subclass of Model."%m)
876          self.__models=[]          self.__models=[]
           
877          for i in range(len(models)):          for i in range(len(models)):
878              self[i] = models[i]              self[i] = models[i]
879                            
# Line 800  class Simulation(Model): Line 918  class Simulation(Model):
918      """      """
919          return len(self.__models)          return len(self.__models)
920    
921      def toDom(self, document, node):      def getAllModels(self):
922          """          """
923      C{toDom} method of Simulation class.          returns a list of all models used in the Simulation including subsimulations
924      """          """
925          simulation = document.createElement('Simulation')          out=[]
926          simulation.setAttribute('type', self.__class__.__name__)          for m in self.iterModels():
927                if isinstance(m, Simulation):
928          for rank, sim in enumerate(self.iterModels()):                 out+=m.getAllModels()
929              component = document.createElement('Component')              else:
930              component.setAttribute('rank', str(rank))                 out.append(m)
931            return list(set(out))
             sim.toDom(document, component)  
   
             simulation.appendChild(component)  
   
         node.appendChild(simulation)  
932    
933      def writeXML(self,ostream=stdout):      def checkModels(self, models, hash):
934          """          """
935      Writes the object as an XML object into an output stream.          returns a list of (model,parameter, target model ) if the the parameter of model
936      """          is linking to the target_model which is not in list of models.
937          document, rootnode = esysDoc()          """
938          self.toDom(document, rootnode)          out=self.checkLinkTargets(models, hash)
939          targetsList = document.getElementsByTagName('Target')          for m in self.iterModels():
940                        if isinstance(m, Simulation):
941          for element in targetsList:                   out+=[ (m,) + f for f in  m.checkModels(models, hash) ]
942              targetId = int(element.firstChild.nodeValue.strip())              else:
943              if document.getElementById(str(targetId)):                   out+=[ (m,) + f for f in  m.checkLinkTargets(models, hash) ]
944                  continue          return out
945              targetObj = LinkableObjectRegistry[targetId]  
             targetObj.toDom(document, rootnode)  
         ostream.write(document.toprettyxml())  
946            
947      def getSafeTimeStepSize(self,dt):      def getSafeTimeStepSize(self,dt):
948          """          """
# Line 840  class Simulation(Model): Line 951  class Simulation(Model):
951          This is the minimum over the time step sizes of all models.          This is the minimum over the time step sizes of all models.
952      """      """
953          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)  
954          return out          return out
955            
956      def doInitialization(self):      def doInitialization(self):
# Line 850  class Simulation(Model): Line 960  class Simulation(Model):
960          self.n=0          self.n=0
961          self.tn=0.          self.tn=0.
962          for o in self.iterModels():          for o in self.iterModels():
963              o.doInitialization()               o.doInitialization()
964            def doInitialStep(self):
965            """
966        performs an iteration step in the initialization step for all models
967        """
968            iter=0
969            while not self.terminateInitialIteration():
970                if iter==0: self.trace("iteration for initialization starts")
971                iter+=1
972                self.trace("iteration step %d"%(iter))
973                for o in self.iterModels():
974                     o.doInitialStep()
975                if iter>self.MAX_ITER_STEPS:
976                     raise IterationDivergenceError("initial iteration did not converge after %s steps."%iter)
977            self.trace("Initialization finalized after %s iteration steps."%iter)
978    
979        def doInitialPostprocessing(self):
980            """
981        finalises the initialization iteration process for all models.
982        """
983            for o in self.iterModels():
984                o.doInitialPostprocessing()
985      def finalize(self):      def finalize(self):
986          """          """
987      Returns True if any of the models is to be finalized.      Returns True if any of the models is to be finalized.
# Line 860  class Simulation(Model): Line 990  class Simulation(Model):
990                
991      def doFinalization(self):      def doFinalization(self):
992          """          """
993      Finalalizes the time stepping for all models.      finalises the time stepping for all models.
994      """      """
995          for i in self.iterModels(): i.doFinalization()          for i in self.iterModels(): i.doFinalization()
996          self.trace("end of time integation.")          self.trace("end of time integation.")
# Line 878  class Simulation(Model): Line 1008  class Simulation(Model):
1008      """      """
1009          out=all([o.terminateIteration() for o in self.iterModels()])          out=all([o.terminateIteration() for o in self.iterModels()])
1010          return out          return out
1011    
1012        def terminateInitialIteration(self):
1013            """
1014        Returns True if all initial iterations for all models are terminated.
1015        """
1016            out=all([o.terminateInitialIteration() for o in self.iterModels()])
1017            return out
1018                
1019      def doStepPostprocessing(self,dt):      def doStepPostprocessing(self,dt):
1020          """          """
1021      Finalalizes the iteration process for all models.      finalises the iteration process for all models.
1022      """      """
1023          for o in self.iterModels():          for o in self.iterModels():
1024              o.doStepPostprocessing(dt)              o.doStepPostprocessing(dt)
# Line 912  class Simulation(Model): Line 1049  class Simulation(Model):
1049      Run the simulation by performing essentially::      Run the simulation by performing essentially::
1050            
1051          self.doInitialization()          self.doInitialization()
1052                while not self.terminateInitialIteration(): self.doInitialStep()
1053                self.doInitialPostprocessing()
1054          while not self.finalize():          while not self.finalize():
1055              dt=self.getSafeTimeStepSize()              dt=self.getSafeTimeStepSize()
1056              self.doStep(dt)              self.doStep(dt)
# Line 929  class Simulation(Model): Line 1068  class Simulation(Model):
1068          In both cases the time integration is given up after          In both cases the time integration is given up after
1069      C{Simulation.FAILED_TIME_STEPS_MAX} attempts.      C{Simulation.FAILED_TIME_STEPS_MAX} attempts.
1070          """          """
1071          dt=self.UNDEF_DT          # check the completness of the models:
1072            # first a list of all the models involved in the simulation including subsimulations:
1073            #
1074            missing=self.checkModels(self.getAllModels(), [])
1075            if len(missing)>0:
1076                msg=""
1077                for l in missing:
1078                     msg+="\n\t"+str(l[-1])+" at "+str(self)
1079                     for i in xrange(len(l)-1): msg+="."+str(l[i])
1080                raise MissingLink("link targets missing in the Simulation: %s"%msg)
1081            #==============================
1082          self.doInitialization()          self.doInitialization()
1083            self.doInitialStep()
1084            self.doInitialPostprocessing()
1085            dt=self.UNDEF_DT
1086          while not self.finalize():          while not self.finalize():
1087              step_fail_counter=0              step_fail_counter=0
1088              iteration_fail_counter=0              iteration_fail_counter=0
# Line 969  class Simulation(Model): Line 1121  class Simulation(Model):
1121                      self.writeXML()                      self.writeXML()
1122          self.doFinalization()          self.doFinalization()
1123    
     def fromDom(cls, doc):  
         sims = []  
         for node in doc.childNodes:  
             if isinstance(node, minidom.Text):  
                 continue  
1124    
1125              sims.append(getComponent(node))      def toDom(self, esysxml, node):
1126            """
1127        C{toDom} method of Simulation class.
1128        """
1129            simulation = esysxml.createElement('Simulation')
1130            esysxml.registerLinkableObject(self, simulation)
1131            for rank, sim in enumerate(self.iterModels()):
1132                component = esysxml.createElement('Component')
1133                component.setAttribute('rank', str(rank))
1134                sim.toDom(esysxml, component)
1135                simulation.appendChild(component)
1136            node.appendChild(simulation)
1137    
1138    
1139          return cls(sims)      def fromDom(cls, esysxml, node):
1140            sims = []
1141            for n in node.childNodes:
1142                if isinstance(n, minidom.Text):
1143                    continue
1144                sims.append(esysxml.getComponent(n))
1145            sims.sort(cmp=_comp)
1146            sim=cls([s[1] for s in sims], debug=esysxml.debug)
1147            esysxml.registerLinkableObject(sim, node)
1148            return sim
1149    
1150      fromDom = classmethod(fromDom)      fromDom = classmethod(fromDom)
1151    
1152    def _comp(a,b):
1153        if a[0]<a[1]:
1154          return 1
1155        elif a[0]>a[1]:
1156          return -1
1157        else:
1158          return 0
1159    
1160  class IterationDivergenceError(Exception):  class IterationDivergenceError(Exception):
1161      """      """
# Line 1011  class NonPositiveStepSizeError(Exception Line 1186  class NonPositiveStepSizeError(Exception
1186      """      """
1187      pass      pass
1188    
1189    class MissingLink(Exception):
1190        """
1191        Exception thrown when a link is missing
1192        """
1193        pass
1194    
1195  class DataSource(object):  class DataSource(object):
1196      """      """
1197      Class for handling data sources, including local and remote files. This class is under development.      Class for handling data sources, including local and remote files. This class is under development.
# Line 1020  class DataSource(object): Line 1201  class DataSource(object):
1201          self.uri = uri          self.uri = uri
1202          self.fileformat = fileformat          self.fileformat = fileformat
1203    
1204      def toDom(self, document, node):      def toDom(self, esysxml, node):
1205          """          """
1206          C{toDom} method of DataSource. Creates a DataSource node and appends it to the          C{toDom} method of DataSource. Creates a DataSource node and appends it to the
1207      current XML document.      current XML esysxml.
1208          """          """
1209          ds = document.createElement('DataSource')          ds = esysxml.createElement('DataSource')
1210          ds.appendChild(dataNode(document, 'URI', self.uri))          ds.appendChild(esysxml.createDataNode('URI', self.uri))
1211          ds.appendChild(dataNode(document, 'FileFormat', self.fileformat))          ds.appendChild(esysxml.createDataNode('FileFormat', self.fileformat))
1212          node.appendChild(ds)          node.appendChild(ds)
1213    
1214      def fromDom(cls, doc):      def fromDom(cls, esysxml, node):
1215          uri= doc.getElementsByTagName("URI")[0].firstChild.nodeValue.strip()          uri= str(node.getElementsByTagName("URI")[0].firstChild.nodeValue.strip())
1216          fileformat= doc.getElementsByTagName("FileFormat")[0].firstChild.nodeValue.strip()          fileformat= str(node.getElementsByTagName("FileFormat")[0].firstChild.nodeValue.strip())
1217          ds = cls(uri, fileformat)          ds = cls(uri, fileformat)
1218          return ds          return ds
1219    

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

  ViewVC Help
Powered by ViewVC 1.1.26