source: anuga_work/development/anuga_1d/test_quantity.py @ 7818

Last change on this file since 7818 was 7818, checked in by steve, 13 years ago

working test_quantity

File size: 18.3 KB
RevLine 
[7793]1import quantity
[5536]2#!/usr/bin/env python
3
4import unittest
5from math import sqrt, pi
6
[7793]7
[5536]8from quantity import *
[7793]9from domain import *
[5536]10
[5858]11
[7793]12from Numeric import allclose, array, ones, Float, maximum, zeros
[5536]13
14
15class Test_Quantity(unittest.TestCase):
16    def setUp(self):
[7793]17        self.points3        = [0.0, 1.0, 2.0, 3.0]
18        self.vertex_values3 = [[1.0,2.0],[4.0,5.0],[-1.0,2.0]]
19        self.domain3        = Domain(self.points3)
[5536]20
21
[7793]22       
23        self.points4          = [0.0, 1.0, 2.5, 3.0, 5.0]
24        self.vertex_values4   = [[1.0,2.0],[4.0,5.0],[-1.0,2.0],[3.0,6.0]]
25        self.centroid_values4 = [1.5, 4.5, 0.5, 4.5]
26        self.boundary4        = {(0, 0): 'left', (3, 1): 'right'}
27        self.domain4          = Domain(self.points4,self.boundary4)
[5536]28
[7793]29        self.points10 = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
30        self.domain10 = Domain(self.points10)
[5536]31
[7793]32        self.points6 = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
33        self.domain6 = Domain(self.points6)
[5536]34
35
36    def tearDown(self):
37        pass
38        #print "  Tearing down"
39
40
[7793]41    def test_creat_with_boundary(self):
42
43        assert self.domain4.boundary  == {(0, 0): 'left', (3, 1): 'right'}
44       
[5536]45    def test_creation(self):
46
[7793]47        quantity = Quantity(self.domain3)
48        assert allclose(quantity.vertex_values, [[0.0,0.0],[0.0,0.0],[0.0,0.0]])
[5536]49
[7793]50       
[5536]51        try:
52            quantity = Quantity()
53        except:
54            pass
55        else:
56            raise 'Should have raised empty quantity exception'
57
58
59        try:
60            quantity = Quantity([1,2,3])
61        except AssertionError:
62            pass
63        except:
[7793]64            raise 'Should have raised "mising domain object" error'
[5536]65
66
67    def test_creation_zeros(self):
68
[7793]69        quantity = Quantity(self.domain3)
70        assert allclose(quantity.centroid_values, [[0.,0.,0.]])
[5536]71
72
[7793]73        quantity = Quantity(self.domain4)
74        assert allclose(quantity.vertex_values, [[0.,0.], [0.,0.],
75                                                 [0.,0.], [0.,0.]])
[5536]76
77
78    def test_interpolation(self):
[7793]79        quantity = Quantity(self.domain4, self.vertex_values4)
80        assert allclose(quantity.centroid_values, self.centroid_values4) #Centroid
[5536]81
82
83
84    def test_interpolation2(self):
[7793]85        quantity = Quantity(self.domain4, self.vertex_values4)
86        assert allclose(quantity.centroid_values, self.centroid_values4) #Centroid
[5536]87
88        quantity.extrapolate_second_order()
89
90        #print quantity.vertex_values
[7793]91        assert allclose(quantity.vertex_values,[[ 0.3,  2.7],
92                                                [ 4.5,  4.5],
93                                                [ 0.5,  0.5],
94                                                [ 1.3,  7.7]])
[5536]95
[7793]96 
[5536]97
[7793]98 
99    def test_boundary_allocation(self):
100        quantity = Quantity(self.domain4,
101                            [[1,2], [5,5], [0,9], [-6, 3]])
[5536]102
103
[7793]104        assert quantity.boundary_values.shape[0] == len(self.domain4.boundary)
[5536]105
106
107    def test_set_values(self):
[7793]108        quantity = Quantity(self.domain4)
[5536]109
[7815]110        # Test vertices
111        quantity.set_values([[1,2], [5,5], [0,9], [-6, 3]], location = 'vertices')
[5536]112        assert allclose(quantity.vertex_values,
[7815]113                        [[1,2], [5,5], [0,9], [-6, 3]])
114        assert allclose(quantity.centroid_values, [1.5, 5., 4.5, -1.5]) #Centroid
[5536]115
116
[7815]117
118        # Test unique_vertices
119        quantity.set_values([1,2,4,-5,6], location='unique_vertices')
[5536]120        assert allclose(quantity.vertex_values,
[7815]121                        [[1,2], [2,4], [4,-5], [-5,6]])
122        assert allclose(quantity.centroid_values, [1.5, 3., -.5, .5]) #Centroid
[5536]123
[7815]124
[5536]125        # Test centroids
126        quantity.set_values([1,2,3,4], location = 'centroids')
127        assert allclose(quantity.centroid_values, [1., 2., 3., 4.]) #Centroid
128
129        # Test exceptions
130        try:
[7815]131            quantity.set_values([[1,3], [5,5], [0,9], [-6, 3]],
[5536]132                                location = 'bas kamel tuba')
133        except:
134            pass
135
136
137        try:
[7815]138            quantity.set_values([[1,3], [0,9]])
[5536]139        except AssertionError:
140            pass
141        except:
142            raise 'should have raised Assertionerror'
143
144
145
146    def test_set_values_const(self):
[7793]147        quantity = Quantity(self.domain4)
[5536]148
149        quantity.set_values(1.0, location = 'vertices')
150
[7815]151        assert allclose(quantity.vertex_values, [[1,1], [1,1], [1,1], [1, 1]])
[5536]152        assert allclose(quantity.centroid_values, [1, 1, 1, 1]) #Centroid
153
154
155        quantity.set_values(2.0, location = 'centroids')
[7815]156
[5536]157        assert allclose(quantity.centroid_values, [2, 2, 2, 2])
158
159
160    def test_set_values_func(self):
[7793]161        quantity = Quantity(self.domain4)
[5536]162
[7815]163        def f(x):
164            return x*x
[5536]165
[7815]166
167
[5536]168        quantity.set_values(f, location = 'vertices')
[7815]169
170
[5536]171        assert allclose(quantity.vertex_values,
[7815]172                        [[0,1], [1,6.25], [6.25,9], [9,25]])
173
[5536]174        assert allclose(quantity.centroid_values,
[7815]175                        [0.5, 3.625, 7.625, 34*0.5])
[5536]176
177
178        quantity.set_values(f, location = 'centroids')
[7815]179
180       
[5536]181        assert allclose(quantity.centroid_values,
[7815]182                        [0.25, 3.0625, 7.5625, 16.0])
[5536]183
184
185    def test_integral(self):
[7793]186        quantity = Quantity(self.domain4)
[5536]187
188        #Try constants first
189        const = 5
190        quantity.set_values(const, location = 'vertices')
191        #print 'Q', quantity.get_integral()
192
[7793]193        assert allclose(quantity.get_integral(), self.domain4.get_area() * const)
[5536]194
195        #Try with a linear function
[7793]196        def f(x):
197            return x
[5536]198
199        quantity.set_values(f, location = 'vertices')
200
[7793]201 
202        assert allclose (quantity.centroid_values,
203        [ 0.5,   1.75,  2.75,  4.  ])
[5536]204
[7793]205        assert allclose (quantity.vertex_values, [[ 0.,   1. ],
206                                                  [ 1.,   2.5],
207                                                  [ 2.5,  3. ],
208                                                  [ 3.,   5. ]])
[5536]209
[7793]210
211        ref_integral = 0.5 + 1.5*1.75 + 0.5*2.75 + 2.0*4.0
212
[5536]213        assert allclose (quantity.get_integral(), ref_integral)
214
215
216
217
218
219    def test_set_values_from_quantity(self):
220
[7793]221        quantity1 = Quantity(self.domain4)
[7815]222        quantity1.set_values([0,1,2,3,4], location='unique_vertices')
[5536]223
224        assert allclose(quantity1.vertex_values,
[7815]225                        [[0,1], [1,2], [2,3], [3,4]])
[5536]226
227
[7793]228        quantity2 = Quantity(self.domain4)
[7815]229        quantity2.set_values(quantity1)
[5536]230        assert allclose(quantity2.vertex_values,
[7815]231                        [[0,1], [1,2], [2,3], [3,4]])
[5536]232
[7815]233        quantity2.set_values(2*quantity1)
[5536]234
235        assert allclose(quantity2.vertex_values,
[7815]236                        [[0,2], [2,4], [4,6], [6,8]])
[5536]237
238        quantity2.set_values(2*quantity1 + 3)
239        assert allclose(quantity2.vertex_values,
[7815]240                        [[3,5], [5,7], [7,9], [9,11]])
[5536]241
242
243
244    def test_overloading(self):
245
[7793]246        quantity1 = Quantity(self.domain4)
247        quantity1.set_values( [[0,1],[1,2],[2,3],[3,4]],
248                            location = 'vertices')
[5536]249
250        assert allclose(quantity1.vertex_values,
[7793]251                        [[0,1], [1,2], [2,3], [3,4]])
[5536]252
253
[7793]254        quantity2 = Quantity(self.domain4)
255        quantity2.set_values([[1,2], [5,5], [0,9], [-6, 3]],
[5536]256                             location = 'vertices')
257
258
259
[7793]260        quantity3 = Quantity(self.domain4)
261        quantity3.set_values([[2,2], [7,8], [7,6], [3, -8]],
[5536]262                             location = 'vertices')
263
264
265        # Negation
266        Q = -quantity1
267        assert allclose(Q.vertex_values, -quantity1.vertex_values)
268        assert allclose(Q.centroid_values, -quantity1.centroid_values)
269
[7793]270
[5536]271        # Addition
272        Q = quantity1 + 7
273        assert allclose(Q.vertex_values, quantity1.vertex_values + 7)
274        assert allclose(Q.centroid_values, quantity1.centroid_values + 7)
275
276        Q = 7 + quantity1
277        assert allclose(Q.vertex_values, quantity1.vertex_values + 7)
278        assert allclose(Q.centroid_values, quantity1.centroid_values + 7)
279
280        Q = quantity1 + quantity2
281        assert allclose(Q.vertex_values,
282                        quantity1.vertex_values + quantity2.vertex_values)
283        assert allclose(Q.centroid_values,
284                        quantity1.centroid_values + quantity2.centroid_values)
285
286        Q = quantity1 + quantity2 - 3
287        assert allclose(Q.vertex_values,
288                        quantity1.vertex_values + quantity2.vertex_values - 3)
289
290        Q = quantity1 - quantity2
291        assert allclose(Q.vertex_values,
292                        quantity1.vertex_values - quantity2.vertex_values)
293
294        #Scaling
295        Q = quantity1*3
296        assert allclose(Q.vertex_values, quantity1.vertex_values*3)
297        assert allclose(Q.centroid_values, quantity1.centroid_values*3)
[7793]298
[5536]299        Q = 3*quantity1
300        assert allclose(Q.vertex_values, quantity1.vertex_values*3)
301
302        #Multiplication
303        Q = quantity1 * quantity2
304        assert allclose(Q.vertex_values,
305                        quantity1.vertex_values * quantity2.vertex_values)
306
307        #Linear combinations
308        Q = 4*quantity1 + 2
309        assert allclose(Q.vertex_values,
310                        4*quantity1.vertex_values + 2)
311
312        Q = quantity1*quantity2 + 2
313        assert allclose(Q.vertex_values,
314                        quantity1.vertex_values * quantity2.vertex_values + 2)
315
316        Q = quantity1*quantity2 + quantity3
317        assert allclose(Q.vertex_values,
318                        quantity1.vertex_values * quantity2.vertex_values +
319                        quantity3.vertex_values)
320        Q = quantity1*quantity2 + 3*quantity3
321        assert allclose(Q.vertex_values,
322                        quantity1.vertex_values * quantity2.vertex_values +
323                        3*quantity3.vertex_values)
324        Q = quantity1*quantity2 + 3*quantity3 + 5.0
325        assert allclose(Q.vertex_values,
326                        quantity1.vertex_values * quantity2.vertex_values +
327                        3*quantity3.vertex_values + 5)
328
329        Q = quantity1*quantity2 - quantity3
330        assert allclose(Q.vertex_values,
331                        quantity1.vertex_values * quantity2.vertex_values -
332                        quantity3.vertex_values)
333        Q = 1.5*quantity1*quantity2 - 3*quantity3 + 5.0
334        assert allclose(Q.vertex_values,
335                        1.5*quantity1.vertex_values * quantity2.vertex_values -
336                        3*quantity3.vertex_values + 5)
337
338        #Try combining quantities and arrays and scalars
339        Q = 1.5*quantity1*quantity2.vertex_values -\
340            3*quantity3.vertex_values + 5.0
341        assert allclose(Q.vertex_values,
342                        1.5*quantity1.vertex_values * quantity2.vertex_values -
343                        3*quantity3.vertex_values + 5)
344
345
346        #Powers
347        Q = quantity1**2
348        assert allclose(Q.vertex_values, quantity1.vertex_values**2)
349
350        Q = quantity1**2 +quantity2**2
351        assert allclose(Q.vertex_values,
352                        quantity1.vertex_values**2 + \
353                        quantity2.vertex_values**2)
354
355        Q = (quantity1**2 +quantity2**2)**0.5
356        assert allclose(Q.vertex_values,
357                        (quantity1.vertex_values**2 + \
358                        quantity2.vertex_values**2)**0.5)
359
360    def test_compute_gradient(self):
[7793]361        quantity = Quantity(self.domain6)
[5536]362
363        #Set up for a gradient of (2,0) at mid triangle
[7793]364        quantity.set_values([2.0, 4.0, 4.0, 5.0, 10.0, 12.0],
[5536]365                            location = 'centroids')
366
367
368        #Gradients
369        quantity.compute_gradients()
370
[7793]371        a = quantity.gradients
[5536]372
[7793]373        assert allclose(a, [ 3., 1., 0.5, 3., 3.5, 0.5])
374       
[5536]375        quantity.extrapolate_second_order()
376
377
[7793]378        assert allclose(quantity.vertex_values, [[ 1., 3. ],
379                                                 [ 4., 4. ],
380                                                 [ 4., 4. ],
381                                                 [ 4., 6.],
382                                                 [ 8.25, 11.75],
383                                                 [ 11.,  13. ]])
[5536]384
[7793]385                                                 
[5536]386
387    def test_second_order_extrapolation2(self):
[7793]388        quantity = Quantity(self.domain4)
[5536]389
390        #Set up for a gradient of (3,1), f(x) = 3x+y
391        quantity.set_values([2.0+2.0/3, 4.0+4.0/3, 8.0+2.0/3, 2.0+8.0/3],
392                            location = 'centroids')
393
394        #Gradients
395        quantity.compute_gradients()
396
[7815]397        a = quantity.gradients
[5536]398       
399
[7815]400        assert allclose(a[1], 2.8)
[5536]401
402        #Work out the others
403
404        quantity.extrapolate_second_order()
[7815]405       
[5536]406
[7815]407        assert allclose(quantity.vertex_values[1,0], 3.33333333)
408        assert allclose(quantity.vertex_values[1,1], 7.33333333)
[5536]409
[7815]410        assert allclose(quantity.centroid_values[1], 0.5*(7.33333333+3.33333333) )
[5536]411
412
[7815]413
414
[5536]415    def test_backup_saxpy_centroid_values(self):
[7793]416        quantity = Quantity(self.domain4)
[5536]417
418        #Set up for a gradient of (3,1), f(x) = 3x+y
419        c_values = array([2.0+2.0/3, 4.0+4.0/3, 8.0+2.0/3, 2.0+8.0/3])
420        d_values = array([1.0, 2.0, 3.0, 4.0])
421        quantity.set_values(c_values, location = 'centroids')
422
423        #Backup
424        quantity.backup_centroid_values()
425
426        #print quantity.vertex_values
427        assert allclose(quantity.centroid_values, quantity.centroid_backup_values)
428
429
430        quantity.set_values(d_values, location = 'centroids')
431
432        quantity.saxpy_centroid_values(2.0, 3.0)
433
[7815]434        assert allclose(quantity.centroid_values, 2.0*d_values + 3.0*c_values)
[5536]435
436
437
438    def test_first_order_extrapolator(self):
[7793]439        quantity = Quantity(self.domain4)
[5536]440
[7793]441        centroid_values = array([1.,2.,3.,4.])
442        quantity.set_values(centroid_values, location = 'centroids')
443        assert allclose(quantity.centroid_values, centroid_values) #Centroid
[5536]444
445        #Extrapolate
446        quantity.extrapolate_first_order()
447
448        #Check that gradient is zero
[7793]449        a = quantity.gradients
[5536]450        assert allclose(a, [0,0,0,0])
[7793]451       
[5536]452
453        #Check vertices but not edge values
454        assert allclose(quantity.vertex_values,
[7793]455                        [[1,1], [2,2], [3,3], [4,4]])
[5536]456
457
458    def test_second_order_extrapolator(self):
[7793]459        quantity = Quantity(self.domain4)
[5536]460
461        #Set up for a gradient of (3,0) at mid triangle
462        quantity.set_values([2.0, 4.0, 8.0, 2.0],
463                            location = 'centroids')
464
465
466
467        quantity.extrapolate_second_order()
468
469
470        #Assert that quantities are conserved
[7818]471        from Numeric import sum
[5536]472        for k in range(quantity.centroid_values.shape[0]):
473            assert allclose (quantity.centroid_values[k],
[7815]474                             sum(quantity.vertex_values[k,:])/2.0)
[5536]475
476
[7793]477    def test_limit(self):
478        quantity = Quantity(self.domain4)
[5536]479
480        #Create a deliberate overshoot (e.g. from gradient computation)
[7793]481        quantity.set_values([[0,0], [2,20], [-20,3], [8,3]])
[5536]482
483        #Limit
[7793]484        quantity.limit_minmod()
[5536]485
[7793]486       
487        #cells 1 and 2 are local max and min
488        assert quantity.vertex_values[1][0] == quantity.centroid_values[1]
489        assert quantity.vertex_values[1][1] == quantity.centroid_values[1]
[5536]490
[7793]491        assert quantity.vertex_values[2][0] == quantity.centroid_values[2]
492        assert quantity.vertex_values[2][1] == quantity.centroid_values[2]
[5536]493
494
495
496    def test_distribute_first_order(self):
[7793]497        quantity = Quantity(self.domain4)
[5536]498
499        #Test centroids
[7793]500        centroid_values = array([1.,2.,3.,4.])
501        quantity.set_values(centroid_values, location = 'centroids')
502        assert allclose(quantity.centroid_values, centroid_values) #Centroid
[5536]503
504
505        #Extrapolate from centroid to vertices and edges
506        quantity.extrapolate_first_order()
[7793]507       
508        assert allclose(quantity.vertex_values,[[ 1.,  1.],
509                                                [ 2.,  2.],
510                                                [ 3.,  3.],
511                                                [ 4.,  4.]])
512 
[5536]513
514
515    def test_distribute_second_order(self):
[7793]516        quantity = Quantity(self.domain4)
[5536]517
518        #Test centroids
[7793]519        centroid_values = array([2.,4.,8.,2.])
520        quantity.set_values(centroid_values, location = 'centroids')
521        assert allclose(quantity.centroid_values, centroid_values) #Centroid
[5536]522
523
524        #Extrapolate
525        quantity.extrapolate_second_order()
526
[7793]527        assert allclose(quantity.vertex_values, [[ 1.2,  2.8],
528                                                 [ 2.,  6. ],
529                                                 [ 8.,   8. ],
530                                                 [ 6.8, -2.8]])
[5536]531
532
533    def test_update_explicit(self):
[7793]534        quantity = Quantity(self.domain4)
[5536]535
536        #Test centroids
537        quantity.set_values([1.,2.,3.,4.], location = 'centroids')
538        assert allclose(quantity.centroid_values, [1, 2, 3, 4]) #Centroid
539
540        #Set explicit_update
541        quantity.explicit_update = array( [1.,1.,1.,1.] )
542
543        #Update with given timestep
544        quantity.update(0.1)
545
546        x = array([1, 2, 3, 4]) + array( [.1,.1,.1,.1] )
547        assert allclose( quantity.centroid_values, x)
548
549    def test_update_semi_implicit(self):
[7793]550        quantity = Quantity(self.domain4)
[5536]551
552        #Test centroids
553        quantity.set_values([1.,2.,3.,4.], location = 'centroids')
554        assert allclose(quantity.centroid_values, [1, 2, 3, 4]) #Centroid
555
556        #Set semi implicit update
557        quantity.semi_implicit_update = array([1.,1.,1.,1.])
558
559        #Update with given timestep
560        timestep = 0.1
561        quantity.update(timestep)
562
[7818]563        sem = array([1.,1.,1.,1.])
[5536]564        denom = ones(4, Float)-timestep*sem
565
566        x = array([1, 2, 3, 4])/denom
567        assert allclose( quantity.centroid_values, x)
568
569
570    def test_both_updates(self):
[7793]571        quantity = Quantity(self.domain4)
[5536]572
573        #Test centroids
[7793]574        centroid_values = array( [1, 2, 3, 4] )
575        quantity.set_values(centroid_values, location = 'centroids')
576        assert allclose(quantity.centroid_values, centroid_values) #Centroid
[5536]577
578        #Set explicit_update
[7793]579        explicit_update = array( [4.,3.,2.,1.] )
580        quantity.explicit_update[:] = explicit_update
[5536]581
582        #Set semi implicit update
[7793]583        semi_implicit_update = array( [1.,1.,1.,1.] )
584        quantity.semi_implicit_update[:] = semi_implicit_update
[5536]585
586        #Update with given timestep
587        timestep = 0.1
588        quantity.update(0.1)
589
[7793]590        denom = 1.0-timestep*semi_implicit_update
591        x = (centroid_values + timestep*explicit_update)/denom
592 
[5536]593        assert allclose( quantity.centroid_values, x)
594
595
[7793]596 
[5536]597#-------------------------------------------------------------
598if __name__ == "__main__":
[7818]599    suite = unittest.makeSuite(Test_Quantity, 'test')
[5536]600    runner = unittest.TextTestRunner()
601    runner.run(suite)
Note: See TracBrowser for help on using the repository browser.