1 |
#!/usr/bin/python |
2 |
|
3 |
|
4 |
import unittest |
5 |
from modelframe import * |
6 |
import math |
7 |
from cStringIO import StringIO |
8 |
from xml.dom import minidom |
9 |
|
10 |
class XMLDocumentTestCase(unittest.TestCase): |
11 |
|
12 |
def setUp(self): |
13 |
|
14 |
o1=ODETEST(debug=False) |
15 |
o1.u=10 |
16 |
o2=ODETEST(debug=False) |
17 |
o2.u=-10. |
18 |
o1.f=Link(o2,"u") |
19 |
o2.f=Link(o1,"u") |
20 |
m=Messenger() |
21 |
o1.dt=0.01 |
22 |
m.message=Link(o1) |
23 |
s=ExplicitSimulation([Simulation([o1,o2],debug=False),m],debug=False) |
24 |
s.run() |
25 |
output = StringIO() |
26 |
s.writeXML(output) |
27 |
output.reset() |
28 |
outputList = output.readlines() |
29 |
self.xmlList = outputList |
30 |
|
31 |
def testFirstLine(self): |
32 |
firstLine = self.xmlList[0] |
33 |
self.assertEqual('<?xml version="1.0" ?>\n', firstLine) |
34 |
|
35 |
def testEsysHeader(self): |
36 |
header = self.xmlList[1] |
37 |
self.assertEqual('<ESys>\n', header) |
38 |
|
39 |
def testEsysFooter(self): |
40 |
footer = self.xmlList[-1] |
41 |
self.assertEqual('</ESys>\n', footer) |
42 |
|
43 |
def testSimulationHeader(self): |
44 |
pass |
45 |
|
46 |
def testSimulationFooter(self): |
47 |
pass |
48 |
|
49 |
class SimulationTestCase(unittest.TestCase): |
50 |
def setUp(self): |
51 |
o1=ODETEST(debug=False) |
52 |
o1.u=10 |
53 |
o2=ODETEST(debug=False) |
54 |
o2.u=-10. |
55 |
o1.f=Link(o2,"u") |
56 |
o2.f=Link(o1,"u") |
57 |
m=Messenger() |
58 |
o1.dt=0.01 |
59 |
m.message=Link(o1) |
60 |
self.s=s=ExplicitSimulation([Simulation([o1,o2],debug=False),m],debug=False) |
61 |
s.run() |
62 |
output = StringIO() |
63 |
s.writeXML(output) |
64 |
output.reset() |
65 |
self.xml = output.read() |
66 |
|
67 |
def testSimulation(self): |
68 |
assert "<Link" in self.xml, "I should see a link" |
69 |
|
70 |
o = parse(self.xml) |
71 |
output = StringIO() |
72 |
o.writeXML(output) |
73 |
output.reset() |
74 |
xml = output.read() |
75 |
assert '<Link' in xml, "Missing a link! It should be in this!" |
76 |
|
77 |
|
78 |
|
79 |
|
80 |
class LinkTestCase(unittest.TestCase): |
81 |
|
82 |
|
83 |
def setUp(self): |
84 |
|
85 |
self.o1=ODETEST(debug=False) |
86 |
#self.o1.u=10 |
87 |
self.o2=ODETEST(debug=False) |
88 |
self.o2.u=-10. |
89 |
self.o1.f=Link(self.o2,"u") |
90 |
self.o2.f=Link(self.o1,"u") |
91 |
self.o2.declareParameter(child=self.o1) |
92 |
|
93 |
def testLinkCreation(self): |
94 |
self.o1.f=Link(self.o2,"u") |
95 |
assert self.o1.f |
96 |
|
97 |
|
98 |
def testLinkValue(self): |
99 |
self.assertEqual(self.o1.f, -10) |
100 |
|
101 |
def testLinkTarget(self): |
102 |
pass |
103 |
|
104 |
def testLinkDefaultAttribute(self): |
105 |
Link(self.o2) |
106 |
|
107 |
def testLinkXML(self): |
108 |
s = StringIO() |
109 |
self.o2.writeXML(s) |
110 |
s.reset() |
111 |
xmlout = s.read() |
112 |
assert '<Link' in xmlout |
113 |
|
114 |
def testLinkTargetXML(self): |
115 |
pass |
116 |
|
117 |
class ParamaterSetTestCase(unittest.TestCase): |
118 |
|
119 |
|
120 |
def setUp(self): |
121 |
self.p = ParameterSet() |
122 |
self.p.declareParameter(gamma1=1.,gamma2=2.,gamma3=3.) |
123 |
|
124 |
def testParameterSetCreation(self): |
125 |
self.assertEqual(self.p.gamma1, 1.) |
126 |
|
127 |
def testParameterSetXMLCreation(self): |
128 |
s = StringIO() |
129 |
self.p.writeXML(s) |
130 |
s.reset() |
131 |
xmlout = s.read() |
132 |
assert ("gamma1" in xmlout) |
133 |
assert ("gamma2" in xmlout) |
134 |
assert ("gamma3" in xmlout) |
135 |
parsable = minidom.parseString(xmlout) |
136 |
assert parsable.getElementsByTagName("ParameterSet") |
137 |
|
138 |
def testParameterSetFromXML(self): |
139 |
doc = self._dom() |
140 |
pset = ParameterSet.fromDom(doc.getElementsByTagName("ParameterSet")[0]) |
141 |
assert (isinstance(pset, ParameterSet)) |
142 |
self.assertEqual(self.p.gamma1,pset.gamma1) |
143 |
|
144 |
|
145 |
def testParameterSetWithChildrenFromXML(self): |
146 |
p2 = ParameterSet() |
147 |
p2.declareParameter(s="abc", f=3.) |
148 |
self.p.declareParameter(child=p2) |
149 |
doc = self._dom() |
150 |
pset = ParameterSet.fromDom(doc.getElementsByTagName("ParameterSet")[0]) |
151 |
self.assertEqual(self.p.child.f, pset.child.f) |
152 |
|
153 |
def testParameterSetChild(self): |
154 |
p2 = ParameterSet() |
155 |
p2.declareParameter(s="abc", f=3.) |
156 |
self.p.declareParameter(child=p2) |
157 |
self.assertEqual(self.p.child.s, "abc") |
158 |
self.assertEqual(self.p.child.f, 3.) |
159 |
|
160 |
def _dom(self): |
161 |
s = StringIO() |
162 |
self.p.writeXML(s) |
163 |
s.reset() |
164 |
xmlout = s.read() |
165 |
doc = minidom.parseString(xmlout) |
166 |
return doc |
167 |
|
168 |
class ModeltoDomTestCase(unittest.TestCase): |
169 |
|
170 |
def _dom(self): |
171 |
s = StringIO() |
172 |
self.o1.writeXML(s) |
173 |
s.reset() |
174 |
xmlout = s.read() |
175 |
doc = minidom.parseString(xmlout) |
176 |
return doc |
177 |
|
178 |
def setUp(self): |
179 |
self.o1=ODETEST(debug=False) |
180 |
|
181 |
def testModelExists(self): |
182 |
assert self._dom().getElementsByTagName("Model") |
183 |
#print self._dom().toxml() |
184 |
|
185 |
def testModelhasID(self): |
186 |
assert int(self._dom().getElementsByTagName("Model")[0].getAttribute("id"))>99 |
187 |
|
188 |
class Messenger(Model): |
189 |
def __init__(self, *args, **kwargs): |
190 |
Model.__init__(self, *args, **kwargs) |
191 |
self.declareParameter(message="none") |
192 |
|
193 |
def doInitialization(self,t): |
194 |
self.__t=t |
195 |
#print "I start talking now!" |
196 |
|
197 |
def doStep(self,dt): |
198 |
self.__t+=dt |
199 |
#print "Message (time %e) : %s "%(self.__t,self.message) |
200 |
|
201 |
def doFinalization(self): |
202 |
#print "I have no more to say!" |
203 |
pass |
204 |
|
205 |
|
206 |
|
207 |
class ODETEST(Model): |
208 |
""" implements a solver for the ODE |
209 |
|
210 |
du/dt=a*u+f(t) |
211 |
|
212 |
we use a implicit euler scheme : |
213 |
|
214 |
u_n-u_{n-1}= dt*a u_n + st*f(t_n) |
215 |
|
216 |
to get u_n we run an iterative process |
217 |
|
218 |
u_{n.k}=u_{n-1}+dt*(a u_{n.i-1} + f(t_n)) |
219 |
|
220 |
|
221 |
input for this model are step size dt, end time tend and a value for |
222 |
a, f and initial value for u. we need also a tolerance tol for a |
223 |
stopping criterion. |
224 |
|
225 |
""" |
226 |
|
227 |
def __init__(self, *args, **kwargs): |
228 |
Model.__init__(self, *args, **kwargs) |
229 |
self.declareParameter(tend=1.,dt=0.1,a=0.9,u=10.,f=0.,message="",tol=1.e-8) |
230 |
|
231 |
def doInitialization(self,t): |
232 |
self.__tn=t |
233 |
self.__iter=0 |
234 |
|
235 |
def doIterationInitialization(self,dt): |
236 |
self.__iter=0 |
237 |
self.__u_last=self.u |
238 |
|
239 |
def doIterationStep(self,dt): |
240 |
self.__iter+=1 |
241 |
self.__u_old=self.u |
242 |
self.u=self.__u_last+dt*(self.a*self.__u_old+self.f) |
243 |
|
244 |
def terminate(self): |
245 |
if self.__iter<1: |
246 |
return False |
247 |
else: |
248 |
return abs(self.__u_old-self.u)<self.tol*abs(self.u) |
249 |
|
250 |
def doIterationFinalization(self,dt): |
251 |
self.__tn+=dt |
252 |
self.message="current error = %e"%abs(self.u-10.*math.exp((self.a-1.)*self.__tn)) |
253 |
|
254 |
def getSafeTimeStepSize(self,dt): |
255 |
return min(self.dt,1./(abs(self.a)+1.)) |
256 |
|
257 |
def finalize(self): |
258 |
return self.__tn>=self.tend |
259 |
|
260 |
|
261 |
if __name__ == "__main__": |
262 |
unittest.main() |
263 |
|