source: anuga_core/source/anuga/shallow_water/test_shallow_water_domain.py @ 3803

Last change on this file since 3803 was 3803, checked in by steve, 17 years ago

strange error in test_shallow_water_domain on bogong

File size: 136.2 KB
Line 
1#!/usr/bin/env python
2
3import unittest, os
4from math import sqrt, pi
5
6from anuga.config import g, epsilon
7from Numeric import allclose, alltrue, array, zeros, ones, Float, take
8from anuga.utilities.numerical_tools import mean
9
10from shallow_water_domain import *
11from shallow_water_domain import flux_function_central as flux_function
12
13#Variable windfield implemented using functions
14def speed(t,x,y):
15    """Large speeds halfway between center and edges
16    Low speeds at center and edges
17    """
18
19    from math import sqrt, exp, cos, pi
20
21    x = array(x)
22    y = array(y)
23
24    N = len(x)
25    s = 0*#New array
26
27    for k in range(N):
28
29        r = sqrt(x[k]**2 + y[k]**2)
30
31        factor = exp( -(r-0.15)**2 )
32
33        s[k] = 4000 * factor * (cos(t*2*pi/150) + 2)
34
35    return s
36
37
38def scalar_func(t,x,y):
39    """Function that returns a scalar.
40    Used to test error message when Numeric array is expected
41    """
42
43    return 17.7
44
45
46def angle(t,x,y):
47    """Rotating field
48    """
49    from math import sqrt, atan, pi
50
51    x = array(x)
52    y = array(y)
53
54    N = len(x)
55    a = 0*#New array
56
57    for k in range(N):
58        r = sqrt(x[k]**2 + y[k]**2)
59
60        angle = atan(y[k]/x[k])
61
62        if x[k] < 0:
63            angle+=pi #atan in ]-pi/2; pi/2[
64
65        #Take normal direction
66        angle -= pi/2
67
68        #Ensure positive radians
69        if angle < 0:
70            angle += 2*pi
71
72        a[k] = angle/pi*180
73
74    return a
75
76
77class Test_Shallow_Water(unittest.TestCase):
78    def setUp(self):
79        pass
80
81    def tearDown(self):
82        pass
83
84    def test_rotate(self):
85        normal = array([0.0,-1.0])
86
87        q = array([1.0,2.0,3.0])
88
89        r = rotate(q, normal, direction = 1)
90        assert r[0] == 1
91        assert r[1] == -3
92        assert r[2] == 2
93
94        w = rotate(r, normal, direction = -1)
95        assert allclose(w, q)
96
97        #Check error check
98        try:
99            rotate(r, array([1,1,1]) )
100        except:
101            pass
102        else:
103            raise 'Should have raised an exception'
104
105    def test_flux_zero_case(self):
106        ql = zeros( 3, Float )
107        qr = zeros( 3, Float )
108        normal = zeros( 2, Float )
109        zl = zr = 0.
110        flux, max_speed = flux_function(normal, ql, qr, zl, zr)
111
112        assert allclose(flux, [0,0,0])
113        assert max_speed == 0.
114
115    def test_flux_constants(self):
116        w = 2.0
117
118        normal = array([1.,0])
119        ql = array([w, 0, 0])
120        qr = array([w, 0, 0])
121        zl = zr = 0.
122        h = w - (zl+zr)/2
123
124        flux, max_speed = flux_function(normal, ql, qr, zl, zr)
125
126        assert allclose(flux, [0., 0.5*g*h**2, 0.])
127        assert max_speed == sqrt(g*h)
128
129    #def test_flux_slope(self):
130    #    #FIXME: TODO
131    #    w = 2.0
132    #
133    #    normal = array([1.,0])
134    #    ql = array([w, 0, 0])
135    #    qr = array([w, 0, 0])
136    #    zl = zr = 0.
137    #    h = w - (zl+zr)/2
138    #
139    #    flux, max_speed = flux_function(normal, ql, qr, zl, zr)
140    #
141    #    assert allclose(flux, [0., 0.5*g*h**2, 0.])
142    #    assert max_speed == sqrt(g*h)
143
144
145    def test_flux1(self):
146        #Use data from previous version of abstract_2d_finite_volumes
147        normal = array([1.,0])
148        ql = array([-0.2, 2, 3])
149        qr = array([-0.2, 2, 3])
150        zl = zr = -0.5
151        flux, max_speed = flux_function(normal, ql, qr, zl, zr)
152
153        assert allclose(flux, [2.,13.77433333, 20.])
154        assert allclose(max_speed, 8.38130948661)
155
156
157    def test_flux2(self):
158        #Use data from previous version of abstract_2d_finite_volumes
159        normal = array([0., -1.])
160        ql = array([-0.075, 2, 3])
161        qr = array([-0.075, 2, 3])
162        zl = zr = -0.375
163        flux, max_speed = flux_function(normal, ql, qr, zl, zr)
164
165        assert allclose(flux, [-3.,-20.0, -30.441])
166        assert allclose(max_speed, 11.7146428199)
167
168    def test_flux3(self):
169        #Use data from previous version of abstract_2d_finite_volumes
170        normal = array([-sqrt(2)/2, sqrt(2)/2])
171        ql = array([-0.075, 2, 3])
172        qr = array([-0.075, 2, 3])
173        zl = zr = -0.375
174        flux, max_speed = flux_function(normal, ql, qr, zl, zr)
175
176        assert allclose(flux, [sqrt(2)/2, 4.40221112, 7.3829019])
177        assert allclose(max_speed, 4.0716654239)
178
179    def test_flux4(self):
180        #Use data from previous version of abstract_2d_finite_volumes
181        normal = array([-sqrt(2)/2, sqrt(2)/2])
182        ql = array([-0.34319278, 0.10254161, 0.07273855])
183        qr = array([-0.30683287, 0.1071986, 0.05930515])
184        zl = zr = -0.375
185        flux, max_speed = flux_function(normal, ql, qr, zl, zr)
186
187        assert allclose(flux, [-0.04072676, -0.07096636, -0.01604364])
188        assert allclose(max_speed, 1.31414103233)
189
190    def test_sw_domain_simple(self):
191        a = [0.0, 0.0]
192        b = [0.0, 2.0]
193        c = [2.0,0.0]
194        d = [0.0, 4.0]
195        e = [2.0, 2.0]
196        f = [4.0,0.0]
197
198        points = [a, b, c, d, e, f]
199        #bac, bce, ecf, dbe, daf, dae
200        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
201
202
203        #from anuga.abstract_2d_finite_volumes.domain import Domain as Generic_domain
204        #msg = 'The class %s is not a subclass of the generic domain class %s'\
205        #      %(DomainClass, Domain)
206        #assert issubclass(DomainClass, Domain), msg
207
208        domain = Domain(points, vertices)
209        domain.check_integrity()
210
211        for name in ['stage', 'xmomentum', 'ymomentum',
212                     'elevation', 'friction']:
213            assert domain.quantities.has_key(name)
214
215
216        assert domain.get_conserved_quantities(0, edge=1) == 0.
217
218
219    def test_boundary_conditions(self):
220
221        a = [0.0, 0.0]
222        b = [0.0, 2.0]
223        c = [2.0,0.0]
224        d = [0.0, 4.0]
225        e = [2.0, 2.0]
226        f = [4.0,0.0]
227
228        points = [a, b, c, d, e, f]
229        #bac, bce, ecf, dbe
230        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
231        boundary = { (0, 0): 'Third',
232                     (0, 2): 'First',
233                     (2, 0): 'Second',
234                     (2, 1): 'Second',
235                     (3, 1): 'Second',
236                     (3, 2): 'Third'}
237
238
239        domain = Domain(points, vertices, boundary)
240        domain.check_integrity()
241
242
243        domain.set_quantity('stage', [[1,2,3], [5,5,5],
244                                      [0,0,9], [-6, 3, 3]])
245
246        domain.set_quantity('xmomentum', [[1,1,1], [2,2,2],
247                                          [3,3,3], [4, 4, 4]])
248
249        domain.set_quantity('ymomentum', [[10,10,10], [20,20,20],
250                                          [30,30,30], [40, 40, 40]])
251
252
253        D = Dirichlet_boundary([5,2,1])
254        T = Transmissive_boundary(domain)
255        R = Reflective_boundary(domain)
256        domain.set_boundary( {'First': D, 'Second': T, 'Third': R})
257
258        domain.update_boundary()
259
260        #Stage
261        assert domain.quantities['stage'].boundary_values[0] == 2.5
262        assert domain.quantities['stage'].boundary_values[0] ==\
263               domain.get_conserved_quantities(0, edge=0)[0] #Reflective (2.5)
264        assert domain.quantities['stage'].boundary_values[1] == 5. #Dirichlet
265        assert domain.quantities['stage'].boundary_values[2] ==\
266               domain.get_conserved_quantities(2, edge=0)[0] #Transmissive (4.5)
267        assert domain.quantities['stage'].boundary_values[3] ==\
268               domain.get_conserved_quantities(2, edge=1)[0] #Transmissive (4.5)
269        assert domain.quantities['stage'].boundary_values[4] ==\
270               domain.get_conserved_quantities(3, edge=1)[0] #Transmissive (-1.5)
271        assert domain.quantities['stage'].boundary_values[5] ==\
272               domain.get_conserved_quantities(3, edge=2)[0] #Reflective (-1.5)
273
274        #Xmomentum
275        assert domain.quantities['xmomentum'].boundary_values[0] == 1.0 #Reflective
276        assert domain.quantities['xmomentum'].boundary_values[1] == 2. #Dirichlet
277        assert domain.quantities['xmomentum'].boundary_values[2] ==\
278               domain.get_conserved_quantities(2, edge=0)[1] #Transmissive
279        assert domain.quantities['xmomentum'].boundary_values[3] ==\
280               domain.get_conserved_quantities(2, edge=1)[1] #Transmissive
281        assert domain.quantities['xmomentum'].boundary_values[4] ==\
282               domain.get_conserved_quantities(3, edge=1)[1] #Transmissive
283        assert domain.quantities['xmomentum'].boundary_values[5] == -4.0  #Reflective
284
285        #Ymomentum
286        assert domain.quantities['ymomentum'].boundary_values[0] == -10.0 #Reflective
287        assert domain.quantities['ymomentum'].boundary_values[1] == 1.  #Dirichlet
288        assert domain.quantities['ymomentum'].boundary_values[2] == 30. #Transmissive
289        assert domain.quantities['ymomentum'].boundary_values[3] == 30. #Transmissive
290        assert domain.quantities['ymomentum'].boundary_values[4] == 40. #Transmissive
291        assert domain.quantities['ymomentum'].boundary_values[5] == 40. #Reflective
292
293
294    def test_boundary_conditionsII(self):
295
296        a = [0.0, 0.0]
297        b = [0.0, 2.0]
298        c = [2.0,0.0]
299        d = [0.0, 4.0]
300        e = [2.0, 2.0]
301        f = [4.0,0.0]
302
303        points = [a, b, c, d, e, f]
304        #bac, bce, ecf, dbe
305        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
306        boundary = { (0, 0): 'Third',
307                     (0, 2): 'First',
308                     (2, 0): 'Second',
309                     (2, 1): 'Second',
310                     (3, 1): 'Second',
311                     (3, 2): 'Third',
312                     (0, 1): 'Internal'}
313
314
315        domain = Domain(points, vertices, boundary)
316        domain.check_integrity()
317
318
319        domain.set_quantity('stage', [[1,2,3], [5,5,5],
320                                      [0,0,9], [-6, 3, 3]])
321
322        domain.set_quantity('xmomentum', [[1,1,1], [2,2,2],
323                                          [3,3,3], [4, 4, 4]])
324
325        domain.set_quantity('ymomentum', [[10,10,10], [20,20,20],
326                                          [30,30,30], [40, 40, 40]])
327
328
329        D = Dirichlet_boundary([5,2,1])
330        T = Transmissive_boundary(domain)
331        R = Reflective_boundary(domain)
332        domain.set_boundary( {'First': D, 'Second': T,
333                              'Third': R, 'Internal': None})
334
335        domain.update_boundary()
336        domain.check_integrity()
337
338
339    def test_compute_fluxes0(self):
340        #Do a full triangle and check that fluxes cancel out for
341        #the constant stage case
342
343        a = [0.0, 0.0]
344        b = [0.0, 2.0]
345        c = [2.0,0.0]
346        d = [0.0, 4.0]
347        e = [2.0, 2.0]
348        f = [4.0,0.0]
349
350        points = [a, b, c, d, e, f]
351        #bac, bce, ecf, dbe
352        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
353
354        domain = Domain(points, vertices)
355        domain.set_quantity('stage', [[2,2,2], [2,2,2],
356                                      [2,2,2], [2,2,2]])
357        domain.check_integrity()
358
359        assert allclose(domain.neighbours, [[-1,1,-1], [2,3,0], [-1,-1,1],[1,-1,-1]])
360        assert allclose(domain.neighbour_edges, [[-1,2,-1], [2,0,1], [-1,-1,0],[1,-1,-1]])
361
362        zl=zr=0. #Assume flat bed
363
364        #Flux across right edge of volume 1
365        normal = domain.get_normal(1,0)
366        ql = domain.get_conserved_quantities(vol_id=1, edge=0)
367        qr = domain.get_conserved_quantities(vol_id=2, edge=2)
368        flux0, max_speed = flux_function(normal, ql, qr, zl, zr)
369
370        #Check that flux seen from other triangles is inverse
371        tmp = qr; qr=ql; ql=tmp
372        normal = domain.get_normal(2,2)
373        flux, max_speed = flux_function(normal, ql, qr, zl, zr)
374        assert allclose(flux + flux0, 0.)
375
376        #Flux across upper edge of volume 1
377        normal = domain.get_normal(1,1)
378        ql = domain.get_conserved_quantities(vol_id=1, edge=1)
379        qr = domain.get_conserved_quantities(vol_id=3, edge=0)
380        flux1, max_speed = flux_function(normal, ql, qr, zl, zr)
381
382        #Check that flux seen from other triangles is inverse
383        tmp = qr; qr=ql; ql=tmp
384        normal = domain.get_normal(3,0)
385        flux, max_speed = flux_function(normal, ql, qr, zl, zr)
386        assert allclose(flux + flux1, 0.)
387
388        #Flux across lower left hypotenuse of volume 1
389        normal = domain.get_normal(1,2)
390        ql = domain.get_conserved_quantities(vol_id=1, edge=2)
391        qr = domain.get_conserved_quantities(vol_id=0, edge=1)
392        flux2, max_speed = flux_function(normal, ql, qr, zl, zr)
393
394        #Check that flux seen from other triangles is inverse
395        tmp = qr; qr=ql; ql=tmp
396        normal = domain.get_normal(0,1)
397        flux, max_speed = flux_function(normal, ql, qr, zl, zr)
398        assert allclose(flux + flux2, 0.)
399
400
401        #Scale by edgelengths, add up anc check that total flux is zero
402        e0 = domain.edgelengths[1, 0]
403        e1 = domain.edgelengths[1, 1]
404        e2 = domain.edgelengths[1, 2]
405
406        assert allclose(e0*flux0+e1*flux1+e2*flux2, 0.)
407
408        #Now check that compute_flux yields zeros as well
409        domain.compute_fluxes()
410
411        for name in ['stage', 'xmomentum', 'ymomentum']:
412            #print name, domain.quantities[name].explicit_update
413            assert allclose(domain.quantities[name].explicit_update[1], 0)
414
415
416
417    def test_compute_fluxes1(self):
418        #Use values from previous version
419
420        a = [0.0, 0.0]
421        b = [0.0, 2.0]
422        c = [2.0,0.0]
423        d = [0.0, 4.0]
424        e = [2.0, 2.0]
425        f = [4.0,0.0]
426
427        points = [a, b, c, d, e, f]
428        #bac, bce, ecf, dbe
429        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
430
431        domain = Domain(points, vertices)
432        val0 = 2.+2.0/3
433        val1 = 4.+4.0/3
434        val2 = 8.+2.0/3
435        val3 = 2.+8.0/3
436
437        domain.set_quantity('stage', [[val0, val0, val0], [val1, val1, val1],
438                                      [val2, val2, val2], [val3, val3, val3]])
439        domain.check_integrity()
440
441        zl=zr=0. #Assume flat bed
442
443        #Flux across right edge of volume 1
444        normal = domain.get_normal(1,0) #Get normal 0 of triangle 1
445        assert allclose(normal, [1, 0])
446       
447        ql = domain.get_conserved_quantities(vol_id=1, edge=0)
448        assert allclose(ql, [val1, 0, 0])
449       
450        qr = domain.get_conserved_quantities(vol_id=2, edge=2)
451        assert allclose(qr, [val2, 0, 0])
452       
453        flux0, max_speed = flux_function(normal, ql, qr, zl, zr)
454
455        #Flux across edge in the east direction (as per normal vector)
456        assert allclose(flux0, [-15.3598804, 253.71111111, 0.])
457        assert allclose(max_speed, 9.21592824046)
458
459
460        #Flux across edge in the west direction (opposite sign for xmomentum)
461        normal_opposite = domain.get_normal(2,2) #Get normal 2 of triangle 2
462        assert allclose(normal_opposite, [-1, 0])
463        flux_opposite, max_speed = flux_function([-1, 0], ql, qr, zl, zr)
464        assert allclose(flux_opposite, [-15.3598804, -253.71111111, 0.])
465       
466
467        #Flux across upper edge of volume 1
468        normal = domain.get_normal(1,1)
469        ql = domain.get_conserved_quantities(vol_id=1, edge=1)
470        qr = domain.get_conserved_quantities(vol_id=3, edge=0)
471        flux1, max_speed = flux_function(normal, ql, qr, zl, zr)
472        assert allclose(flux1, [2.4098563, 0., 123.04444444])
473        assert allclose(max_speed, 7.22956891292)
474
475        #Flux across lower left hypotenuse of volume 1
476        normal = domain.get_normal(1,2)
477        ql = domain.get_conserved_quantities(vol_id=1, edge=2)
478        qr = domain.get_conserved_quantities(vol_id=0, edge=1)
479        flux2, max_speed = flux_function(normal, ql, qr, zl, zr)
480
481        assert allclose(flux2, [9.63942522, -61.59685738, -61.59685738])
482        assert allclose(max_speed, 7.22956891292)
483
484        #Scale, add up and check that compute_fluxes is correct for vol 1
485        e0 = domain.edgelengths[1, 0]
486        e1 = domain.edgelengths[1, 1]
487        e2 = domain.edgelengths[1, 2]
488
489        total_flux = -(e0*flux0+e1*flux1+e2*flux2)/domain.areas[1]
490        assert allclose(total_flux, [-0.68218178, -166.6, -35.93333333])
491
492
493        domain.compute_fluxes()
494
495        #assert allclose(total_flux, domain.explicit_update[1,:])
496        for i, name in enumerate(['stage', 'xmomentum', 'ymomentum']):
497            assert allclose(total_flux[i],
498                            domain.quantities[name].explicit_update[1])
499
500        #assert allclose(domain.explicit_update, [
501        #    [0., -69.68888889, -69.68888889],
502        #    [-0.68218178, -166.6, -35.93333333],
503        #    [-111.77316251, 69.68888889, 0.],
504        #    [-35.68522449, 0., 69.68888889]])
505
506        assert allclose(domain.quantities['stage'].explicit_update,
507                        [0., -0.68218178, -111.77316251, -35.68522449])
508        assert allclose(domain.quantities['xmomentum'].explicit_update,
509                        [-69.68888889, -166.6, 69.68888889, 0])
510        assert allclose(domain.quantities['ymomentum'].explicit_update,
511                        [-69.68888889, -35.93333333, 0., 69.68888889])
512
513
514        #assert allclose(domain.quantities[name].explicit_update
515
516
517
518
519
520    def test_compute_fluxes2(self):
521        #Random values, incl momentum
522
523        a = [0.0, 0.0]
524        b = [0.0, 2.0]
525        c = [2.0,0.0]
526        d = [0.0, 4.0]
527        e = [2.0, 2.0]
528        f = [4.0,0.0]
529
530        points = [a, b, c, d, e, f]
531        #bac, bce, ecf, dbe
532        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
533
534        domain = Domain(points, vertices)
535        val0 = 2.+2.0/3
536        val1 = 4.+4.0/3
537        val2 = 8.+2.0/3
538        val3 = 2.+8.0/3
539
540        zl=zr=0 #Assume flat zero bed
541
542        domain.set_quantity('elevation', zl*ones( (4,3) ))
543
544
545        domain.set_quantity('stage', [[val0, val0-1, val0-2],
546                                      [val1, val1+1, val1],
547                                      [val2, val2-2, val2],
548                                      [val3-0.5, val3, val3]])
549
550        domain.set_quantity('xmomentum',
551                            [[1, 2, 3], [3, 4, 5],
552                             [1, -1, 0], [0, -2, 2]])
553
554        domain.set_quantity('ymomentum',
555                            [[1, -1, 0], [0, -3, 2],
556                             [0, 1, 0], [-1, 2, 2]])
557
558
559        domain.check_integrity()
560
561
562
563        #Flux across right edge of volume 1
564        normal = domain.get_normal(1,0)
565        ql = domain.get_conserved_quantities(vol_id=1, edge=0)
566        qr = domain.get_conserved_quantities(vol_id=2, edge=2)
567        flux0, max_speed = flux_function(normal, ql, qr, zl, zr)
568
569        #Flux across upper edge of volume 1
570        normal = domain.get_normal(1,1)
571        ql = domain.get_conserved_quantities(vol_id=1, edge=1)
572        qr = domain.get_conserved_quantities(vol_id=3, edge=0)
573        flux1, max_speed = flux_function(normal, ql, qr, zl, zr)
574
575        #Flux across lower left hypotenuse of volume 1
576        normal = domain.get_normal(1,2)
577        ql = domain.get_conserved_quantities(vol_id=1, edge=2)
578        qr = domain.get_conserved_quantities(vol_id=0, edge=1)
579        flux2, max_speed = flux_function(normal, ql, qr, zl, zr)
580
581        #Scale, add up and check that compute_fluxes is correct for vol 1
582        e0 = domain.edgelengths[1, 0]
583        e1 = domain.edgelengths[1, 1]
584        e2 = domain.edgelengths[1, 2]
585
586        total_flux = -(e0*flux0+e1*flux1+e2*flux2)/domain.areas[1]
587
588
589        domain.compute_fluxes()
590        for i, name in enumerate(['stage', 'xmomentum', 'ymomentum']):
591            assert allclose(total_flux[i],
592                            domain.quantities[name].explicit_update[1])
593        #assert allclose(total_flux, domain.explicit_update[1,:])
594
595
596    def test_compute_fluxes3(self):
597        #Random values, incl momentum
598
599        a = [0.0, 0.0]
600        b = [0.0, 2.0]
601        c = [2.0,0.0]
602        d = [0.0, 4.0]
603        e = [2.0, 2.0]
604        f = [4.0,0.0]
605
606        points = [a, b, c, d, e, f]
607        #bac, bce, ecf, dbe
608        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
609
610        domain = Domain(points, vertices)
611        val0 = 2.+2.0/3
612        val1 = 4.+4.0/3
613        val2 = 8.+2.0/3
614        val3 = 2.+8.0/3
615
616        zl=zr=-3.75 #Assume constant bed (must be less than stage)
617        domain.set_quantity('elevation', zl*ones( (4,3) ))
618
619
620        domain.set_quantity('stage', [[val0, val0-1, val0-2],
621                                      [val1, val1+1, val1],
622                                      [val2, val2-2, val2],
623                                      [val3-0.5, val3, val3]])
624
625        domain.set_quantity('xmomentum',
626                            [[1, 2, 3], [3, 4, 5],
627                             [1, -1, 0], [0, -2, 2]])
628
629        domain.set_quantity('ymomentum',
630                            [[1, -1, 0], [0, -3, 2],
631                             [0, 1, 0], [-1, 2, 2]])
632
633
634        domain.check_integrity()
635
636
637
638        #Flux across right edge of volume 1
639        normal = domain.get_normal(1,0)
640        ql = domain.get_conserved_quantities(vol_id=1, edge=0)
641        qr = domain.get_conserved_quantities(vol_id=2, edge=2)
642        flux0, max_speed = flux_function(normal, ql, qr, zl, zr)
643
644        #Flux across upper edge of volume 1
645        normal = domain.get_normal(1,1)
646        ql = domain.get_conserved_quantities(vol_id=1, edge=1)
647        qr = domain.get_conserved_quantities(vol_id=3, edge=0)
648        flux1, max_speed = flux_function(normal, ql, qr, zl, zr)
649
650        #Flux across lower left hypotenuse of volume 1
651        normal = domain.get_normal(1,2)
652        ql = domain.get_conserved_quantities(vol_id=1, edge=2)
653        qr = domain.get_conserved_quantities(vol_id=0, edge=1)
654        flux2, max_speed = flux_function(normal, ql, qr, zl, zr)
655
656        #Scale, add up and check that compute_fluxes is correct for vol 1
657        e0 = domain.edgelengths[1, 0]
658        e1 = domain.edgelengths[1, 1]
659        e2 = domain.edgelengths[1, 2]
660
661        total_flux = -(e0*flux0+e1*flux1+e2*flux2)/domain.areas[1]
662
663        domain.compute_fluxes()
664        for i, name in enumerate(['stage', 'xmomentum', 'ymomentum']):
665            assert allclose(total_flux[i],
666                            domain.quantities[name].explicit_update[1])
667
668
669
670    def xtest_catching_negative_heights(self):
671
672        #OBSOLETE
673       
674        a = [0.0, 0.0]
675        b = [0.0, 2.0]
676        c = [2.0,0.0]
677        d = [0.0, 4.0]
678        e = [2.0, 2.0]
679        f = [4.0,0.0]
680
681        points = [a, b, c, d, e, f]
682        #bac, bce, ecf, dbe
683        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
684
685        domain = Domain(points, vertices)
686        val0 = 2.+2.0/3
687        val1 = 4.+4.0/3
688        val2 = 8.+2.0/3
689        val3 = 2.+8.0/3
690
691        zl=zr=4  #Too large
692        domain.set_quantity('elevation', zl*ones( (4,3) ))
693        domain.set_quantity('stage', [[val0, val0-1, val0-2],
694                                      [val1, val1+1, val1],
695                                      [val2, val2-2, val2],
696                                      [val3-0.5, val3, val3]])
697
698        #Should fail
699        try:
700            domain.check_integrity()
701        except:
702            pass
703
704
705
706    def test_get_wet_elements(self):
707
708        a = [0.0, 0.0]
709        b = [0.0, 2.0]
710        c = [2.0,0.0]
711        d = [0.0, 4.0]
712        e = [2.0, 2.0]
713        f = [4.0,0.0]
714
715        points = [a, b, c, d, e, f]
716        #bac, bce, ecf, dbe
717        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
718
719        domain = Domain(points, vertices)
720        val0 = 2.+2.0/3
721        val1 = 4.+4.0/3
722        val2 = 8.+2.0/3
723        val3 = 2.+8.0/3
724
725        zl=zr=5
726        domain.set_quantity('elevation', zl*ones( (4,3) ))
727        domain.set_quantity('stage', [[val0, val0-1, val0-2],
728                                      [val1, val1+1, val1],
729                                      [val2, val2-2, val2],
730                                      [val3-0.5, val3, val3]])
731
732
733
734        #print domain.get_quantity('elevation').get_values(location='centroids')
735        #print domain.get_quantity('stage').get_values(location='centroids')       
736        domain.check_integrity()
737
738        indices = domain.get_wet_elements()
739        assert allclose(indices, [1,2])
740
741        indices = domain.get_wet_elements(indices=[0,1,3])
742        assert allclose(indices, [1])
743       
744
745
746    def test_get_maximum_inundation_1(self):
747
748        a = [0.0, 0.0]
749        b = [0.0, 2.0]
750        c = [2.0,0.0]
751        d = [0.0, 4.0]
752        e = [2.0, 2.0]
753        f = [4.0,0.0]
754
755        points = [a, b, c, d, e, f]
756        #bac, bce, ecf, dbe
757        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
758
759        domain = Domain(points, vertices)
760
761        domain.set_quantity('elevation', lambda x, y: x+2*y) #2 4 4 6
762        domain.set_quantity('stage', 3)
763
764        domain.check_integrity()
765
766        indices = domain.get_wet_elements()
767        assert allclose(indices, [0])
768
769        q = domain.get_maximum_inundation_elevation()
770        assert allclose(q, domain.get_quantity('elevation').get_values(location='centroids')[0])
771
772        x, y = domain.get_maximum_inundation_location()
773        assert allclose([x, y], domain.get_centroid_coordinates()[0])
774
775
776    def test_get_maximum_inundation_2(self):
777        """test_get_maximum_inundation_2(self)
778
779        Test multiple wet cells with same elevation
780        """
781       
782        a = [0.0, 0.0]
783        b = [0.0, 2.0]
784        c = [2.0,0.0]
785        d = [0.0, 4.0]
786        e = [2.0, 2.0]
787        f = [4.0,0.0]
788
789        points = [a, b, c, d, e, f]
790        #bac, bce, ecf, dbe
791        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
792
793        domain = Domain(points, vertices)
794
795        domain.set_quantity('elevation', lambda x, y: x+2*y) #2 4 4 6
796        domain.set_quantity('stage', 4.1)
797
798        domain.check_integrity()
799
800        indices = domain.get_wet_elements()
801        assert allclose(indices, [0,1,2])
802
803        q = domain.get_maximum_inundation_elevation()
804        assert allclose(q, 4)       
805
806        x, y = domain.get_maximum_inundation_location()
807        assert allclose([x, y], domain.get_centroid_coordinates()[1])       
808       
809
810    def test_get_maximum_inundation_3(self):
811        """test_get_maximum_inundation_3(self)
812
813        Test real runup example
814        """
815
816        from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross
817
818        initial_runup_height = -0.4
819        final_runup_height = -0.3
820
821
822        #--------------------------------------------------------------
823        # Setup computational domain
824        #--------------------------------------------------------------
825        N = 5
826        points, vertices, boundary = rectangular_cross(N, N) 
827        domain = Domain(points, vertices, boundary)           
828
829        #--------------------------------------------------------------
830        # Setup initial conditions
831        #--------------------------------------------------------------
832        def topography(x,y):
833            return -x/2                             # linear bed slope
834           
835
836        domain.set_quantity('elevation', topography)       # Use function for elevation
837        domain.set_quantity('friction', 0.)                # Zero friction
838        domain.set_quantity('stage', initial_runup_height) # Constant negative initial stage
839
840
841        #--------------------------------------------------------------
842        # Setup boundary conditions
843        #--------------------------------------------------------------
844        Br = Reflective_boundary(domain)              # Reflective wall
845        Bd = Dirichlet_boundary([final_runup_height,  # Constant inflow
846                                 0,
847                                 0])
848
849        # All reflective to begin with (still water)
850        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
851
852
853        #--------------------------------------------------------------
854        # Test initial inundation height
855        #--------------------------------------------------------------
856
857        indices = domain.get_wet_elements()
858        z = domain.get_quantity('elevation').\
859            get_values(location='centroids', indices=indices)
860        assert alltrue(z<initial_runup_height)
861
862        q = domain.get_maximum_inundation_elevation()
863        assert allclose(q, initial_runup_height, rtol = 1.0/N) # First order accuracy
864
865        x, y = domain.get_maximum_inundation_location()
866
867        qref = domain.get_quantity('elevation').get_values(interpolation_points = [[x, y]])
868        assert allclose(q, qref)
869
870
871        wet_elements = domain.get_wet_elements()
872        wet_elevations = domain.get_quantity('elevation').get_values(location='centroids',
873                                                                     indices=wet_elements)
874        assert alltrue(wet_elevations<initial_runup_height)
875        assert allclose(wet_elevations, z)       
876
877
878        #print domain.get_quantity('elevation').get_maximum_value(indices=wet_elements)
879        #print domain.get_quantity('elevation').get_maximum_location(indices=wet_elements)
880        #print domain.get_quantity('elevation').get_maximum_index(indices=wet_elements)
881
882       
883        #--------------------------------------------------------------
884        # Let triangles adjust
885        #--------------------------------------------------------------
886        for t in domain.evolve(yieldstep = 0.1, finaltime = 1.0):
887            pass
888
889
890        #--------------------------------------------------------------
891        # Test inundation height again
892        #--------------------------------------------------------------
893
894        indices = domain.get_wet_elements()
895        z = domain.get_quantity('elevation').\
896            get_values(location='centroids', indices=indices)
897
898        assert alltrue(z<initial_runup_height)
899
900        q = domain.get_maximum_inundation_elevation()
901        assert allclose(q, initial_runup_height, rtol = 1.0/N) # First order accuracy
902       
903        x, y = domain.get_maximum_inundation_location()
904        qref = domain.get_quantity('elevation').get_values(interpolation_points = [[x, y]])
905        assert allclose(q, qref)       
906
907
908        #--------------------------------------------------------------
909        # Update boundary to allow inflow
910        #--------------------------------------------------------------
911        domain.modify_boundary({'right': Bd})
912
913       
914        #--------------------------------------------------------------
915        # Evolve system through time
916        #--------------------------------------------------------------
917        for t in domain.evolve(yieldstep = 0.1, finaltime = 3.0):
918            #domain.write_time()
919            pass
920   
921        #--------------------------------------------------------------
922        # Test inundation height again
923        #--------------------------------------------------------------
924
925        indices = domain.get_wet_elements()
926        z = domain.get_quantity('elevation').\
927            get_values(location='centroids', indices=indices)
928
929        assert alltrue(z<final_runup_height)
930
931        q = domain.get_maximum_inundation_elevation()
932        assert allclose(q, final_runup_height, rtol = 1.0/N) # First order accuracy
933
934        x, y = domain.get_maximum_inundation_location()
935        qref = domain.get_quantity('elevation').get_values(interpolation_points = [[x, y]])
936        assert allclose(q, qref)       
937
938
939        wet_elements = domain.get_wet_elements()
940        wet_elevations = domain.get_quantity('elevation').get_values(location='centroids',
941                                                                     indices=wet_elements)
942        assert alltrue(wet_elevations<final_runup_height)
943        assert allclose(wet_elevations, z)       
944       
945
946
947    def test_another_runup_example(self):
948        """test_another_runup_example
949
950        Test runup example where actual timeseries at interpolated
951        points are tested.
952        """
953
954        #-----------------------------------------------------------------
955        # Import necessary modules
956        #-----------------------------------------------------------------
957
958        from anuga.pmesh.mesh_interface import create_mesh_from_regions
959        from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross
960        from anuga.shallow_water import Domain
961        from anuga.shallow_water import Reflective_boundary
962        from anuga.shallow_water import Dirichlet_boundary
963
964
965        #-----------------------------------------------------------------
966        # Setup computational domain
967        #-----------------------------------------------------------------
968        points, vertices, boundary = rectangular_cross(10, 10) # Basic mesh
969        domain = Domain(points, vertices, boundary) # Create domain
970        domain.set_quantities_to_be_stored(None)
971       
972
973        #-----------------------------------------------------------------
974        # Setup initial conditions
975        #-----------------------------------------------------------------
976
977        def topography(x,y): 
978            return -x/2                              # linear bed slope
979
980        domain.set_quantity('elevation', topography) 
981        domain.set_quantity('friction', 0.0)         
982        domain.set_quantity('stage', expression='elevation')           
983
984
985        #----------------------------------------------------------------
986        # Setup boundary conditions
987        #----------------------------------------------------------------
988
989        Br = Reflective_boundary(domain)      # Solid reflective wall
990        Bd = Dirichlet_boundary([-0.2,0.,0.]) # Constant boundary values
991        domain.set_boundary({'left': Br, 'right': Bd, 'top': Br, 'bottom': Br})
992
993
994        #----------------------------------------------------------------
995        # Evolve system through time
996        #----------------------------------------------------------------
997
998        interpolation_points = [[0.4,0.5], [0.6,0.5], [0.8,0.5], [0.9,0.5]]
999        gauge_values = []
1000        for _ in interpolation_points:
1001            gauge_values.append([])
1002
1003        time = []
1004        for t in domain.evolve(yieldstep = 0.1, finaltime = 5.0):
1005            # Record time series at known points
1006            time.append(domain.get_time())
1007           
1008            stage = domain.get_quantity('stage')
1009            w = stage.get_values(interpolation_points=interpolation_points)
1010           
1011            for i, _ in enumerate(interpolation_points):
1012                gauge_values[i].append(w[i])
1013
1014
1015        #print
1016        #print time
1017        #print
1018        #for i, (x,y) in enumerate(interpolation_points):
1019        #    print i, gauge_values[i]
1020        #    print
1021
1022        #Reference (nautilus 13/10/2006)
1023
1024        G0 = [-0.20000000000000001, -0.19999681443389281, -0.1986192343695303, -0.19147413648863046, -0.19132688908678019, -0.17642317476621105, -0.167376262630034, -0.16192452887426961, -0.15609171725778803, -0.15127107084302249, -0.14048864340360018, -0.19296484125327093, -0.19997006390580363, -0.19999999999937063, -0.19999999999937063, -0.19999999999938772, -0.19999999999938772, -0.19999999999938772, -0.19999999999938772, -0.19974288463035494, -0.19951636867991712, -0.19966301435195755, -0.19981082259800226, -0.19978575003960128, -0.19992942471933109, -0.19999999931029933, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989, -0.19999999999906989]
1025
1026
1027        G1 = [-0.29999999999999993, -0.29988962537199199, -0.29293904425532025, -0.28329367722887888, -0.25999146407696289, -0.22613875068011896, -0.21190705052094994, -0.19900707995208217, -0.18876305176191882, -0.18132447501091936, -0.17395459512711151, -0.15562414200985644, -0.16212999953643359, -0.18964422820514618, -0.20871181844346975, -0.21672207791083464, -0.21774940291862779, -0.21482868050219833, -0.21057786776704043, -0.20649663432591045, -0.20294932949211578, -0.19974459897911329, -0.19733648772704043, -0.19641404599824669, -0.19654095699184146, -0.19709942852191994, -0.19780873983410741, -0.19853259125123518, -0.19916495938961168, -0.19965391267799168, -0.19993539587158982, -0.2001383705551133, -0.20029344332295113, -0.20035349748150011, -0.20029886541561631, -0.20015541958920294, -0.19997273066429103, -0.19979879448668514, -0.19966016997024041, -0.19957558009501869, -0.19955725674938532, -0.19958083002853366, -0.19961752462568647, -0.19965296611330258, -0.19968998132634594, -0.19972532942208607, -0.19975372922008239, -0.19977196116929855, -0.19977951443660594, -0.19977792107284789, -0.19976991595502003]
1028
1029        G2 = [-0.40000000000000002, -0.39011996186687281, -0.33359026016903887, -0.29757449757405952, -0.27594124995715791, -0.25970211955309436, -0.24482929492054245, -0.23156757139219822, -0.21956485769139392, -0.20844522129026694, -0.19856327660654355, -0.18962303467030903, -0.17371085465024955, -0.16429840256208336, -0.17793711732368575, -0.19287799702389993, -0.20236271260796762, -0.20700727993623128, -0.20847704371373174, -0.20796895600687262, -0.20653398626186478, -0.20480656169870676, -0.20295863990994492, -0.20100199602968896, -0.19940642689498472, -0.19858371478015749, -0.19838672154605322, -0.19851093923669558, -0.19878191998909323, -0.19910827645394291, -0.19943514333832094, -0.19971231361970535, -0.19992429278849655, -0.20010744405928019, -0.20025927002359642, -0.20034751667523681, -0.20035504591467249, -0.20029401385620157, -0.20019492358237226, -0.20008934249434918, -0.19999808924091636, -0.19993869218976712, -0.19991589568150098, -0.19991815777945968, -0.19993012995477188, -0.19994576118144997, -0.19996497193815974, -0.19998586151236197, -0.20000487253824847, -0.20001903000364174, -0.20002698661385457]
1030
1031        G3 = [-0.45000000000000001, -0.37713945714588398, -0.33029565026933816, -0.30598209033945367, -0.28847101155177313, -0.27211191064563195, -0.25701544058818926, -0.24298945948410997, -0.23010402733784807, -0.21820351802867713, -0.20709938367218383, -0.19719881806182216, -0.18568281604361933, -0.16828653906676322, -0.16977310768235579, -0.1832707289594605, -0.19483524345250974, -0.20233480051649216, -0.20630757214159207, -0.20763927857964531, -0.20724458160595791, -0.20599191745446047, -0.20438329669495012, -0.20256105512496606, -0.20071269486729407, -0.19934403619901719, -0.19866860191898347, -0.19849975056296071, -0.19860870923007437, -0.19885838217851401, -0.19916422433758982, -0.19946861981642039, -0.19972267778871666, -0.19993013816258154, -0.20011063428833351, -0.20024891930311628, -0.20031882555219671, -0.20031326268593497, -0.20024881068472311, -0.20015443214902759, -0.20005669097631221, -0.19997542564643309, -0.19992564006223304, -0.19990746148869892, -0.19990923999172872, -0.19991956416813192, -0.19993484556273733, -0.1999538628054662, -0.19997381636620407, -0.19999130900268777, -0.20000388227457688]
1032
1033        #assert allclose(gauge_values[0], G0)
1034        print len(G0), len(gauge_values[0])
1035        print len(G1), len(gauge_values[1])
1036
1037       
1038        assert allclose(gauge_values[1], G1)
1039        assert allclose(gauge_values[2], G2)
1040        assert allclose(gauge_values[3], G3)       
1041
1042
1043
1044
1045
1046
1047
1048    #####################################################
1049    def test_initial_condition(self):
1050        """Test that initial condition is output at time == 0
1051        """
1052
1053        from anuga.config import g
1054        import copy
1055
1056        a = [0.0, 0.0]
1057        b = [0.0, 2.0]
1058        c = [2.0, 0.0]
1059        d = [0.0, 4.0]
1060        e = [2.0, 2.0]
1061        f = [4.0, 0.0]
1062
1063        points = [a, b, c, d, e, f]
1064        #bac, bce, ecf, dbe
1065        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1066
1067        domain = Domain(points, vertices)
1068
1069        #Set up for a gradient of (3,0) at mid triangle
1070        def slope(x, y):
1071            return 3*x
1072
1073        h = 0.1
1074        def stage(x,y):
1075            return slope(x,y)+h
1076
1077        domain.set_quantity('elevation', slope)
1078        domain.set_quantity('stage', stage)
1079
1080        initial_stage = copy.copy(domain.quantities['stage'].vertex_values)
1081
1082        domain.set_boundary({'exterior': Reflective_boundary(domain)})
1083
1084        #Evolution
1085        for t in domain.evolve(yieldstep = 1.0, finaltime = 2.0):
1086            stage = domain.quantities['stage'].vertex_values
1087
1088            if t == 0.0:
1089                assert allclose(stage, initial_stage)
1090            else:
1091                assert not allclose(stage, initial_stage)
1092
1093        os.remove(domain.filename + '.sww')
1094
1095
1096
1097    #####################################################
1098    def test_gravity(self):
1099        #Assuming no friction
1100
1101        from anuga.config import g
1102
1103        a = [0.0, 0.0]
1104        b = [0.0, 2.0]
1105        c = [2.0, 0.0]
1106        d = [0.0, 4.0]
1107        e = [2.0, 2.0]
1108        f = [4.0, 0.0]
1109
1110        points = [a, b, c, d, e, f]
1111        #bac, bce, ecf, dbe
1112        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1113
1114        domain = Domain(points, vertices)
1115
1116        #Set up for a gradient of (3,0) at mid triangle
1117        def slope(x, y):
1118            return 3*x
1119
1120        h = 0.1
1121        def stage(x,y):
1122            return slope(x,y)+h
1123
1124        domain.set_quantity('elevation', slope)
1125        domain.set_quantity('stage', stage)
1126
1127        for name in domain.conserved_quantities:
1128            assert allclose(domain.quantities[name].explicit_update, 0)
1129            assert allclose(domain.quantities[name].semi_implicit_update, 0)
1130
1131        domain.compute_forcing_terms()
1132
1133        assert allclose(domain.quantities['stage'].explicit_update, 0)
1134        assert allclose(domain.quantities['xmomentum'].explicit_update, -g*h*3)
1135        assert allclose(domain.quantities['ymomentum'].explicit_update, 0)
1136
1137
1138    def test_manning_friction(self):
1139        from anuga.config import g
1140
1141        a = [0.0, 0.0]
1142        b = [0.0, 2.0]
1143        c = [2.0, 0.0]
1144        d = [0.0, 4.0]
1145        e = [2.0, 2.0]
1146        f = [4.0, 0.0]
1147
1148        points = [a, b, c, d, e, f]
1149        #bac, bce, ecf, dbe
1150        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1151
1152        domain = Domain(points, vertices)
1153
1154        #Set up for a gradient of (3,0) at mid triangle
1155        def slope(x, y):
1156            return 3*x
1157
1158        h = 0.1
1159        def stage(x,y):
1160            return slope(x,y)+h
1161
1162        eta = 0.07
1163        domain.set_quantity('elevation', slope)
1164        domain.set_quantity('stage', stage)
1165        domain.set_quantity('friction', eta)
1166
1167        for name in domain.conserved_quantities:
1168            assert allclose(domain.quantities[name].explicit_update, 0)
1169            assert allclose(domain.quantities[name].semi_implicit_update, 0)
1170
1171        domain.compute_forcing_terms()
1172
1173        assert allclose(domain.quantities['stage'].explicit_update, 0)
1174        assert allclose(domain.quantities['xmomentum'].explicit_update, -g*h*3)
1175        assert allclose(domain.quantities['ymomentum'].explicit_update, 0)
1176
1177        assert allclose(domain.quantities['stage'].semi_implicit_update, 0)
1178        assert allclose(domain.quantities['xmomentum'].semi_implicit_update, 0)
1179        assert allclose(domain.quantities['ymomentum'].semi_implicit_update, 0)
1180
1181        #Create some momentum for friction to work with
1182        domain.set_quantity('xmomentum', 1)
1183        S = -g * eta**2 / h**(7.0/3)
1184
1185        domain.compute_forcing_terms()
1186        assert allclose(domain.quantities['stage'].semi_implicit_update, 0)
1187        assert allclose(domain.quantities['xmomentum'].semi_implicit_update, S)
1188        assert allclose(domain.quantities['ymomentum'].semi_implicit_update, 0)
1189
1190        #A more complex example
1191        domain.quantities['stage'].semi_implicit_update[:] = 0.0
1192        domain.quantities['xmomentum'].semi_implicit_update[:] = 0.0
1193        domain.quantities['ymomentum'].semi_implicit_update[:] = 0.0
1194
1195        domain.set_quantity('xmomentum', 3)
1196        domain.set_quantity('ymomentum', 4)
1197
1198        S = -g * eta**2 * 5 / h**(7.0/3)
1199
1200
1201        domain.compute_forcing_terms()
1202
1203        assert allclose(domain.quantities['stage'].semi_implicit_update, 0)
1204        assert allclose(domain.quantities['xmomentum'].semi_implicit_update, 3*S)
1205        assert allclose(domain.quantities['ymomentum'].semi_implicit_update, 4*S)
1206
1207    def test_constant_wind_stress(self):
1208        from anuga.config import rho_a, rho_w, eta_w
1209        from math import pi, cos, sin, sqrt
1210
1211        a = [0.0, 0.0]
1212        b = [0.0, 2.0]
1213        c = [2.0, 0.0]
1214        d = [0.0, 4.0]
1215        e = [2.0, 2.0]
1216        f = [4.0, 0.0]
1217
1218        points = [a, b, c, d, e, f]
1219        #bac, bce, ecf, dbe
1220        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1221
1222
1223        domain = Domain(points, vertices)
1224
1225        #Flat surface with 1m of water
1226        domain.set_quantity('elevation', 0)
1227        domain.set_quantity('stage', 1.0)
1228        domain.set_quantity('friction', 0)
1229
1230        Br = Reflective_boundary(domain)
1231        domain.set_boundary({'exterior': Br})
1232
1233        #Setup only one forcing term, constant wind stress
1234        s = 100
1235        phi = 135
1236        domain.forcing_terms = []
1237        domain.forcing_terms.append( Wind_stress(s, phi) )
1238
1239        domain.compute_forcing_terms()
1240
1241
1242        const = eta_w*rho_a/rho_w
1243
1244        #Convert to radians
1245        phi = phi*pi/180
1246
1247        #Compute velocity vector (u, v)
1248        u = s*cos(phi)
1249        v = s*sin(phi)
1250
1251        #Compute wind stress
1252        S = const * sqrt(u**2 + v**2)
1253
1254        assert allclose(domain.quantities['stage'].explicit_update, 0)
1255        assert allclose(domain.quantities['xmomentum'].explicit_update, S*u)
1256        assert allclose(domain.quantities['ymomentum'].explicit_update, S*v)
1257
1258
1259    def test_variable_wind_stress(self):
1260        from anuga.config import rho_a, rho_w, eta_w
1261        from math import pi, cos, sin, sqrt
1262
1263        a = [0.0, 0.0]
1264        b = [0.0, 2.0]
1265        c = [2.0, 0.0]
1266        d = [0.0, 4.0]
1267        e = [2.0, 2.0]
1268        f = [4.0, 0.0]
1269
1270        points = [a, b, c, d, e, f]
1271        #bac, bce, ecf, dbe
1272        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1273
1274        domain = Domain(points, vertices)
1275
1276        #Flat surface with 1m of water
1277        domain.set_quantity('elevation', 0)
1278        domain.set_quantity('stage', 1.0)
1279        domain.set_quantity('friction', 0)
1280
1281        Br = Reflective_boundary(domain)
1282        domain.set_boundary({'exterior': Br})
1283
1284
1285        domain.time = 5.54 #Take a random time (not zero)
1286
1287        #Setup only one forcing term, constant wind stress
1288        s = 100
1289        phi = 135
1290        domain.forcing_terms = []
1291        domain.forcing_terms.append( Wind_stress(s = speed, phi = angle) )
1292
1293        domain.compute_forcing_terms()
1294
1295        #Compute reference solution
1296        const = eta_w*rho_a/rho_w
1297
1298        N = domain.number_of_elements
1299
1300        xc = domain.get_centroid_coordinates()
1301        t = domain.time
1302
1303        x = xc[:,0]
1304        y = xc[:,1]
1305        s_vec = speed(t,x,y)
1306        phi_vec = angle(t,x,y)
1307
1308
1309        for k in range(N):
1310            #Convert to radians
1311            phi = phi_vec[k]*pi/180
1312            s = s_vec[k]
1313
1314            #Compute velocity vector (u, v)
1315            u = s*cos(phi)
1316            v = s*sin(phi)
1317
1318            #Compute wind stress
1319            S = const * sqrt(u**2 + v**2)
1320
1321            assert allclose(domain.quantities['stage'].explicit_update[k], 0)
1322            assert allclose(domain.quantities['xmomentum'].explicit_update[k], S*u)
1323            assert allclose(domain.quantities['ymomentum'].explicit_update[k], S*v)
1324
1325
1326
1327
1328    def test_windfield_from_file(self):
1329        from anuga.config import rho_a, rho_w, eta_w
1330        from math import pi, cos, sin, sqrt
1331        from anuga.config import time_format
1332        from anuga.abstract_2d_finite_volumes.util import file_function
1333        import time
1334
1335
1336        a = [0.0, 0.0]
1337        b = [0.0, 2.0]
1338        c = [2.0, 0.0]
1339        d = [0.0, 4.0]
1340        e = [2.0, 2.0]
1341        f = [4.0, 0.0]
1342
1343        points = [a, b, c, d, e, f]
1344        #bac, bce, ecf, dbe
1345        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1346
1347        domain = Domain(points, vertices)
1348
1349        #Flat surface with 1m of water
1350        domain.set_quantity('elevation', 0)
1351        domain.set_quantity('stage', 1.0)
1352        domain.set_quantity('friction', 0)
1353
1354        Br = Reflective_boundary(domain)
1355        domain.set_boundary({'exterior': Br})
1356
1357
1358        domain.time = 7 #Take a time that is represented in file (not zero)
1359
1360        #Write wind stress file (ensure that domain.time is covered)
1361        #Take x=1 and y=0
1362        filename = 'test_windstress_from_file'
1363        start = time.mktime(time.strptime('2000', '%Y'))
1364        fid = open(filename + '.txt', 'w')
1365        dt = 1  #One second interval
1366        t = 0.0
1367        while t <= 10.0:
1368            t_string = time.strftime(time_format, time.gmtime(t+start))
1369
1370            fid.write('%s, %f %f\n' %(t_string,
1371                                      speed(t,[1],[0])[0],
1372                                      angle(t,[1],[0])[0]))
1373            t += dt
1374
1375        fid.close()
1376
1377
1378        #Convert ASCII file to NetCDF (Which is what we really like!)
1379        from data_manager import timefile2netcdf       
1380        timefile2netcdf(filename)
1381        os.remove(filename + '.txt')
1382
1383       
1384        #Setup wind stress
1385        F = file_function(filename + '.tms', quantities = ['Attribute0',
1386                                                           'Attribute1'])
1387        os.remove(filename + '.tms')
1388       
1389
1390        #print 'F(5)', F(5)
1391
1392        #print 'F(5,x,y)', F(5,x=zeros(3),y=zeros(3))
1393       
1394        #print dir(F)
1395        #print F.T
1396        #print F.precomputed_values
1397        #
1398        #F = file_function(filename + '.txt')       
1399        #
1400        #print dir(F)
1401        #print F.T       
1402        #print F.Q
1403       
1404        W = Wind_stress(F)
1405
1406        domain.forcing_terms = []
1407        domain.forcing_terms.append(W)
1408
1409        domain.compute_forcing_terms()
1410
1411        #Compute reference solution
1412        const = eta_w*rho_a/rho_w
1413
1414        N = domain.number_of_elements
1415
1416        t = domain.time
1417
1418        s = speed(t,[1],[0])[0]
1419        phi = angle(t,[1],[0])[0]
1420
1421        #Convert to radians
1422        phi = phi*pi/180
1423
1424
1425        #Compute velocity vector (u, v)
1426        u = s*cos(phi)
1427        v = s*sin(phi)
1428
1429        #Compute wind stress
1430        S = const * sqrt(u**2 + v**2)
1431
1432        for k in range(N):
1433            assert allclose(domain.quantities['stage'].explicit_update[k], 0)
1434            assert allclose(domain.quantities['xmomentum'].explicit_update[k], S*u)
1435            assert allclose(domain.quantities['ymomentum'].explicit_update[k], S*v)
1436
1437
1438       
1439
1440    def test_wind_stress_error_condition(self):
1441        """Test that windstress reacts properly when forcing functions
1442        are wrong - e.g. returns a scalar
1443        """
1444
1445        from anuga.config import rho_a, rho_w, eta_w
1446        from math import pi, cos, sin, sqrt
1447
1448        a = [0.0, 0.0]
1449        b = [0.0, 2.0]
1450        c = [2.0, 0.0]
1451        d = [0.0, 4.0]
1452        e = [2.0, 2.0]
1453        f = [4.0, 0.0]
1454
1455        points = [a, b, c, d, e, f]
1456        #bac, bce, ecf, dbe
1457        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1458
1459        domain = Domain(points, vertices)
1460
1461        #Flat surface with 1m of water
1462        domain.set_quantity('elevation', 0)
1463        domain.set_quantity('stage', 1.0)
1464        domain.set_quantity('friction', 0)
1465
1466        Br = Reflective_boundary(domain)
1467        domain.set_boundary({'exterior': Br})
1468
1469
1470        domain.time = 5.54 #Take a random time (not zero)
1471
1472        #Setup only one forcing term, bad func
1473        domain.forcing_terms = []
1474
1475        try:
1476            domain.forcing_terms.append(Wind_stress(s = scalar_func,
1477                                                    phi = angle))
1478        except AssertionError:
1479            pass
1480        else:
1481            msg = 'Should have raised exception'
1482            raise msg
1483
1484
1485        try:
1486            domain.forcing_terms.append(Wind_stress(s = speed,
1487                                                    phi = scalar_func))
1488        except AssertionError:
1489            pass
1490        else:
1491            msg = 'Should have raised exception'
1492            raise msg
1493
1494        try:
1495            domain.forcing_terms.append(Wind_stress(s = speed,
1496                                                    phi = 'xx'))
1497        except:
1498            pass
1499        else:
1500            msg = 'Should have raised exception'
1501            raise msg
1502
1503
1504    #####################################################
1505    def test_first_order_extrapolator_const_z(self):
1506
1507        a = [0.0, 0.0]
1508        b = [0.0, 2.0]
1509        c = [2.0, 0.0]
1510        d = [0.0, 4.0]
1511        e = [2.0, 2.0]
1512        f = [4.0, 0.0]
1513
1514        points = [a, b, c, d, e, f]
1515        #bac, bce, ecf, dbe
1516        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1517
1518        domain = Domain(points, vertices)
1519        val0 = 2.+2.0/3
1520        val1 = 4.+4.0/3
1521        val2 = 8.+2.0/3
1522        val3 = 2.+8.0/3
1523
1524        zl=zr=-3.75 #Assume constant bed (must be less than stage)
1525        domain.set_quantity('elevation', zl*ones( (4,3) ))
1526        domain.set_quantity('stage', [[val0, val0-1, val0-2],
1527                                      [val1, val1+1, val1],
1528                                      [val2, val2-2, val2],
1529                                      [val3-0.5, val3, val3]])
1530
1531
1532
1533        domain._order_ = 1
1534        domain.distribute_to_vertices_and_edges()
1535
1536        #Check that centroid values were distributed to vertices
1537        C = domain.quantities['stage'].centroid_values
1538        for i in range(3):
1539            assert allclose( domain.quantities['stage'].vertex_values[:,i], C)
1540
1541
1542    def test_first_order_limiter_variable_z(self):
1543        #Check that first order limiter follows bed_slope
1544        from Numeric import alltrue, greater_equal
1545        from anuga.config import epsilon
1546
1547        a = [0.0, 0.0]
1548        b = [0.0, 2.0]
1549        c = [2.0,0.0]
1550        d = [0.0, 4.0]
1551        e = [2.0, 2.0]
1552        f = [4.0,0.0]
1553
1554        points = [a, b, c, d, e, f]
1555        #bac, bce, ecf, dbe
1556        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1557
1558        domain = Domain(points, vertices)
1559        val0 = 2.+2.0/3
1560        val1 = 4.+4.0/3
1561        val2 = 8.+2.0/3
1562        val3 = 2.+8.0/3
1563
1564        domain.set_quantity('elevation', [[0,0,0], [6,0,0],
1565                                          [6,6,6], [6,6,6]])
1566        domain.set_quantity('stage', [[val0, val0, val0],
1567                                      [val1, val1, val1],
1568                                      [val2, val2, val2],
1569                                      [val3, val3, val3]])
1570
1571        E = domain.quantities['elevation'].vertex_values
1572        L = domain.quantities['stage'].vertex_values
1573
1574
1575        #Check that some stages are not above elevation (within eps)
1576        #- so that the limiter has something to work with
1577        assert not alltrue(alltrue(greater_equal(L,E-epsilon)))
1578
1579        domain._order_ = 1
1580        domain.distribute_to_vertices_and_edges()
1581
1582        #Check that all stages are above elevation (within eps)
1583        assert alltrue(alltrue(greater_equal(L,E-epsilon)))
1584
1585
1586    #####################################################
1587    def test_distribute_basic(self):
1588        #Using test data generated by abstract_2d_finite_volumes-2
1589        #Assuming no friction and flat bed (0.0)
1590
1591        a = [0.0, 0.0]
1592        b = [0.0, 2.0]
1593        c = [2.0, 0.0]
1594        d = [0.0, 4.0]
1595        e = [2.0, 2.0]
1596        f = [4.0, 0.0]
1597
1598        points = [a, b, c, d, e, f]
1599        #bac, bce, ecf, dbe
1600        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1601
1602        domain = Domain(points, vertices)
1603
1604        val0 = 2.
1605        val1 = 4.
1606        val2 = 8.
1607        val3 = 2.
1608
1609        domain.set_quantity('stage', [val0, val1, val2, val3],
1610                            location='centroids')
1611        L = domain.quantities['stage'].vertex_values
1612
1613        #First order
1614        domain._order_ = 1
1615        domain.distribute_to_vertices_and_edges()
1616        assert allclose(L[1], val1)
1617
1618        #Second order
1619        domain._order_ = 2
1620        domain.beta_w      = 0.9
1621        domain.beta_w_dry  = 0.9
1622        domain.beta_uh     = 0.9
1623        domain.beta_uh_dry = 0.9
1624        domain.beta_vh     = 0.9
1625        domain.beta_vh_dry = 0.9
1626        domain.distribute_to_vertices_and_edges()
1627        assert allclose(L[1], [2.2, 4.9, 4.9])
1628
1629
1630
1631    def test_distribute_away_from_bed(self):
1632        #Using test data generated by abstract_2d_finite_volumes-2
1633        #Assuming no friction and flat bed (0.0)
1634
1635        a = [0.0, 0.0]
1636        b = [0.0, 2.0]
1637        c = [2.0, 0.0]
1638        d = [0.0, 4.0]
1639        e = [2.0, 2.0]
1640        f = [4.0, 0.0]
1641
1642        points = [a, b, c, d, e, f]
1643        #bac, bce, ecf, dbe
1644        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1645
1646        domain = Domain(points, vertices)
1647        L = domain.quantities['stage'].vertex_values
1648
1649        def stage(x,y):
1650            return x**2
1651
1652        domain.set_quantity('stage', stage, location='centroids')
1653
1654        a, b = domain.quantities['stage'].compute_gradients()
1655        assert allclose(a[1], 3.33333334)
1656        assert allclose(b[1], 0.0)
1657
1658        domain._order_ = 1
1659        domain.distribute_to_vertices_and_edges()
1660        assert allclose(L[1], 1.77777778)
1661
1662        domain._order_ = 2
1663        domain.beta_w      = 0.9
1664        domain.beta_w_dry  = 0.9
1665        domain.beta_uh     = 0.9
1666        domain.beta_uh_dry = 0.9
1667        domain.beta_vh     = 0.9
1668        domain.beta_vh_dry = 0.9
1669        domain.distribute_to_vertices_and_edges()
1670        assert allclose(L[1], [0.57777777, 2.37777778, 2.37777778])
1671
1672
1673
1674    def test_distribute_away_from_bed1(self):
1675        #Using test data generated by abstract_2d_finite_volumes-2
1676        #Assuming no friction and flat bed (0.0)
1677
1678        a = [0.0, 0.0]
1679        b = [0.0, 2.0]
1680        c = [2.0, 0.0]
1681        d = [0.0, 4.0]
1682        e = [2.0, 2.0]
1683        f = [4.0, 0.0]
1684
1685        points = [a, b, c, d, e, f]
1686        #bac, bce, ecf, dbe
1687        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1688
1689        domain = Domain(points, vertices)
1690        L = domain.quantities['stage'].vertex_values
1691
1692        def stage(x,y):
1693            return x**4+y**2
1694
1695        domain.set_quantity('stage', stage, location='centroids')
1696        #print domain.quantities['stage'].centroid_values
1697
1698        a, b = domain.quantities['stage'].compute_gradients()
1699        assert allclose(a[1], 25.18518519)
1700        assert allclose(b[1], 3.33333333)
1701
1702        domain._order_ = 1
1703        domain.distribute_to_vertices_and_edges()
1704        assert allclose(L[1], 4.9382716)
1705
1706        domain._order_ = 2
1707        domain.beta_w      = 0.9
1708        domain.beta_w_dry  = 0.9
1709        domain.beta_uh     = 0.9
1710        domain.beta_uh_dry = 0.9
1711        domain.beta_vh     = 0.9
1712        domain.beta_vh_dry = 0.9
1713        domain.distribute_to_vertices_and_edges()
1714        assert allclose(L[1], [1.07160494, 6.46058131, 7.28262855])
1715
1716
1717
1718    def test_distribute_near_bed(self):
1719        #Using test data generated by abstract_2d_finite_volumes-2
1720        #Assuming no friction and flat bed (0.0)
1721
1722        a = [0.0, 0.0]
1723        b = [0.0, 2.0]
1724        c = [2.0, 0.0]
1725        d = [0.0, 4.0]
1726        e = [2.0, 2.0]
1727        f = [4.0, 0.0]
1728
1729        points = [a, b, c, d, e, f]
1730        #bac, bce, ecf, dbe
1731        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1732
1733        domain = Domain(points, vertices)
1734
1735
1736        #Set up for a gradient of (3,0) at mid triangle
1737        def slope(x, y):
1738            return 10*x
1739
1740        h = 0.1
1741        def stage(x,y):
1742            return slope(x,y)+h
1743
1744        domain.set_quantity('elevation', slope)
1745        domain.set_quantity('stage', stage, location='centroids')
1746
1747        #print domain.quantities['elevation'].centroid_values
1748        #print domain.quantities['stage'].centroid_values
1749
1750        E = domain.quantities['elevation'].vertex_values
1751        L = domain.quantities['stage'].vertex_values
1752
1753        #print E
1754        domain._order_ = 1
1755        domain.distribute_to_vertices_and_edges()
1756        ##assert allclose(L[1], [0.19999999, 20.05, 20.05])
1757        assert allclose(L[1], [0.1, 20.1, 20.1])
1758
1759        domain._order_ = 2
1760        domain.distribute_to_vertices_and_edges()
1761        assert allclose(L[1], [0.1, 20.1, 20.1])
1762
1763    def test_distribute_near_bed1(self):
1764        #Using test data generated by abstract_2d_finite_volumes-2
1765        #Assuming no friction and flat bed (0.0)
1766
1767        a = [0.0, 0.0]
1768        b = [0.0, 2.0]
1769        c = [2.0, 0.0]
1770        d = [0.0, 4.0]
1771        e = [2.0, 2.0]
1772        f = [4.0, 0.0]
1773
1774        points = [a, b, c, d, e, f]
1775        #bac, bce, ecf, dbe
1776        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1777
1778        domain = Domain(points, vertices)
1779
1780
1781        #Set up for a gradient of (3,0) at mid triangle
1782        def slope(x, y):
1783            return x**4+y**2
1784
1785        h = 0.1
1786        def stage(x,y):
1787            return slope(x,y)+h
1788
1789        domain.set_quantity('elevation', slope)
1790        domain.set_quantity('stage', stage)
1791
1792        #print domain.quantities['elevation'].centroid_values
1793        #print domain.quantities['stage'].centroid_values
1794
1795        E = domain.quantities['elevation'].vertex_values
1796        L = domain.quantities['stage'].vertex_values
1797
1798        #print E
1799        domain._order_ = 1
1800        domain.distribute_to_vertices_and_edges()
1801        ##assert allclose(L[1], [4.19999999, 16.07142857, 20.02857143])
1802        assert allclose(L[1], [4.1, 16.1, 20.1])
1803
1804        domain._order_ = 2
1805        domain.distribute_to_vertices_and_edges()
1806        assert allclose(L[1], [4.1, 16.1, 20.1])
1807
1808
1809
1810    def test_second_order_distribute_real_data(self):
1811        #Using test data generated by abstract_2d_finite_volumes-2
1812        #Assuming no friction and flat bed (0.0)
1813
1814        a = [0.0, 0.0]
1815        b = [0.0, 1.0/5]
1816        c = [0.0, 2.0/5]
1817        d = [1.0/5, 0.0]
1818        e = [1.0/5, 1.0/5]
1819        f = [1.0/5, 2.0/5]
1820        g = [2.0/5, 2.0/5]
1821
1822        points = [a, b, c, d, e, f, g]
1823        #bae, efb, cbf, feg
1824        vertices = [ [1,0,4], [4,5,1], [2,1,5], [5,4,6]]
1825
1826        domain = Domain(points, vertices)
1827
1828        def slope(x, y):
1829            return -x/3
1830
1831        domain.set_quantity('elevation', slope)
1832        domain.set_quantity('stage',
1833                            [0.01298164, 0.00365611,
1834                             0.01440365, -0.0381856437096],
1835                            location='centroids')
1836        domain.set_quantity('xmomentum',
1837                            [0.00670439, 0.01263789,
1838                             0.00647805, 0.0178180740668],
1839                            location='centroids')
1840        domain.set_quantity('ymomentum',
1841                            [-7.23510980e-004, -6.30413883e-005,
1842                             6.30413883e-005, 0.000200907255866],
1843                            location='centroids')
1844
1845        E = domain.quantities['elevation'].vertex_values
1846        L = domain.quantities['stage'].vertex_values
1847        X = domain.quantities['xmomentum'].vertex_values
1848        Y = domain.quantities['ymomentum'].vertex_values
1849
1850        #print E
1851        domain._order_ = 2
1852        domain.beta_w      = 0.9
1853        domain.beta_w_dry  = 0.9
1854        domain.beta_uh     = 0.9
1855        domain.beta_uh_dry = 0.9
1856        domain.beta_vh     = 0.9
1857        domain.beta_vh_dry = 0.9
1858        domain.beta_h = 0.0 #Use first order in h-limiter
1859        domain.distribute_to_vertices_and_edges()
1860
1861        #print L[1,:]
1862        #print X[1,:]
1863        #print Y[1,:]
1864
1865        assert allclose(L[1,:], [-0.00825735775384,
1866                                 -0.00801881482869,
1867                                 0.0272445025825])
1868        assert allclose(X[1,:], [0.0143507718962,
1869                                 0.0142502147066,
1870                                 0.00931268339717])
1871        assert allclose(Y[1,:], [-0.000117062180693,
1872                                 7.94434448109e-005,
1873                                 -0.000151505429018])
1874
1875
1876
1877    def test_balance_deep_and_shallow(self):
1878        """Test that balanced limiters preserve conserved quantites.
1879        """
1880        import copy
1881
1882        a = [0.0, 0.0]
1883        b = [0.0, 2.0]
1884        c = [2.0, 0.0]
1885        d = [0.0, 4.0]
1886        e = [2.0, 2.0]
1887        f = [4.0, 0.0]
1888
1889        points = [a, b, c, d, e, f]
1890
1891        #bac, bce, ecf, dbe
1892        elements = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
1893
1894        mesh = Domain(points, elements)
1895        mesh.check_integrity()
1896
1897        #Create a deliberate overshoot
1898        mesh.set_quantity('stage', [[3,0,3], [2,2,6], [5,3,8], [8,3,5]])
1899        mesh.set_quantity('elevation', 0) #Flat bed
1900        stage = mesh.quantities['stage']
1901
1902        ref_centroid_values = copy.copy(stage.centroid_values[:]) #Copy
1903
1904        #Limit
1905        mesh.distribute_to_vertices_and_edges()
1906
1907        #Assert that quantities are conserved
1908        from Numeric import sum
1909        for k in range(mesh.number_of_elements):
1910            assert allclose (ref_centroid_values[k],
1911                             sum(stage.vertex_values[k,:])/3)
1912
1913
1914        #Now try with a non-flat bed - closely hugging initial stage in places
1915        #This will create alphas in the range [0, 0.478260, 1]
1916        mesh.set_quantity('stage', [[3,0,3], [2,2,6], [5,3,8], [8,3,5]])
1917        mesh.set_quantity('elevation', [[0,0,0],
1918                                        [1.8,1.9,5.9],
1919                                        [4.6,0,0],
1920                                        [0,2,4]])
1921        stage = mesh.quantities['stage']
1922
1923        ref_centroid_values = copy.copy(stage.centroid_values[:]) #Copy
1924        ref_vertex_values = copy.copy(stage.vertex_values[:]) #Copy
1925
1926        #Limit
1927        mesh.distribute_to_vertices_and_edges()
1928
1929
1930        #Assert that all vertex quantities have changed
1931        for k in range(mesh.number_of_elements):
1932            #print ref_vertex_values[k,:], stage.vertex_values[k,:]
1933            assert not allclose (ref_vertex_values[k,:], stage.vertex_values[k,:])
1934        #and assert that quantities are still conserved
1935        from Numeric import sum
1936        for k in range(mesh.number_of_elements):
1937            assert allclose (ref_centroid_values[k],
1938                             sum(stage.vertex_values[k,:])/3)
1939
1940
1941        #Also check that Python and C version produce the same
1942        assert allclose (stage.vertex_values,
1943                         [[2,2,2],
1944                          [1.93333333, 2.03333333, 6.03333333],
1945                          [6.93333333, 4.53333333, 4.53333333],
1946                          [5.33333333, 5.33333333, 5.33333333]])
1947
1948
1949
1950
1951    def test_conservation_1(self):
1952        """Test that stage is conserved globally
1953
1954        This one uses a flat bed, reflective bdries and a suitable
1955        initial condition
1956        """
1957        from mesh_factory import rectangular
1958        from Numeric import array
1959
1960        #Create basic mesh
1961        points, vertices, boundary = rectangular(6, 6)
1962
1963        #Create shallow water domain
1964        domain = Domain(points, vertices, boundary)
1965        domain.smooth = False
1966        domain.default_order=2
1967
1968        #IC
1969        def x_slope(x, y):
1970            return x/3
1971
1972        domain.set_quantity('elevation', 0)
1973        domain.set_quantity('friction', 0)
1974        domain.set_quantity('stage', x_slope)
1975
1976        # Boundary conditions (reflective everywhere)
1977        Br = Reflective_boundary(domain)
1978        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
1979
1980        domain.check_integrity()
1981
1982        #domain.visualise = True #If you want to take a sticky beak
1983
1984        initial_volume = domain.quantities['stage'].get_integral()
1985        initial_xmom = domain.quantities['xmomentum'].get_integral()
1986
1987        #print initial_xmom
1988
1989        #Evolution
1990        for t in domain.evolve(yieldstep = 0.05, finaltime = 5.0):
1991            volume =  domain.quantities['stage'].get_integral()
1992            assert allclose (volume, initial_volume)
1993
1994            #I don't believe that the total momentum should be the same
1995            #It starts with zero and ends with zero though
1996            #xmom = domain.quantities['xmomentum'].get_integral()
1997            #print xmom
1998            #assert allclose (xmom, initial_xmom)
1999
2000        os.remove(domain.filename + '.sww')
2001
2002
2003    def test_conservation_2(self):
2004        """Test that stage is conserved globally
2005
2006        This one uses a slopy bed, reflective bdries and a suitable
2007        initial condition
2008        """
2009        from mesh_factory import rectangular
2010        from Numeric import array
2011
2012        #Create basic mesh
2013        points, vertices, boundary = rectangular(6, 6)
2014
2015        #Create shallow water domain
2016        domain = Domain(points, vertices, boundary)
2017        domain.smooth = False
2018        domain.default_order=2
2019
2020        #IC
2021        def x_slope(x, y):
2022            return x/3
2023
2024        domain.set_quantity('elevation', x_slope)
2025        domain.set_quantity('friction', 0)
2026        domain.set_quantity('stage', 0.4) #Steady
2027
2028        # Boundary conditions (reflective everywhere)
2029        Br = Reflective_boundary(domain)
2030        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
2031
2032        domain.check_integrity()
2033
2034        #domain.visualise = True #If you want to take a sticky beak
2035
2036        initial_volume = domain.quantities['stage'].get_integral()
2037        initial_xmom = domain.quantities['xmomentum'].get_integral()
2038
2039        #print initial_xmom
2040
2041        #Evolution
2042        for t in domain.evolve(yieldstep = 0.05, finaltime = 5.0):
2043            volume =  domain.quantities['stage'].get_integral()
2044            assert allclose (volume, initial_volume)
2045
2046            #FIXME: What would we expect from momentum
2047            #xmom = domain.quantities['xmomentum'].get_integral()
2048            #print xmom
2049            #assert allclose (xmom, initial_xmom)
2050
2051        os.remove(domain.filename + '.sww')
2052
2053    def test_conservation_3(self):
2054        """Test that stage is conserved globally
2055
2056        This one uses a larger grid, convoluted bed, reflective bdries and a suitable
2057        initial condition
2058        """
2059        from mesh_factory import rectangular
2060        from Numeric import array
2061
2062        #Create basic mesh
2063        points, vertices, boundary = rectangular(2, 1)
2064
2065        #Create shallow water domain
2066        domain = Domain(points, vertices, boundary)
2067        domain.smooth = False
2068        domain.default_order = 2
2069        domain.beta_h = 0.2
2070        domain.set_quantities_to_be_stored(['stage'])
2071
2072        #IC
2073        def x_slope(x, y):
2074            z = 0*x
2075            for i in range(len(x)):
2076                if x[i] < 0.3:
2077                    z[i] = x[i]/3
2078                if 0.3 <= x[i] < 0.5:
2079                    z[i] = -0.5
2080                if 0.5 <= x[i] < 0.7:
2081                    z[i] = 0.39
2082                if 0.7 <= x[i]:
2083                    z[i] = x[i]/3
2084            return z
2085
2086
2087
2088        domain.set_quantity('elevation', x_slope)
2089        domain.set_quantity('friction', 0)
2090        domain.set_quantity('stage', 0.4) #Steady
2091
2092        # Boundary conditions (reflective everywhere)
2093        Br = Reflective_boundary(domain)
2094        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
2095
2096        domain.check_integrity()
2097
2098        #domain.visualise = True #If you want to take a sticky beak
2099
2100        initial_volume = domain.quantities['stage'].get_integral()
2101        initial_xmom = domain.quantities['xmomentum'].get_integral()
2102
2103        import copy
2104        ref_centroid_values =\
2105                 copy.copy(domain.quantities['stage'].centroid_values)
2106
2107        #print 'ORG', domain.quantities['stage'].centroid_values
2108        domain.distribute_to_vertices_and_edges()
2109
2110
2111        #print domain.quantities['stage'].centroid_values
2112        assert allclose(domain.quantities['stage'].centroid_values,
2113                        ref_centroid_values)
2114
2115
2116        #Check that initial limiter doesn't violate cons quan
2117        assert allclose (domain.quantities['stage'].get_integral(),
2118                         initial_volume)
2119
2120        #Evolution
2121        for t in domain.evolve(yieldstep = 0.05, finaltime = 10):
2122            volume =  domain.quantities['stage'].get_integral()
2123            #print t, volume, initial_volume
2124            assert allclose (volume, initial_volume)
2125
2126        os.remove(domain.filename + '.sww')
2127
2128    def test_conservation_4(self):
2129        """Test that stage is conserved globally
2130
2131        This one uses a larger grid, convoluted bed, reflective bdries and a suitable
2132        initial condition
2133        """
2134        from mesh_factory import rectangular
2135        from Numeric import array
2136
2137        #Create basic mesh
2138        points, vertices, boundary = rectangular(6, 6)
2139
2140        #Create shallow water domain
2141        domain = Domain(points, vertices, boundary)
2142        domain.smooth = False
2143        domain.default_order=2
2144        domain.beta_h = 0.0
2145
2146        #IC
2147        def x_slope(x, y):
2148            z = 0*x
2149            for i in range(len(x)):
2150                if x[i] < 0.3:
2151                    z[i] = x[i]/3
2152                if 0.3 <= x[i] < 0.5:
2153                    z[i] = -0.5
2154                if 0.5 <= x[i] < 0.7:
2155                    #z[i] = 0.3 #OK with beta == 0.2
2156                    z[i] = 0.34 #OK with beta == 0.0
2157                    #z[i] = 0.35#Fails after 80 timesteps with an error
2158                                #of the order 1.0e-5
2159                if 0.7 <= x[i]:
2160                    z[i] = x[i]/3
2161            return z
2162
2163
2164
2165        domain.set_quantity('elevation', x_slope)
2166        domain.set_quantity('friction', 0)
2167        domain.set_quantity('stage', 0.4) #Steady
2168
2169        # Boundary conditions (reflective everywhere)
2170        Br = Reflective_boundary(domain)
2171        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
2172
2173        domain.check_integrity()
2174
2175        #domain.visualise = True #If you want to take a sticky beak
2176
2177        initial_volume = domain.quantities['stage'].get_integral()
2178        initial_xmom = domain.quantities['xmomentum'].get_integral()
2179
2180        import copy
2181        ref_centroid_values =\
2182                 copy.copy(domain.quantities['stage'].centroid_values)
2183
2184        #Test limiter by itself
2185        domain.distribute_to_vertices_and_edges()
2186
2187        #Check that initial limiter doesn't violate cons quan
2188        assert allclose (domain.quantities['stage'].get_integral(),
2189                         initial_volume)
2190        #NOTE: This would fail if any initial stage was less than the
2191        #corresponding bed elevation - but that is reasonable.
2192
2193
2194        #Evolution
2195        for t in domain.evolve(yieldstep = 0.05, finaltime = 10.0):
2196            volume =  domain.quantities['stage'].get_integral()
2197
2198            #print t, volume, initial_volume
2199
2200
2201            #if not allclose (volume, initial_volume):
2202            #    print 't==4.05'
2203            #    for k in range(domain.number_of_elements):
2204            #       pass
2205            #       print domain.quantities['stage'].centroid_values[k] -\
2206            #             ref_centroid_values[k]
2207
2208            assert allclose (volume, initial_volume)
2209
2210
2211        os.remove(domain.filename + '.sww')
2212
2213
2214    def test_conservation_5(self):
2215        """Test that momentum is conserved globally in
2216        steady state scenario
2217
2218        This one uses a slopy bed, dirichlet and reflective bdries
2219        """
2220        from mesh_factory import rectangular
2221        from Numeric import array
2222
2223        #Create basic mesh
2224        points, vertices, boundary = rectangular(6, 6)
2225
2226        #Create shallow water domain
2227        domain = Domain(points, vertices, boundary)
2228        domain.smooth = False
2229        domain.default_order=2
2230
2231        #IC
2232        def x_slope(x, y):
2233            return x/3
2234
2235        domain.set_quantity('elevation', x_slope)
2236        domain.set_quantity('friction', 0)
2237        domain.set_quantity('stage', 0.4) #Steady
2238
2239        # Boundary conditions (reflective everywhere)
2240        Br = Reflective_boundary(domain)
2241        Bleft = Dirichlet_boundary([0.5,0,0])
2242        Bright = Dirichlet_boundary([0.1,0,0])
2243        domain.set_boundary({'left': Bleft, 'right': Bright,
2244                             'top': Br, 'bottom': Br})
2245
2246        domain.check_integrity()
2247
2248        #domain.visualise = True #If you want to take a sticky beak
2249
2250        initial_volume = domain.quantities['stage'].get_integral()
2251        initial_xmom = domain.quantities['xmomentum'].get_integral()
2252
2253
2254        #Evolution
2255        for t in domain.evolve(yieldstep = 0.05, finaltime = 15.0):
2256            stage =  domain.quantities['stage'].get_integral()
2257            xmom = domain.quantities['xmomentum'].get_integral()
2258            ymom = domain.quantities['ymomentum'].get_integral()
2259
2260            if allclose(t, 6):  #Steady state reached
2261                steady_xmom = domain.quantities['xmomentum'].get_integral()
2262                steady_ymom = domain.quantities['ymomentum'].get_integral()
2263                steady_stage = domain.quantities['stage'].get_integral()
2264
2265            if t > 6:
2266                #print '%.2f %14.8f %14.8f' %(t, ymom, steady_ymom)
2267                assert allclose(xmom, steady_xmom)
2268                assert allclose(ymom, steady_ymom)
2269                assert allclose(stage, steady_stage)
2270
2271
2272        os.remove(domain.filename + '.sww')
2273
2274
2275
2276
2277
2278    def test_conservation_real(self):
2279        """Test that momentum is conserved globally
2280       
2281        Stephen finally made a test that revealed the problem.
2282        This test failed with code prior to 25 July 2005
2283        """
2284
2285        yieldstep = 0.01
2286        finaltime = 0.05
2287        min_depth = 1.0e-2
2288
2289
2290        import sys
2291        from os import sep; sys.path.append('..'+sep+'abstract_2d_finite_volumes')
2292        from mesh_factory import rectangular
2293
2294
2295        #Create shallow water domain
2296        points, vertices, boundary = rectangular(10, 10, len1=500, len2=500)
2297        domain = Domain(points, vertices, boundary)
2298        domain.smooth = False
2299        domain.visualise = False
2300        domain.default_order = 1
2301        domain.minimum_allowed_height = min_depth
2302
2303        # Set initial condition
2304        class Set_IC:
2305            """Set an initial condition with a constant value, for x0<x<x1
2306            """
2307
2308            def __init__(self, x0=0.25, x1=0.5, h=1.0):
2309                self.x0 = x0
2310                self.x1 = x1
2311                self.= h
2312
2313            def __call__(self, x, y):
2314                return self.h*((x>self.x0)&(x<self.x1))
2315
2316
2317        domain.set_quantity('stage', Set_IC(200.0,300.0,5.0))
2318
2319
2320        #Boundaries
2321        R = Reflective_boundary(domain)
2322        domain.set_boundary( {'left': R, 'right': R, 'top':R, 'bottom': R})
2323
2324        ref = domain.quantities['stage'].get_integral()
2325
2326        # Evolution
2327        for t in domain.evolve(yieldstep = yieldstep, finaltime = finaltime):
2328            pass
2329            #print 'Integral stage = ',\
2330            #      domain.quantities['stage'].get_integral(),\
2331            #      ' Time = ',domain.time
2332
2333
2334        now = domain.quantities['stage'].get_integral()
2335
2336        msg = 'Stage not conserved: was %f, now %f' %(ref, now)
2337        assert allclose(ref, now), msg
2338
2339        os.remove(domain.filename + '.sww')
2340
2341    def test_second_order_flat_bed_onestep(self):
2342
2343        from mesh_factory import rectangular
2344        from Numeric import array
2345
2346        #Create basic mesh
2347        points, vertices, boundary = rectangular(6, 6)
2348
2349        #Create shallow water domain
2350        domain = Domain(points, vertices, boundary)
2351        domain.smooth = False
2352        domain.default_order=2
2353        domain.beta_w      = 0.9
2354        domain.beta_w_dry  = 0.9
2355        domain.beta_uh     = 0.9
2356        domain.beta_uh_dry = 0.9
2357        domain.beta_vh     = 0.9
2358        domain.beta_vh_dry = 0.9
2359       
2360        # Boundary conditions
2361        Br = Reflective_boundary(domain)
2362        Bd = Dirichlet_boundary([0.1, 0., 0.])
2363        domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
2364
2365        domain.check_integrity()
2366
2367        #Evolution
2368        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.05):
2369            pass# domain.write_time()
2370
2371        #Data from earlier version of abstract_2d_finite_volumes
2372        assert allclose(domain.min_timestep, 0.0396825396825)
2373        assert allclose(domain.max_timestep, 0.0396825396825)
2374
2375        assert allclose(domain.quantities['stage'].centroid_values[:12],
2376                        [0.00171396, 0.02656103, 0.00241523, 0.02656103,
2377                        0.00241523, 0.02656103, 0.00241523, 0.02656103,
2378                        0.00241523, 0.02656103, 0.00241523, 0.0272623])
2379
2380        domain.distribute_to_vertices_and_edges()
2381        assert allclose(domain.quantities['stage'].vertex_values[:12,0],
2382                        [0.0001714, 0.02656103, 0.00024152,
2383                        0.02656103, 0.00024152, 0.02656103,
2384                        0.00024152, 0.02656103, 0.00024152,
2385                        0.02656103, 0.00024152, 0.0272623])
2386
2387        assert allclose(domain.quantities['stage'].vertex_values[:12,1],
2388                        [0.00315012, 0.02656103, 0.00024152, 0.02656103,
2389                         0.00024152, 0.02656103, 0.00024152, 0.02656103,
2390                         0.00024152, 0.02656103, 0.00040506, 0.0272623])
2391
2392        assert allclose(domain.quantities['stage'].vertex_values[:12,2],
2393                        [0.00182037, 0.02656103, 0.00676264,
2394                         0.02656103, 0.00676264, 0.02656103,
2395                         0.00676264, 0.02656103, 0.00676264,
2396                         0.02656103, 0.0065991, 0.0272623])
2397
2398        assert allclose(domain.quantities['xmomentum'].centroid_values[:12],
2399                        [0.00113961, 0.01302432, 0.00148672,
2400                         0.01302432, 0.00148672, 0.01302432,
2401                         0.00148672, 0.01302432, 0.00148672 ,
2402                         0.01302432, 0.00148672, 0.01337143])
2403
2404        assert allclose(domain.quantities['ymomentum'].centroid_values[:12],
2405                        [-2.91240050e-004 , 1.22721531e-004,
2406                         -1.22721531e-004, 1.22721531e-004 ,
2407                         -1.22721531e-004, 1.22721531e-004,
2408                         -1.22721531e-004 , 1.22721531e-004,
2409                         -1.22721531e-004, 1.22721531e-004,
2410                         -1.22721531e-004, -4.57969873e-005])
2411
2412        os.remove(domain.filename + '.sww')
2413
2414
2415    def test_second_order_flat_bed_moresteps(self):
2416
2417        from mesh_factory import rectangular
2418        from Numeric import array
2419
2420        #Create basic mesh
2421        points, vertices, boundary = rectangular(6, 6)
2422
2423        #Create shallow water domain
2424        domain = Domain(points, vertices, boundary)
2425        domain.smooth = False
2426        domain.default_order=2
2427
2428        # Boundary conditions
2429        Br = Reflective_boundary(domain)
2430        Bd = Dirichlet_boundary([0.1, 0., 0.])
2431        domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
2432
2433        domain.check_integrity()
2434
2435        #Evolution
2436        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.1):
2437            pass
2438
2439        #Data from earlier version of abstract_2d_finite_volumes
2440        #assert allclose(domain.min_timestep, 0.0396825396825)
2441        #assert allclose(domain.max_timestep, 0.0396825396825)
2442        #print domain.quantities['stage'].centroid_values
2443
2444        os.remove(domain.filename + '.sww')       
2445
2446
2447    def test_flatbed_first_order(self):
2448        from mesh_factory import rectangular
2449        from Numeric import array
2450
2451        #Create basic mesh
2452        N = 8
2453        points, vertices, boundary = rectangular(N, N)
2454
2455        #Create shallow water domain
2456        domain = Domain(points, vertices, boundary)
2457        domain.smooth = False
2458        domain.visualise = False
2459        domain.default_order=1
2460
2461        # Boundary conditions
2462        Br = Reflective_boundary(domain)
2463        Bd = Dirichlet_boundary([0.2,0.,0.])
2464
2465        domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
2466        domain.check_integrity()
2467
2468
2469        #Evolution
2470        for t in domain.evolve(yieldstep = 0.02, finaltime = 0.5):
2471            pass
2472            #domain.write_time()
2473
2474        #FIXME: These numbers were from version before 25/10
2475        #assert allclose(domain.min_timestep, 0.0140413643926)
2476        #assert allclose(domain.max_timestep, 0.0140947355753)
2477
2478        for i in range(3):
2479            #assert allclose(domain.quantities['stage'].edge_values[:4,i],
2480            #                [0.10730244,0.12337617,0.11200126,0.12605666])
2481
2482            assert allclose(domain.quantities['xmomentum'].edge_values[:4,i],
2483                            [0.07610894,0.06901572,0.07284461,0.06819712])
2484
2485            #assert allclose(domain.quantities['ymomentum'].edge_values[:4,i],
2486            #                [-0.0060238, -0.00157404, -0.00309633, -0.0001637])
2487
2488
2489        os.remove(domain.filename + '.sww')           
2490
2491    def test_flatbed_second_order(self):
2492        from mesh_factory import rectangular
2493        from Numeric import array
2494
2495        #Create basic mesh
2496        N = 8
2497        points, vertices, boundary = rectangular(N, N)
2498
2499        #Create shallow water domain
2500        domain = Domain(points, vertices, boundary)
2501        domain.smooth = False
2502        domain.visualise = False
2503        domain.default_order=2
2504        domain.beta_w      = 0.9
2505        domain.beta_w_dry  = 0.9
2506        domain.beta_uh     = 0.9
2507        domain.beta_uh_dry = 0.9
2508        domain.beta_vh     = 0.9
2509        domain.beta_vh_dry = 0.9       
2510        #domain.minimum_allowed_height = 0.0 #Makes it like the 'oldstyle' balance
2511
2512        # Boundary conditions
2513        Br = Reflective_boundary(domain)
2514        Bd = Dirichlet_boundary([0.2,0.,0.])
2515
2516        domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
2517        domain.check_integrity()
2518
2519        #Evolution
2520        for t in domain.evolve(yieldstep = 0.01, finaltime = 0.03):
2521            pass
2522
2523
2524        assert allclose(domain.min_timestep, 0.0210448446782)
2525        assert allclose(domain.max_timestep, 0.0210448446782)
2526
2527        #print domain.quantities['stage'].vertex_values[:4,0]
2528        #print domain.quantities['xmomentum'].vertex_values[:4,0]
2529        #print domain.quantities['ymomentum'].vertex_values[:4,0]
2530
2531        #FIXME: These numbers were from version before 25/10
2532        #assert allclose(domain.quantities['stage'].vertex_values[:4,0],
2533        #                [0.00101913,0.05352143,0.00104852,0.05354394])
2534
2535        #FIXME: These numbers were from version before 21/3/6 -
2536        #could be recreated by setting maximum_allowed_speed to 0 maybe
2537        #assert allclose(domain.quantities['xmomentum'].vertex_values[:4,0],
2538        #                [ 0.00064835, 0.03685719, 0.00085073, 0.03687313])
2539       
2540        assert allclose(domain.quantities['xmomentum'].vertex_values[:4,0],
2541                        [ 0.00090581, 0.03685719, 0.00088303, 0.03687313])
2542                       
2543                       
2544
2545        #assert allclose(domain.quantities['xmomentum'].vertex_values[:4,0],
2546        #                [0.00090581,0.03685719,0.00088303,0.03687313])
2547
2548        assert allclose(domain.quantities['ymomentum'].vertex_values[:4,0],
2549                        [-0.00139463,0.0006156,-0.00060364,0.00061827])
2550
2551
2552        os.remove(domain.filename + '.sww')
2553
2554       
2555    def test_flatbed_second_order_vmax_0(self):
2556        from mesh_factory import rectangular
2557        from Numeric import array
2558
2559        #Create basic mesh
2560        N = 8
2561        points, vertices, boundary = rectangular(N, N)
2562
2563        #Create shallow water domain
2564        domain = Domain(points, vertices, boundary)
2565        domain.smooth = False
2566        domain.visualise = False
2567        domain.default_order=2
2568        domain.beta_w      = 0.9
2569        domain.beta_w_dry  = 0.9
2570        domain.beta_uh     = 0.9
2571        domain.beta_uh_dry = 0.9
2572        domain.beta_vh     = 0.9
2573        domain.beta_vh_dry = 0.9       
2574        domain.maximum_allowed_speed = 0.0 #Makes it like the 'oldstyle'
2575
2576        # Boundary conditions
2577        Br = Reflective_boundary(domain)
2578        Bd = Dirichlet_boundary([0.2,0.,0.])
2579
2580        domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
2581        domain.check_integrity()
2582
2583        #Evolution
2584        for t in domain.evolve(yieldstep = 0.01, finaltime = 0.03):
2585            pass
2586
2587
2588        assert allclose(domain.min_timestep, 0.0210448446782)
2589        assert allclose(domain.max_timestep, 0.0210448446782)
2590
2591        #FIXME: These numbers were from version before 21/3/6 -
2592        #could be recreated by setting maximum_allowed_speed to 0 maybe
2593        assert allclose(domain.quantities['xmomentum'].vertex_values[:4,0],
2594                        [ 0.00064835, 0.03685719, 0.00085073, 0.03687313]) 
2595       
2596
2597        assert allclose(domain.quantities['ymomentum'].vertex_values[:4,0],
2598                        [-0.00139463,0.0006156,-0.00060364,0.00061827])
2599
2600
2601        os.remove(domain.filename + '.sww')
2602
2603       
2604
2605    def test_flatbed_second_order_distribute(self):
2606        #Use real data from anuga.abstract_2d_finite_volumes 2
2607        #painfully setup and extracted.
2608        from mesh_factory import rectangular
2609        from Numeric import array
2610
2611        #Create basic mesh
2612        N = 8
2613        points, vertices, boundary = rectangular(N, N)
2614
2615        #Create shallow water domain
2616        domain = Domain(points, vertices, boundary)
2617        domain.smooth = False
2618        domain.visualise = False
2619        domain.default_order=domain._order_=2
2620        domain.beta_w      = 0.9
2621        domain.beta_w_dry  = 0.9
2622        domain.beta_uh     = 0.9
2623        domain.beta_uh_dry = 0.9
2624        domain.beta_vh     = 0.9
2625        domain.beta_vh_dry = 0.9       
2626
2627        # Boundary conditions
2628        Br = Reflective_boundary(domain)
2629        Bd = Dirichlet_boundary([0.2,0.,0.])
2630
2631        domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
2632        domain.check_integrity()
2633
2634
2635
2636        for V in [False, True]:
2637            if V:
2638                #Set centroids as if system had been evolved
2639                L = zeros(2*N*N, Float)
2640                L[:32] = [7.21205592e-003, 5.35214298e-002, 1.00910824e-002,
2641                          5.35439433e-002, 1.00910824e-002, 5.35439433e-002,
2642                          1.00910824e-002, 5.35439433e-002, 1.00910824e-002,
2643                          5.35439433e-002, 1.00910824e-002, 5.35439433e-002,
2644                          1.00910824e-002, 5.35393928e-002, 1.02344264e-002,
2645                          5.59605058e-002, 0.00000000e+000, 3.31027800e-004,
2646                          0.00000000e+000, 4.37962142e-005, 0.00000000e+000,
2647                          4.37962142e-005, 0.00000000e+000, 4.37962142e-005,
2648                          0.00000000e+000, 4.37962142e-005, 0.00000000e+000,
2649                          4.37962142e-005, 0.00000000e+000, 4.37962142e-005,
2650                          0.00000000e+000, 5.57305948e-005]
2651
2652                X = zeros(2*N*N, Float)
2653                X[:32] = [6.48351607e-003, 3.68571894e-002, 8.50733285e-003,
2654                          3.68731327e-002, 8.50733285e-003, 3.68731327e-002,
2655                          8.50733285e-003, 3.68731327e-002, 8.50733285e-003,
2656                          3.68731327e-002, 8.50733285e-003, 3.68731327e-002,
2657                          8.50733285e-003, 3.68693861e-002, 8.65220973e-003,
2658                          3.85055387e-002, 0.00000000e+000, 2.86060840e-004,
2659                          0.00000000e+000, 3.58905503e-005, 0.00000000e+000,
2660                          3.58905503e-005, 0.00000000e+000, 3.58905503e-005,
2661                          0.00000000e+000, 3.58905503e-005, 0.00000000e+000,
2662                          3.58905503e-005, 0.00000000e+000, 3.58905503e-005,
2663                          0.00000000e+000, 4.57662812e-005]
2664
2665                Y = zeros(2*N*N, Float)
2666                Y[:32]=[-1.39463104e-003, 6.15600298e-004, -6.03637382e-004,
2667                        6.18272251e-004, -6.03637382e-004, 6.18272251e-004,
2668                        -6.03637382e-004, 6.18272251e-004, -6.03637382e-004,
2669                        6.18272251e-004, -6.03637382e-004, 6.18272251e-004,
2670                        -6.03637382e-004, 6.18599320e-004, -6.74622797e-004,
2671                        -1.48934756e-004, 0.00000000e+000, -5.35079969e-005,
2672                        0.00000000e+000, -2.57264987e-005, 0.00000000e+000,
2673                        -2.57264987e-005, 0.00000000e+000, -2.57264987e-005,
2674                        0.00000000e+000, -2.57264987e-005, 0.00000000e+000,
2675                        -2.57264987e-005, 0.00000000e+000, -2.57264987e-005,
2676                        0.00000000e+000, -2.57635178e-005]
2677
2678
2679                domain.set_quantity('stage', L, location='centroids')
2680                domain.set_quantity('xmomentum', X, location='centroids')
2681                domain.set_quantity('ymomentum', Y, location='centroids')
2682
2683                domain.check_integrity()
2684            else:
2685                #Evolution
2686                for t in domain.evolve(yieldstep = 0.01, finaltime = 0.03):
2687                    pass
2688                assert allclose(domain.min_timestep, 0.0210448446782)
2689                assert allclose(domain.max_timestep, 0.0210448446782)
2690
2691
2692            #Centroids were correct but not vertices.
2693            #Hence the check of distribute below.
2694            assert allclose(domain.quantities['stage'].centroid_values[:4],
2695                            [0.00721206,0.05352143,0.01009108,0.05354394])
2696
2697            assert allclose(domain.quantities['xmomentum'].centroid_values[:4],
2698                            [0.00648352,0.03685719,0.00850733,0.03687313])
2699
2700            assert allclose(domain.quantities['ymomentum'].centroid_values[:4],
2701                            [-0.00139463,0.0006156,-0.00060364,0.00061827])
2702
2703            #print 'C17=', domain.quantities['xmomentum'].centroid_values[17]
2704            #print 'C19=', domain.quantities['xmomentum'].centroid_values[19]
2705
2706            #assert allclose(domain.quantities['xmomentum'].centroid_values[17],0.00028606084)
2707            ##print domain.quantities['xmomentum'].centroid_values[17], V
2708            ##print
2709            if not V:
2710                #FIXME: These numbers were from version before 21/3/6 -
2711                #could be recreated by setting maximum_allowed_speed to 0 maybe           
2712               
2713                #assert allclose(domain.quantities['xmomentum'].centroid_values[17], 0.0)               
2714                assert allclose(domain.quantities['xmomentum'].centroid_values[17], 0.000286060839592)                         
2715
2716            else:
2717                assert allclose(domain.quantities['xmomentum'].centroid_values[17], 0.00028606084)
2718
2719            import copy
2720            XX = copy.copy(domain.quantities['xmomentum'].centroid_values)
2721            assert allclose(domain.quantities['xmomentum'].centroid_values, XX)
2722
2723            domain.distribute_to_vertices_and_edges()
2724
2725            #assert allclose(domain.quantities['xmomentum'].centroid_values, XX)
2726
2727            #assert allclose(domain.quantities['xmomentum'].centroid_values[17],
2728            #                0.0)
2729            assert allclose(domain.quantities['xmomentum'].centroid_values[17], 0.000286060839592)                                                 
2730
2731
2732            #FIXME: These numbers were from version before 25/10
2733            #assert allclose(domain.quantities['stage'].vertex_values[:4,0],
2734            #                [0.00101913,0.05352143,0.00104852,0.05354394])
2735
2736            assert allclose(domain.quantities['ymomentum'].vertex_values[:4,0],
2737                            [-0.00139463,0.0006156,-0.00060364,0.00061827])
2738
2739
2740            assert allclose(domain.quantities['xmomentum'].vertex_values[:4,0],
2741                            [0.00090581,0.03685719,0.00088303,0.03687313])
2742
2743
2744            #NB NO longer relvant:
2745
2746            #This was the culprit. First triangles vertex 0 had an
2747            #x-momentum of 0.0064835 instead of 0.00090581 and
2748            #third triangle had 0.00850733 instead of 0.00088303
2749            #print domain.quantities['xmomentum'].vertex_values[:4,0]
2750
2751            #print domain.quantities['xmomentum'].vertex_values[:4,0]
2752            #assert allclose(domain.quantities['xmomentum'].vertex_values[:4,0],
2753            #                [0.00090581,0.03685719,0.00088303,0.03687313])
2754
2755        os.remove(domain.filename + '.sww')
2756
2757
2758
2759    def test_bedslope_problem_first_order(self):
2760
2761        from mesh_factory import rectangular
2762        from Numeric import array
2763
2764        #Create basic mesh
2765        points, vertices, boundary = rectangular(6, 6)
2766
2767        #Create shallow water domain
2768        domain = Domain(points, vertices, boundary)
2769        domain.smooth = False
2770        domain.default_order=1
2771
2772        #Bed-slope and friction
2773        def x_slope(x, y):
2774            return -x/3
2775
2776        domain.set_quantity('elevation', x_slope)
2777
2778        # Boundary conditions
2779        Br = Reflective_boundary(domain)
2780        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
2781
2782        #Initial condition
2783        domain.set_quantity('stage', Constant_height(x_slope, 0.05))
2784        domain.check_integrity()
2785
2786        #Evolution
2787        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.05):
2788            pass# domain.write_time()
2789
2790        assert allclose(domain.min_timestep, 0.050010003001)
2791        assert allclose(domain.max_timestep, 0.050010003001)
2792
2793
2794        os.remove(domain.filename + '.sww')
2795       
2796    def test_bedslope_problem_first_order_moresteps(self):
2797
2798        from mesh_factory import rectangular
2799        from Numeric import array
2800
2801        #Create basic mesh
2802        points, vertices, boundary = rectangular(6, 6)
2803
2804        #Create shallow water domain
2805        domain = Domain(points, vertices, boundary)
2806        domain.smooth = False
2807        domain.default_order=1
2808        domain.beta_h = 0.0 #Use first order in h-limiter
2809
2810        #Bed-slope and friction
2811        def x_slope(x, y):
2812            return -x/3
2813
2814        domain.set_quantity('elevation', x_slope)
2815
2816        # Boundary conditions
2817        Br = Reflective_boundary(domain)
2818        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
2819
2820        #Initial condition
2821        domain.set_quantity('stage', Constant_height(x_slope, 0.05))
2822        domain.check_integrity()
2823
2824        #Evolution
2825        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.5):
2826            pass# domain.write_time()
2827
2828        #Data from earlier version of abstract_2d_finite_volumes
2829        #print domain.quantities['stage'].centroid_values
2830
2831        assert allclose(domain.quantities['stage'].centroid_values,
2832                        [-0.02998628, -0.01520652, -0.03043492,
2833                        -0.0149132, -0.03004706, -0.01476251,
2834                        -0.0298215, -0.01467976, -0.02988158,
2835                        -0.01474662, -0.03036161, -0.01442995,
2836                        -0.07624583, -0.06297061, -0.07733792,
2837                        -0.06342237, -0.07695439, -0.06289595,
2838                        -0.07635559, -0.0626065, -0.07633628,
2839                        -0.06280072, -0.07739632, -0.06386738,
2840                        -0.12161738, -0.11028239, -0.1223796,
2841                        -0.11095953, -0.12189744, -0.11048616,
2842                        -0.12074535, -0.10987605, -0.12014311,
2843                        -0.10976691, -0.12096859, -0.11087692,
2844                        -0.16868259, -0.15868061, -0.16801135,
2845                        -0.1588003, -0.16674343, -0.15813323,
2846                        -0.16457595, -0.15693826, -0.16281096,
2847                        -0.15585154, -0.16283873, -0.15540068,
2848                        -0.17450362, -0.19919913, -0.18062882,
2849                        -0.19764131, -0.17783111, -0.19407213,
2850                        -0.1736915, -0.19053624, -0.17228678,
2851                        -0.19105634, -0.17920133, -0.1968828,
2852                        -0.14244395, -0.14604641, -0.14473537,
2853                        -0.1506107, -0.14510055, -0.14919522,
2854                        -0.14175896, -0.14560798, -0.13911658,
2855                        -0.14439383, -0.13924047, -0.14829043])
2856
2857        os.remove(domain.filename + '.sww')
2858       
2859    def test_bedslope_problem_second_order_one_step(self):
2860
2861        from mesh_factory import rectangular
2862        from Numeric import array
2863
2864        #Create basic mesh
2865        points, vertices, boundary = rectangular(6, 6)
2866
2867        #Create shallow water domain
2868        domain = Domain(points, vertices, boundary)
2869        domain.smooth = False
2870        domain.default_order=2
2871        domain.beta_w      = 0.9
2872        domain.beta_w_dry  = 0.9
2873        domain.beta_uh     = 0.9
2874        domain.beta_uh_dry = 0.9
2875        domain.beta_vh     = 0.9
2876        domain.beta_vh_dry = 0.9
2877
2878        #Bed-slope and friction at vertices (and interpolated elsewhere)
2879        def x_slope(x, y):
2880            return -x/3
2881
2882        domain.set_quantity('elevation', x_slope)
2883
2884        # Boundary conditions
2885        Br = Reflective_boundary(domain)
2886        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
2887
2888        #Initial condition
2889        domain.set_quantity('stage', Constant_height(x_slope, 0.05))
2890        domain.check_integrity()
2891
2892        assert allclose(domain.quantities['stage'].centroid_values,
2893                        [0.01296296, 0.03148148, 0.01296296,
2894                        0.03148148, 0.01296296, 0.03148148,
2895                        0.01296296, 0.03148148, 0.01296296,
2896                        0.03148148, 0.01296296, 0.03148148,
2897                        -0.04259259, -0.02407407, -0.04259259,
2898                        -0.02407407, -0.04259259, -0.02407407,
2899                        -0.04259259, -0.02407407, -0.04259259,
2900                        -0.02407407, -0.04259259, -0.02407407,
2901                        -0.09814815, -0.07962963, -0.09814815,
2902                        -0.07962963, -0.09814815, -0.07962963,
2903                        -0.09814815, -0.07962963, -0.09814815,
2904                        -0.07962963, -0.09814815, -0.07962963,
2905                        -0.1537037 , -0.13518519, -0.1537037,
2906                        -0.13518519, -0.1537037, -0.13518519,
2907                        -0.1537037 , -0.13518519, -0.1537037,
2908                        -0.13518519, -0.1537037, -0.13518519,
2909                        -0.20925926, -0.19074074, -0.20925926,
2910                        -0.19074074, -0.20925926, -0.19074074,
2911                        -0.20925926, -0.19074074, -0.20925926,
2912                        -0.19074074, -0.20925926, -0.19074074,
2913                        -0.26481481, -0.2462963, -0.26481481,
2914                        -0.2462963, -0.26481481, -0.2462963,
2915                        -0.26481481, -0.2462963, -0.26481481,
2916                        -0.2462963, -0.26481481, -0.2462963])
2917
2918
2919        #print domain.quantities['stage'].extrapolate_second_order()
2920        #domain.distribute_to_vertices_and_edges()
2921        #print domain.quantities['stage'].vertex_values[:,0]
2922
2923        #Evolution
2924        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.05):
2925            #domain.write_time()
2926            pass
2927
2928
2929        #print domain.quantities['stage'].centroid_values
2930        assert allclose(domain.quantities['stage'].centroid_values,
2931                 [0.01290985, 0.02356019, 0.01619096, 0.02356019, 0.01619096,
2932                  0.02356019, 0.01619096, 0.02356019, 0.01619096, 0.02356019,
2933                  0.01619096, 0.0268413, -0.04411074, -0.0248011, -0.04186556,
2934                  -0.0248011, -0.04186556, -0.0248011, -0.04186556, -0.0248011,
2935                  -0.04186556, -0.0248011, -0.04186556, -0.02255593,
2936                  -0.09966629, -0.08035666, -0.09742112, -0.08035666,
2937                  -0.09742112, -0.08035666, -0.09742112, -0.08035666,
2938                  -0.09742112, -0.08035666, -0.09742112, -0.07811149,
2939                  -0.15522185, -0.13591222, -0.15297667, -0.13591222,
2940                  -0.15297667, -0.13591222, -0.15297667, -0.13591222,
2941                  -0.15297667, -0.13591222, -0.15297667, -0.13366704,
2942                  -0.2107774, -0.19146777, -0.20853223, -0.19146777,
2943                  -0.20853223, -0.19146777, -0.20853223, -0.19146777,
2944                  -0.20853223, -0.19146777, -0.20853223, -0.1892226,
2945                  -0.26120669, -0.24776246, -0.25865535, -0.24776246,
2946                  -0.25865535, -0.24776246, -0.25865535, -0.24776246,
2947                  -0.25865535, -0.24776246, -0.25865535, -0.24521113])
2948
2949        os.remove(domain.filename + '.sww')
2950
2951    def test_bedslope_problem_second_order_two_steps(self):
2952
2953        from mesh_factory import rectangular
2954        from Numeric import array
2955
2956        #Create basic mesh
2957        points, vertices, boundary = rectangular(6, 6)
2958
2959        #Create shallow water domain
2960        domain = Domain(points, vertices, boundary)
2961        domain.smooth = False
2962        domain.default_order=2
2963        domain.beta_w      = 0.9
2964        domain.beta_w_dry  = 0.9
2965        domain.beta_uh     = 0.9
2966        domain.beta_uh_dry = 0.9
2967        domain.beta_vh     = 0.9
2968        domain.beta_vh_dry = 0.9
2969        domain.beta_h = 0.0 #Use first order in h-limiter
2970
2971        #Bed-slope and friction at vertices (and interpolated elsewhere)
2972        def x_slope(x, y):
2973            return -x/3
2974
2975        domain.set_quantity('elevation', x_slope)
2976
2977        # Boundary conditions
2978        Br = Reflective_boundary(domain)
2979        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
2980
2981        #Initial condition
2982        domain.set_quantity('stage', Constant_height(x_slope, 0.05))
2983        domain.check_integrity()
2984
2985        assert allclose(domain.quantities['stage'].centroid_values,
2986                        [0.01296296, 0.03148148, 0.01296296,
2987                        0.03148148, 0.01296296, 0.03148148,
2988                        0.01296296, 0.03148148, 0.01296296,
2989                        0.03148148, 0.01296296, 0.03148148,
2990                        -0.04259259, -0.02407407, -0.04259259,
2991                        -0.02407407, -0.04259259, -0.02407407,
2992                        -0.04259259, -0.02407407, -0.04259259,
2993                        -0.02407407, -0.04259259, -0.02407407,
2994                        -0.09814815, -0.07962963, -0.09814815,
2995                        -0.07962963, -0.09814815, -0.07962963,
2996                        -0.09814815, -0.07962963, -0.09814815,
2997                        -0.07962963, -0.09814815, -0.07962963,
2998                        -0.1537037 , -0.13518519, -0.1537037,
2999                        -0.13518519, -0.1537037, -0.13518519,
3000                        -0.1537037 , -0.13518519, -0.1537037,
3001                        -0.13518519, -0.1537037, -0.13518519,
3002                        -0.20925926, -0.19074074, -0.20925926,
3003                        -0.19074074, -0.20925926, -0.19074074,
3004                        -0.20925926, -0.19074074, -0.20925926,
3005                        -0.19074074, -0.20925926, -0.19074074,
3006                        -0.26481481, -0.2462963, -0.26481481,
3007                        -0.2462963, -0.26481481, -0.2462963,
3008                        -0.26481481, -0.2462963, -0.26481481,
3009                        -0.2462963, -0.26481481, -0.2462963])
3010
3011
3012        #print domain.quantities['stage'].extrapolate_second_order()
3013        #domain.distribute_to_vertices_and_edges()
3014        #print domain.quantities['stage'].vertex_values[:,0]
3015
3016        #Evolution
3017        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.1):
3018            pass
3019
3020
3021        #Data from earlier version of abstract_2d_finite_volumes ft=0.1
3022        assert allclose(domain.min_timestep, 0.0376895634803)
3023        assert allclose(domain.max_timestep, 0.0415635655309)
3024
3025
3026        assert allclose(domain.quantities['stage'].centroid_values,
3027                        [0.00855788, 0.01575204, 0.00994606, 0.01717072,
3028                         0.01005985, 0.01716362, 0.01005985, 0.01716299,
3029                         0.01007098, 0.01736248, 0.01216452, 0.02026776,
3030                         -0.04462374, -0.02479045, -0.04199789, -0.0229465,
3031                         -0.04184033, -0.02295693, -0.04184013, -0.02295675,
3032                         -0.04184486, -0.0228168, -0.04028876, -0.02036486,
3033                         -0.10029444, -0.08170809, -0.09772846, -0.08021704,
3034                         -0.09760006, -0.08022143, -0.09759984, -0.08022124,
3035                         -0.09760261, -0.08008893, -0.09603914, -0.07758209,
3036                         -0.15584152, -0.13723138, -0.15327266, -0.13572906,
3037                         -0.15314427, -0.13573349, -0.15314405, -0.13573331,
3038                         -0.15314679, -0.13560104, -0.15158523, -0.13310701,
3039                         -0.21208605, -0.19283913, -0.20955631, -0.19134189,
3040                         -0.20942821, -0.19134598, -0.20942799, -0.1913458,
3041                         -0.20943005, -0.19120952, -0.20781177, -0.18869401,
3042                         -0.25384082, -0.2463294, -0.25047649, -0.24464654,
3043                         -0.25031159, -0.24464253, -0.25031112, -0.24464253,
3044                         -0.25031463, -0.24454764, -0.24885323, -0.24286438])
3045
3046
3047        os.remove(domain.filename + '.sww')
3048
3049    def test_bedslope_problem_second_order_two_yieldsteps(self):
3050
3051        from mesh_factory import rectangular
3052        from Numeric import array
3053
3054        #Create basic mesh
3055        points, vertices, boundary = rectangular(6, 6)
3056
3057        #Create shallow water domain
3058        domain = Domain(points, vertices, boundary)
3059        domain.smooth = False
3060        domain.default_order=2
3061        domain.beta_w      = 0.9
3062        domain.beta_w_dry  = 0.9
3063        domain.beta_uh     = 0.9
3064        domain.beta_uh_dry = 0.9
3065        domain.beta_vh     = 0.9
3066        domain.beta_vh_dry = 0.9
3067        domain.beta_h = 0.0 #Use first order in h-limiter
3068
3069        #Bed-slope and friction at vertices (and interpolated elsewhere)
3070        def x_slope(x, y):
3071            return -x/3
3072
3073        domain.set_quantity('elevation', x_slope)
3074
3075        # Boundary conditions
3076        Br = Reflective_boundary(domain)
3077        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
3078
3079        #Initial condition
3080        domain.set_quantity('stage', Constant_height(x_slope, 0.05))
3081        domain.check_integrity()
3082
3083        assert allclose(domain.quantities['stage'].centroid_values,
3084                        [0.01296296, 0.03148148, 0.01296296,
3085                        0.03148148, 0.01296296, 0.03148148,
3086                        0.01296296, 0.03148148, 0.01296296,
3087                        0.03148148, 0.01296296, 0.03148148,
3088                        -0.04259259, -0.02407407, -0.04259259,
3089                        -0.02407407, -0.04259259, -0.02407407,
3090                        -0.04259259, -0.02407407, -0.04259259,
3091                        -0.02407407, -0.04259259, -0.02407407,
3092                        -0.09814815, -0.07962963, -0.09814815,
3093                        -0.07962963, -0.09814815, -0.07962963,
3094                        -0.09814815, -0.07962963, -0.09814815,
3095                        -0.07962963, -0.09814815, -0.07962963,
3096                        -0.1537037 , -0.13518519, -0.1537037,
3097                        -0.13518519, -0.1537037, -0.13518519,
3098                        -0.1537037 , -0.13518519, -0.1537037,
3099                        -0.13518519, -0.1537037, -0.13518519,
3100                        -0.20925926, -0.19074074, -0.20925926,
3101                        -0.19074074, -0.20925926, -0.19074074,
3102                        -0.20925926, -0.19074074, -0.20925926,
3103                        -0.19074074, -0.20925926, -0.19074074,
3104                        -0.26481481, -0.2462963, -0.26481481,
3105                        -0.2462963, -0.26481481, -0.2462963,
3106                        -0.26481481, -0.2462963, -0.26481481,
3107                        -0.2462963, -0.26481481, -0.2462963])
3108
3109
3110        #print domain.quantities['stage'].extrapolate_second_order()
3111        #domain.distribute_to_vertices_and_edges()
3112        #print domain.quantities['stage'].vertex_values[:,0]
3113
3114        #Evolution
3115        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.1):   #0.05??
3116            #domain.write_time()
3117            pass
3118
3119
3120
3121        assert allclose(domain.quantities['stage'].centroid_values,
3122                 [0.00855788, 0.01575204, 0.00994606, 0.01717072, 0.01005985,
3123                  0.01716362, 0.01005985, 0.01716299, 0.01007098, 0.01736248,
3124                  0.01216452, 0.02026776, -0.04462374, -0.02479045, -0.04199789,
3125                  -0.0229465, -0.04184033, -0.02295693, -0.04184013,
3126                  -0.02295675, -0.04184486, -0.0228168, -0.04028876,
3127                  -0.02036486, -0.10029444, -0.08170809, -0.09772846,
3128                  -0.08021704, -0.09760006, -0.08022143, -0.09759984,
3129                  -0.08022124, -0.09760261, -0.08008893, -0.09603914,
3130                  -0.07758209, -0.15584152, -0.13723138, -0.15327266,
3131                  -0.13572906, -0.15314427, -0.13573349, -0.15314405,
3132                  -0.13573331, -0.15314679, -0.13560104, -0.15158523,
3133                  -0.13310701, -0.21208605, -0.19283913, -0.20955631,
3134                  -0.19134189, -0.20942821, -0.19134598, -0.20942799,
3135                  -0.1913458, -0.20943005, -0.19120952, -0.20781177,
3136                  -0.18869401, -0.25384082, -0.2463294, -0.25047649,
3137                  -0.24464654, -0.25031159, -0.24464253, -0.25031112,
3138                  -0.24464253, -0.25031463, -0.24454764, -0.24885323,
3139                  -0.24286438])
3140
3141        os.remove(domain.filename + '.sww')
3142
3143    def test_bedslope_problem_second_order_more_steps(self):
3144
3145        from mesh_factory import rectangular
3146        from Numeric import array
3147
3148        #Create basic mesh
3149        points, vertices, boundary = rectangular(6, 6)
3150
3151        #Create shallow water domain
3152        domain = Domain(points, vertices, boundary)
3153        domain.smooth = False
3154        domain.default_order=2
3155        domain.beta_w      = 0.9
3156        domain.beta_w_dry  = 0.9
3157        domain.beta_uh     = 0.9
3158        domain.beta_uh_dry = 0.9
3159        domain.beta_vh     = 0.9
3160        domain.beta_vh_dry = 0.9
3161        domain.beta_h = 0.0 #Use first order in h-limiter
3162
3163        #Bed-slope and friction at vertices (and interpolated elsewhere)
3164        def x_slope(x, y):
3165            return -x/3
3166
3167        domain.set_quantity('elevation', x_slope)
3168
3169        # Boundary conditions
3170        Br = Reflective_boundary(domain)
3171        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
3172
3173        #Initial condition
3174        domain.set_quantity('stage', expression = 'elevation + 0.05')
3175        domain.check_integrity()
3176
3177        assert allclose(domain.quantities['stage'].centroid_values,
3178                        [0.01296296, 0.03148148, 0.01296296,
3179                        0.03148148, 0.01296296, 0.03148148,
3180                        0.01296296, 0.03148148, 0.01296296,
3181                        0.03148148, 0.01296296, 0.03148148,
3182                        -0.04259259, -0.02407407, -0.04259259,
3183                        -0.02407407, -0.04259259, -0.02407407,
3184                        -0.04259259, -0.02407407, -0.04259259,
3185                        -0.02407407, -0.04259259, -0.02407407,
3186                        -0.09814815, -0.07962963, -0.09814815,
3187                        -0.07962963, -0.09814815, -0.07962963,
3188                        -0.09814815, -0.07962963, -0.09814815,
3189                        -0.07962963, -0.09814815, -0.07962963,
3190                        -0.1537037 , -0.13518519, -0.1537037,
3191                        -0.13518519, -0.1537037, -0.13518519,
3192                        -0.1537037 , -0.13518519, -0.1537037,
3193                        -0.13518519, -0.1537037, -0.13518519,
3194                        -0.20925926, -0.19074074, -0.20925926,
3195                        -0.19074074, -0.20925926, -0.19074074,
3196                        -0.20925926, -0.19074074, -0.20925926,
3197                        -0.19074074, -0.20925926, -0.19074074,
3198                        -0.26481481, -0.2462963, -0.26481481,
3199                        -0.2462963, -0.26481481, -0.2462963,
3200                        -0.26481481, -0.2462963, -0.26481481,
3201                        -0.2462963, -0.26481481, -0.2462963])
3202
3203
3204        #print domain.quantities['stage'].extrapolate_second_order()
3205        #domain.distribute_to_vertices_and_edges()
3206        #print domain.quantities['stage'].vertex_values[:,0]
3207
3208        #Evolution
3209        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.5):
3210            pass
3211
3212
3213        assert allclose(domain.quantities['stage'].centroid_values,
3214     [-0.02907028, -0.01475478, -0.02973417, -0.01447186, -0.02932665, -0.01428285,
3215      -0.02901975, -0.0141361,  -0.02898816, -0.01418135, -0.02961409, -0.01403487,
3216      -0.07597998, -0.06252591, -0.07664854, -0.06312532, -0.07638287, -0.06265139,
3217      -0.07571145, -0.06235231, -0.0756817,  -0.06245309, -0.07652292, -0.06289946,
3218      -0.12367464, -0.11088981, -0.12237277, -0.11115338, -0.1218934,  -0.1107174,
3219      -0.12081485, -0.11000491, -0.12038451, -0.11010335, -0.12102113, -0.11012105,
3220      -0.16909116, -0.15831543, -0.16730214, -0.15786249, -0.1665493,  -0.15697919,
3221      -0.16496618, -0.15559852, -0.16338679, -0.15509088, -0.16364092, -0.15424423,
3222      -0.18771107, -0.19903904, -0.18903759, -0.19858437, -0.18701552, -0.19697797,
3223      -0.1833593,  -0.19505871, -0.1818806,  -0.19418042, -0.18586159, -0.19576946,
3224      -0.13986873, -0.14170053, -0.14132188, -0.14560674, -0.14095617, -0.14373292,
3225      -0.13785933, -0.14033364, -0.13592955, -0.13936356, -0.13596008, -0.14216296])
3226
3227        assert allclose(domain.quantities['xmomentum'].centroid_values,
3228     [ 0.00831121,  0.00317948,  0.00731797,  0.00334939,  0.00764717,  0.00348053,
3229       0.00788729,  0.00356522,  0.00780649,  0.00341919,  0.00693525,  0.00310375,
3230       0.02166196,  0.01421475,  0.02017737,  0.01316839,  0.02037015,  0.01368659,
3231       0.02106,     0.01399161,  0.02074514,  0.01354935,  0.01887407,  0.0123113,
3232       0.03775083,  0.02855197,  0.03689337,  0.02759782,  0.03732848,  0.02812072,
3233       0.03872545,  0.02913348,  0.03880939,  0.02803804,  0.03546499,  0.0260039,
3234       0.0632131,   0.04730634,  0.0576324,   0.04592336,  0.05790921,  0.04690514,
3235       0.05986467,  0.04871165,  0.06170068,  0.04811572,  0.05657041,  0.04416292,
3236       0.08489642,  0.07188097,  0.07835261,  0.06843406,  0.07986412,  0.0698247,
3237       0.08201071,  0.07216756,  0.08378418,  0.07273624,  0.080399,    0.06645841,
3238       0.01631548,  0.04691608,  0.0206632,   0.044409,    0.02115518,  0.04560305,
3239       0.02160608,  0.04663725,  0.02174734,  0.04795559,  0.02281427,  0.05667111])
3240
3241
3242        assert allclose(domain.quantities['ymomentum'].centroid_values,
3243     [ 1.45876601e-004, -3.24627393e-004, -1.57572719e-004, -2.92790187e-004,
3244      -9.90988382e-005, -3.06677335e-004, -1.62493106e-004, -3.71310004e-004,
3245      -1.99445058e-004, -3.28493467e-004,  6.68217349e-005, -8.42042805e-006,
3246       5.05093371e-004, -1.42842214e-004, -6.81454718e-005, -5.02084057e-004,
3247      -8.50583861e-005, -4.65443981e-004, -1.96406564e-004, -5.88889562e-004,
3248      -2.70160173e-004, -5.35485454e-004,  2.60780997e-004,  3.12145471e-005,
3249       5.16189608e-004,  1.07069062e-004,  9.29989252e-005, -3.71211119e-004,
3250       1.16350246e-004, -3.82407830e-004, -1.62077969e-004, -6.30906636e-004,
3251      -4.74025708e-004, -6.94463009e-004,  6.15092843e-005,  2.22106820e-004,
3252      -6.29589294e-004,  2.43611937e-004, -5.88125094e-004, -6.94293192e-005,
3253      -4.17914641e-004,  6.64609019e-005, -7.68334577e-004, -3.40232101e-004,
3254      -1.67424308e-003, -7.39485066e-004, -1.59966988e-003,  5.68262838e-005,
3255      -1.48470633e-003, -1.84554882e-003, -2.27200099e-003, -1.67506848e-003,
3256      -1.95610258e-003, -1.47638801e-003, -1.73779477e-003, -1.85498791e-003,
3257      -2.01357843e-003, -2.17675471e-003, -1.65783870e-003, -1.15818681e-003,
3258      -1.18663036e-003, -2.94229849e-003, -3.59309018e-003, -5.13496584e-003,
3259      -6.17359400e-003, -5.98761937e-003, -6.00540116e-003, -5.01121966e-003,
3260      -4.50964850e-003, -3.06319963e-003,  6.08950810e-004, -4.79537921e-004])
3261
3262        os.remove(domain.filename + '.sww')
3263
3264
3265    def test_temp_play(self):
3266
3267        from mesh_factory import rectangular
3268        from Numeric import array
3269
3270        #Create basic mesh
3271        points, vertices, boundary = rectangular(5, 5)
3272
3273        #Create shallow water domain
3274        domain = Domain(points, vertices, boundary)
3275        domain.smooth = False
3276        domain.default_order=2
3277        domain.beta_w      = 0.9
3278        domain.beta_w_dry  = 0.9
3279        domain.beta_uh     = 0.9
3280        domain.beta_uh_dry = 0.9
3281        domain.beta_vh     = 0.9
3282        domain.beta_vh_dry = 0.9
3283        domain.beta_h = 0.0 #Use first order in h-limiter
3284
3285        #Bed-slope and friction at vertices (and interpolated elsewhere)
3286        def x_slope(x, y):
3287            return -x/3
3288
3289        domain.set_quantity('elevation', x_slope)
3290
3291        # Boundary conditions
3292        Br = Reflective_boundary(domain)
3293        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
3294
3295        #Initial condition
3296        domain.set_quantity('stage', Constant_height(x_slope, 0.05))
3297        domain.check_integrity()
3298
3299        #Evolution
3300        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.1):
3301            pass
3302
3303        assert allclose(domain.quantities['stage'].centroid_values[:4],
3304                        [0.00206836, 0.01296714, 0.00363415, 0.01438924])
3305        #print domain.quantities['xmomentum'].centroid_values[:4]
3306        assert allclose(domain.quantities['xmomentum'].centroid_values[:4],
3307                        [0.01360154, 0.00671133, 0.01264578, 0.00648503])
3308        assert allclose(domain.quantities['ymomentum'].centroid_values[:4],
3309                        [-1.19201077e-003, -7.23647546e-004,
3310                        -6.39083123e-005, 6.29815168e-005])
3311
3312        os.remove(domain.filename + '.sww')
3313
3314    def test_complex_bed(self):
3315        #No friction is tested here
3316
3317        from mesh_factory import rectangular
3318        from Numeric import array
3319
3320        N = 12
3321        points, vertices, boundary = rectangular(N, N/2, len1=1.2,len2=0.6,
3322                                                 origin=(-0.07, 0))
3323
3324
3325        domain = Domain(points, vertices, boundary)
3326        domain.smooth = False
3327        domain.visualise = False
3328        domain.default_order=2
3329
3330
3331        inflow_stage = 0.1
3332        Z = Weir(inflow_stage)
3333        domain.set_quantity('elevation', Z)
3334
3335        Br = Reflective_boundary(domain)
3336        Bd = Dirichlet_boundary([inflow_stage, 0.0, 0.0])
3337        domain.set_boundary({'left': Bd, 'right': Br, 'bottom': Br, 'top': Br})
3338
3339        domain.set_quantity('stage', Constant_height(Z, 0.))
3340
3341        for t in domain.evolve(yieldstep = 0.02, finaltime = 0.2):
3342            pass
3343
3344
3345        #print domain.quantities['stage'].centroid_values
3346
3347        #FIXME: These numbers were from version before 25/10
3348        #assert allclose(domain.quantities['stage'].centroid_values,
3349# [3.95822638e-002,  5.61022588e-002,  4.66437868e-002,  5.73081011e-002,
3350#  4.72394613e-002,  5.74684939e-002,  4.74309483e-002,  5.77458084e-002,
3351#  4.80628177e-002,  5.85656225e-002,  4.90498542e-002,  6.02609831e-002,
3352#  1.18470315e-002,  1.75136443e-002,  1.18035266e-002,  2.15565695e-002,
3353#  1.31620268e-002,  2.14351640e-002,  1.32351076e-002,  2.15450687e-002,
3354#  1.36414028e-002,  2.24274619e-002,  1.51689511e-002,  2.21789655e-002,
3355# -7.54337535e-003, -6.86362021e-004, -7.74146760e-003, -1.83756530e-003,
3356# -8.16773628e-003, -4.49916813e-004, -8.08202599e-003, -3.91118720e-004,
3357# -8.10292716e-003, -3.88584984e-004, -7.35226124e-003,  2.73985295e-004,
3358#  1.86166683e-001,  8.74070369e-002,  1.86166712e-001,  8.74035875e-002,
3359#  6.11666935e-002, -3.76173225e-002, -6.38333276e-002, -3.76147365e-002,
3360#  6.11666725e-002,  8.73846774e-002,  1.86166697e-001,  8.74171550e-002,
3361# -4.83333333e-002,  1.18333333e-001, -4.83333333e-002,  1.18333333e-001,
3362# -4.83333333e-002, -6.66666667e-003, -1.73333333e-001, -1.31666667e-001,
3363# -1.73333333e-001, -6.66666667e-003, -4.83333333e-002,  1.18333333e-001,
3364# -2.48333333e-001, -2.31666667e-001, -2.48333333e-001, -2.31666667e-001,
3365# -2.48333333e-001, -2.31666667e-001, -2.48333333e-001, -2.31666667e-001,
3366# -2.48333333e-001, -2.31666667e-001, -2.48333333e-001, -2.31666667e-001,
3367# -4.65000000e-001, -3.65000000e-001, -4.65000000e-001, -3.65000000e-001,
3368# -4.65000000e-001, -3.65000000e-001, -4.65000000e-001, -3.65000000e-001,
3369# -4.65000000e-001, -3.65000000e-001, -4.65000000e-001, -3.65000000e-001,
3370# -5.98333333e-001, -5.81666667e-001, -5.98333333e-001, -5.81666667e-001,
3371# -5.98333333e-001, -5.81666667e-001, -5.98333333e-001, -5.81666667e-001,
3372# -5.98333333e-001, -5.81666667e-001, -5.98333333e-001, -5.81666667e-001,
3373# -6.48333333e-001, -6.31666667e-001, -6.48333333e-001, -6.31666667e-001,
3374# -6.48333333e-001, -6.31666667e-001, -6.48333333e-001, -6.31666667e-001,
3375# -6.48333333e-001, -6.31666667e-001, -6.48333333e-001, -6.31666667e-001,
3376# -5.31666667e-001, -5.98333333e-001, -5.31666667e-001, -5.98333333e-001,
3377# -5.31666667e-001, -5.98333333e-001, -5.31666667e-001, -5.98333333e-001,
3378# -5.31666667e-001, -5.98333333e-001, -5.31666667e-001, -5.98333333e-001,
3379# -4.98333333e-001, -4.81666667e-001, -4.98333333e-001, -4.81666667e-001,
3380# -4.98333333e-001, -4.81666667e-001, -4.98333333e-001, -4.81666667e-001,
3381# -4.98333333e-001, -4.81666667e-001, -4.98333333e-001, -4.81666667e-001,
3382# -5.48333333e-001, -5.31666667e-001, -5.48333333e-001, -5.31666667e-001,
3383# -5.48333333e-001, -5.31666667e-001, -5.48333333e-001, -5.31666667e-001,
3384# -5.48333333e-001, -5.31666667e-001, -5.48333333e-001, -5.31666667e-001])
3385
3386        os.remove(domain.filename + '.sww')
3387
3388    def test_spatio_temporal_boundary_1(self):
3389        """Test that boundary values can be read from file and interpolated
3390        in both time and space.
3391
3392        Verify that the same steady state solution is arrived at and that
3393        time interpolation works.
3394
3395        The full solution history is not exactly the same as
3396        file boundary must read and interpolate from *smoothed* version
3397        as stored in sww.
3398        """
3399        import time
3400
3401        #Create sww file of simple propagation from left to right
3402        #through rectangular domain
3403
3404        from mesh_factory import rectangular
3405
3406        #Create basic mesh
3407        points, vertices, boundary = rectangular(3, 3)
3408
3409        #Create shallow water domain
3410        domain1 = Domain(points, vertices, boundary)
3411
3412        domain1.reduction = mean
3413        domain1.smooth = False  #Exact result
3414
3415        domain1.default_order = 2
3416        domain1.store = True
3417        domain1.set_datadir('.')
3418        domain1.set_name('spatio_temporal_boundary_source' + str(time.time()))
3419
3420        #FIXME: This is extremely important!
3421        #How can we test if they weren't stored?
3422        domain1.quantities_to_be_stored = ['stage', 'xmomentum', 'ymomentum']
3423
3424
3425        #Bed-slope and friction at vertices (and interpolated elsewhere)
3426        domain1.set_quantity('elevation', 0)
3427        domain1.set_quantity('friction', 0)
3428
3429        # Boundary conditions
3430        Br = Reflective_boundary(domain1)
3431        Bd = Dirichlet_boundary([0.3,0,0])
3432        domain1.set_boundary({'left': Bd, 'top': Bd, 'right': Br, 'bottom': Br})
3433        #Initial condition
3434        domain1.set_quantity('stage', 0)
3435        domain1.check_integrity()
3436
3437        finaltime = 5
3438        #Evolution  (full domain - large steps)
3439        for t in domain1.evolve(yieldstep = 0.671, finaltime = finaltime):
3440            pass
3441            #domain1.write_time()
3442
3443        cv1 = domain1.quantities['stage'].centroid_values
3444
3445
3446        #Create a triangle shaped domain (reusing coordinates from domain 1),
3447        #formed from the lower and right hand  boundaries and
3448        #the sw-ne diagonal
3449        #from domain 1. Call it domain2
3450
3451        points = [ [0,0], [1.0/3,0], [1.0/3,1.0/3],
3452                   [2.0/3,0], [2.0/3,1.0/3], [2.0/3,2.0/3],
3453                   [1,0], [1,1.0/3], [1,2.0/3], [1,1]]
3454
3455        vertices = [ [1,2,0], [3,4,1], [2,1,4], [4,5,2],
3456                     [6,7,3], [4,3,7], [7,8,4], [5,4,8], [8,9,5]]
3457
3458        boundary = { (0,1):'bottom', (1,1):'bottom', (4,1): 'bottom',
3459                     (4,2):'right', (6,2):'right', (8,2):'right',
3460                     (0,0):'diagonal', (3,0):'diagonal', (8,0):'diagonal'}
3461
3462        domain2 = Domain(points, vertices, boundary)
3463
3464        domain2.reduction = domain1.reduction
3465        domain2.smooth = False
3466        domain2.default_order = 2
3467
3468        #Bed-slope and friction at vertices (and interpolated elsewhere)
3469        domain2.set_quantity('elevation', 0)
3470        domain2.set_quantity('friction', 0)
3471        domain2.set_quantity('stage', 0)
3472
3473        # Boundary conditions
3474        Br = Reflective_boundary(domain2)
3475        Bf = Spatio_temporal_boundary(domain1.filename + '.' + domain1.format,
3476                                      domain2)
3477        domain2.set_boundary({'right':Br, 'bottom':Br, 'diagonal':Bf})
3478        domain2.check_integrity()
3479
3480
3481
3482        #Evolution (small steps)
3483        for t in domain2.evolve(yieldstep = 0.0711, finaltime = finaltime):
3484            pass
3485
3486
3487        #Use output from domain1 as spatio-temporal boundary for domain2
3488        #and verify that results at right hand side are close.
3489
3490        cv2 = domain2.quantities['stage'].centroid_values
3491
3492        #print take(cv1, (12,14,16))  #Right
3493        #print take(cv2, (4,6,8))
3494        #print take(cv1, (0,6,12))  #Bottom
3495        #print take(cv2, (0,1,4))
3496        #print take(cv1, (0,8,16))  #Diag
3497        #print take(cv2, (0,3,8))
3498
3499        assert allclose( take(cv1, (0,8,16)), take(cv2, (0,3,8))) #Diag
3500        assert allclose( take(cv1, (0,6,12)), take(cv2, (0,1,4))) #Bottom
3501        assert allclose( take(cv1, (12,14,16)), take(cv2, (4,6,8))) #RHS
3502
3503        #Cleanup
3504        os.remove(domain1.filename + '.' + domain1.format)
3505        os.remove(domain2.filename + '.' + domain2.format)       
3506
3507
3508
3509    def test_spatio_temporal_boundary_2(self):
3510        """Test that boundary values can be read from file and interpolated
3511        in both time and space.
3512        This is a more basic test, verifying that boundary object
3513        produces the expected results
3514
3515
3516        """
3517        import time
3518
3519        #Create sww file of simple propagation from left to right
3520        #through rectangular domain
3521
3522        from mesh_factory import rectangular
3523
3524        #Create basic mesh
3525        points, vertices, boundary = rectangular(3, 3)
3526
3527        #Create shallow water domain
3528        domain1 = Domain(points, vertices, boundary)
3529
3530        domain1.reduction = mean
3531        domain1.smooth = True #To mimic MOST output
3532
3533        domain1.default_order = 2
3534        domain1.store = True
3535        domain1.set_datadir('.')
3536        domain1.set_name('spatio_temporal_boundary_source' + str(time.time()))
3537
3538        #FIXME: This is extremely important!
3539        #How can we test if they weren't stored?
3540        domain1.quantities_to_be_stored = ['stage', 'xmomentum', 'ymomentum']
3541
3542
3543        #Bed-slope and friction at vertices (and interpolated elsewhere)
3544        domain1.set_quantity('elevation', 0)
3545        domain1.set_quantity('friction', 0)
3546
3547        # Boundary conditions
3548        Br = Reflective_boundary(domain1)
3549        Bd = Dirichlet_boundary([0.3,0,0])
3550        domain1.set_boundary({'left': Bd, 'top': Bd, 'right': Br, 'bottom': Br})
3551        #Initial condition
3552        domain1.set_quantity('stage', 0)
3553        domain1.check_integrity()
3554
3555        finaltime = 5
3556        #Evolution  (full domain - large steps)
3557        for t in domain1.evolve(yieldstep = 1, finaltime = finaltime):
3558            pass
3559            #domain1.write_time()
3560
3561
3562        #Create an triangle shaped domain (coinciding with some
3563        #coordinates from domain 1),
3564        #formed from the lower and right hand  boundaries and
3565        #the sw-ne diagonal
3566        #from domain 1. Call it domain2
3567
3568        points = [ [0,0], [1.0/3,0], [1.0/3,1.0/3],
3569                   [2.0/3,0], [2.0/3,1.0/3], [2.0/3,2.0/3],
3570                   [1,0], [1,1.0/3], [1,2.0/3], [1,1]]
3571
3572        vertices = [ [1,2,0],
3573                     [3,4,1], [2,1,4], [4,5,2],
3574                     [6,7,3], [4,3,7], [7,8,4], [5,4,8], [8,9,5]]
3575
3576        boundary = { (0,1):'bottom', (1,1):'bottom', (4,1): 'bottom',
3577                     (4,2):'right', (6,2):'right', (8,2):'right',
3578                     (0,0):'diagonal', (3,0):'diagonal', (8,0):'diagonal'}
3579
3580        domain2 = Domain(points, vertices, boundary)
3581
3582        domain2.reduction = domain1.reduction
3583        domain2.smooth = False
3584        domain2.default_order = 2
3585
3586        #Bed-slope and friction at vertices (and interpolated elsewhere)
3587        domain2.set_quantity('elevation', 0)
3588        domain2.set_quantity('friction', 0)
3589        domain2.set_quantity('stage', 0)
3590
3591
3592        #Read results for specific timesteps t=1 and t=2
3593        from Scientific.IO.NetCDF import NetCDFFile
3594        fid = NetCDFFile(domain1.filename + '.' + domain1.format)
3595
3596        x = fid.variables['x'][:]
3597        y = fid.variables['y'][:]
3598        s1 = fid.variables['stage'][1,:]
3599        s2 = fid.variables['stage'][2,:]
3600        fid.close()
3601
3602        from Numeric import take, reshape, concatenate
3603        shp = (len(x), 1)
3604        points = concatenate( (reshape(x, shp), reshape(y, shp)), axis=1)
3605        #The diagonal points of domain 1 are 0, 5, 10, 15
3606
3607        #print points[0], points[5], points[10], points[15]
3608        assert allclose( take(points, [0,5,10,15]),
3609                         [[0,0], [1.0/3, 1.0/3], [2.0/3, 2.0/3], [1,1]])
3610
3611
3612        # Boundary conditions
3613        Br = Reflective_boundary(domain2)
3614        Bf = Spatio_temporal_boundary(domain1.filename + '.' + domain1.format,
3615                                      domain2)
3616        domain2.set_boundary({'right':Br, 'bottom':Br, 'diagonal':Bf})
3617        domain2.check_integrity()
3618
3619        #Test that interpolation points are the mid points of the all boundary
3620        #segments
3621
3622        boundary_midpoints = [[1.0/6, 0], [1.0/2, 0], [5.0/6,0],
3623                              [1.0, 1.0/6], [1.0, 1.0/2], [1.0, 5.0/6],
3624                              [1.0/6, 1.0/6], [0.5, 0.5], [5.0/6, 5.0/6]]
3625
3626        boundary_midpoints.sort()
3627        R = Bf.F.interpolation_points.tolist()
3628        R.sort()
3629        assert allclose(boundary_midpoints, R)
3630
3631        #Check spatially interpolated output at time == 1
3632        domain2.time = 1
3633
3634        #First diagonal midpoint
3635        R0 = Bf.evaluate(0,0)
3636        assert allclose(R0[0], (s1[0] + s1[5])/2)
3637
3638        #Second diagonal midpoint
3639        R0 = Bf.evaluate(3,0)
3640        assert allclose(R0[0], (s1[5] + s1[10])/2)
3641
3642        #First diagonal midpoint
3643        R0 = Bf.evaluate(8,0)
3644        assert allclose(R0[0], (s1[10] + s1[15])/2)
3645
3646        #Check spatially interpolated output at time == 2
3647        domain2.time = 2
3648
3649        #First diagonal midpoint
3650        R0 = Bf.evaluate(0,0)
3651        assert allclose(R0[0], (s2[0] + s2[5])/2)
3652
3653        #Second diagonal midpoint
3654        R0 = Bf.evaluate(3,0)
3655        assert allclose(R0[0], (s2[5] + s2[10])/2)
3656
3657        #First diagonal midpoint
3658        R0 = Bf.evaluate(8,0)
3659        assert allclose(R0[0], (s2[10] + s2[15])/2)
3660
3661
3662        #Now check temporal interpolation
3663
3664        domain2.time = 1 + 2.0/3
3665
3666        #First diagonal midpoint
3667        R0 = Bf.evaluate(0,0)
3668        assert allclose(R0[0], ((s1[0] + s1[5])/2 + 2.0*(s2[0] + s2[5])/2)/3)
3669
3670        #Second diagonal midpoint
3671        R0 = Bf.evaluate(3,0)
3672        assert allclose(R0[0], ((s1[5] + s1[10])/2 + 2.0*(s2[5] + s2[10])/2)/3)
3673
3674        #First diagonal midpoint
3675        R0 = Bf.evaluate(8,0)
3676        assert allclose(R0[0], ((s1[10] + s1[15])/2 + 2.0*(s2[10] + s2[15])/2)/3)
3677
3678
3679
3680        #Cleanup
3681        os.remove(domain1.filename + '.' + domain1.format)
3682
3683
3684    def test_pmesh2Domain(self):
3685         import os
3686         import tempfile
3687
3688         fileName = tempfile.mktemp(".tsh")
3689         file = open(fileName,"w")
3690         file.write("4 3 # <vertex #> <x> <y> [attributes]\n \
36910 0.0 0.0 0.0 0.0 0.01 \n \
36921 1.0 0.0 10.0 10.0 0.02  \n \
36932 0.0 1.0 0.0 10.0 0.03  \n \
36943 0.5 0.25 8.0 12.0 0.04  \n \
3695# Vert att title  \n \
3696elevation  \n \
3697stage  \n \
3698friction  \n \
36992 # <triangle #> [<vertex #>] [<neigbouring triangle #>]  \n\
37000 0 3 2 -1  -1  1 dsg\n\
37011 0 1 3 -1  0 -1   ole nielsen\n\
37024 # <segment #> <vertex #>  <vertex #> [boundary tag] \n\
37030 1 0 2 \n\
37041 0 2 3 \n\
37052 2 3 \n\
37063 3 1 1 \n\
37073 0 # <x> <y> [attributes] ...Mesh Vertices... \n \
37080 216.0 -86.0 \n \
37091 160.0 -167.0 \n \
37102 114.0 -91.0 \n \
37113 # <vertex #>  <vertex #> [boundary tag] ...Mesh Segments... \n \
37120 0 1 0 \n \
37131 1 2 0 \n \
37142 2 0 0 \n \
37150 # <x> <y> ...Mesh Holes... \n \
37160 # <x> <y> <attribute>...Mesh Regions... \n \
37170 # <x> <y> <attribute>...Mesh Regions, area... \n\
3718#Geo reference \n \
371956 \n \
3720140 \n \
3721120 \n")
3722         file.close()
3723
3724         tags = {}
3725         b1 =  Dirichlet_boundary(conserved_quantities = array([0.0]))
3726         b2 =  Dirichlet_boundary(conserved_quantities = array([1.0]))
3727         b3 =  Dirichlet_boundary(conserved_quantities = array([2.0]))
3728         tags["1"] = b1
3729         tags["2"] = b2
3730         tags["3"] = b3
3731
3732         #from anuga.abstract_2d_finite_volumes.pmesh2domain import pmesh_to_domain_instance
3733         #domain = pmesh_to_domain_instance(fileName, Domain)
3734
3735         domain = Domain(mesh_filename=fileName)
3736                         #verbose=True, use_cache=True)
3737         
3738         #print "domain.tagged_elements", domain.tagged_elements
3739         ## check the quantities
3740         #print domain.quantities['elevation'].vertex_values
3741         answer = [[0., 8., 0.],
3742                   [0., 10., 8.]]
3743         assert allclose(domain.quantities['elevation'].vertex_values,
3744                        answer)
3745
3746         #print domain.quantities['stage'].vertex_values
3747         answer = [[0., 12., 10.],
3748                   [0., 10., 12.]]
3749         assert allclose(domain.quantities['stage'].vertex_values,
3750                        answer)
3751
3752         #print domain.quantities['friction'].vertex_values
3753         answer = [[0.01, 0.04, 0.03],
3754                   [0.01, 0.02, 0.04]]
3755         assert allclose(domain.quantities['friction'].vertex_values,
3756                        answer)
3757
3758         #print domain.quantities['friction'].vertex_values
3759         assert allclose(domain.tagged_elements['dsg'][0],0)
3760         assert allclose(domain.tagged_elements['ole nielsen'][0],1)
3761
3762         self.failUnless( domain.boundary[(1, 0)]  == '1',
3763                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
3764         self.failUnless( domain.boundary[(1, 2)]  == '2',
3765                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
3766         self.failUnless( domain.boundary[(0, 1)]  == '3',
3767                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
3768         self.failUnless( domain.boundary[(0, 0)]  == 'exterior',
3769                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
3770         #print "domain.boundary",domain.boundary
3771         self.failUnless( len(domain.boundary)  == 4,
3772                          "test_pmesh2Domain Too many boundaries")
3773         #FIXME change to use get_xllcorner
3774         #print "d.geo_reference.xllcorner",domain.geo_reference.xllcorner
3775         self.failUnless(domain.geo_reference.xllcorner  == 140.0,
3776                          "bad geo_referece")
3777
3778
3779         #************
3780
3781   
3782         domain = Domain(fileName)
3783         
3784         #print "domain.tagged_elements", domain.tagged_elements
3785         ## check the quantities
3786         #print domain.quantities['elevation'].vertex_values
3787         answer = [[0., 8., 0.],
3788                   [0., 10., 8.]]
3789         assert allclose(domain.quantities['elevation'].vertex_values,
3790                        answer)
3791
3792         #print domain.quantities['stage'].vertex_values
3793         answer = [[0., 12., 10.],
3794                   [0., 10., 12.]]
3795         assert allclose(domain.quantities['stage'].vertex_values,
3796                        answer)
3797
3798         #print domain.quantities['friction'].vertex_values
3799         answer = [[0.01, 0.04, 0.03],
3800                   [0.01, 0.02, 0.04]]
3801         assert allclose(domain.quantities['friction'].vertex_values,
3802                        answer)
3803
3804         #print domain.quantities['friction'].vertex_values
3805         assert allclose(domain.tagged_elements['dsg'][0],0)
3806         assert allclose(domain.tagged_elements['ole nielsen'][0],1)
3807
3808         self.failUnless( domain.boundary[(1, 0)]  == '1',
3809                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
3810         self.failUnless( domain.boundary[(1, 2)]  == '2',
3811                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
3812         self.failUnless( domain.boundary[(0, 1)]  == '3',
3813                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
3814         self.failUnless( domain.boundary[(0, 0)]  == 'exterior',
3815                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
3816         #print "domain.boundary",domain.boundary
3817         self.failUnless( len(domain.boundary)  == 4,
3818                          "test_pmesh2Domain Too many boundaries")
3819         #FIXME change to use get_xllcorner
3820         #print "d.geo_reference.xllcorner",domain.geo_reference.xllcorner
3821         self.failUnless(domain.geo_reference.xllcorner  == 140.0,
3822                          "bad geo_referece")
3823         #************
3824         os.remove(fileName)
3825
3826        #-------------------------------------------------------------
3827       
3828if __name__ == "__main__":
3829    suite = unittest.makeSuite(Test_Shallow_Water,'test')
3830    #suite = unittest.makeSuite(Test_Shallow_Water,'test_get_maximum_inundation_3')
3831    runner = unittest.TextTestRunner(verbosity=1)   
3832    runner.run(suite)
Note: See TracBrowser for help on using the repository browser.