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

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

Quantities Working

File size: 12.9 KB
RevLine 
[256]1#!/usr/bin/env python
2
3import unittest
4from math import sqrt, pi
5
6
7from quantity import *
8#from config import epsilon
[335]9from Numeric import allclose, array, zeros, Float
[256]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
[279]79    def test_set_values(self):
80        quantity = Quantity(self.domain5)
[256]81
82
[279]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
[256]88
[279]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
[256]94
[279]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
[256]98
[513]99        #Test exceptions
[279]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
[256]105
106
[279]107        try:
108            quantity.set_values([[1,2], [0,0]])
109        except AssertionError:
110            pass
111        except:
112            raise 'should have raised AssertionError'
[256]113
[279]114    def test_set_values_const(self):
115        quantity = Quantity(self.domain5)
[256]116
[279]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
[256]121
122
[279]123        quantity.set_values(2.0, location = 'centroids')
124        assert allclose(quantity.centroid_values, [2, 2, 2, 2, 2])
[256]125
126
[279]127    def test_set_values_func(self):
128        quantity = Quantity(self.domain5)
[256]129
[279]130        def f(x):
131            return x**2
[256]132
[279]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 ])
[256]138       
[279]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])       
[256]142
143
[335]144    def test_gradient(self):
145       
146        quantity = Conserved_quantity(self.domain5)
[256]147
[335]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')
[256]151       
[335]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
[256]160
[335]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)
[256]163
[335]164        def grad1(x0,x1,q0,q1):
165            return  (q1 - q0)/(x1 - x0)
[256]166
[335]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])
[256]172
[335]173        assert allclose(G,G0)
[256]174
[335]175        quantity.extrapolate_first_order()
[256]176       
[335]177        assert allclose(quantity.vertex_values, [[2., 2.],
178                                                 [4., 4.],
179                                                 [8., 8.],
180                                                 [2., 2.],
181                                                 [5., 5.]])
[256]182
[335]183        quantity.extrapolate_second_order()
[256]184
[335]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
[256]188
[335]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]]])
[256]194
195
196
[335]197    def test_second_order_extrapolation2(self):
198        quantity = Conserved_quantity(self.domain5)       
[256]199
[335]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')
[256]203       
[335]204        #Gradients
205        quantity.compute_gradients()
206        G = quantity.gradients
[256]207       
[335]208        allclose(G, 2.0)
[256]209
[335]210        quantity.extrapolate_second_order()
[256]211
[335]212        V = quantity.domain.vertices
213        Q = quantity.vertex_values
[256]214       
[335]215        assert allclose(Q[:,0], 2.0*V[:,0])
216        assert allclose(Q[:,1], 2.0*V[:,1])       
[256]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
[335]240    def test_second_order_limit_extrapolator(self):
241        quantity = Conserved_quantity(self.domain5)                       
[256]242
[335]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')
[256]246       
[335]247        quantity.extrapolate_second_order()
248        quantity.limit()
[256]249
[335]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
[256]255       
[335]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
[256]275
[335]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)
[256]281       
282       
283       
284
[335]285    def test_limiter(self):
286        quantity = Conserved_quantity(self.domain5)
[256]287
[335]288        #Create a deliberate overshoot (e.g. from gradient computation)
[513]289        quantity.set_values([[3,4], [5,5], [0,0], [-6, 3], [-2,4]],
290                            location = 'vertices')       
[256]291
[335]292        #Limit
293        quantity.limit()
[256]294
[335]295        #Assert that central triangle is limited by neighbours
[513]296        assert quantity.vertex_values[0,1] >= quantity.centroid_values[0]
297        assert quantity.vertex_values[1,0] <= quantity.centroid_values[1]
[256]298       
[513]299        assert quantity.vertex_values[1,1] >= quantity.centroid_values[1]
[256]300
301       
[335]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],
[513]306                             sum(quantity.vertex_values[k,:])/2)
[256]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
[296]331    def test_update_explicit(self):
332        quantity = Conserved_quantity(self.domain5)
[256]333
[296]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
[256]337
[296]338        #Set explicit_update
339        quantity.explicit_update = array( [1.,1.,1.,1.,1.] )
[256]340
[296]341        #Update with given timestep
342        quantity.update(0.1)
[256]343
[296]344        x = array([1, 2, 3, 4, 5]) + array( [.1,.1,.1,.1,.1] )
345        assert allclose( quantity.centroid_values, x)
[256]346
[296]347    def test_update_semi_implicit(self):
348        quantity = Conserved_quantity(self.domain5)
[256]349
[296]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
[256]353
[296]354        #Set semi implicit update
355        quantity.semi_implicit_update = array( [1.,1.,1.,1.,1.] )
[256]356
[296]357        #Update with given timestep
358        quantity.update(0.1)
[256]359
[296]360        x = array([1, 2, 3, 4, 5])/array( [.9,.9,.9,.9,.9] )
361        assert allclose( quantity.centroid_values, x)
[256]362
[296]363    def test_both_updates(self):
364        quantity = Conserved_quantity(self.domain5)
[256]365
[296]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
[256]369
[296]370        #Set explicit_update
371        quantity.explicit_update = array( [4.,3.,2.,1.,0.0] )
[256]372       
[296]373        #Set semi implicit update
374        quantity.semi_implicit_update = array( [1.,1.,1.,1.,1.] )
[256]375
[296]376        #Update with given timestep
377        quantity.update(0.1)
[256]378
[296]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)       
[256]382
383       
384       
385#-------------------------------------------------------------
386if __name__ == "__main__":
387    suite = unittest.makeSuite(TestCase,'test')
[513]388    runner = unittest.TextTestRunner(verbosity=2)
[256]389    runner.run(suite)
390
391
Note: See TracBrowser for help on using the repository browser.