source: trunk/anuga_core/source/anuga/operators/test_kinematic_viscosity.py @ 8152

Last change on this file since 8152 was 8152, checked in by steve, 14 years ago

Working towards passing unit tests

File size: 10.2 KB
Line 
1from anuga import Domain
2from anuga import Quantity
3from anuga import Dirichlet_boundary
4from kinematic_viscosity import Kinematic_Viscosity
5
6import numpy as num
7from math import sqrt
8import unittest
9
10class Test_Kinematic_Viscosity(unittest.TestCase):
11    def setUp(self):
12        pass
13
14    def tearDown(self):
15        pass
16   
17    #First test operator class (1 triangle)
18    def operator1(self):
19        points = num.array([[0.0,0.0],[1.0,0.0],[0.0,1.0]])
20        elements = num.array([[0,1,2]])
21        boundary_map = {}
22        boundary_map[(0,0)] = 'edge0'
23        boundary_map[(0,1)] = 'edge1'
24        boundary_map[(0,2)] = 'edge2'
25        domain = Domain(coordinates=points,vertices=elements,boundary=boundary_map)
26
27        D0 = Dirichlet_boundary([1,0,3])
28        D1 = Dirichlet_boundary([2,1,0])
29        D2 = Dirichlet_boundary([3,1,2])
30        domain.set_boundary({'edge0': D0, 'edge1': D1, 'edge2': D2})
31
32        domain.set_quantity('stage', lambda x,y : x+2*y )
33        domain.set_quantity('elevation', lambda x,y : 3*x+5*y )
34
35
36
37        #print domain.quantities['stage'].vertex_values
38
39        #print domain.quantities['stage'].edge_values
40
41        domain.update_boundary()
42
43
44        #print domain.quantities['stage'].boundary_values
45       
46        return Kinematic_Viscosity(domain)
47
48    #Second test operator class (2 triangles)
49    def operator2(self):
50        points = num.array([[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0]])
51        elements = num.array([[0,1,3],[1,2,3]])
52        boundary_map = {}
53        boundary_map[(0,1)] = 'edge0'
54        boundary_map[(0,2)] = 'edge1'
55        boundary_map[(1,0)] = 'edge2'
56        boundary_map[(1,2)] = 'edge3'
57        domain = Domain(coordinates=points,vertices=elements,boundary=boundary_map)
58
59        D0 = Dirichlet_boundary([1,1,2])
60        D1 = Dirichlet_boundary([1,2,2])
61        D2 = Dirichlet_boundary([1,1,0])
62        D3 = Dirichlet_boundary([1,2,1])
63
64        domain.set_boundary({'edge0': D0, 'edge1': D1, 'edge2': D2, 'edge3': D3})
65        domain.update_boundary()
66
67
68
69        return Kinematic_Viscosity(domain)
70
71    def test_enumerate_boundary(self):
72        operator1 = self.operator1()
73        boundary_enumeration = operator1.domain.boundary_enumeration
74
75        assert boundary_enumeration[(0,0)] == 0
76        assert boundary_enumeration[(0,1)] == 1
77        assert boundary_enumeration[(0,2)] == 2
78
79        operator2 = self.operator2()
80        boundary_enumeration = operator2.domain.boundary_enumeration
81
82
83        assert boundary_enumeration[(0,1)] == 0
84        assert boundary_enumeration[(0,2)] == 1
85        assert boundary_enumeration[(1,0)] == 2
86        assert boundary_enumeration[(1,2)] == 3
87
88    def test_geo_structure(self):
89        operator1 = self.operator1()
90        indices = operator1.geo_structure_indices
91        values = operator1.geo_structure_values
92
93        assert num.allclose(indices, num.array([[1, 2, 3]]))
94        assert num.allclose(values, num.array([[-6.0, -6.0/sqrt(5), -6.0/sqrt(5)]]))
95
96        operator2 = self.operator2()
97        indices = operator2.geo_structure_indices
98        values = operator2.geo_structure_values
99        assert num.allclose(indices, num.array([[1,2,3],[4,0,5]]))
100        assert num.allclose(values, num.array([[-3.0,-6.0/sqrt(5),-6.0/sqrt(5)],[-6.0/sqrt(5),-3.0,-6.0/sqrt(5)]]))
101
102    def test_elliptic_matrix_one_triangle(self):
103
104        operator = self.operator1()
105        domain = operator.domain
106       
107        operator.update_elliptic_matrix()
108
109        A = operator.elliptic_matrix
110
111        assert num.allclose(A.todense(), num.array([-6.0-12.0/sqrt(5), 6.0,  6.0/sqrt(5), 6.0/sqrt(5)]))
112
113        diffusivity = operator.diffusivity
114        diffusivity.set_values(10.0)
115        diffusivity.set_boundary_values(10.0)
116       
117        operator.update_elliptic_matrix()
118
119        assert num.allclose(A.todense(), 10*num.array([-6.0-12.0/sqrt(5), 6.0,  6.0/sqrt(5), 6.0/sqrt(5)]))
120   
121
122    def test_elliptic_matrix_two_triangles(self):
123
124
125        operator = self.operator2()
126
127        domain = operator.domain
128        diffusivity = operator.diffusivity
129
130        A = operator.elliptic_matrix
131
132        diffusivity.set_values(1.0)
133        diffusivity.set_boundary_values(1.0)
134        operator.update_elliptic_matrix()
135
136        A0 = num.array([[-3.0,3.0,0.0,0.0,0.0,0.0],
137                        [0.0,-6.0/sqrt(5.0),0.0,0.0,6.0/sqrt(5.0),0.0]])
138        A1 = num.array([[-6.0/sqrt(5.0),0.0,6.0/sqrt(5.0),0.0,0.0,0.0],\
139                        [3.0,-3.0,0.0,0.0,0.0,0.0]])
140        A2 = num.array([[-6.0/sqrt(5.0),0.0,0.0,6.0/sqrt(5.0),0.0,0.0],\
141                        [0.0, -6.0/sqrt(5.0), 0.0, 0.0, 0.0, 6.0/sqrt(5.0)]])
142
143
144        assert num.allclose(A.todense(), A0+A1+A2)
145
146        diffusivity.set_values([2.0, 1.0], location = 'centroids')
147        diffusivity.set_boundary_values(1.0)
148        operator.update_elliptic_matrix()
149
150        A = operator.elliptic_matrix
151       
152
153        assert num.allclose(A.todense()[0,:], 1.5*A0[0,:]+1.5*A1[0,:]+1.5*A2[0,:])
154        assert num.allclose(A.todense()[1,:], A0[1,:]+1.5*A1[1,:]+A2[1,:])
155
156        diffusivity.set_values([-2.0, -2.0], location = 'centroids')
157        diffusivity.set_boundary_values(1.0)
158        operator.update_elliptic_matrix()
159
160        assert num.allclose(A.todense()[0,:], -2*A0[0,:]-0.5*A1[0,:]-0.5*A2[0,:])
161        assert num.allclose(A.todense()[1,:], -0.5*A0[1,:]-2*A1[1,:]-0.5*A2[1,:])
162
163    def test_elliptic_multiply_include_boundary_one_triangle(self):
164        operator = self.operator1()
165        operator.set_triangle_areas(False)
166
167        print operator.apply_triangle_areas
168       
169        n = operator.n
170
171        q_in = Quantity(operator.domain)
172        q_in.set_values(1.0)
173        q_in.set_boundary_values(1.0)
174        operator.update_elliptic_matrix()
175
176       
177        A = num.array([-6.0-12.0/sqrt(5), 6.0,  6.0/sqrt(5), 6.0/sqrt(5)])
178
179
180        q_1 = operator.elliptic_multiply(q_in)
181
182        q_2 = operator.elliptic_multiply(q_in, quantity_out = q_in)
183
184        assert id(q_in) == id(q_2)
185
186        assert num.allclose(q_1.centroid_values,q_2.centroid_values)
187
188        assert num.allclose( num.zeros((n,), num.float), q_1.centroid_values )
189
190        #Now have different boundary values
191
192        q_in.set_values(1.0)
193        q_in.set_boundary_values(0.0)
194        operator.update_elliptic_matrix()
195
196
197        A = num.array([-6.0-12.0/sqrt(5), 6.0,  6.0/sqrt(5), 6.0/sqrt(5)])
198
199
200        q_1 = operator.elliptic_multiply(q_in)
201
202        assert num.allclose( [-6.0-12.0/sqrt(5)], q_1.centroid_values )
203       
204    def test_elliptic_multiply_exclude_boundary_one_triangle(self):
205        operator = self.operator1()
206        operator.set_triangle_areas(False)
207
208        print operator.apply_triangle_areas
209        #n = operator.n
210
211        q_in = Quantity(operator.domain)
212        q_in.set_values(1.0)
213        q_in.set_boundary_values(1.0)
214        operator.update_elliptic_matrix()
215
216
217        A = num.array([-6.0-12.0/sqrt(5), 6.0,  6.0/sqrt(5), 6.0/sqrt(5)])
218
219
220        q_1 = operator.elliptic_multiply(q_in, include_boundary=False)
221
222
223        assert num.allclose( [-6.0-12.0/sqrt(5)], q_1.centroid_values )
224
225    def test_elliptic_multiply_include_boundary_one_triangle(self):
226        operator = self.operator1()
227        operator.set_triangle_areas(True)
228
229        n = operator.n
230
231        q_in = Quantity(operator.domain)
232        q_in.set_values(1.0)
233        q_in.set_boundary_values(1.0)
234        operator.update_elliptic_matrix()
235
236
237        A = num.array([-6.0-12.0/sqrt(5), 6.0,  6.0/sqrt(5), 6.0/sqrt(5)])
238
239
240        q_1 = operator.elliptic_multiply(q_in)
241
242        q_2 = operator.elliptic_multiply(q_in, quantity_out = q_in)
243
244        assert id(q_in) == id(q_2)
245
246        assert num.allclose(q_1.centroid_values,q_2.centroid_values)
247
248        assert num.allclose( num.zeros((n,), num.float), q_1.centroid_values )
249
250        #Now have different boundary values
251
252        q_in.set_values(1.0)
253        q_in.set_boundary_values(0.0)
254        operator.update_elliptic_matrix()
255
256
257        A = num.array([-6.0-12.0/sqrt(5), 6.0,  6.0/sqrt(5), 6.0/sqrt(5)])
258
259
260        q_1 = operator.elliptic_multiply(q_in)
261
262        assert num.allclose( [-12.0-24.0/sqrt(5)], q_1.centroid_values )
263
264    def test_elliptic_multiply_exclude_boundary_one_triangle(self):
265        operator = self.operator1()
266        operator.set_triangle_areas(True)
267
268        q_in = Quantity(operator.domain)
269        q_in.set_values(1.0)
270        q_in.set_boundary_values(1.0)
271        operator.update_elliptic_matrix()
272
273
274        A = num.array([-6.0-12.0/sqrt(5), 6.0,  6.0/sqrt(5), 6.0/sqrt(5)])
275
276
277        q_1 = operator.elliptic_multiply(q_in, include_boundary=False)
278
279
280        assert num.allclose( [-12.0-24.0/sqrt(5)], q_1.centroid_values )
281
282
283
284    def test_mul(self):
285        operator = self.operator1()
286
287        q = Quantity(operator.domain)
288        q.set_values(2.0)
289        #q boundary_values should equal 0.0
290
291        operator.build_elliptic_boundary_term()
292        A = num.array([-6.0-12.0/sqrt(5), 6.0,  6.0/sqrt(5), 6.0/sqrt(5)])
293        V1 = num.array([2.0]) #(uh)=2
294        U1 = num.array([[2.0],[0.0],[0.0],[0.0]])
295        assert num.allclose(operator * q, 2*num.array(num.mat(A)*num.mat(U1)).reshape(1,))
296
297    def test_cg_solve(self):
298        #cf self.test_mul()
299        operator1 = self.operator1()
300        operator1.apply_stage_heights(num.array([[1.0]])) #h=1
301        operator1.set_qty_considered('u')
302        V = num.array([2.0]) #h=1, (uh)=2
303        A = num.array([-6.0-12.0/sqrt(5), 6.0,  6.0/sqrt(5), 6.0/sqrt(5)])
304        U = num.array([[2.0,2.0],[2.0,1.0],[1.0,2.0],[1.0,0.0]])
305        test = 2*num.mat(A)*num.mat(U[:,0].reshape(4,1))
306        X = operator1.cg_solve(num.array(test).reshape(1,))
307        assert num.allclose(V, X)
308
309    def test_parabolic_solve(self):
310        operator1 = self.operator1()
311        operator1.apply_stage_heights(num.array([[1.0]])) #h=1
312        A = num.array([-6.0-12.0/sqrt(5), 6.0,  6.0/sqrt(5), 6.0/sqrt(5)])
313        U = num.array([[2.0,1.0],[2.0,1.0],[1.0,2.0],[1.0,0.0]])
314        u = num.array([[2.0,1.0]])
315        U_new = operator1.parabolic_solver(u)
316        U_mod = num.array([[0.0,0.0],[2.0,1.0],[1.0,2.0],[1.0,0.0]])
317        U_mod[0,:] = U_new
318        assert num.allclose(U_new - operator1.dt * 2 * num.mat(A)*num.mat(U_mod), U[0,:])
319
320################################################################################
321
322if __name__ == "__main__":
323    suite = unittest.makeSuite(Test_Kinematic_Viscosity, 'test')
324    runner = unittest.TextTestRunner()
325    runner.run(suite)
Note: See TracBrowser for help on using the repository browser.