source: inundation/ga/storm_surge/pyvolution/test_domain.py @ 700

Last change on this file since 700 was 700, checked in by ole, 19 years ago

Added error message if indices is not a list, array or None. Also fixed up Hobart examples.

File size: 13.6 KB
Line 
1#!/usr/bin/env python
2
3import unittest
4from math import sqrt
5
6from domain import *
7from config import epsilon
8from Numeric import allclose, array, ones, Float
9
10
11def add_to_verts(tag, elements, domain):
12    if tag == "mound":
13        domain.test = "Mound"
14
15
16def set_bottom_friction(tag, elements, domain):
17    if tag == "bottom":
18        #print 'bottom - indexes',elements
19        domain.set_quantity('friction', 0.09, indexes = elements)
20 
21def set_top_friction(tag, elements, domain):
22    if tag == "top":
23        #print 'top - indexes',elements
24        domain.set_quantity('friction', 1., indexes = elements)
25       
26 
27def set_all_friction(tag, elements, domain):
28    if tag == "all":
29        new_values = domain.get_quantity('friction', indexes = elements) + 10.0
30       
31        domain.set_quantity('friction', new_values, indexes = elements)
32                 
33     
34class TestCase(unittest.TestCase):
35    def setUp(self):
36        pass
37
38       
39    def tearDown(self):
40        pass
41
42           
43    def test_simple(self):
44        a = [0.0, 0.0]
45        b = [0.0, 2.0]
46        c = [2.0,0.0]
47        d = [0.0, 4.0]
48        e = [2.0, 2.0]
49        f = [4.0,0.0]
50
51        points = [a, b, c, d, e, f]
52        #bac, bce, ecf, dbe, daf, dae
53        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4], [3,0,5], [3,0,4]]
54
55        conserved_quantities = ['level', 'xmomentum', 'ymomentum']
56        other_quantities = ['elevation', 'friction']
57       
58        domain = Domain(points, vertices, None,
59                        conserved_quantities, other_quantities)       
60        domain.check_integrity()
61
62        for name in conserved_quantities + other_quantities:
63            assert domain.quantities.has_key(name)
64
65
66        assert domain.get_conserved_quantities(0, edge=1) == 0.   
67
68
69    def test_conserved_quantities(self):
70       
71        a = [0.0, 0.0]
72        b = [0.0, 2.0]
73        c = [2.0,0.0]
74        d = [0.0, 4.0]
75        e = [2.0, 2.0]
76        f = [4.0,0.0]
77
78        points = [a, b, c, d, e, f]
79        #bac, bce, ecf, dbe, daf, dae
80        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4], [3,0,5], [3,0,4]]
81
82        domain = Domain(points, vertices, boundary=None,
83                        conserved_quantities =\
84                        ['level', 'xmomentum', 'ymomentum'])
85
86
87        domain.set_quantity('level', [[1,2,3], [5,5,5],
88                                      [0,0,9], [-6, 3, 3],
89                                      [0,0,0], [0,0,0]])       
90
91        domain.set_quantity('xmomentum', [[1,2,3], [5,5,5],
92                                          [0,0,9], [-6, 3, 3],
93                                          [0,0,0], [0,0,0]])       
94
95        domain.check_integrity()
96
97        #Centroids
98        q = domain.get_conserved_quantities(0)
99        assert allclose(q, [2., 2., 0.])
100
101        q = domain.get_conserved_quantities(1)
102        assert allclose(q, [5., 5., 0.])         
103
104        q = domain.get_conserved_quantities(2)
105        assert allclose(q, [3., 3., 0.])
106
107        q = domain.get_conserved_quantities(3)
108        assert allclose(q, [0., 0., 0.])                         
109       
110
111        #Edges
112        q = domain.get_conserved_quantities(0, edge=0)
113        assert allclose(q, [2.5, 2.5, 0.])
114        q = domain.get_conserved_quantities(0, edge=1)
115        assert allclose(q, [2., 2., 0.])
116        q = domain.get_conserved_quantities(0, edge=2)
117        assert allclose(q, [1.5, 1.5, 0.])
118
119        for i in range(3):
120            q = domain.get_conserved_quantities(1, edge=i)
121            assert allclose(q, [5, 5, 0.])
122
123
124        q = domain.get_conserved_quantities(2, edge=0)
125        assert allclose(q, [4.5, 4.5, 0.])
126        q = domain.get_conserved_quantities(2, edge=1)
127        assert allclose(q, [4.5, 4.5, 0.])
128        q = domain.get_conserved_quantities(2, edge=2)
129        assert allclose(q, [0., 0., 0.])
130
131
132        q = domain.get_conserved_quantities(3, edge=0)
133        assert allclose(q, [3., 3., 0.])
134        q = domain.get_conserved_quantities(3, edge=1)
135        assert allclose(q, [-1.5, -1.5, 0.])
136        q = domain.get_conserved_quantities(3, edge=2)
137        assert allclose(q, [-1.5, -1.5, 0.])                   
138
139
140    def test_boundary_indices(self):
141
142        from config import default_boundary_tag
143
144       
145        a = [0.0, 0.5]
146        b = [0.0, 0.0]               
147        c = [0.5, 0.5]
148
149        points = [a, b, c]
150        vertices = [ [0,1,2] ]
151        domain = Domain(points, vertices)
152
153        domain.set_boundary( {default_boundary_tag: Dirichlet_boundary([5,2,1])} )
154
155       
156        domain.check_integrity()
157
158        assert allclose(domain.neighbours, [[-1,-2,-3]])       
159               
160
161
162    def test_boundary_conditions(self):
163       
164        a = [0.0, 0.0]
165        b = [0.0, 2.0]
166        c = [2.0,0.0]
167        d = [0.0, 4.0]
168        e = [2.0, 2.0]
169        f = [4.0,0.0]
170
171        points = [a, b, c, d, e, f]
172        #bac, bce, ecf, dbe
173        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
174        boundary = { (0, 0): 'First',
175                     (0, 2): 'First',
176                     (2, 0): 'Second',
177                     (2, 1): 'Second',
178                     (3, 1): 'Second',
179                     (3, 2): 'Second'}                                         
180                     
181
182        domain = Domain(points, vertices, boundary,
183                        conserved_quantities =\
184                        ['level', 'xmomentum', 'ymomentum'])       
185        domain.check_integrity()
186
187
188
189        domain.set_quantity('level', [[1,2,3], [5,5,5],
190                                      [0,0,9], [-6, 3, 3]])
191
192
193        domain.set_boundary( {'First': Dirichlet_boundary([5,2,1]),
194                              'Second': Transmissive_boundary(domain)} )
195
196        domain.update_boundary()
197
198        assert domain.quantities['level'].boundary_values[0] == 5. #Dirichlet
199        assert domain.quantities['level'].boundary_values[1] == 5. #Dirichlet
200        assert domain.quantities['level'].boundary_values[2] ==\
201               domain.get_conserved_quantities(2, edge=0)[0] #Transmissive (4.5)
202        assert domain.quantities['level'].boundary_values[3] ==\
203               domain.get_conserved_quantities(2, edge=1)[0] #Transmissive (4.5)
204        assert domain.quantities['level'].boundary_values[4] ==\
205               domain.get_conserved_quantities(3, edge=1)[0] #Transmissive (-1.5)
206        assert domain.quantities['level'].boundary_values[5] ==\
207               domain.get_conserved_quantities(3, edge=2)[0] #Transmissive (-1.5)         
208
209        #Check enumeration
210        for k, ((vol_id, edge_id), _) in enumerate(domain.boundary_objects):
211            assert domain.neighbours[vol_id, edge_id] == -k-1
212
213
214
215
216    def test_distribute_first_order(self):
217        """Domain implements a default first order gradient limiter
218        """
219       
220        a = [0.0, 0.0]
221        b = [0.0, 2.0]
222        c = [2.0,0.0]
223        d = [0.0, 4.0]
224        e = [2.0, 2.0]
225        f = [4.0,0.0]
226
227        points = [a, b, c, d, e, f]
228        #bac, bce, ecf, dbe
229        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
230        boundary = { (0, 0): 'Third',
231                     (0, 2): 'First',
232                     (2, 0): 'Second',
233                     (2, 1): 'Second',
234                     (3, 1): 'Second',
235                     (3, 2): 'Third'}                                         
236                     
237
238        domain = Domain(points, vertices, boundary,
239                        conserved_quantities =\
240                        ['level', 'xmomentum', 'ymomentum'])               
241        domain.check_integrity()
242
243
244        domain.set_quantity('level', [[1,2,3], [5,5,5],
245                                      [0,0,9], [-6, 3, 3]])
246
247        assert allclose( domain.quantities['level'].centroid_values,
248                         [2,5,3,0] )
249                         
250        domain.set_quantity('xmomentum', [[1,1,1], [2,2,2],
251                                          [3,3,3], [4, 4, 4]])
252
253        domain.set_quantity('ymomentum', [[10,10,10], [20,20,20],
254                                          [30,30,30], [40, 40, 40]])       
255
256
257        domain.distribute_to_vertices_and_edges()
258
259        #First order extrapolation
260        assert allclose( domain.quantities['level'].vertex_values,
261                         [[ 2.,  2.,  2.],
262                          [ 5.,  5.,  5.],
263                          [ 3.,  3.,  3.],
264                          [ 0.,  0.,  0.]])
265
266
267
268
269    def test_update_conserved_quantities(self):
270        a = [0.0, 0.0]
271        b = [0.0, 2.0]
272        c = [2.0,0.0]
273        d = [0.0, 4.0]
274        e = [2.0, 2.0]
275        f = [4.0,0.0]
276
277        points = [a, b, c, d, e, f]
278        #bac, bce, ecf, dbe
279        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
280        boundary = { (0, 0): 'Third',
281                     (0, 2): 'First',
282                     (2, 0): 'Second',
283                     (2, 1): 'Second',
284                     (3, 1): 'Second',
285                     (3, 2): 'Third'}                                         
286                     
287
288        domain = Domain(points, vertices, boundary,
289                        conserved_quantities =\
290                        ['level', 'xmomentum', 'ymomentum'])               
291        domain.check_integrity()
292
293
294        domain.set_quantity('level', [1,2,3,4], 'centroids')
295        domain.set_quantity('xmomentum', [1,2,3,4], 'centroids')
296        domain.set_quantity('ymomentum', [1,2,3,4], 'centroids')
297                                         
298
299        #Assign some values to update vectors
300        #Set explicit_update
301
302        for name in domain.conserved_quantities:
303            domain.quantities[name].explicit_update = array([4.,3.,2.,1.])
304            domain.quantities[name].semi_implicit_update = array([1.,1.,1.,1.])
305           
306
307        #Update with given timestep (assuming no other forcing terms)
308        domain.timestep = 0.1
309        domain.update_conserved_quantities()
310
311        sem = array([1.,1.,1.,1.])/array([1, 2, 3, 4])
312        denom = ones(4, Float)-domain.timestep*sem
313
314        x = array([1, 2, 3, 4]) + array( [.4,.3,.2,.1] )
315        x /= denom
316
317        for name in domain.conserved_quantities:
318            assert allclose(domain.quantities[name].centroid_values, x)   
319
320
321    def test_set_region(self):
322        """Set quantities for sub region
323        """
324       
325        a = [0.0, 0.0]
326        b = [0.0, 2.0]
327        c = [2.0,0.0]
328        d = [0.0, 4.0]
329        e = [2.0, 2.0]
330        f = [4.0,0.0]
331
332        points = [a, b, c, d, e, f]
333        #bac, bce, ecf, dbe
334        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
335        boundary = { (0, 0): 'Third',
336                     (0, 2): 'First',
337                     (2, 0): 'Second',
338                     (2, 1): 'Second',
339                     (3, 1): 'Second',
340                     (3, 2): 'Third'}             
341
342        domain = Domain(points, vertices, boundary,
343                        conserved_quantities =\
344                        ['level', 'xmomentum', 'ymomentum'])               
345        domain.check_integrity()
346
347        domain.set_quantity('level', [[1,2,3], [5,5,5],
348                                      [0,0,9], [-6, 3, 3]])
349
350        assert allclose( domain.quantities['level'].centroid_values,
351                         [2,5,3,0] )
352                         
353        domain.set_quantity('xmomentum', [[1,1,1], [2,2,2],
354                                          [3,3,3], [4, 4, 4]])
355
356        domain.set_quantity('ymomentum', [[10,10,10], [20,20,20],
357                                          [30,30,30], [40, 40, 40]])       
358
359
360        domain.distribute_to_vertices_and_edges()
361
362        #First order extrapolation
363        assert allclose( domain.quantities['level'].vertex_values,
364                         [[ 2.,  2.,  2.],
365                          [ 5.,  5.,  5.],
366                          [ 3.,  3.,  3.],
367                          [ 0.,  0.,  0.]])
368
369        domain.build_tagged_elements_dictionary({'mound':[0,1]})
370        domain.set_region([add_to_verts])
371       
372        self.failUnless(domain.test == "Mound",
373                        'set region failed')
374       
375
376
377    def test_region_tags(self):
378        """
379        get values based on triangle lists.
380        """
381        from mesh_factory import rectangular
382        from shallow_water import Domain
383        from Numeric import zeros, Float
384       
385        #Create basic mesh
386        points, vertices, boundary = rectangular(1, 3)
387
388        #Create shallow water domain
389        domain = Domain(points, vertices, boundary)
390        domain.build_tagged_elements_dictionary({'bottom':[0,1],
391                                                 'top':[4,5],
392                                                 'all':[0,1,2,3,4,5]})
393
394       
395        #Set friction
396        manning = 0.07
397        domain.set_quantity('friction', manning)
398
399        domain.set_region([set_bottom_friction, set_top_friction])
400        #print domain.quantities['friction'].get_values()
401        assert allclose(domain.quantities['friction'].get_values(),\
402                        [[ 0.09,  0.09,  0.09],
403                         [ 0.09,  0.09,  0.09],
404                         [ 0.07,  0.07,  0.07],
405                         [ 0.07,  0.07,  0.07],
406                         [ 1.0,  1.0,  1.0],
407                         [ 1.0,  1.0,  1.0]])
408       
409        domain.set_region([set_all_friction])
410        #print domain.quantities['friction'].get_values()
411        assert allclose(domain.quantities['friction'].get_values(),
412                        [[ 10.09, 10.09, 10.09],
413                         [ 10.09, 10.09, 10.09],
414                         [ 10.07, 10.07, 10.07],
415                         [ 10.07, 10.07, 10.07],
416                         [ 11.0,  11.0,  11.0],
417                         [ 11.0,  11.0,  11.0]])
418#-------------------------------------------------------------
419if __name__ == "__main__":
420    suite = unittest.makeSuite(TestCase,'test')
421    runner = unittest.TextTestRunner()
422    runner.run(suite)
Note: See TracBrowser for help on using the repository browser.