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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 147 - (hide annotations)
Fri Aug 12 01:45:47 2005 UTC (14 years, 2 months ago) by jgs
Original Path: trunk/esys2/escript/py_src/modelframe.py
File MIME type: text/x-python
File size: 27004 byte(s)
erge of development branch dev-02 back to main trunk on 2005-08-12

1 jgs 121 # $Id$
2    
3 jgs 122 from types import StringType,IntType,FloatType,BooleanType,ListType,DictType
4     from sys import stdout
5 jgs 123 import itertools
6 jgs 142 # import modellib temporarily removed!!!
7 jgs 121
8 jgs 123 # import the 'set' module if it's not defined (python2.3/2.4 difference)
9     try:
10     set
11     except NameError:
12     from sets import Set as set
13    
14 jgs 122 from xml.dom import minidom
15 jgs 121
16 jgs 122 def dataNode(document, tagName, data):
17 jgs 126 """
18     dataNodes are the building blocks of the xml documents constructed in
19     this module. document is the current xml document, tagName is the
20     associated xml tag, and data is the values in the tag.
21     """
22 jgs 123 t = document.createTextNode(str(data))
23     n = document.createElement(tagName)
24     n.appendChild(t)
25     return n
26 jgs 121
27 jgs 122 def esysDoc():
28 jgs 126 """
29     Global method for creating an instance of an EsysXML document.
30     """
31 jgs 123 doc = minidom.Document()
32     esys = doc.createElement('ESys')
33     doc.appendChild(esys)
34     return doc, esys
35 jgs 121
36 jgs 123 def all(seq):
37     for x in seq:
38     if not x:
39     return False
40     return True
41    
42 jgs 147 def any(seq):
43     for x in seq:
44     if x:
45     return True
46     return False
47    
48 jgs 123 LinkableObjectRegistry = {}
49    
50     def registerLinkableObject(obj_id, o):
51     LinkableObjectRegistry[obj_id] = o
52    
53     LinkRegistry = []
54    
55     def registerLink(obj_id, l):
56     LinkRegistry.append((obj_id,l))
57    
58     def parse(xml):
59 jgs 147 """
60     Generic parse method for EsysXML. Without this, Links don't work.
61     """
62 jgs 123 global LinkRegistry, LinkableObjectRegistry
63     LinkRegistry = []
64     LinkableObjectRegistry = {}
65    
66     doc = minidom.parseString(xml)
67     sim = getComponent(doc.firstChild)
68     for obj_id, link in LinkRegistry:
69     link.target = LinkableObjectRegistry[obj_id]
70    
71     return sim
72    
73     def getComponent(doc):
74 jgs 147 """
75     Used to get components of Simualtions, Models.
76     """
77 jgs 123 for node in doc.childNodes:
78 jgs 147
79 jgs 123 if isinstance(node, minidom.Element):
80     if node.tagName == 'Simulation':
81     if node.getAttribute("type") == 'Simulation':
82     return Simulation.fromDom(node)
83     if node.tagName == 'Model':
84     model_type = node.getAttribute("type")
85     model_subclasses = Model.__subclasses__()
86     for model in model_subclasses:
87     if model_type == model.__name__:
88 jgs 147 return Model.fromDom(node)
89     if node.tagName == 'ParameterSet':
90     parameter_type = node.getAttribute("type")
91     return ParameterSet.fromDom(node)
92 jgs 123 raise "Invalid simulation type, %r" % node.getAttribute("type")
93 jgs 147
94 jgs 123
95     raise ValueError("No Simulation Found")
96    
97    
98 jgs 122 class Link:
99 jgs 123 """
100     a Link makes an attribute of an object callable:
101     o.object()
102     o.a=8
103     l=Link(o,"a")
104     assert l()==8
105     """
106    
107     def __init__(self,target,attribute=None):
108 jgs 126 """
109     creates a link to the object target. If attribute is given, the link is
110 jgs 123 establised to this attribute of the target. Otherwise the attribute is
111 jgs 126 undefined.
112     """
113 jgs 123 self.target = target
114     self.attribute = None
115     self.setAttributeName(attribute)
116    
117     def setAttributeName(self,attribute):
118 jgs 126 """
119     set a new attribute name to be collected from the target object. The
120     target object must have the attribute with name attribute.
121     """
122 jgs 147 if attribute and self.target:
123     if isinstance(self.target,LinkableObject):
124     if not self.target.hasAttribute(attribute):
125     raise AttributeError("%s: target %s has no attribute %s."%(self, self.target, attribute))
126     else:
127     if not hasattr(self.target,attribute):
128     raise AttributeError("%s: target %s has no attribute %s."%(self, self.target, attribute))
129 jgs 123 self.attribute = attribute
130    
131     def hasDefinedAttributeName(self):
132 jgs 126 """
133     returns true if an attribute name is set
134     """
135 jgs 123 return self.attribute != None
136    
137     def __repr__(self):
138 jgs 126 """
139     returns a string representation of the link
140     """
141 jgs 123 if self.hasDefinedAttributeName():
142     return "<Link to attribute %s of %s>" % (self.attribute, self.target)
143     else:
144     return "<Link to target %s>" % self.target
145    
146     def __call__(self,name=None):
147 jgs 126 """
148     returns the value of the attribute of the target object. If the
149     atrribute is callable then the return value of the call is returned.
150     """
151 jgs 123 if name:
152     out=getattr(self.target, name)
153     else:
154     out=getattr(self.target, self.attribute)
155 jgs 121
156 jgs 123 if callable(out):
157     return out()
158     else:
159     return out
160 jgs 121
161 jgs 123 def toDom(self, document, node):
162 jgs 126 """
163     toDom method of Link. Creates a Link node and appends it to the current XML
164     document
165     """
166 jgs 123 link = document.createElement('Link')
167 jgs 147 assert (self.target != None), ("Target was none, name was %r" % self.attribute)
168 jgs 123 link.appendChild(dataNode(document, 'Target', self.target.id))
169     # this use of id will not work for purposes of being able to retrieve the intended
170     # target from the xml later. I need a better unique identifier.
171     assert self.attribute, "You can't xmlify a Link without a target attribute"
172     link.appendChild(dataNode(document, 'Attribute', self.attribute))
173     node.appendChild(link)
174 jgs 121
175 jgs 123 def fromDom(cls, doc):
176     targetid = doc.getElementsByTagName("Target")[0].firstChild.nodeValue.strip()
177     attribute = doc.getElementsByTagName("Attribute")[0].firstChild.nodeValue.strip()
178     l = cls(None, attribute)
179     registerLink(targetid, l)
180     return l
181 jgs 121
182 jgs 123 fromDom = classmethod(fromDom)
183    
184     def writeXML(self,ostream=stdout):
185 jgs 126 """
186     writes an XML representation of self to the output stream ostream.
187 jgs 123 If ostream is nor present the standart output stream is used. If
188 jgs 126 esysheader==True the esys XML header is written
189     """
190 jgs 147 print 'I got to the Link writeXML method'
191 jgs 123 document, rootnode = esysDoc()
192     self.toDom(document, rootnode)
193    
194     ostream.write(document.toprettyxml())
195    
196 jgs 122 class LinkableObject(object):
197 jgs 123 """
198     An object that allows to link its attributes to attributes of other objects
199     via a Link object. For instance
200    
201     p = LinkableObject()
202     p.x = Link(o,"name")
203     print p.x
204    
205     links attribute x of p to the attribute name of object o.
206 jgs 121
207 jgs 123 p.x will contain the current value of attribute name of object o.
208 jgs 121
209 jgs 123 If the value of getattr(o, "name") is callable, p.x will rturn the return
210     value of the call.
211     """
212    
213     number_sequence = itertools.count(100)
214    
215     def __init__(self, debug=False):
216     """ initializes LinkableObject so that we can operate on Links """
217     self.debug = debug
218     self.__linked_attributes={}
219     self.id = self.number_sequence.next()
220    
221     def trace(self, msg):
222     """ If debugging is on, print the message, otherwise do nothing
223     """
224     if self.debug:
225 jgs 147 print "%s: %s"%(str(self),msg)
226 jgs 123
227     def __getattr__(self,name):
228     """returns the value of attribute name. If the value is a Link object the
229     object is called and the return value is returned."""
230     out = self.getAttributeObject(name)
231     if isinstance(out,Link):
232     return out()
233     else:
234     return out
235    
236     def getAttributeObject(self,name):
237     """return the object stored for attribute name."""
238    
239     if self.__dict__.has_key(name):
240     return self.__dict__[name]
241    
242     if self.__linked_attributes.has_key(name):
243     return self.__linked_attributes[name]
244    
245 jgs 147 if self.__class__.__dict__.has_key(name):
246     return self.__class.__dict__[name]
247    
248 jgs 123 raise AttributeError,"No attribute %s."%name
249    
250 jgs 147 def hasAttribute(self,name):
251     """returns True if self as attribute name"""
252     return self.__dict__.has_key(name) or self.__linked_attributes.has_key(name) or self.__class__.__dict__.has_key(name)
253    
254 jgs 123 def __setattr__(self,name,value):
255     """sets the value for attribute name. If value is a Link the target
256     attribute is set to name if no attribute has been specified."""
257    
258    
259     if self.__dict__.has_key(name):
260     del self.__dict__[name]
261    
262     if isinstance(value,Link):
263     if not value.hasDefinedAttributeName():
264     value.setAttributeName(name)
265     self.__linked_attributes[name] = value
266    
267 jgs 147 self.trace("attribute %s is now linked by %s."%(name,value))
268 jgs 123 else:
269     self.__dict__[name] = value
270    
271     def __delattr__(self,name):
272     """removes the attribute name."""
273    
274     if self.__linked_attributes.has_key[name]:
275     del self.__linked_attributes[name]
276     elif self.__dict__.has_key(name):
277     del self.__dict__[name]
278     else:
279     raise AttributeError,"No attribute %s."%name
280    
281 jgs 122 class _ParameterIterator:
282 jgs 123 def __init__(self,parameterset):
283 jgs 121
284 jgs 123 self.__set=parameterset
285     self.__iter=iter(parameterset.parameters)
286    
287     def next(self):
288     o=self.__iter.next()
289     return (o,self.__set.getAttributeObject(o))
290    
291     def __iter__(self):
292     return self
293    
294 jgs 122 class ParameterSet(LinkableObject):
295 jgs 123 """a class which allows to emphazise attributes to be written and read to XML
296    
297     Leaves of an ESySParameters objects can be
298    
299     a real number
300     a integer number
301     a string
302     a boolean value
303     a ParameterSet object
304     a Simulation object
305     a Model object
306     any other object (not considered by writeESySXML and writeXML)
307    
308     Example how to create an ESySParameters object:
309    
310     p11=ParameterSet(gamma1=1.,gamma2=2.,gamma3=3.)
311     p1=ParameterSet(dim=2,tol_v=0.001,output_file="/tmp/u.%3.3d.dx",runFlag=True,parm11=p11)
312     parm=ParameterSet(parm1=p1,parm2=ParameterSet(alpha=Link(p11,"gamma1")))
313    
314     This can be accessed as
315    
316     parm.parm1.gamma=0.
317     parm.parm1.dim=2
318     parm.parm1.tol_v=0.001
319     parm.parm1.output_file="/tmp/u.%3.3d.dx"
320     parm.parm1.runFlag=True
321     parm.parm1.parm11.gamma1=1.
322     parm.parm1.parm11.gamma2=2.
323     parm.parm1.parm11.gamma3=3.
324     parm.parm2.alpha=1. (value of parm.parm1.parm11.gamma1)
325    
326     """
327     def __init__(self, parameters=[], **kwargs):
328     """creates a ParameterSet with parameters parameters"""
329     LinkableObject.__init__(self, **kwargs)
330     self.parameters = set()
331     self.declareParameters(parameters)
332 jgs 147
333     def __repr__(self):
334     return "<%s %r>" % (self.__class__.__name__,
335     [(p, getattr(self, p, None)) for p in self.parameters])
336 jgs 123
337     def declareParameter(self,**parameters):
338     """declares a new parameter(s) and its (their) inital value."""
339     self.declareParameters(parameters)
340    
341     def declareParameters(self,parameters):
342     """declares a set of parameters. parameters can be a list, a dictonary or a ParameterSet."""
343     if isinstance(parameters,ListType):
344     parameters = zip(parameters, itertools.repeat(None))
345     if isinstance(parameters,DictType):
346     parameters = parameters.iteritems()
347 jgs 121
348 jgs 123 for prm, value in parameters:
349     setattr(self,prm,value)
350     self.parameters.add(prm)
351 jgs 121
352 jgs 147 self.trace("parameter %s has been declared."%prm)
353 jgs 121
354 jgs 123 def releaseParameters(self,name):
355     """removes parameter name from the paramameters"""
356     if self.isParameter(name):
357     self.parameters.remove(name)
358 jgs 147 self.trace("parameter %s has been removed."%name)
359 jgs 123
360     def __iter__(self):
361     """creates an iterator over the parameter and their values"""
362     return _ParameterIterator(self)
363    
364     def showParameters(self):
365     """returns a descrition of the parameters"""
366     out="{"
367     notfirst=False
368     for i,v in self:
369     if notfirst: out=out+","
370     notfirst=True
371     if isinstance(v,ParameterSet):
372     out="%s\"%s\" : %s"%(out,i,v.showParameters())
373     else:
374     out="%s\"%s\" : %s"%(out,i,v)
375     return out+"}"
376    
377     def __delattr__(self,name):
378     """removes the attribute name."""
379     LinkableObject.__delattr__(self,name)
380     try:
381     self.releaseParameter(name)
382     except:
383     pass
384 jgs 121
385 jgs 123 def toDom(self, document, node):
386     """ toDom method of ParameterSet class """
387     pset = document.createElement('ParameterSet')
388     node.appendChild(pset)
389     self._parametersToDom(document, pset)
390 jgs 121
391 jgs 123 def _parametersToDom(self, document, node):
392     node.setAttribute ('id', str(self.id))
393     for name,value in self:
394     param = document.createElement('Parameter')
395     param.setAttribute('type', value.__class__.__name__)
396 jgs 121
397 jgs 123 param.appendChild(dataNode(document, 'Name', name))
398 jgs 121
399 jgs 123 val = document.createElement('Value')
400    
401     if isinstance(value,ParameterSet):
402     value.toDom(document, val)
403     param.appendChild(val)
404     elif isinstance(value, Link):
405     value.toDom(document, val)
406     param.appendChild(val)
407     elif isinstance(value,StringType):
408     param.appendChild(dataNode(document, 'Value', value))
409     else:
410     param.appendChild(dataNode(document, 'Value', str(value)))
411    
412     node.appendChild(param)
413    
414     def fromDom(cls, doc):
415    
416     # Define a host of helper functions to assist us.
417     def _children(node):
418     """
419     Remove the empty nodes from the children of this node
420     """
421     return [x for x in node.childNodes
422     if not isinstance(x, minidom.Text) or x.nodeValue.strip()]
423    
424     def _floatfromValue(doc):
425     return float(doc.nodeValue.strip())
426    
427     def _stringfromValue(doc):
428     return str(doc.nodeValue.strip())
429 jgs 126
430     def _intfromValue(doc):
431     return int(doc.nodeValue.strip())
432    
433     def _boolfromValue(doc):
434     return bool(doc.nodeValue.strip())
435    
436 jgs 123 # Mapping from text types in the xml to methods used to process trees of that type
437     ptypemap = {"Simulation": Simulation.fromDom,
438     "Model":Model.fromDom,
439     "ParameterSet":ParameterSet.fromDom,
440     "Link":Link.fromDom,
441     "float":_floatfromValue,
442 jgs 126 "int":_intfromValue,
443 jgs 123 "str":_stringfromValue,
444 jgs 126 "bool":_boolfromValue
445 jgs 123 }
446    
447 jgs 147 # print doc.toxml()
448    
449 jgs 123 parameters = {}
450     for node in _children(doc):
451     ptype = node.getAttribute("type")
452    
453     pname = pvalue = None
454     for childnode in _children(node):
455    
456     if childnode.tagName == "Name":
457     pname = childnode.firstChild.nodeValue.strip()
458    
459     if childnode.tagName == "Value":
460     nodes = _children(childnode)
461     pvalue = ptypemap[ptype](nodes[0])
462    
463     parameters[pname] = pvalue
464    
465     # Create the instance of ParameterSet
466     o = cls()
467     o.declareParameters(parameters)
468     registerLinkableObject(doc.getAttribute("id"), o)
469     return o
470    
471     fromDom = classmethod(fromDom)
472    
473     def writeXML(self,ostream=stdout):
474     """writes the object as an XML object into an output stream"""
475     # ParameterSet(d) with d[Name]=Value
476     document, node = esysDoc()
477     self.toDom(document, node)
478     ostream.write(document.toprettyxml())
479    
480 jgs 147 class Model(ParameterSet):
481     """
482 jgs 121
483 jgs 147 A Model object represents a processess marching over time
484     until a finalizing condition is fullfilled. At each time step an iterative
485     process can be performed and the time step size can be controlled. A Model has
486     the following work flow:
487 jgs 121
488 jgs 147 doInitialization()
489     while not finalize():
490     dt=getSafeTimeStepSize(dt)
491     doStepPreprocessing(dt)
492     while not terminateIteration(): doStep(dt)
493     doStepPostprocessing(dt)
494     doFinalization()
495 jgs 121
496 jgs 147 where doInitialization,finalize, getSafeTimeStepSize, doStepPreprocessing, terminateIteration, doStepPostprocessing, doFinalization
497     are methods of the particular instance of a Model. The default implementations of these methods have to be overwritten by
498     the subclass implementinf a Model.
499 jgs 123
500 jgs 147 """
501 jgs 121
502 jgs 147 UNDEF_DT=1.e300
503 jgs 121
504 jgs 147 def __init__(self,parameters=[],**kwarg):
505     """creates a model
506 jgs 121
507 jgs 147 Just calls the parent constructor.
508     """
509     ParameterSet.__init__(self, parameters=parameters,**kwarg)
510 jgs 121
511 jgs 147 def __str__(self):
512     return "<%s %d>"%(self.__class__,id(self))
513 jgs 121
514 jgs 147 def toDom(self, document, node):
515     """ toDom method of Model class """
516     pset = document.createElement('Model')
517     pset.setAttribute('type', self.__class__.__name__)
518     node.appendChild(pset)
519     self._parametersToDom(document, pset)
520 jgs 121
521 jgs 147 def doInitialization(self):
522     """initializes the time stepping scheme. This function may be overwritten."""
523     pass
524    
525     def getSafeTimeStepSize(self,dt):
526     """returns a time step size which can safely be used.
527     dt gives the previously used step size.
528     This function may be overwritten."""
529     return self.UNDEF_DT
530    
531     def finalize(self):
532     """returns False if the time stepping is finalized. This function may be
533     overwritten."""
534     return False
535 jgs 123
536 jgs 147 def doFinalization(self):
537     """finalizes the time stepping. This function may be overwritten."""
538     pass
539    
540     def doStepPreprocessing(self,dt):
541     """sets up a time step of step size dt. This function may be overwritten."""
542     pass
543    
544     def doStep(self,dt):
545     """executes an iteration step at a time step.
546     dt is the currently used time step size.
547     This function may be overwritten."""
548     pass
549    
550     def terminateIteration(self):
551     """returns True if iteration on a time step is terminated."""
552     return True
553    
554     def doStepPostprocessing(self,dt):
555     """finalalizes the time step.
556     dt is the currently used time step size.
557     This function may be overwritten."""
558     pass
559    
560     def writeXML(self, ostream=stdout):
561     document, node = esysDoc()
562     self.toDom(document, node)
563     ostream.write(document.toprettyxml())
564    
565    
566 jgs 121
567 jgs 147 class Simulation(Model):
568     """
569     A Simulation object is special Model which runs a sequence of Models.
570 jgs 121
571 jgs 147 The methods doInitialization,finalize, getSafeTimeStepSize, doStepPreprocessing,
572     terminateIteration, doStepPostprocessing, doFinalization
573     are executing the corresponding methods of the models in the simulation.
574 jgs 123
575 jgs 147 """
576    
577     FAILED_TIME_STEPS_MAX=20
578     MAX_ITER_STEPS=50
579    
580     def __init__(self, models=[], **kwargs):
581     """initiates a simulation from a list of models. """
582     Model.__init__(self, **kwargs)
583     self.__models=[]
584 jgs 121
585 jgs 147 for i in range(len(models)):
586     self[i] = models[i]
587 jgs 121
588 jgs 147 def __repr__(self):
589     """
590     returns a string representation of the Simulation
591     """
592     return "<Simulation %r>" % self.__models
593 jgs 121
594 jgs 147 def __str__(self):
595     """
596     returning Simulation as a string
597     """
598     return "<Simulation %d>"%id(self)
599    
600     def iterModels(self):
601     """returns an iterator over the models"""
602     return self.__models
603    
604     def __getitem__(self,i):
605     """returns the i-th model"""
606     return self.__models[i]
607    
608     def __setitem__(self,i,value):
609     """sets the i-th model"""
610     if not isinstance(value,Model):
611     raise ValueError("assigned value is not a Model")
612     for j in range(max(i-len(self.__models)+1,0)): self.__models.append(None)
613     self.__models[i]=value
614    
615     def __len__(self):
616     """returns the number of models"""
617     return len(self.__models)
618 jgs 121
619 jgs 147 def toDom(self, document, node):
620     """ toDom method of Simulation class """
621     simulation = document.createElement('Simulation')
622     simulation.setAttribute('type', self.__class__.__name__)
623 jgs 121
624 jgs 147 for rank, sim in enumerate(self.iterModels()):
625     component = document.createElement('Component')
626     component.setAttribute('rank', str(rank))
627 jgs 121
628 jgs 147 sim.toDom(document, component)
629 jgs 121
630 jgs 147 simulation.appendChild(component)
631 jgs 121
632 jgs 147 node.appendChild(simulation)
633 jgs 121
634 jgs 147 def writeXML(self,ostream=stdout):
635     """writes the object as an XML object into an output stream"""
636     document, rootnode = esysDoc()
637     self.toDom(document, rootnode)
638     ostream.write(document.toprettyxml())
639    
640     def getSafeTimeStepSize(self,dt):
641     """returns a time step size which can safely be used by all models.
642     This is the minimum over the time step sizes of all models."""
643     out=min([o.getSafeTimeStepSize(dt) for o in self.iterModels()])
644     print "%s: safe step size is %e."%(str(self),out)
645     return out
646    
647     def doInitialization(self):
648     """initializes all models """
649     self.n=0
650     self.tn=0.
651     for o in self.iterModels():
652     o.doInitialization()
653    
654     def finalize(self):
655     """returns True if any of the models is to be finalized"""
656     return any([o.finalize() for o in self.iterModels()])
657 jgs 123
658 jgs 147 def doFinalization(self):
659     """finalalizes the time stepping for all models."""
660     for i in self.iterModels(): i.doFinalization()
661     self.trace("end of time integation.")
662    
663     def doStepPreprocessing(self,dt):
664     """initializes the time step for all models."""
665     for o in self.iterModels():
666     o.doStepPreprocessing(dt)
667    
668     def terminateIteration(self):
669     """returns True if all iterations for all models are terminated."""
670     out=all([o.terminateIteration() for o in self.iterModels()])
671     return out
672 jgs 123
673 jgs 147 def doStepPostprocessing(self,dt):
674     """finalalizes the iteration process for all models."""
675     for o in self.iterModels():
676     o.doStepPostprocessing(dt)
677     self.n+=1
678     self.tn+=dt
679    
680     def doStep(self,dt):
681     """
682     executes the iteration step at a time step for all model:
683    
684     self.doStepPreprocessing(dt)
685     while not self.terminateIteration(): for all models: self.doStep(dt)
686     self.doStepPostprocessing(dt)
687 jgs 121
688 jgs 147 """
689     self.iter=0
690     while not self.terminateIteration():
691     if self.iter==0: self.trace("iteration at %d-th time step %e starts"%(self.n+1,self.tn+dt))
692     self.iter+=1
693     self.trace("iteration step %d"%(self.iter))
694     for o in self.iterModels():
695     o.doStep(dt)
696     if self.iter>0: self.trace("iteration at %d-th time step %e finalized."%(self.n+1,self.tn+dt))
697 jgs 121
698 jgs 147 def run(self,check_point=None):
699     """
700 jgs 121
701 jgs 147 run the simulation by performing essentially
702 jgs 123
703 jgs 147 self.doInitialization()
704     while not self.finalize():
705     dt=self.getSafeTimeStepSize()
706     self.doStep(dt)
707     if n%check_point==0: self.writeXML()
708     self.doFinalization()
709 jgs 121
710 jgs 147 If one of the models in throws a FailedTimeStepError exception a new time step size is
711     computed through getSafeTimeStepSize() and the time step is repeated.
712 jgs 121
713 jgs 147 If one of the models in throws a IterationDivergenceError exception the time step size
714     is halved and the time step is repeated.
715 jgs 121
716 jgs 147 In both cases the time integration is given up after Simulation.FAILED_TIME_STEPS_MAX
717     attempts.
718 jgs 121
719 jgs 147
720     """
721     dt=self.UNDEF_DT
722     self.doInitialization()
723     while not self.finalize():
724     step_fail_counter=0
725     iteration_fail_counter=0
726     dt_new=self.getSafeTimeStepSize(dt)
727     self.trace("%d. time step %e (step size %e.)" % (self.n+1,self.tn+dt_new,dt_new))
728     end_of_step=False
729     while not end_of_step:
730     end_of_step=True
731     if not dt_new>0:
732     raise NonPositiveStepSizeError("non-positive step size in step %d",self.n+1)
733     try:
734     self.doStepPreprocessing(dt_new)
735     self.doStep(dt_new)
736     self.doStepPostprocessing(dt_new)
737     except IterationDivergenceError:
738     dt_new*=0.5
739     end_of_step=False
740     iteration_fail_counter+=1
741     if iteration_fail_counter>self.FAILED_TIME_STEPS_MAX:
742     raise SimulationBreakDownError("reduction of time step to achieve convergence failed.")
743     self.trace("iteration fails. time step is repeated with new step size.")
744     except FailedTimeStepError:
745     dt_new=self.getSafeTimeStepSize(dt)
746     end_of_step=False
747     step_fail_counter+=1
748     self.trace("time step is repeated.")
749     if step_fail_counter>self.FAILED_TIME_STEPS_MAX:
750     raise SimulationBreakDownError("time integration is given up after %d attempts."%step_fail_counter)
751     dt=dt_new
752     if not check_point==None:
753     if n%check_point==0:
754     self.trace("check point is created.")
755     self.writeXML()
756     self.doFinalization()
757 jgs 121
758 jgs 147 def fromDom(cls, doc):
759     sims = []
760     for node in doc.childNodes:
761     if isinstance(node, minidom.Text):
762     continue
763 jgs 121
764 jgs 147 sims.append(getComponent(node))
765 jgs 121
766 jgs 147 return cls(sims)
767 jgs 121
768 jgs 147 fromDom = classmethod(fromDom)
769 jgs 121
770    
771 jgs 147 class IterationDivergenceError(Exception):
772     """
773     excpetion which is thrown if there is no convergence of the iteration process at a time step
774     but there is a chance taht a smaller step could help to reach convergence.
775 jgs 121
776 jgs 147 """
777     pass
778 jgs 121
779 jgs 147 class FailedTimeStepError(Exception):
780     """excpetion which is thrown if the time step fails because of a step size that have been choosen to be too large"""
781     pass
782 jgs 121
783 jgs 147 class SimulationBreakDownError(Exception):
784     """excpetion which is thrown if the simulation does not manage to progress in time."""
785     pass
786 jgs 121
787 jgs 147 class NonPositiveStepSizeError(Exception):
788     """excpetion which is thrown if the step size is not positive"""
789     pass

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26