source: inundation/ga/storm_surge/pyvolution/test_mesh.py @ 642

Last change on this file since 642 was 601, checked in by ole, 20 years ago

Allowed for internal boundaries (again:-)

File size: 19.6 KB
Line 
1#!/usr/bin/env python
2
3 #FIXME: Seperate the tests for mesh and general_mesh
4
5import unittest
6from math import sqrt
7
8from mesh import *
9from mesh_factory import rectangular
10from config import epsilon
11from Numeric import allclose, array
12
13def distance(x, y):
14    return sqrt( sum( (array(x)-array(y))**2 ))         
15       
16class TestCase(unittest.TestCase):
17    def setUp(self):
18        pass
19       
20    def tearDown(self):
21        pass
22
23    def test_triangle_inputs(self):
24        points = [[0.0, 0.0], [4.0, 0.0], [0.0, 3.0]]
25        vertices = [0,1,2] #Wrong
26
27        try:
28            mesh = Mesh(points, vertices)
29        except:
30            pass
31        else:
32            msg = 'Should have raised exception'
33            raise msg
34       
35       
36    def test_basic_triangle(self):
37
38        a = [0.0, 0.0]
39        b = [4.0, 0.0]
40        c = [0.0, 3.0]
41       
42        points = [a, b, c]
43        vertices = [[0,1,2]]
44        mesh = Mesh(points, vertices) 
45
46        #Centroid
47        centroid = mesh.centroid_coordinates[0]
48        assert centroid[0] == 4.0/3
49        assert centroid[1] == 1.0
50
51        #Area
52        assert mesh.areas[0] == 6.0,\
53               'Area was %f, should have been 6.0' %mesh.areas[0]
54
55        #Normals
56        normals = mesh.get_normals()
57        assert allclose(normals[0, 0:2], [3.0/5, 4.0/5])
58        assert allclose(normals[0, 2:4], [-1.0, 0.0])
59        assert allclose(normals[0, 4:6], [0.0, -1.0])       
60
61        assert allclose(mesh.get_normal(0,0), [3.0/5, 4.0/5])
62        assert allclose(mesh.get_normal(0,1), [-1.0, 0.0])
63        assert allclose(mesh.get_normal(0,2), [0.0, -1.0])               
64       
65        #Edge lengths
66        assert allclose(mesh.edgelengths[0], [5.0, 3.0, 4.0])
67
68
69        #Vertex coordinates
70        V = mesh.get_vertex_coordinates()
71        assert allclose(V[0], [0.0, 0.0, 4.0, 0.0, 0.0, 3.0])
72
73        V0 = mesh.get_vertex_coordinate(0, 0)
74        assert allclose(V0, [0.0, 0.0])
75
76        V1 = mesh.get_vertex_coordinate(0, 1)
77        assert allclose(V1, [4.0, 0.0])
78
79        V2 = mesh.get_vertex_coordinate(0, 2)
80        assert allclose(V2, [0.0, 3.0])               
81
82
83        #General tests:
84
85        #Test that points are arranged in a counter clock wise order etc
86        mesh.check_integrity()
87
88       
89        #Test that the centroid is located 2/3 of the way
90        #from each vertex to the midpoint of the opposite side
91
92        V = mesh.get_vertex_coordinates()
93       
94        x0 = V[0,0]
95        y0 = V[0,1]
96        x1 = V[0,2]
97        y1 = V[0,3]
98        x2 = V[0,4]
99        y2 = V[0,5]
100       
101        m0 = [(x1 + x2)/2, (y1 + y2)/2]
102        m1 = [(x0 + x2)/2, (y0 + y2)/2]
103        m2 = [(x1 + x0)/2, (y1 + y0)/2]
104
105        d0 = distance(centroid, [x0, y0])
106        d1 = distance(m0, [x0, y0])
107        assert d0 == 2*d1/3
108        #
109        d0 = distance(centroid, [x1, y1])
110        d1 = distance(m1, [x1, y1])       
111        assert abs(d0 - 2*d1/3) < epsilon, '%e, %e' %(d0, 2*d1/3)
112
113        d0 = distance(centroid, [x2, y2])
114        d1 = distance(m2, [x2, y2])
115        assert abs(d0 - 2*d1/3) < epsilon, '%e, %e' %(d0, 2*d1/3)       
116       
117        #Radius
118        d0 = distance(centroid, m0)
119        assert d0 == 5.0/6
120       
121        d1 = distance(centroid, m1)
122        assert d1 == sqrt(73.0/36)       
123
124        d2 = distance(centroid, m2)       
125        assert d2 == sqrt(13.0/9)       
126       
127        assert mesh.radii[0] == min(d0, d1, d2)
128        assert mesh.radii[0] == 5.0/6
129
130
131        #Let x be the centroid of triangle abc.
132        #Test that areas of the three triangles axc, cxb, and bxa are equal.
133        points = [a, b, c, centroid]
134        vertices = [[0,3,2], [2,3,1], [1,3,0]]
135        new_mesh = Mesh(points, vertices)
136       
137        assert new_mesh.areas[0] == new_mesh.areas[1]
138        assert new_mesh.areas[1] == new_mesh.areas[2]       
139        assert new_mesh.areas[1] == new_mesh.areas[2]       
140
141        assert new_mesh.areas[1] == mesh.areas[0]/3       
142
143
144
145    def test_general_triangle(self):
146        a = [2.0, 1.0]
147        b = [6.0, 2.0]
148        c = [1.0, 3.0]
149
150        points = [a, b, c]
151        vertices = [[0,1,2]]
152
153        mesh = Mesh(points, vertices) 
154        centroid = mesh.centroid_coordinates[0]
155
156       
157        #Test that the centroid is located 2/3 of the way
158        #from each vertex to the midpoint of the opposite side
159
160        V = mesh.get_vertex_coordinates()
161       
162        x0 = V[0,0]
163        y0 = V[0,1]
164        x1 = V[0,2]
165        y1 = V[0,3]
166        x2 = V[0,4]
167        y2 = V[0,5]
168       
169        m0 = [(x1 + x2)/2, (y1 + y2)/2]
170        m1 = [(x0 + x2)/2, (y0 + y2)/2]
171        m2 = [(x1 + x0)/2, (y1 + y0)/2]
172
173        d0 = distance(centroid, [x0, y0])
174        d1 = distance(m0, [x0, y0])
175        assert abs(d0 - 2*d1/3) < epsilon, '%e, %e' %(d0, 2*d1/3)
176        #
177        d0 = distance(centroid, [x1, y1])
178        d1 = distance(m1, [x1, y1])       
179        assert abs(d0 - 2*d1/3) < epsilon, '%e, %e' %(d0, 2*d1/3)
180
181        d0 = distance(centroid, [x2, y2])
182        d1 = distance(m2, [x2, y2])
183        assert abs(d0 - 2*d1/3) < epsilon, '%e, %e' %(d0, 2*d1/3)       
184       
185        #Radius
186        d0 = distance(centroid, m0)
187        d1 = distance(centroid, m1)
188        d2 = distance(centroid, m2)       
189        assert mesh.radii[0] == min(d0, d1, d2)
190
191
192
193        #Let x be the centroid of triangle abc.
194        #Test that areas of the three triangles axc, cxb, and bxa are equal.
195
196        points = [a, b, c, centroid]
197        vertices = [[0,3,2], [2,3,1], [1,3,0]]
198        new_mesh = Mesh(points, vertices)
199       
200        assert new_mesh.areas[0] == new_mesh.areas[1]
201        assert new_mesh.areas[1] == new_mesh.areas[2]       
202        assert new_mesh.areas[1] == new_mesh.areas[2]       
203
204        assert new_mesh.areas[1] == mesh.areas[0]/3       
205       
206
207        #Test that points are arranged in a counter clock wise order
208        mesh.check_integrity()
209
210
211    def test_boundary_indices(self):
212        a = [0.0, 0.5]
213        b = [0.0, 0.0]               
214        c = [0.5, 0.5]
215
216        points = [a, b, c]
217        vertices = [ [0,1,2] ]
218        mesh = Mesh(points, vertices)       
219        mesh.check_integrity()
220
221        assert allclose(mesh.neighbours, [[-1,-2,-3]]) 
222               
223
224
225    def test_two_triangles(self):
226        a = [0.0, 0.0]
227        b = [0.0, 2.0]
228        c = [2.0,0.0]
229        e = [2.0, 2.0]
230        points = [a, b, c, e]
231        vertices = [ [1,0,2], [1,2,3] ]   #bac, bce
232        mesh = Mesh(points, vertices)
233       
234        assert mesh.areas[0] == 2.0
235
236        assert allclose(mesh.centroid_coordinates[0], [2.0/3, 2.0/3])       
237
238
239        #Test that points are arranged in a counter clock wise order
240        mesh.check_integrity()       
241
242
243           
244    def test_more_triangles(self):
245       
246        a = [0.0, 0.0]
247        b = [0.0, 2.0]
248        c = [2.0, 0.0]
249        d = [0.0, 4.0]
250        e = [2.0, 2.0]
251        f = [4.0, 0.0]
252
253        points = [a, b, c, d, e, f]
254        #bac, bce, ecf, dbe, daf, dae
255        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4], [3,0,5], [3,0,4]]
256        mesh = Mesh(points, vertices)       
257
258        #Test that points are arranged in a counter clock wise order
259        mesh.check_integrity()       
260
261        assert mesh.areas[0] == 2.0
262        assert mesh.areas[1] == 2.0
263        assert mesh.areas[2] == 2.0
264        assert mesh.areas[3] == 2.0
265        assert mesh.areas[4] == 8.0
266        assert mesh.areas[5] == 4.0                               
267       
268        assert mesh.edgelengths[1,0] == 2.0
269        assert mesh.edgelengths[1,1] == 2.0
270        assert mesh.edgelengths[1,2] == sqrt(8.0)
271
272        assert allclose(mesh.centroid_coordinates[0], [2.0/3, 2.0/3])
273        assert allclose(mesh.centroid_coordinates[1], [4.0/3, 4.0/3]) 
274        assert allclose(mesh.centroid_coordinates[2], [8.0/3, 2.0/3])
275        assert allclose(mesh.centroid_coordinates[3], [2.0/3, 8.0/3])         
276
277
278    def test_mesh_and_neighbours(self):
279        a = [0.0, 0.0]
280        b = [0.0, 2.0]
281        c = [2.0,0.0]
282        d = [0.0, 4.0]
283        e = [2.0, 2.0]
284        f = [4.0,0.0]
285
286
287        points = [a, b, c, d, e, f]
288
289        #bac, bce, ecf, dbe
290        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
291        mesh = Mesh(points, vertices)
292       
293        mesh.check_integrity()
294
295
296        T = mesh
297        tid = 0
298        assert T.number_of_boundaries[tid] == 2   
299        assert T.neighbours[tid, 0] < 0  #Opposite point b (0,2)
300        assert T.neighbours[tid, 1] == 1 #Opposite point a (0,0)
301        assert T.neighbours[tid, 2] < 0  #Opposite point c (2,0)       
302
303        tid = 1
304        assert T.number_of_boundaries[tid] == 0           
305        assert T.neighbours[tid, 0] == 2  #Opposite point b (0,2)
306        assert T.neighbours[tid, 1] == 3  #Opposite point c (2,0)
307        assert T.neighbours[tid, 2] == 0  #Opposite point e (2,2)
308
309        tid = 2
310        assert T.number_of_boundaries[tid] == 2           
311        assert T.neighbours[tid, 0] < 0   #Opposite point e (2,2)
312        assert T.neighbours[tid, 1] < 0   #Opposite point c (2,0)
313        assert T.neighbours[tid, 2] == 1  #Opposite point f (4,0)       
314
315        tid = 3
316        assert T.number_of_boundaries[tid] == 2           
317        assert T.neighbours[tid, 0] == 1  #Opposite point d (0,4)
318        assert T.neighbours[tid, 1] < 0   #Opposite point b (0,3)
319        assert T.neighbours[tid, 2] < 0   #Opposite point e (2,2)
320
321        #Neighbouring edges
322        tid = 0
323        assert T.neighbour_edges[tid, 0] < 0  #Opposite point b (0,2)
324        assert T.neighbour_edges[tid, 1] == 2 #Opposite point a (0,0)
325        assert T.neighbour_edges[tid, 2] < 0  #Opposite point c (2,0)       
326
327        tid = 1       
328        assert T.neighbour_edges[tid, 0] == 2 #Opposite point b (0,2)
329        assert T.neighbour_edges[tid, 1] == 0 #Opposite point c (2,0)
330        assert T.neighbour_edges[tid, 2] == 1 #Opposite point e (2,2)
331
332        tid = 2       
333        assert T.neighbour_edges[tid, 0] < 0  #Opposite point e (2,2)
334        assert T.neighbour_edges[tid, 1] < 0  #Opposite point c (2,0)
335        assert T.neighbour_edges[tid, 2] == 0 #Opposite point f (4,0)       
336
337        tid = 3       
338        assert T.neighbour_edges[tid, 0] == 1 #Opposite point d (0,4)
339        assert T.neighbour_edges[tid, 1] < 0  #Opposite point b (0,3)
340        assert T.neighbour_edges[tid, 2] < 0  #Opposite point e (2,2)
341
342       
343    def test_rectangular_mesh_basic(self):
344        M=1
345        N=1
346
347        points, vertices, boundary = rectangular(M, N)
348        mesh = Mesh(points, vertices, boundary)
349
350        #Test that points are arranged in a counter clock wise order       
351        mesh.check_integrity()
352
353        M=2
354        N=2
355        points, vertices, boundary = rectangular(M, N)
356        mesh = Mesh(points, vertices, boundary)
357       
358        #Test that points are arranged in a counter clock wise order       
359        mesh.check_integrity()
360
361        #assert mesh.boundary[(7,1)] == 2 # top
362        assert mesh.boundary[(7,1)] == 'top' # top
363        assert mesh.boundary[(3,1)] == 'top' # top               
364
365       
366    def test_boundary_tags(self):
367       
368
369        points, vertices, boundary = rectangular(4, 4)
370        mesh = Mesh(points, vertices, boundary)
371       
372
373        #Test that points are arranged in a counter clock wise order       
374        mesh.check_integrity()
375
376        #print mesh.get_boundary_tags()
377        #print mesh.boundary
378
379        for k in [1, 3, 5, 7]:
380            assert mesh.boundary[(k,2)] == 'left'
381
382        for k in [24, 26, 28, 30]:
383            assert mesh.boundary[(k,2)] == 'right'           
384           
385        for k in [7, 15, 23, 31]:
386            assert mesh.boundary[(k,1)] == 'top'
387        for k in [0, 8, 16, 24]:
388            assert mesh.boundary[(k,1)] == 'bottom'
389
390
391       
392    def test_rectangular_mesh(self):
393        M=4
394        N=16
395        len1 = 100.0
396        len2 = 17.0
397       
398        points, vertices, boundary = rectangular(M, N, len1, len2)
399        mesh = Mesh(points, vertices, boundary)
400
401        assert len(mesh) == 2*M*N       
402
403        for i in range(len(mesh)):
404            assert mesh.areas[i] == len1*len2/(2*M*N)
405
406            hypo = sqrt((len1/M)**2 + (len2/N)**2) #hypothenuse
407            assert mesh.edgelengths[i, 0] == hypo
408            assert mesh.edgelengths[i, 1] == len1/M #x direction
409            assert mesh.edgelengths[i, 2] == len2/N #y direction
410           
411        #Test that points are arranged in a counter clock wise order     
412        mesh.check_integrity()   
413
414
415    def test_rectangular_mesh2(self):
416        #Check that integers don't cause trouble
417        N = 16
418       
419        points, vertices, boundary = rectangular(2*N, N, len1=10, len2=10)
420        mesh = Mesh(points, vertices, boundary)
421
422
423
424    def test_surrogate_neighbours(self):
425        a = [0.0, 0.0]
426        b = [0.0, 2.0]
427        c = [2.0,0.0]
428        d = [0.0, 4.0]
429        e = [2.0, 2.0]
430        f = [4.0,0.0]
431
432        points = [a, b, c, d, e, f]
433
434        #bac, bce, ecf, dbe
435        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
436        mesh = Mesh(points, vertices)       
437        mesh.check_integrity()
438
439
440        T = mesh
441        tid = 0
442        assert T.number_of_boundaries[tid] == 2   
443        assert T.surrogate_neighbours[tid, 0] == tid
444        assert T.surrogate_neighbours[tid, 1] == 1   
445        assert T.surrogate_neighbours[tid, 2] == tid
446
447        tid = 1
448        assert T.number_of_boundaries[tid] == 0           
449        assert T.surrogate_neighbours[tid, 0] == 2
450        assert T.surrogate_neighbours[tid, 1] == 3
451        assert T.surrogate_neighbours[tid, 2] == 0
452
453        tid = 2
454        assert T.number_of_boundaries[tid] == 2           
455        assert T.surrogate_neighbours[tid, 0] == tid
456        assert T.surrogate_neighbours[tid, 1] == tid
457        assert T.surrogate_neighbours[tid, 2] == 1
458
459        tid = 3
460        assert T.number_of_boundaries[tid] == 2           
461        assert T.surrogate_neighbours[tid, 0] == 1 
462        assert T.surrogate_neighbours[tid, 1] == tid
463        assert T.surrogate_neighbours[tid, 2] == tid
464
465
466    def test_boundary_inputs(self):
467        a = [0.0, 0.0]
468        b = [0.0, 2.0]
469        c = [2.0,0.0]
470        d = [0.0, 4.0]
471        e = [2.0, 2.0]
472        f = [4.0,0.0]
473
474        points = [a, b, c, d, e, f]
475
476        #bac, bce, ecf, dbe
477        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
478
479        boundary = { (0, 0): 'First',
480                     (0, 2): 'Second',
481                     (2, 0): 'Third',
482                     (2, 1): 'Fourth',
483                     (3, 1): 'Fifth',
484                     (3, 2): 'Sixth'}                                         
485                     
486       
487        mesh = Mesh(points, vertices, boundary)       
488        mesh.check_integrity()
489
490
491        #Check enumeration
492        for k, (vol_id, edge_id) in enumerate(mesh.boundary_segments):       
493            b = -k-1
494            assert mesh.neighbours[vol_id, edge_id] == b
495
496
497
498    def test_boundary_inputs_using_one_default(self):
499        a = [0.0, 0.0]
500        b = [0.0, 2.0]
501        c = [2.0,0.0]
502        d = [0.0, 4.0]
503        e = [2.0, 2.0]
504        f = [4.0,0.0]
505
506        points = [a, b, c, d, e, f]
507
508        #bac, bce, ecf, dbe
509        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
510
511        boundary = { (0, 0): 'First',
512                     (0, 2): 'Second',
513                     (2, 0): 'Third',
514                     (2, 1): 'Fourth',
515                     #(3, 1): 'Fifth',  #Skip this
516                     (3, 2): 'Sixth'}                                         
517                     
518       
519        mesh = Mesh(points, vertices, boundary)       
520        mesh.check_integrity()
521
522        from config import default_boundary_tag
523        assert mesh.boundary[ (3, 1) ] == default_boundary_tag
524
525
526        #Check enumeration
527        for k, (vol_id, edge_id) in enumerate(mesh.boundary_segments):       
528            b = -k-1
529            assert mesh.neighbours[vol_id, edge_id] == b
530
531    def test_boundary_inputs_using_all_defaults(self):
532        a = [0.0, 0.0]
533        b = [0.0, 2.0]
534        c = [2.0,0.0]
535        d = [0.0, 4.0]
536        e = [2.0, 2.0]
537        f = [4.0,0.0]
538
539        points = [a, b, c, d, e, f]
540
541        #bac, bce, ecf, dbe
542        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
543
544        boundary = { (0, 0): 'First',
545                     (0, 2): 'Second',
546                     (2, 0): 'Third',
547                     (2, 1): 'Fourth',
548                     #(3, 1): 'Fifth',  #Skip this
549                     (3, 2): 'Sixth'}                                         
550                     
551       
552        mesh = Mesh(points, vertices) #, boundary)       
553        mesh.check_integrity()
554
555        from config import default_boundary_tag
556        assert mesh.boundary[ (0, 0) ] == default_boundary_tag
557        assert mesh.boundary[ (0, 2) ] == default_boundary_tag
558        assert mesh.boundary[ (2, 0) ] == default_boundary_tag
559        assert mesh.boundary[ (2, 1) ] == default_boundary_tag               
560        assert mesh.boundary[ (3, 1) ] == default_boundary_tag
561        assert mesh.boundary[ (3, 2) ] == default_boundary_tag               
562
563
564        #Check enumeration
565        for k, (vol_id, edge_id) in enumerate(mesh.boundary_segments):       
566            b = -k-1
567            assert mesh.neighbours[vol_id, edge_id] == b
568
569
570
571
572
573
574    def test_inputs(self):
575        a = [0.0, 0.0]
576        b = [0.0, 2.0]
577        c = [2.0,0.0]
578        d = [0.0, 4.0]
579        e = [2.0, 2.0]
580        f = [4.0,0.0]
581
582        points = [a, b, c, d, e, f]
583
584        #bac, bce, ecf, dbe
585        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
586
587        #Too few points
588        try:
589            mesh = Mesh([points[0]], vertices)       
590        except AssertionError:
591            pass
592        else:
593            raise 'Should have raised an exception'
594
595        #Too few points - 1 element
596        try:
597            mesh = Mesh([points[0]], [vertices[0]])       
598        except AssertionError:
599            pass
600        else:
601            raise 'Should have raised an exception'       
602       
603        #Wrong dimension of vertices
604        try:
605            mesh = Mesh(points, vertices[0])       
606        except AssertionError:
607            pass
608        else:
609            raise 'Should have raised an exception'
610
611        #Unsubscriptable coordinates object raises exception
612        try:
613            mesh = Mesh(points[0], [vertices[0]])       
614        except AssertionError:
615            pass
616        else:
617            raise 'Should have raised an exception'
618
619        #FIXME: This has been commented out pending a decision
620        #whether to allow partial boundary tags or not
621        #
622        #Not specifying all boundary tags
623        #try:
624        #    mesh = Mesh(points, vertices, {(3,0): 'x'})       
625        #except AssertionError:
626        #    pass
627        #else:
628        #    raise 'Should have raised an exception'
629
630        #Specifying wrong non existing segment
631        try:
632            mesh = Mesh(points, vertices, {(5,0): 'x'})       
633        except AssertionError:
634            pass
635        else:
636            raise 'Should have raised an exception'
637
638
639
640
641    def test_internal_boundaries(self):
642        """
643        get values based on triangle lists.
644        """
645        from mesh_factory import rectangular
646        from shallow_water import Domain
647        from Numeric import zeros, Float
648       
649        #Create basic mesh
650        points, vertices, boundary = rectangular(1, 3)
651
652        # Add an internal boundary
653        boundary[(2,0)] = 'internal'
654        boundary[(1,0)] = 'internal'
655
656        #Create shallow water domain
657        domain = Domain(points, vertices, boundary)
658        domain.build_tagged_elements_dictionary({'bottom':[0,1],
659                                                 'top':[4,5],
660                                                 'all':[0,1,2,3,4,5]})
661
662       
663       
664       
665#-------------------------------------------------------------
666if __name__ == "__main__":
667    suite = unittest.makeSuite(TestCase,'test')
668    runner = unittest.TextTestRunner()
669    runner.run(suite)
670
671   
672   
673
674
675
Note: See TracBrowser for help on using the repository browser.