source: inundation/ga/storm_surge/pyvolution-1d/test_quantity.py @ 1507

Last change on this file since 1507 was 513, checked in by steve, 20 years ago

Quantities Working

File size: 12.9 KB
Line 
1#!/usr/bin/env python
2
3import unittest
4from math import sqrt, pi
5
6
7from quantity import *
8#from config import epsilon
9from Numeric import allclose, array, zeros, Float
10
11       
12class TestCase(unittest.TestCase):
13    def setUp(self):
14        from domain import Domain
15       
16        a = 0.0
17        b = 1.0
18        c = 2.0
19        d = 2.5
20        e = 3.1
21        f = 4.0
22
23        self.points          = [a, b, c, d, e, f]
24        self.centroids       = [(a+b)/2,(b+c)/2,(c+d)/2,(d+e)/2,(e+f)/2]
25        self.vertex_values   = [[1.0,2.0],[2.0,3.0],[3.0,4.0],[4.5,5],[5.5,5.6]]
26        self.centroid_values = [[1.5,      2.5,      3.5,      4.75,   5.55]]
27
28        self.domain1 = Domain(self.points[0:2])
29        self.domain5 = Domain(self.points)
30       
31    def tearDown(self):
32        pass
33        #print "  Tearing down"
34
35
36    def test_creation(self):
37       
38        quantity = Quantity(self.domain5, self.vertex_values)
39        assert allclose(quantity.centroid_values, self.centroid_values)
40
41        try:
42            quantity = Quantity()
43        except:
44            pass
45        else:
46            raise 'Should have raised empty quantity exception'
47
48
49        try:
50            quantity = Quantity([1,2])
51        except AssertionError:
52            pass
53        except:
54            raise 'Should have raised "missing domain object" error'       
55       
56
57    def test_creation_zeros(self):
58       
59        quantity = Quantity(self.domain1)
60        assert allclose(quantity.vertex_values, [[0.,0.]])
61
62
63        quantity = Quantity(self.domain5)
64        assert allclose(quantity.vertex_values, [[0.,0.], [0.,0.],
65                                                 [0.,0.], [0.,0.],
66                                                 [0.,0.]])       
67
68       
69    def test_interpolation(self):
70        quantity = Quantity(self.domain1, [[1,2]])
71        assert allclose(quantity.centroid_values, 1.5) #Centroid
72
73
74    def test_interpolation2(self):
75        quantity = Quantity(self.domain5,
76                            [[1,2], [5,5], [0,9], [-6, 3], [3,4]])
77        assert allclose(quantity.centroid_values, [1.5, 5., 4.5, -1.5, 3.5 ]) #Centroid
78
79    def test_set_values(self):
80        quantity = Quantity(self.domain5)
81
82
83        quantity.set_values([[1,2], [5,5], [0,0], [-6, 3], [-2,4]],
84                            location = 'vertices')
85        assert allclose(quantity.vertex_values,
86                        [[1,2], [5,5], [0,0], [-6, 3], [-2,4]])
87        assert allclose(quantity.centroid_values, [1.5, 5., 0., -1.5, 1.0]) #Centroid
88
89        #Test default
90        quantity.set_values([[1,2], [5,5], [0,0], [-6, 3], [-2,4]])
91        assert allclose(quantity.vertex_values,
92                        [[1,2], [5,5], [0,0], [-6, 3], [-2,4]])       
93        assert allclose(quantity.centroid_values, [1.5, 5., 0., -1.5, 1.0]) #Centroid
94
95        #Test centroids
96        quantity.set_values([1,2,3,4,5], location = 'centroids')
97        assert allclose(quantity.centroid_values, [1., 2., 3., 4., 5.]) #Centroid
98
99        #Test exceptions
100        try:
101            quantity.set_values([[1,2], [5,5], [0,0], [-6, 3], [-2,4]],
102                                location = 'bas kamel tuba')
103        except:
104            pass
105
106
107        try:
108            quantity.set_values([[1,2], [0,0]])
109        except AssertionError:
110            pass
111        except:
112            raise 'should have raised AssertionError'
113
114    def test_set_values_const(self):
115        quantity = Quantity(self.domain5)
116
117        quantity.set_values(1.0, location = 'vertices')
118        assert allclose(quantity.vertex_values,
119                        [[1,1], [1,1], [1,1], [1,1], [1,1]])
120        assert allclose(quantity.centroid_values, [1, 1, 1, 1, 1]) #Centroid
121
122
123        quantity.set_values(2.0, location = 'centroids')
124        assert allclose(quantity.centroid_values, [2, 2, 2, 2, 2])
125
126
127    def test_set_values_func(self):
128        quantity = Quantity(self.domain5)
129
130        def f(x):
131            return x**2
132
133        quantity.set_values(f, location = 'vertices')
134        assert allclose(quantity.vertex_values,
135                        [[0,1], [1,4], [4,6.25], [6.25,9.61], [9.61,16]])       
136        assert allclose(quantity.centroid_values,
137                        [0.5, 2.5, 5.125, 7.93, 12.805 ])
138       
139        quantity.set_values(f, location = 'centroids')
140        assert allclose(quantity.centroid_values,
141                        [0.25, 1.5**2, 2.25**2, 2.8**2, 3.55**2])       
142
143
144    def test_gradient(self):
145       
146        quantity = Conserved_quantity(self.domain5)
147
148        #Set up for a gradient of (3,0) at mid triangle
149        quantity.set_values([2.0, 4.0, 8.0, 2.0, 5.0],
150                            location = 'centroids')
151       
152        #Gradients
153        quantity.compute_gradients()
154        N = quantity.gradients.shape[0]
155       
156        G = quantity.gradients
157        G0 = zeros(N, Float)
158        Q = quantity.centroid_values
159        X = quantity.domain.centroids
160
161        def grad0(x0,x1,x2,q0,q1,q2):
162            return ((q0-q1)/(x0-x1)*(x2-x1) - (q2-q1)/(x2-x1)*(x0-x1))/(x2-x0)
163
164        def grad1(x0,x1,q0,q1):
165            return  (q1 - q0)/(x1 - x0)
166
167        #Check Gradients
168        G0[0] = grad1(X[0],X[1],Q[0],Q[1])
169        for i in range(1,4):
170            G0[i] = grad0(X[i-1],X[i],X[i+1],Q[i-1],Q[i],Q[i+1])
171        G0[4] = grad1(X[3],X[4],Q[3],Q[4])
172
173        assert allclose(G,G0)
174
175        quantity.extrapolate_first_order()
176       
177        assert allclose(quantity.vertex_values, [[2., 2.],
178                                                 [4., 4.],
179                                                 [8., 8.],
180                                                 [2., 2.],
181                                                 [5., 5.]])
182
183        quantity.extrapolate_second_order()
184
185        V = quantity.domain.vertices
186        for k in range(quantity.domain.number_of_elements):
187            G0[k] = G0[k]*(V[k,1]-V[k,0])*0.5
188
189        assert allclose(quantity.vertex_values, [[2.-G0[0], 2.+G0[0]],
190                                                 [4.-G0[1], 4.+G0[1]],
191                                                 [8.-G0[2], 8.+G0[2]],
192                                                 [2.-G0[3], 2.+G0[3]],
193                                                 [5.-G0[4], 5.+G0[4]]])
194
195
196
197    def test_second_order_extrapolation2(self):
198        quantity = Conserved_quantity(self.domain5)       
199
200        #Set up for a gradient of (2), f(x) = 2x
201        quantity.set_values([1., 3., 4.5, 5.6, 7.1],
202                            location = 'centroids')
203       
204        #Gradients
205        quantity.compute_gradients()
206        G = quantity.gradients
207       
208        allclose(G, 2.0)
209
210        quantity.extrapolate_second_order()
211
212        V = quantity.domain.vertices
213        Q = quantity.vertex_values
214       
215        assert allclose(Q[:,0], 2.0*V[:,0])
216        assert allclose(Q[:,1], 2.0*V[:,1])       
217
218
219
220
221
222       
223
224
225##     def test_first_order_extrapolator(self):
226##         quantity = Conserved_quantity(self.mesh4)               
227
228##         #Test centroids
229##         quantity.set_values([1.,2.,3.,4.], location = 'centroids')
230##         assert allclose(quantity.centroid_values, [1, 2, 3, 4]) #Centroid
231
232##         #Extrapolate
233##         quantity.extrapolate_first_order()
234
235##         #Check vertices but not edge values
236##         assert allclose(quantity.vertex_values,
237##                         [[1,1,1], [2,2,2], [3,3,3], [4, 4, 4]])
238
239
240    def test_second_order_limit_extrapolator(self):
241        quantity = Conserved_quantity(self.domain5)                       
242
243        #Set up for a gradient of (3,0) at mid triangle
244        quantity.set_values([2.0, 4.0, 8.0, 2.0, 0.0],
245                            location = 'centroids')
246       
247        quantity.extrapolate_second_order()
248        quantity.limit()
249
250        #Assert that central triangle is limited by neighbours
251        assert quantity.vertex_values[0,0] >= 2.0
252        assert quantity.vertex_values[0,0] <= 4.0
253        assert quantity.vertex_values[0,1] >= 2.0
254        assert quantity.vertex_values[0,1] <= 4.0
255       
256        assert quantity.vertex_values[1,0] >= 2.0
257        assert quantity.vertex_values[1,0] <= 8.0
258        assert quantity.vertex_values[1,1] >= 2.0
259        assert quantity.vertex_values[1,1] <= 8.0
260
261        assert quantity.vertex_values[2,0] >= 2.0
262        assert quantity.vertex_values[2,0] <= 8.0
263        assert quantity.vertex_values[2,1] >= 2.0
264        assert quantity.vertex_values[2,1] <= 8.0
265
266        assert quantity.vertex_values[3,0] >= 0.0
267        assert quantity.vertex_values[3,0] <= 8.0
268        assert quantity.vertex_values[3,1] >= 0.0
269        assert quantity.vertex_values[3,1] <= 8.0
270
271        assert quantity.vertex_values[4,0] >= 0.0
272        assert quantity.vertex_values[4,0] <= 2.0
273        assert quantity.vertex_values[4,1] >= 0.0
274        assert quantity.vertex_values[4,1] <= 2.0
275
276        #Assert that quantities are conserved
277        from Numeric import sum
278        for k in range(quantity.centroid_values.shape[0]):
279            assert allclose (quantity.centroid_values[k],
280                             sum(quantity.vertex_values[k,:])/2)
281       
282       
283       
284
285    def test_limiter(self):
286        quantity = Conserved_quantity(self.domain5)
287
288        #Create a deliberate overshoot (e.g. from gradient computation)
289        quantity.set_values([[3,4], [5,5], [0,0], [-6, 3], [-2,4]],
290                            location = 'vertices')       
291
292        #Limit
293        quantity.limit()
294
295        #Assert that central triangle is limited by neighbours
296        assert quantity.vertex_values[0,1] >= quantity.centroid_values[0]
297        assert quantity.vertex_values[1,0] <= quantity.centroid_values[1]
298       
299        assert quantity.vertex_values[1,1] >= quantity.centroid_values[1]
300
301       
302        #Assert that quantities are conserved
303        from Numeric import sum
304        for k in range(quantity.centroid_values.shape[0]):
305            assert allclose (quantity.centroid_values[k],
306                             sum(quantity.vertex_values[k,:])/2)
307       
308
309
310##     def test_distribute_first_order(self):
311##         quantity = Conserved_quantity(self.mesh4)       
312
313##         #Test centroids
314##         quantity.set_values([1.,2.,3.,4.], location = 'centroids')
315##         assert allclose(quantity.centroid_values, [1, 2, 3, 4]) #Centroid
316
317
318##         #Extrapolate
319##         quantity.extrapolate_first_order()
320
321##         #Interpolate
322##         quantity.interpolate_from_vertices_to_edges()       
323
324##         assert allclose(quantity.vertex_values,
325##                         [[1,1,1], [2,2,2], [3,3,3], [4, 4, 4]])
326##         assert allclose(quantity.edge_values, [[1,1,1], [2,2,2],
327##                                                [3,3,3], [4, 4, 4]])
328
329
330
331    def test_update_explicit(self):
332        quantity = Conserved_quantity(self.domain5)
333
334        #Test centroids
335        quantity.set_values([1.,2.,3.,4.,5.], location = 'centroids')
336        assert allclose(quantity.centroid_values, [1, 2, 3, 4, 5]) #Centroid
337
338        #Set explicit_update
339        quantity.explicit_update = array( [1.,1.,1.,1.,1.] )
340
341        #Update with given timestep
342        quantity.update(0.1)
343
344        x = array([1, 2, 3, 4, 5]) + array( [.1,.1,.1,.1,.1] )
345        assert allclose( quantity.centroid_values, x)
346
347    def test_update_semi_implicit(self):
348        quantity = Conserved_quantity(self.domain5)
349
350        #Test centroids
351        quantity.set_values([1.,2.,3.,4.,5.], location = 'centroids')
352        assert allclose(quantity.centroid_values, [1, 2, 3, 4, 5]) #Centroid
353
354        #Set semi implicit update
355        quantity.semi_implicit_update = array( [1.,1.,1.,1.,1.] )
356
357        #Update with given timestep
358        quantity.update(0.1)
359
360        x = array([1, 2, 3, 4, 5])/array( [.9,.9,.9,.9,.9] )
361        assert allclose( quantity.centroid_values, x)
362
363    def test_both_updates(self):
364        quantity = Conserved_quantity(self.domain5)
365
366        #Test centroids
367        quantity.set_values([1.,2.,3.,4.,5.], location = 'centroids')
368        assert allclose(quantity.centroid_values, [1, 2, 3, 4, 5]) #Centroid
369
370        #Set explicit_update
371        quantity.explicit_update = array( [4.,3.,2.,1.,0.0] )
372       
373        #Set semi implicit update
374        quantity.semi_implicit_update = array( [1.,1.,1.,1.,1.] )
375
376        #Update with given timestep
377        quantity.update(0.1)
378
379        x = array([1, 2, 3, 4, 5]) + array( [.4,.3,.2,.1,0.0] )
380        x /= array( [.9,.9,.9,.9,.9] )
381        assert allclose( quantity.centroid_values, x)       
382
383       
384       
385#-------------------------------------------------------------
386if __name__ == "__main__":
387    suite = unittest.makeSuite(TestCase,'test')
388    runner = unittest.TextTestRunner(verbosity=2)
389    runner.run(suite)
390
391
Note: See TracBrowser for help on using the repository browser.