source: branches/numpy/anuga/shallow_water/test_shallow_water_domain.py @ 6304

Last change on this file since 6304 was 6304, checked in by rwilson, 16 years ago

Initial commit of numpy changes. Still a long way to go.

File size: 243.5 KB
Line 
1#!/usr/bin/env python
2
3import unittest, os
4from math import pi, sqrt
5import tempfile
6
7from anuga.config import g, epsilon
8from anuga.config import netcdf_mode_r, netcdf_mode_w, netcdf_mode_a
9import numpy as num
10from anuga.utilities.numerical_tools import mean
11from anuga.utilities.polygon import is_inside_polygon
12from anuga.coordinate_transforms.geo_reference import Geo_reference
13from anuga.abstract_2d_finite_volumes.quantity import Quantity
14from anuga.geospatial_data.geospatial_data import Geospatial_data
15from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross
16from shallow_water_domain import *
17
18# Get gateway to C implementation of flux function for direct testing
19from shallow_water_ext import flux_function_central as flux_function
20
21# For test_fitting_using_shallow_water_domain example
22def linear_function(point):
23    point = num.array(point)
24    return point[:,0]+point[:,1]
25
26class Weir:
27    """Set a bathymetry for weir with a hole and a downstream gutter
28    x,y are assumed to be in the unit square
29    """
30
31    def __init__(self, stage):
32        self.inflow_stage = stage
33
34    def __call__(self, x, y):
35
36        N = len(x)
37        assert N == len(y)
38
39        z = num.zeros(N, num.float)
40        for i in range(N):
41            z[i] = -x[i]/2  #General slope
42
43            #Flattish bit to the left
44            if x[i] < 0.3:
45                z[i] = -x[i]/10
46
47            #Weir
48            if x[i] >= 0.3 and x[i] < 0.4:
49                z[i] = -x[i]+0.9
50
51            #Dip
52            x0 = 0.6
53            #depth = -1.3
54            depth = -1.0
55            #plateaux = -0.9
56            plateaux = -0.6
57            if y[i] < 0.7:
58                if x[i] > x0 and x[i] < 0.9:
59                    z[i] = depth
60
61                #RHS plateaux
62                if x[i] >= 0.9:
63                    z[i] = plateaux
64
65
66            elif y[i] >= 0.7 and y[i] < 1.5:
67                #Restrict and deepen
68                if x[i] >= x0 and x[i] < 0.8:
69                    z[i] = depth-(y[i]/3-0.3)
70                    #z[i] = depth-y[i]/5
71                    #z[i] = depth
72                elif x[i] >= 0.8:
73                    #RHS plateaux
74                    z[i] = plateaux
75
76            elif y[i] >= 1.5:
77                if x[i] >= x0 and x[i] < 0.8 + (y[i]-1.5)/1.2:
78                    #Widen up and stay at constant depth
79                    z[i] = depth-1.5/5
80                elif x[i] >= 0.8 + (y[i]-1.5)/1.2:
81                    #RHS plateaux
82                    z[i] = plateaux
83
84
85            #Hole in weir (slightly higher than inflow condition)
86            if x[i] >= 0.3 and x[i] < 0.4 and y[i] > 0.2 and y[i] < 0.4:
87                z[i] = -x[i]+self.inflow_stage + 0.02
88
89            #Channel behind weir
90            x0 = 0.5
91            if x[i] >= 0.4 and x[i] < x0 and y[i] > 0.2 and y[i] < 0.4:
92                z[i] = -x[i]+self.inflow_stage + 0.02
93
94            if x[i] >= x0 and x[i] < 0.6 and y[i] > 0.2 and y[i] < 0.4:
95                #Flatten it out towards the end
96                z[i] = -x0+self.inflow_stage + 0.02 + (x0-x[i])/5
97
98            #Hole to the east
99            x0 = 1.1; y0 = 0.35
100            #if x[i] < -0.2 and y < 0.5:
101            if num.sqrt((2*(x[i]-x0))**2 + (2*(y[i]-y0))**2) < 0.2:
102                z[i] = num.sqrt(((x[i]-x0))**2 + ((y[i]-y0))**2)-1.0
103
104            #Tiny channel draining hole
105            if x[i] >= 1.14 and x[i] < 1.2 and y[i] >= 0.4 and y[i] < 0.6:
106                z[i] = -0.9 #North south
107
108            if x[i] >= 0.9 and x[i] < 1.18 and y[i] >= 0.58 and y[i] < 0.65:
109                z[i] = -1.0 + (x[i]-0.9)/3 #East west
110
111
112
113            #Stuff not in use
114
115            #Upward slope at inlet to the north west
116            #if x[i] < 0.0: # and y[i] > 0.5:
117            #    #z[i] = -y[i]+0.5  #-x[i]/2
118            #    z[i] = x[i]/4 - y[i]**2 + 0.5
119
120            #Hole to the west
121            #x0 = -0.4; y0 = 0.35 # center
122            #if sqrt((2*(x[i]-x0))**2 + (2*(y[i]-y0))**2) < 0.2:
123            #    z[i] = sqrt(((x[i]-x0))**2 + ((y[i]-y0))**2)-0.2
124
125
126
127
128
129        return z/2
130
131class Weir_simple:
132    """Set a bathymetry for weir with a hole and a downstream gutter
133    x,y are assumed to be in the unit square
134    """
135
136    def __init__(self, stage):
137        self.inflow_stage = stage
138
139    def __call__(self, x, y):
140
141        N = len(x)
142        assert N == len(y)
143
144        z = num.zeros(N, num.float)
145        for i in range(N):
146            z[i] = -x[i]  #General slope
147
148            #Flat bit to the left
149            if x[i] < 0.3:
150                z[i] = -x[i]/10  #General slope
151
152            #Weir
153            if x[i] > 0.3 and x[i] < 0.4:
154                z[i] = -x[i]+0.9
155
156            #Dip
157            if x[i] > 0.6 and x[i] < 0.9:
158                z[i] = -x[i]-0.5  #-y[i]/5
159
160            #Hole in weir (slightly higher than inflow condition)
161            if x[i] > 0.3 and x[i] < 0.4 and y[i] > 0.2 and y[i] < 0.4:
162                z[i] = -x[i]+self.inflow_stage + 0.05
163
164
165        return z/2
166
167
168
169
170#Variable windfield implemented using functions
171def speed(t,x,y):
172    """Large speeds halfway between center and edges
173    Low speeds at center and edges
174    """
175
176    from math import exp, cos, pi
177
178    x = num.array(x)
179    y = num.array(y)
180
181    N = len(x)
182    s = 0*#New array
183
184    for k in range(N):
185
186        r = num.sqrt(x[k]**2 + y[k]**2)
187
188        factor = exp( -(r-0.15)**2 )
189
190        s[k] = 4000 * factor * (cos(t*2*pi/150) + 2)
191
192    return s
193
194
195def scalar_func(t,x,y):
196    """Function that returns a scalar.
197    Used to test error message when numeric array is expected
198    """
199
200    return 17.7
201
202
203def angle(t,x,y):
204    """Rotating field
205    """
206    from math import atan, pi
207
208    x = num.array(x)
209    y = num.array(y)
210
211    N = len(x)
212    a = 0*#New array
213
214    for k in range(N):
215        r = num.sqrt(x[k]**2 + y[k]**2)
216
217        angle = atan(y[k]/x[k])
218
219        if x[k] < 0:
220            angle+=pi #atan in ]-pi/2; pi/2[
221
222        #Take normal direction
223        angle -= pi/2
224
225        #Ensure positive radians
226        if angle < 0:
227            angle += 2*pi
228
229        a[k] = angle/pi*180
230
231    return a
232
233
234class Test_Shallow_Water(unittest.TestCase):
235    def setUp(self):
236        pass
237
238    def tearDown(self):
239        pass
240
241    def test_rotate(self):
242        normal = num.array([0.0,-1.0])
243
244        q = num.array([1.0,2.0,3.0])
245
246        r = rotate(q, normal, direction = 1)
247        assert r[0] == 1
248        assert r[1] == -3
249        assert r[2] == 2
250
251        w = rotate(r, normal, direction = -1)
252        assert num.allclose(w, q)
253
254        #Check error check
255        try:
256            rotate(r, num.array([1,1,1]))
257        except:
258            pass
259        else:
260            raise 'Should have raised an exception'
261
262
263    # Individual flux tests
264    def test_flux_zero_case(self):
265        ql = num.zeros( 3, num.float )
266        qr = num.zeros( 3, num.float )
267        normal = num.zeros( 2, num.float )
268        edgeflux = num.zeros( 3, num.float )
269        zl = zr = 0.
270        H0 = 0.0
271       
272        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0)
273
274        assert num.allclose(edgeflux, [0,0,0])
275        assert max_speed == 0.
276
277    def test_flux_constants(self):
278        w = 2.0
279
280        normal = num.array([1.,0])
281        ql = num.array([w, 0, 0])
282        qr = num.array([w, 0, 0])
283        edgeflux = num.zeros(3, num.float)       
284        zl = zr = 0.
285        h = w - (zl+zr)/2
286        H0 = 0.0
287
288        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0)       
289        assert num.allclose(edgeflux, [0., 0.5*g*h**2, 0.])
290        assert max_speed == num.sqrt(g*h)
291
292    #def test_flux_slope(self):
293    #    #FIXME: TODO
294    #    w = 2.0
295    #
296    #    normal = array([1.,0])
297    #    ql = array([w, 0, 0])
298    #    qr = array([w, 0, 0])
299    #    zl = zr = 0.
300    #    h = w - (zl+zr)/2
301    #
302    #    flux, max_speed = flux_function(normal, ql, qr, zl, zr)
303    #
304    #    assert allclose(flux, [0., 0.5*g*h**2, 0.])
305    #    assert max_speed == sqrt(g*h)
306
307
308    def test_flux1(self):
309        #Use data from previous version of abstract_2d_finite_volumes
310        normal = num.array([1.,0])
311        ql = num.array([-0.2, 2, 3])
312        qr = num.array([-0.2, 2, 3])
313        zl = zr = -0.5
314        edgeflux = num.zeros(3, num.float)               
315
316        H0 = 0.0
317
318        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0)       
319
320        assert num.allclose(edgeflux, [2.,13.77433333, 20.])
321        assert num.allclose(max_speed, 8.38130948661)
322
323
324    def test_flux2(self):
325        #Use data from previous version of abstract_2d_finite_volumes
326        normal = num.array([0., -1.])
327        ql = num.array([-0.075, 2, 3])
328        qr = num.array([-0.075, 2, 3])
329        zl = zr = -0.375
330
331        edgeflux = num.zeros(3, num.float)               
332        H0 = 0.0
333        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0)       
334
335        assert num.allclose(edgeflux, [-3.,-20.0, -30.441])
336        assert num.allclose(max_speed, 11.7146428199)
337
338    def test_flux3(self):
339        #Use data from previous version of abstract_2d_finite_volumes
340        normal = num.array([-sqrt(2)/2, sqrt(2)/2])
341        ql = num.array([-0.075, 2, 3])
342        qr = num.array([-0.075, 2, 3])
343        zl = zr = -0.375
344
345        edgeflux = num.zeros(3, num.float)               
346        H0 = 0.0
347        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0)       
348
349        assert num.allclose(edgeflux, [sqrt(2)/2, 4.40221112, 7.3829019])
350        assert num.allclose(max_speed, 4.0716654239)
351
352    def test_flux4(self):
353        #Use data from previous version of abstract_2d_finite_volumes
354        normal = num.array([-sqrt(2)/2, sqrt(2)/2])
355        ql = num.array([-0.34319278, 0.10254161, 0.07273855])
356        qr = num.array([-0.30683287, 0.1071986, 0.05930515])
357        zl = zr = -0.375
358
359        edgeflux = num.zeros(3, num.float)               
360        H0 = 0.0
361        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0)               
362
363        assert num.allclose(edgeflux, [-0.04072676, -0.07096636, -0.01604364])
364        assert num.allclose(max_speed, 1.31414103233)
365
366    def test_flux_computation(self):   
367        """test_flux_computation - test flux calculation (actual C implementation)
368        This one tests the constant case where only the pressure term contributes to each edge and cancels out
369        once the total flux has been summed up.
370        """
371               
372        a = [0.0, 0.0]
373        b = [0.0, 2.0]
374        c = [2.0,0.0]
375        d = [0.0, 4.0]
376        e = [2.0, 2.0]
377        f = [4.0,0.0]
378
379        points = [a, b, c, d, e, f]
380        #bac, bce, ecf, dbe, daf, dae
381        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
382
383        domain = Domain(points, vertices)
384        domain.check_integrity()
385
386        # The constant case             
387        domain.set_quantity('elevation', -1)
388        domain.set_quantity('stage', 1) 
389       
390        domain.compute_fluxes()
391        assert num.allclose(domain.get_quantity('stage').explicit_update[1], 0) # Central triangle
392       
393
394        # The more general case                 
395        def surface(x,y):
396            return -x/2                   
397       
398        domain.set_quantity('elevation', -10)
399        domain.set_quantity('stage', surface)   
400        domain.set_quantity('xmomentum', 1)             
401       
402        domain.compute_fluxes()
403       
404        #print domain.get_quantity('stage').explicit_update
405        # FIXME (Ole): TODO the general case
406        #assert allclose(domain.get_quantity('stage').explicit_update[1], ........??)
407               
408       
409               
410    def test_sw_domain_simple(self):
411        a = [0.0, 0.0]
412        b = [0.0, 2.0]
413        c = [2.0,0.0]
414        d = [0.0, 4.0]
415        e = [2.0, 2.0]
416        f = [4.0,0.0]
417
418        points = [a, b, c, d, e, f]
419        #bac, bce, ecf, dbe, daf, dae
420        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
421
422
423        #from anuga.abstract_2d_finite_volumes.domain import Domain as Generic_domain
424        #msg = 'The class %s is not a subclass of the generic domain class %s'\
425        #      %(DomainClass, Domain)
426        #assert issubclass(DomainClass, Domain), msg
427
428        domain = Domain(points, vertices)
429        domain.check_integrity()
430
431        for name in ['stage', 'xmomentum', 'ymomentum',
432                     'elevation', 'friction']:
433            assert domain.quantities.has_key(name)
434
435        assert num.alltrue(domain.get_conserved_quantities(0, edge=1) == 0.)
436
437
438    def test_boundary_conditions(self):
439
440        a = [0.0, 0.0]
441        b = [0.0, 2.0]
442        c = [2.0,0.0]
443        d = [0.0, 4.0]
444        e = [2.0, 2.0]
445        f = [4.0,0.0]
446
447        points = [a, b, c, d, e, f]
448        #bac, bce, ecf, dbe
449        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
450        boundary = { (0, 0): 'Third',
451                     (0, 2): 'First',
452                     (2, 0): 'Second',
453                     (2, 1): 'Second',
454                     (3, 1): 'Second',
455                     (3, 2): 'Third'}
456
457
458        domain = Domain(points, vertices, boundary)
459        domain.check_integrity()
460
461
462        domain.set_quantity('stage', [[1,2,3], [5,5,5],
463                                      [0,0,9], [-6, 3, 3]])
464
465        domain.set_quantity('xmomentum', [[1,1,1], [2,2,2],
466                                          [3,3,3], [4, 4, 4]])
467
468        domain.set_quantity('ymomentum', [[10,10,10], [20,20,20],
469                                          [30,30,30], [40, 40, 40]])
470
471
472        D = Dirichlet_boundary([5,2,1])
473        T = Transmissive_boundary(domain)
474        R = Reflective_boundary(domain)
475        domain.set_boundary( {'First': D, 'Second': T, 'Third': R})
476
477        domain.update_boundary()
478
479        #Stage
480        assert domain.quantities['stage'].boundary_values[0] == 2.5
481        assert domain.quantities['stage'].boundary_values[0] ==\
482               domain.get_conserved_quantities(0, edge=0)[0] #Reflective (2.5)
483        assert domain.quantities['stage'].boundary_values[1] == 5. #Dirichlet
484        assert domain.quantities['stage'].boundary_values[2] ==\
485               domain.get_conserved_quantities(2, edge=0)[0] #Transmissive (4.5)
486        assert domain.quantities['stage'].boundary_values[3] ==\
487               domain.get_conserved_quantities(2, edge=1)[0] #Transmissive (4.5)
488        assert domain.quantities['stage'].boundary_values[4] ==\
489               domain.get_conserved_quantities(3, edge=1)[0] #Transmissive (-1.5)
490        assert domain.quantities['stage'].boundary_values[5] ==\
491               domain.get_conserved_quantities(3, edge=2)[0] #Reflective (-1.5)
492
493        #Xmomentum
494        assert domain.quantities['xmomentum'].boundary_values[0] == 1.0 #Reflective
495        assert domain.quantities['xmomentum'].boundary_values[1] == 2. #Dirichlet
496        assert domain.quantities['xmomentum'].boundary_values[2] ==\
497               domain.get_conserved_quantities(2, edge=0)[1] #Transmissive
498        assert domain.quantities['xmomentum'].boundary_values[3] ==\
499               domain.get_conserved_quantities(2, edge=1)[1] #Transmissive
500        assert domain.quantities['xmomentum'].boundary_values[4] ==\
501               domain.get_conserved_quantities(3, edge=1)[1] #Transmissive
502        assert domain.quantities['xmomentum'].boundary_values[5] == -4.0  #Reflective
503
504        #Ymomentum
505        assert domain.quantities['ymomentum'].boundary_values[0] == -10.0 #Reflective
506        assert domain.quantities['ymomentum'].boundary_values[1] == 1.  #Dirichlet
507        assert domain.quantities['ymomentum'].boundary_values[2] == 30. #Transmissive
508        assert domain.quantities['ymomentum'].boundary_values[3] == 30. #Transmissive
509        assert domain.quantities['ymomentum'].boundary_values[4] == 40. #Transmissive
510        assert domain.quantities['ymomentum'].boundary_values[5] == 40. #Reflective
511
512
513    def test_boundary_conditionsII(self):
514
515        a = [0.0, 0.0]
516        b = [0.0, 2.0]
517        c = [2.0,0.0]
518        d = [0.0, 4.0]
519        e = [2.0, 2.0]
520        f = [4.0,0.0]
521
522        points = [a, b, c, d, e, f]
523        #bac, bce, ecf, dbe
524        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
525        boundary = { (0, 0): 'Third',
526                     (0, 2): 'First',
527                     (2, 0): 'Second',
528                     (2, 1): 'Second',
529                     (3, 1): 'Second',
530                     (3, 2): 'Third',
531                     (0, 1): 'Internal'}
532
533
534        domain = Domain(points, vertices, boundary)
535        domain.check_integrity()
536
537
538        domain.set_quantity('stage', [[1,2,3], [5,5,5],
539                                      [0,0,9], [-6, 3, 3]])
540
541        domain.set_quantity('xmomentum', [[1,1,1], [2,2,2],
542                                          [3,3,3], [4, 4, 4]])
543
544        domain.set_quantity('ymomentum', [[10,10,10], [20,20,20],
545                                          [30,30,30], [40, 40, 40]])
546
547
548        D = Dirichlet_boundary([5,2,1])
549        T = Transmissive_boundary(domain)
550        R = Reflective_boundary(domain)
551        domain.set_boundary( {'First': D, 'Second': T,
552                              'Third': R, 'Internal': None})
553
554        domain.update_boundary()
555        domain.check_integrity()
556
557       
558
559       
560    def test_boundary_conditionsIII(self):
561        """test_boundary_conditionsIII
562       
563        Test Transmissive_stage_zero_momentum_boundary
564        """
565       
566        a = [0.0, 0.0]
567        b = [0.0, 2.0]
568        c = [2.0,0.0]
569        d = [0.0, 4.0]
570        e = [2.0, 2.0]
571        f = [4.0,0.0]
572
573        points = [a, b, c, d, e, f]
574        #bac, bce, ecf, dbe
575        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
576        boundary = { (0, 0): 'Third',
577                     (0, 2): 'First',
578                     (2, 0): 'Second',
579                     (2, 1): 'Second',
580                     (3, 1): 'Second',
581                     (3, 2): 'Third'}
582
583
584        domain = Domain(points, vertices, boundary)
585        domain.check_integrity()
586
587
588        domain.set_quantity('stage', [[1,2,3], [5,5,5],
589                                      [0,0,9], [-6, 3, 3]])
590
591        domain.set_quantity('xmomentum', [[1,1,1], [2,2,2],
592                                          [3,3,3], [4, 4, 4]])
593
594        domain.set_quantity('ymomentum', [[10,10,10], [20,20,20],
595                                          [30,30,30], [40, 40, 40]])
596
597
598        D = Dirichlet_boundary([5,2,1])
599        T = Transmissive_stage_zero_momentum_boundary(domain)
600        R = Reflective_boundary(domain)
601        domain.set_boundary( {'First': D, 'Second': T, 'Third': R})
602
603        domain.update_boundary()
604
605        # Stage
606        assert domain.quantities['stage'].boundary_values[0] == 2.5
607        assert domain.quantities['stage'].boundary_values[0] ==\
608               domain.get_conserved_quantities(0, edge=0)[0] #Reflective (2.5)
609        assert domain.quantities['stage'].boundary_values[1] == 5. #Dirichlet
610        assert domain.quantities['stage'].boundary_values[2] ==\
611               domain.get_conserved_quantities(2, edge=0)[0] #Transmissive (4.5)
612        assert domain.quantities['stage'].boundary_values[3] ==\
613               domain.get_conserved_quantities(2, edge=1)[0] #Transmissive (4.5)
614        assert domain.quantities['stage'].boundary_values[4] ==\
615               domain.get_conserved_quantities(3, edge=1)[0] #Transmissive (-1.5)
616        assert domain.quantities['stage'].boundary_values[5] ==\
617               domain.get_conserved_quantities(3, edge=2)[0] #Reflective (-1.5)
618
619        # Xmomentum
620        assert domain.quantities['xmomentum'].boundary_values[0] == 1.0 #Reflective
621        assert domain.quantities['xmomentum'].boundary_values[1] == 2. #Dirichlet
622        assert domain.quantities['xmomentum'].boundary_values[2] == 0.0 
623        assert domain.quantities['xmomentum'].boundary_values[3] == 0.0 
624        assert domain.quantities['xmomentum'].boundary_values[4] == 0.0 
625        assert domain.quantities['xmomentum'].boundary_values[5] == -4.0  #Reflective
626
627        # Ymomentum
628        assert domain.quantities['ymomentum'].boundary_values[0] == -10.0 #Reflective
629        assert domain.quantities['ymomentum'].boundary_values[1] == 1.  #Dirichlet
630        assert domain.quantities['ymomentum'].boundary_values[2] == 0.0 
631        assert domain.quantities['ymomentum'].boundary_values[3] == 0.0 
632        assert domain.quantities['ymomentum'].boundary_values[4] == 0.0 
633        assert domain.quantities['ymomentum'].boundary_values[5] == 40. #Reflective
634
635               
636               
637       
638    def test_boundary_condition_time(self):
639        """test_boundary_condition_time
640       
641        This tests that boundary conditions are evaluated
642        using the right time from domain.
643
644        """
645       
646        # Setup computational domain
647        from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross
648
649
650        #--------------------------------------------------------------
651        # Setup computational domain
652        #--------------------------------------------------------------
653        N = 5
654        points, vertices, boundary = rectangular_cross(N, N) 
655        domain = Domain(points, vertices, boundary)
656
657        #--------------------------------------------------------------
658        # Setup initial conditions
659        #--------------------------------------------------------------
660        domain.set_quantity('elevation', 0.0)
661        domain.set_quantity('friction', 0.0)
662        domain.set_quantity('stage', 0.0)
663
664
665        #--------------------------------------------------------------
666        # Setup boundary conditions
667        #--------------------------------------------------------------
668        Bt = Time_boundary(domain=domain,             # Time dependent boundary 
669                           f=lambda t: [t, 0.0, 0.0])
670       
671        Br = Reflective_boundary(domain)              # Reflective wall
672
673        domain.set_boundary({'left': Bt, 'right': Br, 'top': Br, 'bottom': Br})
674       
675        for t in domain.evolve(yieldstep = 10, finaltime = 20.0):
676            q = Bt.evaluate()
677   
678            # FIXME (Ole): This test would not have passed in
679            # changeset:5846.
680            msg = 'Time boundary not evaluated correctly'
681            assert num.allclose(t, q[0]), msg
682           
683       
684
685    def test_compute_fluxes0(self):
686        # Do a full triangle and check that fluxes cancel out for
687        # the constant stage case
688
689        a = [0.0, 0.0]
690        b = [0.0, 2.0]
691        c = [2.0,0.0]
692        d = [0.0, 4.0]
693        e = [2.0, 2.0]
694        f = [4.0,0.0]
695
696        points = [a, b, c, d, e, f]
697        #bac, bce, ecf, dbe
698        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
699
700        domain = Domain(points, vertices)
701        domain.set_quantity('stage', [[2,2,2], [2,2,2],
702                                      [2,2,2], [2,2,2]])
703        domain.check_integrity()
704
705        assert num.allclose(domain.neighbours, [[-1,1,-1], [2,3,0], [-1,-1,1],[1,-1,-1]])
706        assert num.allclose(domain.neighbour_edges, [[-1,2,-1], [2,0,1], [-1,-1,0],[1,-1,-1]])
707
708        zl=zr=0. # Assume flat bed
709
710        edgeflux = num.zeros(3, num.float)       
711        edgeflux0 = num.zeros(3, num.float)
712        edgeflux1 = num.zeros(3, num.float)
713        edgeflux2 = num.zeros(3, num.float)                               
714        H0 = 0.0       
715
716        # Flux across right edge of volume 1
717        normal = domain.get_normal(1,0)
718        ql = domain.get_conserved_quantities(vol_id=1, edge=0)
719        qr = domain.get_conserved_quantities(vol_id=2, edge=2)
720        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux0, epsilon, g, H0)                       
721
722        # Check that flux seen from other triangles is inverse
723        tmp = qr; qr=ql; ql=tmp
724        normal = domain.get_normal(2,2)
725        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0)                               
726
727        assert num.allclose(edgeflux0 + edgeflux, 0.)
728
729        # Flux across upper edge of volume 1
730        normal = domain.get_normal(1,1)
731        ql = domain.get_conserved_quantities(vol_id=1, edge=1)
732        qr = domain.get_conserved_quantities(vol_id=3, edge=0)
733        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux1, epsilon, g, H0)                                       
734
735        # Check that flux seen from other triangles is inverse
736        tmp = qr; qr=ql; ql=tmp
737        normal = domain.get_normal(3,0)
738        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0)                                               
739
740        assert num.allclose(edgeflux1 + edgeflux, 0.)       
741       
742
743        # Flux across lower left hypotenuse of volume 1
744        normal = domain.get_normal(1,2)
745        ql = domain.get_conserved_quantities(vol_id=1, edge=2)
746        qr = domain.get_conserved_quantities(vol_id=0, edge=1)
747        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux2, epsilon, g, H0)                                                               
748
749        # Check that flux seen from other triangles is inverse
750        tmp = qr; qr=ql; ql=tmp
751        normal = domain.get_normal(0,1)
752        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0)                                                       
753        assert num.allclose(edgeflux2 + edgeflux, 0.)
754
755
756        # Scale by edgelengths, add up anc check that total flux is zero
757        e0 = domain.edgelengths[1, 0]
758        e1 = domain.edgelengths[1, 1]
759        e2 = domain.edgelengths[1, 2]
760
761        assert num.allclose(e0*edgeflux0+e1*edgeflux1+e2*edgeflux2, 0.)
762
763        # Now check that compute_flux yields zeros as well
764        domain.compute_fluxes()
765
766        for name in ['stage', 'xmomentum', 'ymomentum']:
767            #print name, domain.quantities[name].explicit_update
768            assert num.allclose(domain.quantities[name].explicit_update[1], 0)
769
770
771
772    def test_compute_fluxes1(self):
773        #Use values from previous version
774
775        a = [0.0, 0.0]
776        b = [0.0, 2.0]
777        c = [2.0,0.0]
778        d = [0.0, 4.0]
779        e = [2.0, 2.0]
780        f = [4.0,0.0]
781
782        points = [a, b, c, d, e, f]
783        #bac, bce, ecf, dbe
784        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
785
786        domain = Domain(points, vertices)
787        val0 = 2.+2.0/3
788        val1 = 4.+4.0/3
789        val2 = 8.+2.0/3
790        val3 = 2.+8.0/3
791
792        domain.set_quantity('stage', [[val0, val0, val0], [val1, val1, val1],
793                                      [val2, val2, val2], [val3, val3, val3]])
794        domain.check_integrity()
795
796        zl=zr=0. #Assume flat bed
797
798        edgeflux = num.zeros(3, num.float)       
799        edgeflux0 = num.zeros(3, num.float)
800        edgeflux1 = num.zeros(3, num.float)
801        edgeflux2 = num.zeros(3, num.float)                               
802        H0 = 0.0       
803       
804
805        # Flux across right edge of volume 1
806        normal = domain.get_normal(1,0) #Get normal 0 of triangle 1
807        assert num.allclose(normal, [1, 0])
808       
809        ql = domain.get_conserved_quantities(vol_id=1, edge=0)
810        assert num.allclose(ql, [val1, 0, 0])
811       
812        qr = domain.get_conserved_quantities(vol_id=2, edge=2)
813        assert num.allclose(qr, [val2, 0, 0])
814
815        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux0, epsilon, g, H0)                                                       
816
817        # Flux across edge in the east direction (as per normal vector)
818        assert num.allclose(edgeflux0, [-15.3598804, 253.71111111, 0.])
819        assert num.allclose(max_speed, 9.21592824046)
820
821
822        #Flux across edge in the west direction (opposite sign for xmomentum)
823        normal_opposite = domain.get_normal(2,2) #Get normal 2 of triangle 2
824        assert num.allclose(normal_opposite, [-1, 0])
825
826        max_speed = flux_function(normal_opposite, ql, qr, zl, zr, edgeflux, epsilon, g, H0)                                             
827        #flux_opposite, max_speed = flux_function([-1, 0], ql, qr, zl, zr)
828        assert num.allclose(edgeflux, [-15.3598804, -253.71111111, 0.])
829       
830
831        #Flux across upper edge of volume 1
832        normal = domain.get_normal(1,1)
833        ql = domain.get_conserved_quantities(vol_id=1, edge=1)
834        qr = domain.get_conserved_quantities(vol_id=3, edge=0)
835        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux1, epsilon, g, H0)                                                               
836
837        assert num.allclose(edgeflux1, [2.4098563, 0., 123.04444444])
838        assert num.allclose(max_speed, 7.22956891292)
839
840        #Flux across lower left hypotenuse of volume 1
841        normal = domain.get_normal(1,2)
842        ql = domain.get_conserved_quantities(vol_id=1, edge=2)
843        qr = domain.get_conserved_quantities(vol_id=0, edge=1)
844        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux2, epsilon, g, H0)       
845
846        assert num.allclose(edgeflux2, [9.63942522, -61.59685738, -61.59685738])
847        assert num.allclose(max_speed, 7.22956891292)
848
849        #Scale, add up and check that compute_fluxes is correct for vol 1
850        e0 = domain.edgelengths[1, 0]
851        e1 = domain.edgelengths[1, 1]
852        e2 = domain.edgelengths[1, 2]
853
854        total_flux = -(e0*edgeflux0+e1*edgeflux1+e2*edgeflux2)/domain.areas[1]
855        assert num.allclose(total_flux, [-0.68218178, -166.6, -35.93333333])
856
857
858        domain.compute_fluxes()
859
860        #assert num.allclose(total_flux, domain.explicit_update[1,:])
861        for i, name in enumerate(['stage', 'xmomentum', 'ymomentum']):
862            assert num.allclose(total_flux[i],
863                                domain.quantities[name].explicit_update[1])
864
865        #assert allclose(domain.explicit_update, [
866        #    [0., -69.68888889, -69.68888889],
867        #    [-0.68218178, -166.6, -35.93333333],
868        #    [-111.77316251, 69.68888889, 0.],
869        #    [-35.68522449, 0., 69.68888889]])
870
871        assert num.allclose(domain.quantities['stage'].explicit_update,
872                            [0., -0.68218178, -111.77316251, -35.68522449])
873        assert num.allclose(domain.quantities['xmomentum'].explicit_update,
874                            [-69.68888889, -166.6, 69.68888889, 0])
875        assert num.allclose(domain.quantities['ymomentum'].explicit_update,
876                            [-69.68888889, -35.93333333, 0., 69.68888889])
877
878
879        #assert allclose(domain.quantities[name].explicit_update
880
881
882
883
884
885    def test_compute_fluxes2(self):
886        #Random values, incl momentum
887
888        a = [0.0, 0.0]
889        b = [0.0, 2.0]
890        c = [2.0,0.0]
891        d = [0.0, 4.0]
892        e = [2.0, 2.0]
893        f = [4.0,0.0]
894
895        points = [a, b, c, d, e, f]
896        #bac, bce, ecf, dbe
897        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
898
899        domain = Domain(points, vertices)
900        val0 = 2.+2.0/3
901        val1 = 4.+4.0/3
902        val2 = 8.+2.0/3
903        val3 = 2.+8.0/3
904
905        zl=zr=0 #Assume flat zero bed
906        edgeflux = num.zeros(3, num.float)       
907        edgeflux0 = num.zeros(3, num.float)
908        edgeflux1 = num.zeros(3, num.float)
909        edgeflux2 = num.zeros(3, num.float)                               
910        H0 = 0.0       
911       
912
913        domain.set_quantity('elevation', zl*num.ones( (4,3), num.int )) #array default#
914
915
916        domain.set_quantity('stage', [[val0, val0-1, val0-2],
917                                      [val1, val1+1, val1],
918                                      [val2, val2-2, val2],
919                                      [val3-0.5, val3, val3]])
920
921        domain.set_quantity('xmomentum',
922                            [[1, 2, 3], [3, 4, 5],
923                             [1, -1, 0], [0, -2, 2]])
924
925        domain.set_quantity('ymomentum',
926                            [[1, -1, 0], [0, -3, 2],
927                             [0, 1, 0], [-1, 2, 2]])
928
929
930        domain.check_integrity()
931
932
933
934        #Flux across right edge of volume 1
935        normal = domain.get_normal(1,0)
936        ql = domain.get_conserved_quantities(vol_id=1, edge=0)
937        qr = domain.get_conserved_quantities(vol_id=2, edge=2)
938        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux0, epsilon, g, H0)               
939
940        #Flux across upper edge of volume 1
941        normal = domain.get_normal(1,1)
942        ql = domain.get_conserved_quantities(vol_id=1, edge=1)
943        qr = domain.get_conserved_quantities(vol_id=3, edge=0)
944        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux1, epsilon, g, H0)                       
945
946        #Flux across lower left hypotenuse of volume 1
947        normal = domain.get_normal(1,2)
948        ql = domain.get_conserved_quantities(vol_id=1, edge=2)
949        qr = domain.get_conserved_quantities(vol_id=0, edge=1)
950        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux2, epsilon, g, H0)               
951
952        #Scale, add up and check that compute_fluxes is correct for vol 1
953        e0 = domain.edgelengths[1, 0]
954        e1 = domain.edgelengths[1, 1]
955        e2 = domain.edgelengths[1, 2]
956
957        total_flux = -(e0*edgeflux0+e1*edgeflux1+e2*edgeflux2)/domain.areas[1]
958
959
960        domain.compute_fluxes()
961        for i, name in enumerate(['stage', 'xmomentum', 'ymomentum']):
962            assert num.allclose(total_flux[i],
963                                domain.quantities[name].explicit_update[1])
964        #assert allclose(total_flux, domain.explicit_update[1,:])
965
966
967    # FIXME (Ole): Need test like this for fluxes in very shallow water.   
968    def test_compute_fluxes3(self):
969        #Random values, incl momentum
970
971        a = [0.0, 0.0]
972        b = [0.0, 2.0]
973        c = [2.0,0.0]
974        d = [0.0, 4.0]
975        e = [2.0, 2.0]
976        f = [4.0,0.0]
977
978        points = [a, b, c, d, e, f]
979        #bac, bce, ecf, dbe
980        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
981
982        domain = Domain(points, vertices)
983        val0 = 2.+2.0/3
984        val1 = 4.+4.0/3
985        val2 = 8.+2.0/3
986        val3 = 2.+8.0/3
987
988        zl=zr=-3.75 #Assume constant bed (must be less than stage)
989        domain.set_quantity('elevation', zl*num.ones( (4,3), num.int )) #array default#
990
991
992        edgeflux = num.zeros(3, num.float)       
993        edgeflux0 = num.zeros(3, num.float)
994        edgeflux1 = num.zeros(3, num.float)
995        edgeflux2 = num.zeros(3, num.float)                               
996        H0 = 0.0       
997       
998
999
1000        domain.set_quantity('stage', [[val0, val0-1, val0-2],
1001                                      [val1, val1+1, val1],
1002                                      [val2, val2-2, val2],
1003                                      [val3-0.5, val3, val3]])
1004
1005        domain.set_quantity('xmomentum',
1006                            [[1, 2, 3], [3, 4, 5],
1007                             [1, -1, 0], [0, -2, 2]])
1008
1009        domain.set_quantity('ymomentum',
1010                            [[1, -1, 0], [0, -3, 2],
1011                             [0, 1, 0], [-1, 2, 2]])
1012
1013
1014        domain.check_integrity()
1015
1016
1017
1018        #Flux across right edge of volume 1
1019        normal = domain.get_normal(1,0)
1020        ql = domain.get_conserved_quantities(vol_id=1, edge=0)
1021        qr = domain.get_conserved_quantities(vol_id=2, edge=2)
1022        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux0, epsilon, g, H0)
1023
1024        #Flux across upper edge of volume 1
1025        normal = domain.get_normal(1,1)
1026        ql = domain.get_conserved_quantities(vol_id=1, edge=1)
1027        qr = domain.get_conserved_quantities(vol_id=3, edge=0)
1028        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux1, epsilon, g, H0)       
1029
1030        #Flux across lower left hypotenuse of volume 1
1031        normal = domain.get_normal(1,2)
1032        ql = domain.get_conserved_quantities(vol_id=1, edge=2)
1033        qr = domain.get_conserved_quantities(vol_id=0, edge=1)
1034        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux2, epsilon, g, H0)       
1035
1036        #Scale, add up and check that compute_fluxes is correct for vol 1
1037        e0 = domain.edgelengths[1, 0]
1038        e1 = domain.edgelengths[1, 1]
1039        e2 = domain.edgelengths[1, 2]
1040
1041        total_flux = -(e0*edgeflux0+e1*edgeflux1+e2*edgeflux2)/domain.areas[1]
1042
1043        domain.compute_fluxes()
1044        for i, name in enumerate(['stage', 'xmomentum', 'ymomentum']):
1045            assert num.allclose(total_flux[i],
1046                                domain.quantities[name].explicit_update[1])
1047
1048
1049
1050    def xtest_catching_negative_heights(self):
1051
1052        #OBSOLETE
1053       
1054        a = [0.0, 0.0]
1055        b = [0.0, 2.0]
1056        c = [2.0,0.0]
1057        d = [0.0, 4.0]
1058        e = [2.0, 2.0]
1059        f = [4.0,0.0]
1060
1061        points = [a, b, c, d, e, f]
1062        #bac, bce, ecf, dbe
1063        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1064
1065        domain = Domain(points, vertices)
1066        val0 = 2.+2.0/3
1067        val1 = 4.+4.0/3
1068        val2 = 8.+2.0/3
1069        val3 = 2.+8.0/3
1070
1071        zl=zr=4  #Too large
1072        domain.set_quantity('elevation', zl*num.ones( (4,3), num.int )) #array default#
1073        domain.set_quantity('stage', [[val0, val0-1, val0-2],
1074                                      [val1, val1+1, val1],
1075                                      [val2, val2-2, val2],
1076                                      [val3-0.5, val3, val3]])
1077
1078        #Should fail
1079        try:
1080            domain.check_integrity()
1081        except:
1082            pass
1083
1084
1085
1086    def test_get_wet_elements(self):
1087
1088        a = [0.0, 0.0]
1089        b = [0.0, 2.0]
1090        c = [2.0,0.0]
1091        d = [0.0, 4.0]
1092        e = [2.0, 2.0]
1093        f = [4.0,0.0]
1094
1095        points = [a, b, c, d, e, f]
1096        #bac, bce, ecf, dbe
1097        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1098
1099        domain = Domain(points, vertices)
1100        val0 = 2.+2.0/3
1101        val1 = 4.+4.0/3
1102        val2 = 8.+2.0/3
1103        val3 = 2.+8.0/3
1104
1105        zl=zr=5
1106        domain.set_quantity('elevation', zl*num.ones( (4,3), num.int )) #array default#
1107        domain.set_quantity('stage', [[val0, val0-1, val0-2],
1108                                      [val1, val1+1, val1],
1109                                      [val2, val2-2, val2],
1110                                      [val3-0.5, val3, val3]])
1111
1112
1113
1114        #print domain.get_quantity('elevation').get_values(location='centroids')
1115        #print domain.get_quantity('stage').get_values(location='centroids')       
1116        domain.check_integrity()
1117
1118        indices = domain.get_wet_elements()
1119        assert num.allclose(indices, [1,2])
1120
1121        indices = domain.get_wet_elements(indices=[0,1,3])
1122        assert num.allclose(indices, [1])
1123       
1124
1125
1126    def test_get_maximum_inundation_1(self):
1127
1128        a = [0.0, 0.0]
1129        b = [0.0, 2.0]
1130        c = [2.0,0.0]
1131        d = [0.0, 4.0]
1132        e = [2.0, 2.0]
1133        f = [4.0,0.0]
1134
1135        points = [a, b, c, d, e, f]
1136        #bac, bce, ecf, dbe
1137        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1138
1139        domain = Domain(points, vertices)
1140
1141        domain.set_quantity('elevation', lambda x, y: x+2*y) #2 4 4 6
1142        domain.set_quantity('stage', 3)
1143
1144        domain.check_integrity()
1145
1146        indices = domain.get_wet_elements()
1147        assert num.allclose(indices, [0])
1148
1149        q = domain.get_maximum_inundation_elevation()
1150        assert num.allclose(q, domain.get_quantity('elevation').get_values(location='centroids')[0])
1151
1152        x, y = domain.get_maximum_inundation_location()
1153        assert num.allclose([x, y], domain.get_centroid_coordinates()[0])
1154
1155
1156    def test_get_maximum_inundation_2(self):
1157        """test_get_maximum_inundation_2(self)
1158
1159        Test multiple wet cells with same elevation
1160        """
1161       
1162        a = [0.0, 0.0]
1163        b = [0.0, 2.0]
1164        c = [2.0,0.0]
1165        d = [0.0, 4.0]
1166        e = [2.0, 2.0]
1167        f = [4.0,0.0]
1168
1169        points = [a, b, c, d, e, f]
1170        #bac, bce, ecf, dbe
1171        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1172
1173        domain = Domain(points, vertices)
1174
1175        domain.set_quantity('elevation', lambda x, y: x+2*y) #2 4 4 6
1176        domain.set_quantity('stage', 4.1)
1177
1178        domain.check_integrity()
1179
1180        indices = domain.get_wet_elements()
1181        assert num.allclose(indices, [0,1,2])
1182
1183        q = domain.get_maximum_inundation_elevation()
1184        assert num.allclose(q, 4)       
1185
1186        x, y = domain.get_maximum_inundation_location()
1187        assert num.allclose([x, y], domain.get_centroid_coordinates()[1])       
1188       
1189
1190    def test_get_maximum_inundation_3(self):
1191        """test_get_maximum_inundation_3(self)
1192
1193        Test of real runup example:
1194        """
1195
1196        from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross
1197
1198        initial_runup_height = -0.4
1199        final_runup_height = -0.3
1200
1201
1202        #--------------------------------------------------------------
1203        # Setup computational domain
1204        #--------------------------------------------------------------
1205        N = 5
1206        points, vertices, boundary = rectangular_cross(N, N) 
1207        domain = Domain(points, vertices, boundary)
1208        domain.set_maximum_allowed_speed(1.0)       
1209
1210        #--------------------------------------------------------------
1211        # Setup initial conditions
1212        #--------------------------------------------------------------
1213        def topography(x,y):
1214            return -x/2                             # linear bed slope
1215           
1216
1217        domain.set_quantity('elevation', topography)       # Use function for elevation
1218        domain.set_quantity('friction', 0.)                # Zero friction
1219        domain.set_quantity('stage', initial_runup_height) # Constant negative initial stage
1220
1221
1222        #--------------------------------------------------------------
1223        # Setup boundary conditions
1224        #--------------------------------------------------------------
1225        Br = Reflective_boundary(domain)              # Reflective wall
1226        Bd = Dirichlet_boundary([final_runup_height,  # Constant inflow
1227                                 0,
1228                                 0])
1229
1230        # All reflective to begin with (still water)
1231        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
1232
1233
1234        #--------------------------------------------------------------
1235        # Test initial inundation height
1236        #--------------------------------------------------------------
1237
1238        indices = domain.get_wet_elements()
1239        z = domain.get_quantity('elevation').\
1240            get_values(location='centroids', indices=indices)
1241        assert num.alltrue(z<initial_runup_height)
1242
1243        q = domain.get_maximum_inundation_elevation()
1244        assert num.allclose(q, initial_runup_height, rtol = 1.0/N) # First order accuracy
1245
1246        x, y = domain.get_maximum_inundation_location()
1247
1248        qref = domain.get_quantity('elevation').get_values(interpolation_points = [[x, y]])
1249        assert num.allclose(q, qref)
1250
1251
1252        wet_elements = domain.get_wet_elements()
1253        wet_elevations = domain.get_quantity('elevation').get_values(location='centroids',
1254                                                                     indices=wet_elements)
1255        assert num.alltrue(wet_elevations<initial_runup_height)
1256        assert num.allclose(wet_elevations, z)       
1257
1258
1259        #print domain.get_quantity('elevation').get_maximum_value(indices=wet_elements)
1260        #print domain.get_quantity('elevation').get_maximum_location(indices=wet_elements)
1261        #print domain.get_quantity('elevation').get_maximum_index(indices=wet_elements)
1262
1263       
1264        #--------------------------------------------------------------
1265        # Let triangles adjust
1266        #--------------------------------------------------------------
1267        for t in domain.evolve(yieldstep = 0.1, finaltime = 1.0):
1268            pass
1269
1270
1271        #--------------------------------------------------------------
1272        # Test inundation height again
1273        #--------------------------------------------------------------
1274
1275        indices = domain.get_wet_elements()
1276        z = domain.get_quantity('elevation').\
1277            get_values(location='centroids', indices=indices)
1278
1279        assert num.alltrue(z<initial_runup_height)
1280
1281        q = domain.get_maximum_inundation_elevation()
1282        assert num.allclose(q, initial_runup_height, rtol = 1.0/N) # First order accuracy
1283       
1284        x, y = domain.get_maximum_inundation_location()
1285        qref = domain.get_quantity('elevation').get_values(interpolation_points = [[x, y]])
1286        assert num.allclose(q, qref)       
1287
1288
1289        #--------------------------------------------------------------
1290        # Update boundary to allow inflow
1291        #--------------------------------------------------------------
1292        domain.set_boundary({'right': Bd})
1293
1294       
1295        #--------------------------------------------------------------
1296        # Evolve system through time
1297        #--------------------------------------------------------------
1298        for t in domain.evolve(yieldstep = 0.1, finaltime = 3.0):
1299            #print domain.timestepping_statistics(track_speeds=True)
1300            #domain.write_time()
1301            pass
1302   
1303        #--------------------------------------------------------------
1304        # Test inundation height again
1305        #--------------------------------------------------------------
1306
1307        indices = domain.get_wet_elements()
1308        z = domain.get_quantity('elevation').\
1309            get_values(location='centroids', indices=indices)
1310
1311        assert num.alltrue(z<final_runup_height)
1312
1313        q = domain.get_maximum_inundation_elevation()
1314        assert num.allclose(q, final_runup_height, rtol = 1.0/N) # First order accuracy
1315
1316        x, y = domain.get_maximum_inundation_location()
1317        qref = domain.get_quantity('elevation').get_values(interpolation_points = [[x, y]])
1318        assert num.allclose(q, qref)       
1319
1320
1321        wet_elements = domain.get_wet_elements()
1322        wet_elevations = domain.get_quantity('elevation').get_values(location='centroids',
1323                                                                     indices=wet_elements)
1324        assert num.alltrue(wet_elevations<final_runup_height)
1325        assert num.allclose(wet_elevations, z)       
1326       
1327
1328
1329    def test_get_maximum_inundation_from_sww(self):
1330        """test_get_maximum_inundation_from_sww(self)
1331
1332        Test of get_maximum_inundation_elevation()
1333        and get_maximum_inundation_location() from data_manager.py
1334       
1335        This is based on test_get_maximum_inundation_3(self) but works with the
1336        stored results instead of with the internal data structure.
1337
1338        This test uses the underlying get_maximum_inundation_data for tests
1339        """
1340
1341        from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross
1342        from data_manager import get_maximum_inundation_elevation
1343        from data_manager import get_maximum_inundation_location
1344        from data_manager import get_maximum_inundation_data
1345       
1346
1347        initial_runup_height = -0.4
1348        final_runup_height = -0.3
1349
1350
1351        #--------------------------------------------------------------
1352        # Setup computational domain
1353        #--------------------------------------------------------------
1354        N = 10
1355        points, vertices, boundary = rectangular_cross(N, N) 
1356        domain = Domain(points, vertices, boundary)
1357        domain.set_name('runup_test')
1358        domain.set_maximum_allowed_speed(1.0)
1359
1360        domain.tight_slope_limiters = 0 # FIXME: This works better with old limiters so far
1361
1362        #--------------------------------------------------------------
1363        # Setup initial conditions
1364        #--------------------------------------------------------------
1365        def topography(x,y):
1366            return -x/2                             # linear bed slope
1367           
1368
1369        domain.set_quantity('elevation', topography)       # Use function for elevation
1370        domain.set_quantity('friction', 0.)                # Zero friction
1371        domain.set_quantity('stage', initial_runup_height) # Constant negative initial stage
1372
1373
1374        #--------------------------------------------------------------
1375        # Setup boundary conditions
1376        #--------------------------------------------------------------
1377        Br = Reflective_boundary(domain)              # Reflective wall
1378        Bd = Dirichlet_boundary([final_runup_height,  # Constant inflow
1379                                 0,
1380                                 0])
1381
1382        # All reflective to begin with (still water)
1383        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
1384
1385
1386        #--------------------------------------------------------------
1387        # Test initial inundation height
1388        #--------------------------------------------------------------
1389
1390        indices = domain.get_wet_elements()
1391        z = domain.get_quantity('elevation').\
1392            get_values(location='centroids', indices=indices)
1393        assert num.alltrue(z<initial_runup_height)
1394
1395        q_ref = domain.get_maximum_inundation_elevation()
1396        assert num.allclose(q_ref, initial_runup_height, rtol = 1.0/N) # First order accuracy
1397
1398       
1399        #--------------------------------------------------------------
1400        # Let triangles adjust
1401        #--------------------------------------------------------------
1402        for t in domain.evolve(yieldstep = 0.1, finaltime = 1.0):
1403            pass
1404
1405
1406        #--------------------------------------------------------------
1407        # Test inundation height again
1408        #--------------------------------------------------------------
1409       
1410        q_ref = domain.get_maximum_inundation_elevation()
1411        q = get_maximum_inundation_elevation('runup_test.sww')
1412        msg = 'We got %f, should have been %f' %(q, q_ref)
1413        assert num.allclose(q, q_ref, rtol=1.0/N), msg
1414
1415
1416        q = get_maximum_inundation_elevation('runup_test.sww')
1417        msg = 'We got %f, should have been %f' %(q, initial_runup_height)
1418        assert num.allclose(q, initial_runup_height, rtol = 1.0/N), msg
1419
1420
1421        # Test error condition if time interval is out
1422        try:
1423            q = get_maximum_inundation_elevation('runup_test.sww',
1424                                                 time_interval=[2.0, 3.0])
1425        except ValueError:
1426            pass
1427        else:
1428            msg = 'should have caught wrong time interval'
1429            raise Exception, msg
1430
1431        # Check correct time interval
1432        q, loc = get_maximum_inundation_data('runup_test.sww',
1433                                             time_interval=[0.0, 3.0])       
1434        msg = 'We got %f, should have been %f' %(q, initial_runup_height)
1435        assert num.allclose(q, initial_runup_height, rtol = 1.0/N), msg
1436        assert num.allclose(-loc[0]/2, q) # From topography formula         
1437       
1438
1439        #--------------------------------------------------------------
1440        # Update boundary to allow inflow
1441        #--------------------------------------------------------------
1442        domain.set_boundary({'right': Bd})
1443
1444       
1445        #--------------------------------------------------------------
1446        # Evolve system through time
1447        #--------------------------------------------------------------
1448        q_max = None
1449        for t in domain.evolve(yieldstep = 0.1, finaltime = 3.0,
1450                               skip_initial_step = True): 
1451            q = domain.get_maximum_inundation_elevation()
1452            if q > q_max: q_max = q
1453
1454   
1455        #--------------------------------------------------------------
1456        # Test inundation height again
1457        #--------------------------------------------------------------
1458
1459        indices = domain.get_wet_elements()
1460        z = domain.get_quantity('elevation').\
1461            get_values(location='centroids', indices=indices)
1462
1463        assert num.alltrue(z<final_runup_height)
1464
1465        q = domain.get_maximum_inundation_elevation()
1466        assert num.allclose(q, final_runup_height, rtol = 1.0/N) # First order accuracy
1467
1468        q, loc = get_maximum_inundation_data('runup_test.sww', time_interval=[3.0, 3.0])
1469        msg = 'We got %f, should have been %f' %(q, final_runup_height)
1470        assert num.allclose(q, final_runup_height, rtol=1.0/N), msg
1471        #print 'loc', loc, q       
1472        assert num.allclose(-loc[0]/2, q) # From topography formula         
1473
1474        q = get_maximum_inundation_elevation('runup_test.sww')
1475        loc = get_maximum_inundation_location('runup_test.sww')       
1476        msg = 'We got %f, should have been %f' %(q, q_max)
1477        assert num.allclose(q, q_max, rtol=1.0/N), msg
1478        #print 'loc', loc, q
1479        assert num.allclose(-loc[0]/2, q) # From topography formula
1480
1481       
1482
1483        q = get_maximum_inundation_elevation('runup_test.sww', time_interval=[0, 3])
1484        msg = 'We got %f, should have been %f' %(q, q_max)
1485        assert num.allclose(q, q_max, rtol=1.0/N), msg
1486
1487
1488        # Check polygon mode
1489        polygon = [[0.3, 0.0], [0.9, 0.0], [0.9, 1.0], [0.3, 1.0]] # Runup region
1490        q = get_maximum_inundation_elevation('runup_test.sww',
1491                                             polygon = polygon,
1492                                             time_interval=[0, 3])
1493        msg = 'We got %f, should have been %f' %(q, q_max)
1494        assert num.allclose(q, q_max, rtol=1.0/N), msg
1495
1496       
1497        polygon = [[0.9, 0.0], [1.0, 0.0], [1.0, 1.0], [0.9, 1.0]] # Offshore region
1498        q, loc = get_maximum_inundation_data('runup_test.sww',
1499                                             polygon = polygon,
1500                                             time_interval=[0, 3])
1501        msg = 'We got %f, should have been %f' %(q, -0.475)
1502        assert num.allclose(q, -0.475, rtol=1.0/N), msg
1503        assert is_inside_polygon(loc, polygon)
1504        assert num.allclose(-loc[0]/2, q) # From topography formula         
1505
1506
1507        polygon = [[0.0, 0.0], [0.4, 0.0], [0.4, 1.0], [0.0, 1.0]] # Dry region
1508        q, loc = get_maximum_inundation_data('runup_test.sww',
1509                                             polygon = polygon,
1510                                             time_interval=[0, 3])
1511        msg = 'We got %s, should have been None' %(q)
1512        assert q is None, msg
1513        msg = 'We got %s, should have been None' %(loc)
1514        assert loc is None, msg       
1515
1516        # Check what happens if no time point is within interval
1517        try:
1518            q = get_maximum_inundation_elevation('runup_test.sww', time_interval=[2.75, 2.75])
1519        except AssertionError:
1520            pass
1521        else:
1522            msg = 'Time interval should have raised an exception'
1523            raise msg
1524
1525        # Cleanup
1526        try:
1527            os.remove(domain.get_name() + '.' + domain.format)
1528        except:
1529            pass
1530            #FIXME(Ole): Windows won't allow removal of this
1531           
1532       
1533       
1534    def test_get_flow_through_cross_section_with_geo(self):
1535        """test_get_flow_through_cross_section(self):
1536
1537        Test that the total flow through a cross section can be
1538        correctly obtained at run-time from the ANUGA domain.
1539       
1540        This test creates a flat bed with a known flow through it and tests
1541        that the function correctly returns the expected flow.
1542
1543        The specifics are
1544        e = -1 m
1545        u = 2 m/s
1546        h = 2 m
1547        w = 3 m (width of channel)
1548
1549        q = u*h*w = 12 m^3/s
1550
1551
1552        This run tries it with georeferencing and with elevation = -1
1553       
1554        """
1555
1556        import time, os
1557        from Scientific.IO.NetCDF import NetCDFFile
1558
1559        # Setup
1560        from mesh_factory import rectangular
1561
1562        # Create basic mesh (20m x 3m)
1563        width = 3
1564        length = 20
1565        t_end = 1
1566        points, vertices, boundary = rectangular(length, width,
1567                                                 length, width)
1568
1569        # Create shallow water domain
1570        domain = Domain(points, vertices, boundary,
1571                        geo_reference=Geo_reference(56,308500,6189000))
1572
1573        domain.default_order = 2
1574        domain.set_quantities_to_be_stored(None)
1575
1576
1577        e = -1.0
1578        w = 1.0
1579        h = w-e
1580        u = 2.0
1581        uh = u*h
1582
1583        Br = Reflective_boundary(domain)     # Side walls
1584        Bd = Dirichlet_boundary([w, uh, 0])  # 2 m/s across the 3 m inlet:
1585
1586
1587        # Initial conditions
1588        domain.set_quantity('elevation', e)
1589        domain.set_quantity('stage', w)
1590        domain.set_quantity('xmomentum', uh)
1591        domain.set_boundary( {'left': Bd, 'right': Bd, 'top': Br, 'bottom': Br})
1592       
1593       
1594        # Interpolation points down the middle
1595        I = [[0, width/2.],
1596             [length/2., width/2.],
1597             [length, width/2.]]
1598        interpolation_points = domain.geo_reference.get_absolute(I)       
1599       
1600        # Shortcuts to quantites
1601        stage = domain.get_quantity('stage')       
1602        xmomentum = domain.get_quantity('xmomentum')       
1603        ymomentum = domain.get_quantity('ymomentum')               
1604
1605        for t in domain.evolve(yieldstep=0.1, finaltime = t_end):
1606            # Check that quantities are they should be in the interior
1607
1608            w_t = stage.get_values(interpolation_points)           
1609            uh_t = xmomentum.get_values(interpolation_points)
1610            vh_t = ymomentum.get_values(interpolation_points)           
1611           
1612            assert num.allclose(w_t, w)
1613            assert num.allclose(uh_t, uh)           
1614            assert num.allclose(vh_t, 0.0)                       
1615           
1616           
1617            # Check flows through the middle
1618            for i in range(5):
1619                x = length/2. + i*0.23674563 # Arbitrary
1620                cross_section = [[x, 0], [x, width]]
1621
1622                cross_section = domain.geo_reference.get_absolute(cross_section)           
1623                Q = domain.get_flow_through_cross_section(cross_section,
1624                                                          verbose=False)
1625
1626                assert num.allclose(Q, uh*width)
1627
1628
1629       
1630    def test_get_energy_through_cross_section_with_geo(self):
1631        """test_get_energy_through_cross_section(self):
1632
1633        Test that the total and specific energy through a cross section can be
1634        correctly obtained at run-time from the ANUGA domain.
1635       
1636        This test creates a flat bed with a known flow through it and tests
1637        that the function correctly returns the expected energies.
1638
1639        The specifics are
1640        e = -1 m
1641        u = 2 m/s
1642        h = 2 m
1643        w = 3 m (width of channel)
1644
1645        q = u*h*w = 12 m^3/s
1646
1647
1648        This run tries it with georeferencing and with elevation = -1
1649       
1650        """
1651
1652        import time, os
1653        from Scientific.IO.NetCDF import NetCDFFile
1654
1655        # Setup
1656        from mesh_factory import rectangular
1657
1658        # Create basic mesh (20m x 3m)
1659        width = 3
1660        length = 20
1661        t_end = 1
1662        points, vertices, boundary = rectangular(length, width,
1663                                                 length, width)
1664
1665        # Create shallow water domain
1666        domain = Domain(points, vertices, boundary,
1667                        geo_reference=Geo_reference(56,308500,6189000))
1668
1669        domain.default_order = 2
1670        domain.set_quantities_to_be_stored(None)
1671
1672
1673        e = -1.0
1674        w = 1.0
1675        h = w-e
1676        u = 2.0
1677        uh = u*h
1678
1679        Br = Reflective_boundary(domain)     # Side walls
1680        Bd = Dirichlet_boundary([w, uh, 0])  # 2 m/s across the 3 m inlet:
1681
1682
1683        # Initial conditions
1684        domain.set_quantity('elevation', e)
1685        domain.set_quantity('stage', w)
1686        domain.set_quantity('xmomentum', uh)
1687        domain.set_boundary( {'left': Bd, 'right': Bd, 'top': Br, 'bottom': Br})
1688       
1689       
1690        # Interpolation points down the middle
1691        I = [[0, width/2.],
1692             [length/2., width/2.],
1693             [length, width/2.]]
1694        interpolation_points = domain.geo_reference.get_absolute(I)       
1695       
1696        # Shortcuts to quantites
1697        stage = domain.get_quantity('stage')       
1698        xmomentum = domain.get_quantity('xmomentum')       
1699        ymomentum = domain.get_quantity('ymomentum')               
1700
1701        for t in domain.evolve(yieldstep=0.1, finaltime = t_end):
1702            # Check that quantities are they should be in the interior
1703
1704            w_t = stage.get_values(interpolation_points)           
1705            uh_t = xmomentum.get_values(interpolation_points)
1706            vh_t = ymomentum.get_values(interpolation_points)           
1707           
1708            assert num.allclose(w_t, w)
1709            assert num.allclose(uh_t, uh)           
1710            assert num.allclose(vh_t, 0.0)                       
1711           
1712           
1713            # Check energies through the middle
1714            for i in range(5):
1715                x = length/2. + i*0.23674563 # Arbitrary
1716                cross_section = [[x, 0], [x, width]]
1717
1718                cross_section = domain.geo_reference.get_absolute(cross_section)   
1719                Es = domain.get_energy_through_cross_section(cross_section,
1720                                                             kind='specific',
1721                                                             verbose=False)
1722                                                     
1723                assert num.allclose(Es, h + 0.5*u*u/g)
1724           
1725                Et = domain.get_energy_through_cross_section(cross_section,
1726                                                             kind='total',
1727                                                             verbose=False)
1728                assert num.allclose(Et, w + 0.5*u*u/g)           
1729
1730           
1731       
1732       
1733
1734    def test_another_runup_example(self):
1735        """test_another_runup_example
1736
1737        Test runup example where actual timeseries at interpolated
1738        points are tested.
1739        """
1740
1741        #-----------------------------------------------------------------
1742        # Import necessary modules
1743        #-----------------------------------------------------------------
1744
1745        from anuga.pmesh.mesh_interface import create_mesh_from_regions
1746        from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross
1747        from anuga.shallow_water import Domain
1748        from anuga.shallow_water import Reflective_boundary
1749        from anuga.shallow_water import Dirichlet_boundary
1750
1751
1752        #-----------------------------------------------------------------
1753        # Setup computational domain
1754        #-----------------------------------------------------------------
1755        points, vertices, boundary = rectangular_cross(10, 10) # Basic mesh
1756        domain = Domain(points, vertices, boundary) # Create domain
1757        domain.set_quantities_to_be_stored(None)
1758        domain.set_maximum_allowed_speed(100) #FIXME (Ole): try to remove this
1759       
1760        # FIXME (Ole): Need tests where this is commented out
1761        domain.tight_slope_limiters = 0 # Backwards compatibility (14/4/7)
1762        domain.H0 = 0 # Backwards compatibility (6/2/7)
1763        domain.use_centroid_velocities = 0 # Backwards compatibility (7/5/8)
1764       
1765
1766        #-----------------------------------------------------------------
1767        # Setup initial conditions
1768        #-----------------------------------------------------------------
1769
1770        def topography(x,y): 
1771            return -x/2                              # linear bed slope
1772
1773        domain.set_quantity('elevation', topography) 
1774        domain.set_quantity('friction', 0.0)         
1775        domain.set_quantity('stage', expression='elevation')           
1776
1777
1778        #----------------------------------------------------------------
1779        # Setup boundary conditions
1780        #----------------------------------------------------------------
1781
1782        Br = Reflective_boundary(domain)      # Solid reflective wall
1783        Bd = Dirichlet_boundary([-0.2,0.,0.]) # Constant boundary values
1784        domain.set_boundary({'left': Br, 'right': Bd, 'top': Br, 'bottom': Br})
1785
1786
1787        #----------------------------------------------------------------
1788        # Evolve system through time
1789        #----------------------------------------------------------------
1790
1791        interpolation_points = [[0.4,0.5], [0.6,0.5], [0.8,0.5], [0.9,0.5]]
1792        gauge_values = []
1793        for _ in interpolation_points:
1794            gauge_values.append([])
1795
1796        time = []
1797        for t in domain.evolve(yieldstep = 0.1, finaltime = 5.0):
1798            # Record time series at known points
1799            time.append(domain.get_time())
1800           
1801            stage = domain.get_quantity('stage')
1802            w = stage.get_values(interpolation_points=interpolation_points)
1803           
1804            for i, _ in enumerate(interpolation_points):
1805                gauge_values[i].append(w[i])
1806
1807
1808        #print
1809        #print time
1810        #print
1811        #for i, (x,y) in enumerate(interpolation_points):
1812        #    print i, gauge_values[i]
1813        #    print
1814
1815        #Reference (nautilus 26/6/2008)
1816       
1817        G0 = [-0.20000000000000001, -0.20000000000000001, -0.19920600846161715, -0.19153647344085376, -0.19127622768281194, -0.1770671909675095, -0.16739412133181927, -0.16196038919122191, -0.15621633053131384, -0.15130021599977705, -0.13930978857215484, -0.19349274358263582, -0.19975307598803765, -0.19999897143103357, -0.1999999995532111, -0.19999999999949952, -0.19999999999949952, -0.19999999999949952, -0.19997270012494556, -0.19925805948554556, -0.19934513778450533, -0.19966484196394893, -0.1997352860102084, -0.19968260481750394, -0.19980280797303882, -0.19998804881822749, -0.19999999778075916, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167, -0.19999999999966167]
1818
1819        G1 = [-0.29999999999999993, -0.29999588068034899, -0.29250047332330331, -0.28335081844518584, -0.26142206997410805, -0.22656028856329835, -0.21224087216745585, -0.19934324109114465, -0.1889857939783175, -0.18146311603911383, -0.17401078727434263, -0.15419361061257214, -0.16225060576782063, -0.19010941396999181, -0.20901161407004412, -0.21670683975774699, -0.21771386270738891, -0.21481284465869752, -0.21063120869004387, -0.20669243364582401, -0.20320707386714859, -0.19984087691926442, -0.19725417448019505, -0.19633783049069981, -0.19650494599999785, -0.19708316838336942, -0.19779309449413818, -0.19853070294429562, -0.19917342167307153, -0.19964814677795845, -0.19991627610824922, -0.20013162970144974, -0.20029864969405509, -0.20036259676501131, -0.20030682824965193, -0.20016105135750167, -0.19997664501985918, -0.19980185871568762, -0.19966836175417696, -0.19958856744312226, -0.19955954696194517, -0.19956950051110917, -0.19960377086336181, -0.19964885299433241, -0.19969427478531132, -0.19973301547655564, -0.19976121574277764, -0.19977765285688653, -0.19978315117522441, -0.19977994634841739, -0.19977101394878494]
1820       
1821        G2 = [-0.40000000000000002, -0.39077401254732241, -0.33350466136630474, -0.29771023004255281, -0.27605439066140897, -0.25986156218997497, -0.24502185018573647, -0.231792624329521, -0.21981564668803993, -0.20870707082936543, -0.19877739883776599, -0.18980922837977957, -0.17308011674005838, -0.16306400164013773, -0.17798470933304333, -0.1929554075869116, -0.20236705191987037, -0.20695767560655007, -0.20841025876092567, -0.20792102174869989, -0.20655350005579293, -0.20492002526259828, -0.20310627026780645, -0.20105983335287836, -0.19937394565794653, -0.19853917506699659, -0.19836389977624452, -0.19850305023602796, -0.19877764028836831, -0.19910928131034669, -0.19943705712418805, -0.19970344172958865, -0.19991076989870474, -0.20010020127747646, -0.20025937787100062, -0.20035087292905965, -0.20035829921463297, -0.20029606557316171, -0.20019606915365515, -0.20009096093399206, -0.20000371608204368, -0.19994495432920584, -0.19991535665176338, -0.19990981826533513, -0.19992106419898723, -0.19994189853516578, -0.19996624091229293, -0.19998946016985167, -0.20000842303470234, -0.20002144460718174, -0.20002815561337187]
1822       
1823        G3 = [-0.45000000000000001, -0.37631169657400332, -0.33000044342859486, -0.30586045469008522, -0.28843572253009941, -0.27215308978603808, -0.25712951540331219, -0.2431608296216613, -0.23032023651386374, -0.2184546873456619, -0.20735123704254332, -0.19740397194806389, -0.1859829564064375, -0.16675980728362105, -0.16951575032846536, -0.1832860872609344, -0.19485758939241243, -0.20231368291811427, -0.20625610376074754, -0.20758116241495619, -0.20721445402086161, -0.20603406830353785, -0.20450262808396991, -0.2026769581185151, -0.2007401212066364, -0.19931160535777592, -0.19863606301128725, -0.19848511940572691, -0.19860091042948352, -0.19885490669377764, -0.19916542732701112, -0.19946678238611959, -0.19971209594104697, -0.19991912886512292, -0.2001058430788881, -0.20024959409472989, -0.20032160254609382, -0.20031583165752354, -0.20025051539293123, -0.2001556115816068, -0.20005952955420872, -0.1999814429561611, -0.19992977821558131, -0.19990457708664208, -0.19990104785490476, -0.19991257153954825, -0.19993258231880562, -0.19995548502882532, -0.19997700760919687, -0.19999429663503748, -0.20000588800248761]
1824       
1825        #FIXME (DSG):This is a hack so the anuga install, not precompiled
1826        # works on DSG's win2000, python 2.3
1827        #The problem is the gauge_values[X] are 52 long, not 51.
1828        #
1829        # This was probably fixed by Stephen in changeset:3804
1830        #if len(gauge_values[0]) == 52: gauge_values[0].pop()
1831        #if len(gauge_values[1]) == 52: gauge_values[1].pop()
1832        #if len(gauge_values[2]) == 52: gauge_values[2].pop()
1833        #if len(gauge_values[3]) == 52: gauge_values[3].pop()
1834
1835##         print len(G0), len(gauge_values[0])
1836##         print len(G1), len(gauge_values[1])
1837       
1838        #print gauge_values[3]
1839        #print G0[:4]
1840        #print array(gauge_values[0])-array(G0)
1841       
1842       
1843        assert num.allclose(gauge_values[0], G0)
1844        assert num.allclose(gauge_values[1], G1)
1845        assert num.allclose(gauge_values[2], G2)
1846        assert num.allclose(gauge_values[3], G3)       
1847
1848
1849
1850
1851
1852
1853
1854    #####################################################
1855
1856    def test_flux_optimisation(self):
1857        """test_flux_optimisation
1858        Test that fluxes are correctly computed using
1859        dry and still cell exclusions
1860        """
1861
1862        from anuga.config import g
1863        import copy
1864
1865        a = [0.0, 0.0]
1866        b = [0.0, 2.0]
1867        c = [2.0, 0.0]
1868        d = [0.0, 4.0]
1869        e = [2.0, 2.0]
1870        f = [4.0, 0.0]
1871
1872        points = [a, b, c, d, e, f]
1873        #bac, bce, ecf, dbe
1874        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1875
1876        domain = Domain(points, vertices)
1877
1878        #Set up for a gradient of (3,0) at mid triangle (bce)
1879        def slope(x, y):
1880            return 3*x
1881
1882        h = 0.1
1883        def stage(x,y):
1884            return slope(x,y)+h
1885
1886        domain.set_quantity('elevation', slope)
1887        domain.set_quantity('stage', stage)
1888
1889        # Allow slope limiters to work (FIXME (Ole): Shouldn't this be automatic in ANUGA?)     
1890        domain.distribute_to_vertices_and_edges()       
1891
1892        initial_stage = copy.copy(domain.quantities['stage'].vertex_values)
1893
1894        domain.set_boundary({'exterior': Reflective_boundary(domain)})
1895
1896
1897        #  Check that update arrays are initialised to zero
1898        assert num.allclose(domain.get_quantity('stage').explicit_update, 0)
1899        assert num.allclose(domain.get_quantity('xmomentum').explicit_update, 0)
1900        assert num.allclose(domain.get_quantity('ymomentum').explicit_update, 0)               
1901
1902
1903        # Get true values
1904        domain.optimise_dry_cells = False
1905        domain.compute_fluxes()
1906        stage_ref = copy.copy(domain.get_quantity('stage').explicit_update)
1907        xmom_ref = copy.copy(domain.get_quantity('xmomentum').explicit_update)
1908        ymom_ref = copy.copy(domain.get_quantity('ymomentum').explicit_update)       
1909
1910        # Try with flux optimisation
1911        domain.optimise_dry_cells = True
1912        domain.compute_fluxes()
1913
1914        assert num.allclose(stage_ref, domain.get_quantity('stage').explicit_update)
1915        assert num.allclose(xmom_ref, domain.get_quantity('xmomentum').explicit_update)
1916        assert num.allclose(ymom_ref, domain.get_quantity('ymomentum').explicit_update)
1917       
1918   
1919       
1920    def test_initial_condition(self):
1921        """test_initial_condition
1922        Test that initial condition is output at time == 0 and that
1923        computed values change as system evolves
1924        """
1925
1926        from anuga.config import g
1927        import copy
1928
1929        a = [0.0, 0.0]
1930        b = [0.0, 2.0]
1931        c = [2.0, 0.0]
1932        d = [0.0, 4.0]
1933        e = [2.0, 2.0]
1934        f = [4.0, 0.0]
1935
1936        points = [a, b, c, d, e, f]
1937        #bac, bce, ecf, dbe
1938        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1939
1940        domain = Domain(points, vertices)
1941
1942        #Set up for a gradient of (3,0) at mid triangle (bce)
1943        def slope(x, y):
1944            return 3*x
1945
1946        h = 0.1
1947        def stage(x,y):
1948            return slope(x,y)+h
1949
1950        domain.set_quantity('elevation', slope)
1951        domain.set_quantity('stage', stage)
1952
1953        # Allow slope limiters to work (FIXME (Ole): Shouldn't this be automatic in ANUGA?)     
1954        domain.distribute_to_vertices_and_edges()       
1955
1956        initial_stage = copy.copy(domain.quantities['stage'].vertex_values)
1957
1958        domain.set_boundary({'exterior': Reflective_boundary(domain)})
1959
1960        domain.optimise_dry_cells = True
1961        #Evolution
1962        for t in domain.evolve(yieldstep = 0.5, finaltime = 2.0):
1963            stage = domain.quantities['stage'].vertex_values
1964
1965            if t == 0.0:
1966                assert num.allclose(stage, initial_stage)
1967            else:
1968                assert not num.allclose(stage, initial_stage)
1969
1970
1971        os.remove(domain.get_name() + '.sww')
1972
1973
1974
1975    #####################################################
1976    def test_gravity(self):
1977        #Assuming no friction
1978
1979        from anuga.config import g
1980
1981        a = [0.0, 0.0]
1982        b = [0.0, 2.0]
1983        c = [2.0, 0.0]
1984        d = [0.0, 4.0]
1985        e = [2.0, 2.0]
1986        f = [4.0, 0.0]
1987
1988        points = [a, b, c, d, e, f]
1989        #bac, bce, ecf, dbe
1990        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
1991
1992        domain = Domain(points, vertices)
1993
1994        #Set up for a gradient of (3,0) at mid triangle (bce)
1995        def slope(x, y):
1996            return 3*x
1997
1998        h = 0.1
1999        def stage(x,y):
2000            return slope(x,y)+h
2001
2002        domain.set_quantity('elevation', slope)
2003        domain.set_quantity('stage', stage)
2004
2005        for name in domain.conserved_quantities:
2006            assert num.allclose(domain.quantities[name].explicit_update, 0)
2007            assert num.allclose(domain.quantities[name].semi_implicit_update, 0)
2008
2009        domain.compute_forcing_terms()
2010
2011        assert num.allclose(domain.quantities['stage'].explicit_update, 0)
2012        assert num.allclose(domain.quantities['xmomentum'].explicit_update, -g*h*3)
2013        assert num.allclose(domain.quantities['ymomentum'].explicit_update, 0)
2014
2015
2016    def test_manning_friction(self):
2017        from anuga.config import g
2018
2019        a = [0.0, 0.0]
2020        b = [0.0, 2.0]
2021        c = [2.0, 0.0]
2022        d = [0.0, 4.0]
2023        e = [2.0, 2.0]
2024        f = [4.0, 0.0]
2025
2026        points = [a, b, c, d, e, f]
2027        #bac, bce, ecf, dbe
2028        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2029
2030        domain = Domain(points, vertices)
2031
2032        #Set up for a gradient of (3,0) at mid triangle (bce)
2033        def slope(x, y):
2034            return 3*x
2035
2036        h = 0.1
2037        def stage(x,y):
2038            return slope(x,y)+h
2039
2040        eta = 0.07
2041        domain.set_quantity('elevation', slope)
2042        domain.set_quantity('stage', stage)
2043        domain.set_quantity('friction', eta)
2044
2045        for name in domain.conserved_quantities:
2046            assert num.allclose(domain.quantities[name].explicit_update, 0)
2047            assert num.allclose(domain.quantities[name].semi_implicit_update, 0)
2048
2049        domain.compute_forcing_terms()
2050
2051        assert num.allclose(domain.quantities['stage'].explicit_update, 0)
2052        assert num.allclose(domain.quantities['xmomentum'].explicit_update, -g*h*3)
2053        assert num.allclose(domain.quantities['ymomentum'].explicit_update, 0)
2054
2055        assert num.allclose(domain.quantities['stage'].semi_implicit_update, 0)
2056        assert num.allclose(domain.quantities['xmomentum'].semi_implicit_update, 0)
2057        assert num.allclose(domain.quantities['ymomentum'].semi_implicit_update, 0)
2058
2059        #Create some momentum for friction to work with
2060        domain.set_quantity('xmomentum', 1)
2061        S = -g * eta**2 / h**(7.0/3)
2062
2063        domain.compute_forcing_terms()
2064        assert num.allclose(domain.quantities['stage'].semi_implicit_update, 0)
2065        assert num.allclose(domain.quantities['xmomentum'].semi_implicit_update, S)
2066        assert num.allclose(domain.quantities['ymomentum'].semi_implicit_update, 0)
2067
2068        #A more complex example
2069        domain.quantities['stage'].semi_implicit_update[:] = 0.0
2070        domain.quantities['xmomentum'].semi_implicit_update[:] = 0.0
2071        domain.quantities['ymomentum'].semi_implicit_update[:] = 0.0
2072
2073        domain.set_quantity('xmomentum', 3)
2074        domain.set_quantity('ymomentum', 4)
2075
2076        S = -g * eta**2 * 5 / h**(7.0/3)
2077
2078
2079        domain.compute_forcing_terms()
2080
2081        assert num.allclose(domain.quantities['stage'].semi_implicit_update, 0)
2082        assert num.allclose(domain.quantities['xmomentum'].semi_implicit_update, 3*S)
2083        assert num.allclose(domain.quantities['ymomentum'].semi_implicit_update, 4*S)
2084
2085    def test_constant_wind_stress(self):
2086        from anuga.config import rho_a, rho_w, eta_w
2087        from math import pi, cos, sin
2088
2089        a = [0.0, 0.0]
2090        b = [0.0, 2.0]
2091        c = [2.0, 0.0]
2092        d = [0.0, 4.0]
2093        e = [2.0, 2.0]
2094        f = [4.0, 0.0]
2095
2096        points = [a, b, c, d, e, f]
2097        #bac, bce, ecf, dbe
2098        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2099
2100
2101        domain = Domain(points, vertices)
2102
2103        #Flat surface with 1m of water
2104        domain.set_quantity('elevation', 0)
2105        domain.set_quantity('stage', 1.0)
2106        domain.set_quantity('friction', 0)
2107
2108        Br = Reflective_boundary(domain)
2109        domain.set_boundary({'exterior': Br})
2110
2111        #Setup only one forcing term, constant wind stress
2112        s = 100
2113        phi = 135
2114        domain.forcing_terms = []
2115        domain.forcing_terms.append( Wind_stress(s, phi) )
2116
2117        domain.compute_forcing_terms()
2118
2119
2120        const = eta_w*rho_a/rho_w
2121
2122        #Convert to radians
2123        phi = phi*pi/180
2124
2125        #Compute velocity vector (u, v)
2126        u = s*cos(phi)
2127        v = s*sin(phi)
2128
2129        #Compute wind stress
2130        S = const * num.sqrt(u**2 + v**2)
2131
2132        assert num.allclose(domain.quantities['stage'].explicit_update, 0)
2133        assert num.allclose(domain.quantities['xmomentum'].explicit_update, S*u)
2134        assert num.allclose(domain.quantities['ymomentum'].explicit_update, S*v)
2135
2136
2137    def test_variable_wind_stress(self):
2138        from anuga.config import rho_a, rho_w, eta_w
2139        from math import pi, cos, sin
2140
2141        a = [0.0, 0.0]
2142        b = [0.0, 2.0]
2143        c = [2.0, 0.0]
2144        d = [0.0, 4.0]
2145        e = [2.0, 2.0]
2146        f = [4.0, 0.0]
2147
2148        points = [a, b, c, d, e, f]
2149        #bac, bce, ecf, dbe
2150        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2151
2152        domain = Domain(points, vertices)
2153
2154        #Flat surface with 1m of water
2155        domain.set_quantity('elevation', 0)
2156        domain.set_quantity('stage', 1.0)
2157        domain.set_quantity('friction', 0)
2158
2159        Br = Reflective_boundary(domain)
2160        domain.set_boundary({'exterior': Br})
2161
2162
2163        domain.time = 5.54 #Take a random time (not zero)
2164
2165        #Setup only one forcing term, constant wind stress
2166        s = 100
2167        phi = 135
2168        domain.forcing_terms = []
2169        domain.forcing_terms.append( Wind_stress(s = speed, phi = angle) )
2170
2171        domain.compute_forcing_terms()
2172
2173        #Compute reference solution
2174        const = eta_w*rho_a/rho_w
2175
2176        N = len(domain) # number_of_triangles
2177
2178        xc = domain.get_centroid_coordinates()
2179        t = domain.time
2180
2181        x = xc[:,0]
2182        y = xc[:,1]
2183        s_vec = speed(t,x,y)
2184        phi_vec = angle(t,x,y)
2185
2186
2187        for k in range(N):
2188            #Convert to radians
2189            phi = phi_vec[k]*pi/180
2190            s = s_vec[k]
2191
2192            #Compute velocity vector (u, v)
2193            u = s*cos(phi)
2194            v = s*sin(phi)
2195
2196            #Compute wind stress
2197            S = const * num.sqrt(u**2 + v**2)
2198
2199            assert num.allclose(domain.quantities['stage'].explicit_update[k], 0)
2200            assert num.allclose(domain.quantities['xmomentum'].explicit_update[k], S*u)
2201            assert num.allclose(domain.quantities['ymomentum'].explicit_update[k], S*v)
2202
2203
2204
2205
2206
2207
2208    def test_windfield_from_file(self):
2209        from anuga.config import rho_a, rho_w, eta_w
2210        from math import pi, cos, sin
2211        from anuga.config import time_format
2212        from anuga.abstract_2d_finite_volumes.util import file_function
2213        import time
2214
2215
2216        a = [0.0, 0.0]
2217        b = [0.0, 2.0]
2218        c = [2.0, 0.0]
2219        d = [0.0, 4.0]
2220        e = [2.0, 2.0]
2221        f = [4.0, 0.0]
2222
2223        points = [a, b, c, d, e, f]
2224        #bac, bce, ecf, dbe
2225        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2226
2227        domain = Domain(points, vertices)
2228
2229        #Flat surface with 1m of water
2230        domain.set_quantity('elevation', 0)
2231        domain.set_quantity('stage', 1.0)
2232        domain.set_quantity('friction', 0)
2233
2234        Br = Reflective_boundary(domain)
2235        domain.set_boundary({'exterior': Br})
2236
2237
2238        domain.time = 7 #Take a time that is represented in file (not zero)
2239
2240        #Write wind stress file (ensure that domain.time is covered)
2241        #Take x=1 and y=0
2242        filename = 'test_windstress_from_file'
2243        start = time.mktime(time.strptime('2000', '%Y'))
2244        fid = open(filename + '.txt', 'w')
2245        dt = 1  #One second interval
2246        t = 0.0
2247        while t <= 10.0:
2248            t_string = time.strftime(time_format, time.gmtime(t+start))
2249
2250            fid.write('%s, %f %f\n' %(t_string,
2251                                      speed(t,[1],[0])[0],
2252                                      angle(t,[1],[0])[0]))
2253            t += dt
2254
2255        fid.close()
2256
2257
2258        #Convert ASCII file to NetCDF (Which is what we really like!)
2259        from data_manager import timefile2netcdf       
2260        timefile2netcdf(filename)
2261        os.remove(filename + '.txt')
2262
2263       
2264        #Setup wind stress
2265        F = file_function(filename + '.tms', quantities = ['Attribute0',
2266                                                           'Attribute1'])
2267        os.remove(filename + '.tms')
2268       
2269
2270        #print 'F(5)', F(5)
2271
2272        #print 'F(5,x,y)', F(5,x=zeros(3),y=zeros(3))
2273       
2274        #print dir(F)
2275        #print F.T
2276        #print F.precomputed_values
2277        #
2278        #F = file_function(filename + '.txt')       
2279        #
2280        #print dir(F)
2281        #print F.T       
2282        #print F.Q
2283       
2284        W = Wind_stress(F)
2285
2286        domain.forcing_terms = []
2287        domain.forcing_terms.append(W)
2288
2289        domain.compute_forcing_terms()
2290
2291        #Compute reference solution
2292        const = eta_w*rho_a/rho_w
2293
2294        N = len(domain) # number_of_triangles
2295
2296        t = domain.time
2297
2298        s = speed(t,[1],[0])[0]
2299        phi = angle(t,[1],[0])[0]
2300
2301        #Convert to radians
2302        phi = phi*pi/180
2303
2304
2305        #Compute velocity vector (u, v)
2306        u = s*cos(phi)
2307        v = s*sin(phi)
2308
2309        #Compute wind stress
2310        S = const * num.sqrt(u**2 + v**2)
2311
2312        for k in range(N):
2313            assert num.allclose(domain.quantities['stage'].explicit_update[k], 0)
2314            assert num.allclose(domain.quantities['xmomentum'].explicit_update[k], S*u)
2315            assert num.allclose(domain.quantities['ymomentum'].explicit_update[k], S*v)
2316
2317
2318    def test_windfield_from_file_seconds(self):
2319        from anuga.config import rho_a, rho_w, eta_w
2320        from math import pi, cos, sin
2321        from anuga.config import time_format
2322        from anuga.abstract_2d_finite_volumes.util import file_function
2323        import time
2324
2325
2326        a = [0.0, 0.0]
2327        b = [0.0, 2.0]
2328        c = [2.0, 0.0]
2329        d = [0.0, 4.0]
2330        e = [2.0, 2.0]
2331        f = [4.0, 0.0]
2332
2333        points = [a, b, c, d, e, f]
2334        #bac, bce, ecf, dbe
2335        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2336
2337        domain = Domain(points, vertices)
2338
2339        #Flat surface with 1m of water
2340        domain.set_quantity('elevation', 0)
2341        domain.set_quantity('stage', 1.0)
2342        domain.set_quantity('friction', 0)
2343
2344        Br = Reflective_boundary(domain)
2345        domain.set_boundary({'exterior': Br})
2346
2347
2348        domain.time = 7 #Take a time that is represented in file (not zero)
2349
2350        #Write wind stress file (ensure that domain.time is covered)
2351        #Take x=1 and y=0
2352        filename = 'test_windstress_from_file'
2353        start = time.mktime(time.strptime('2000', '%Y'))
2354        fid = open(filename + '.txt', 'w')
2355        dt = 0.5 #1  #One second interval
2356        t = 0.0
2357        while t <= 10.0:
2358            fid.write('%s, %f %f\n' %(str(t),
2359                                      speed(t,[1],[0])[0],
2360                                      angle(t,[1],[0])[0]))
2361            t += dt
2362
2363        fid.close()
2364
2365
2366        #Convert ASCII file to NetCDF (Which is what we really like!)
2367        from data_manager import timefile2netcdf       
2368        timefile2netcdf(filename, time_as_seconds=True)
2369        os.remove(filename + '.txt')
2370
2371       
2372        #Setup wind stress
2373        F = file_function(filename + '.tms', quantities = ['Attribute0',
2374                                                           'Attribute1'])
2375        os.remove(filename + '.tms')
2376       
2377
2378        #print 'F(5)', F(5)
2379
2380        #print 'F(5,x,y)', F(5,x=zeros(3),y=zeros(3))
2381       
2382        #print dir(F)
2383        #print F.T
2384        #print F.precomputed_values
2385        #
2386        #F = file_function(filename + '.txt')       
2387        #
2388        #print dir(F)
2389        #print F.T       
2390        #print F.Q
2391       
2392        W = Wind_stress(F)
2393
2394        domain.forcing_terms = []
2395        domain.forcing_terms.append(W)
2396
2397        domain.compute_forcing_terms()
2398
2399        #Compute reference solution
2400        const = eta_w*rho_a/rho_w
2401
2402        N = len(domain) # number_of_triangles
2403
2404        t = domain.time
2405
2406        s = speed(t,[1],[0])[0]
2407        phi = angle(t,[1],[0])[0]
2408
2409        #Convert to radians
2410        phi = phi*pi/180
2411
2412
2413        #Compute velocity vector (u, v)
2414        u = s*cos(phi)
2415        v = s*sin(phi)
2416
2417        #Compute wind stress
2418        S = const * num.sqrt(u**2 + v**2)
2419
2420        for k in range(N):
2421            assert num.allclose(domain.quantities['stage'].explicit_update[k], 0)
2422            assert num.allclose(domain.quantities['xmomentum'].explicit_update[k], S*u)
2423            assert num.allclose(domain.quantities['ymomentum'].explicit_update[k], S*v)
2424
2425
2426       
2427
2428    def test_wind_stress_error_condition(self):
2429        """Test that windstress reacts properly when forcing functions
2430        are wrong - e.g. returns a scalar
2431        """
2432
2433        from anuga.config import rho_a, rho_w, eta_w
2434        from math import pi, cos, sin
2435
2436        a = [0.0, 0.0]
2437        b = [0.0, 2.0]
2438        c = [2.0, 0.0]
2439        d = [0.0, 4.0]
2440        e = [2.0, 2.0]
2441        f = [4.0, 0.0]
2442
2443        points = [a, b, c, d, e, f]
2444        #bac, bce, ecf, dbe
2445        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2446
2447        domain = Domain(points, vertices)
2448
2449        #Flat surface with 1m of water
2450        domain.set_quantity('elevation', 0)
2451        domain.set_quantity('stage', 1.0)
2452        domain.set_quantity('friction', 0)
2453
2454        Br = Reflective_boundary(domain)
2455        domain.set_boundary({'exterior': Br})
2456
2457
2458        domain.time = 5.54 #Take a random time (not zero)
2459
2460        #Setup only one forcing term, bad func
2461        domain.forcing_terms = []
2462
2463        try:
2464            domain.forcing_terms.append(Wind_stress(s = scalar_func,
2465                                                    phi = angle))
2466        except AssertionError:
2467            pass
2468        else:
2469            msg = 'Should have raised exception'
2470            raise msg
2471
2472
2473        try:
2474            domain.forcing_terms.append(Wind_stress(s = speed,
2475                                                    phi = scalar_func))
2476        except AssertionError:
2477            pass
2478        else:
2479            msg = 'Should have raised exception'
2480            raise msg
2481
2482        try:
2483            domain.forcing_terms.append(Wind_stress(s = speed,
2484                                                    phi = 'xx'))
2485        except:
2486            pass
2487        else:
2488            msg = 'Should have raised exception'
2489            raise msg
2490
2491
2492
2493    def test_rainfall(self):
2494        from math import pi, cos, sin
2495
2496        a = [0.0, 0.0]
2497        b = [0.0, 2.0]
2498        c = [2.0, 0.0]
2499        d = [0.0, 4.0]
2500        e = [2.0, 2.0]
2501        f = [4.0, 0.0]
2502
2503        points = [a, b, c, d, e, f]
2504        #bac, bce, ecf, dbe
2505        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2506
2507
2508        domain = Domain(points, vertices)
2509
2510        #Flat surface with 1m of water
2511        domain.set_quantity('elevation', 0)
2512        domain.set_quantity('stage', 1.0)
2513        domain.set_quantity('friction', 0)
2514
2515        Br = Reflective_boundary(domain)
2516        domain.set_boundary({'exterior': Br})
2517
2518        # Setup only one forcing term, constant rainfall
2519        domain.forcing_terms = []
2520        domain.forcing_terms.append( Rainfall(domain, rate=2.0) )
2521
2522        domain.compute_forcing_terms()
2523        assert num.allclose(domain.quantities['stage'].explicit_update, 2.0/1000)
2524
2525
2526
2527    def test_rainfall_restricted_by_polygon(self):
2528        from math import pi, cos, sin
2529
2530        a = [0.0, 0.0]
2531        b = [0.0, 2.0]
2532        c = [2.0, 0.0]
2533        d = [0.0, 4.0]
2534        e = [2.0, 2.0]
2535        f = [4.0, 0.0]
2536
2537        points = [a, b, c, d, e, f]
2538        #bac, bce, ecf, dbe
2539        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2540
2541
2542        domain = Domain(points, vertices)
2543
2544        #Flat surface with 1m of water
2545        domain.set_quantity('elevation', 0)
2546        domain.set_quantity('stage', 1.0)
2547        domain.set_quantity('friction', 0)
2548
2549        Br = Reflective_boundary(domain)
2550        domain.set_boundary({'exterior': Br})
2551
2552        # Setup only one forcing term, constant rainfall restricted to a polygon enclosing triangle #1 (bce)
2553        domain.forcing_terms = []
2554        R = Rainfall(domain,
2555                     rate=2.0,
2556                     polygon = [[1,1], [2,1], [2,2], [1,2]])
2557
2558        assert num.allclose(R.exchange_area, 1)
2559       
2560        domain.forcing_terms.append(R)
2561
2562        domain.compute_forcing_terms()
2563        #print domain.quantities['stage'].explicit_update
2564       
2565        assert num.allclose(domain.quantities['stage'].explicit_update[1],
2566                            2.0/1000)
2567        assert num.allclose(domain.quantities['stage'].explicit_update[0], 0)
2568        assert num.allclose(domain.quantities['stage'].explicit_update[2:], 0)       
2569       
2570
2571
2572    def test_time_dependent_rainfall_restricted_by_polygon(self):
2573
2574        a = [0.0, 0.0]
2575        b = [0.0, 2.0]
2576        c = [2.0, 0.0]
2577        d = [0.0, 4.0]
2578        e = [2.0, 2.0]
2579        f = [4.0, 0.0]
2580
2581        points = [a, b, c, d, e, f]
2582        #bac, bce, ecf, dbe
2583        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2584
2585
2586        domain = Domain(points, vertices)
2587
2588        #Flat surface with 1m of water
2589        domain.set_quantity('elevation', 0)
2590        domain.set_quantity('stage', 1.0)
2591        domain.set_quantity('friction', 0)
2592
2593        Br = Reflective_boundary(domain)
2594        domain.set_boundary({'exterior': Br})
2595
2596        # Setup only one forcing term, time dependent rainfall restricted to a polygon enclosing triangle #1 (bce)
2597        domain.forcing_terms = []
2598        R = Rainfall(domain,
2599                     rate=lambda t: 3*t + 7,
2600                     polygon = [[1,1], [2,1], [2,2], [1,2]])
2601
2602        assert num.allclose(R.exchange_area, 1)
2603       
2604        domain.forcing_terms.append(R)
2605
2606
2607        domain.time = 10.
2608
2609        domain.compute_forcing_terms()
2610        #print domain.quantities['stage'].explicit_update
2611       
2612        assert num.allclose(domain.quantities['stage'].explicit_update[1],
2613                            (3*domain.time+7)/1000)
2614        assert num.allclose(domain.quantities['stage'].explicit_update[0], 0)
2615        assert num.allclose(domain.quantities['stage'].explicit_update[2:], 0)       
2616       
2617
2618
2619
2620    def test_time_dependent_rainfall_using_starttime(self):
2621   
2622        rainfall_poly = ensure_numeric([[1,1], [2,1], [2,2], [1,2]], num.float)   
2623
2624        a = [0.0, 0.0]
2625        b = [0.0, 2.0]
2626        c = [2.0, 0.0]
2627        d = [0.0, 4.0]
2628        e = [2.0, 2.0]
2629        f = [4.0, 0.0]
2630
2631        points = [a, b, c, d, e, f]
2632        #bac, bce, ecf, dbe
2633        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2634
2635
2636        domain = Domain(points, vertices)
2637
2638        #Flat surface with 1m of water
2639        domain.set_quantity('elevation', 0)
2640        domain.set_quantity('stage', 1.0)
2641        domain.set_quantity('friction', 0)
2642
2643        Br = Reflective_boundary(domain)
2644        domain.set_boundary({'exterior': Br})
2645
2646        # Setup only one forcing term, time dependent rainfall restricted to a polygon enclosing triangle #1 (bce)
2647        domain.forcing_terms = []
2648        R = Rainfall(domain,
2649                     rate=lambda t: 3*t + 7,
2650                     polygon=rainfall_poly)                     
2651
2652        assert num.allclose(R.exchange_area, 1)
2653       
2654        domain.forcing_terms.append(R)
2655
2656        # This will test that time used in the forcing function takes
2657        # startime into account.
2658        domain.starttime = 5.0
2659
2660        domain.time = 7.
2661
2662        domain.compute_forcing_terms()
2663        #print domain.quantities['stage'].explicit_update
2664
2665        #print domain.get_time()
2666        assert num.allclose(domain.quantities['stage'].explicit_update[1],
2667                            (3*domain.get_time()+7)/1000)
2668        assert num.allclose(domain.quantities['stage'].explicit_update[1],
2669                            (3*(domain.time + domain.starttime)+7)/1000)
2670
2671        # Using internal time her should fail
2672        assert not num.allclose(domain.quantities['stage'].explicit_update[1],
2673                                (3*domain.time+7)/1000)               
2674
2675        assert num.allclose(domain.quantities['stage'].explicit_update[0], 0)
2676        assert num.allclose(domain.quantities['stage'].explicit_update[2:], 0)       
2677       
2678
2679
2680       
2681    def test_time_dependent_rainfall_using_georef(self):
2682        """test_time_dependent_rainfall_using_georef
2683       
2684        This will also test the General forcing term using georef
2685        """
2686       
2687        #Mesh in zone 56 (absolute coords)
2688
2689        x0 = 314036.58727982
2690        y0 = 6224951.2960092
2691
2692       
2693        rainfall_poly = ensure_numeric([[1,1], [2,1], [2,2], [1,2]], num.float)
2694        rainfall_poly += [x0, y0]
2695
2696        a = [0.0, 0.0]
2697        b = [0.0, 2.0]
2698        c = [2.0, 0.0]
2699        d = [0.0, 4.0]
2700        e = [2.0, 2.0]
2701        f = [4.0, 0.0]
2702
2703        points = [a, b, c, d, e, f]
2704        #bac, bce, ecf, dbe
2705        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2706
2707
2708        domain = Domain(points, vertices,
2709                        geo_reference = Geo_reference(56, x0, y0))
2710
2711        #Flat surface with 1m of water
2712        domain.set_quantity('elevation', 0)
2713        domain.set_quantity('stage', 1.0)
2714        domain.set_quantity('friction', 0)
2715
2716        Br = Reflective_boundary(domain)
2717        domain.set_boundary({'exterior': Br})
2718
2719        # Setup only one forcing term, time dependent rainfall restricted to a polygon enclosing triangle #1 (bce)
2720        domain.forcing_terms = []
2721        R = Rainfall(domain,
2722                     rate=lambda t: 3*t + 7,
2723                     polygon=rainfall_poly)
2724
2725        assert num.allclose(R.exchange_area, 1)
2726       
2727        domain.forcing_terms.append(R)
2728
2729        # This will test that time used in the forcing function takes
2730        # startime into account.
2731        domain.starttime = 5.0
2732
2733        domain.time = 7.
2734
2735        domain.compute_forcing_terms()
2736        #print domain.quantities['stage'].explicit_update
2737
2738        #print domain.get_time()
2739        assert num.allclose(domain.quantities['stage'].explicit_update[1],
2740                            (3*domain.get_time()+7)/1000)
2741        assert num.allclose(domain.quantities['stage'].explicit_update[1],
2742                            (3*(domain.time + domain.starttime)+7)/1000)
2743
2744        # Using internal time her should fail
2745        assert not num.allclose(domain.quantities['stage'].explicit_update[1],
2746                                (3*domain.time+7)/1000)               
2747
2748        assert num.allclose(domain.quantities['stage'].explicit_update[0], 0)
2749        assert num.allclose(domain.quantities['stage'].explicit_update[2:], 0)       
2750       
2751
2752       
2753       
2754
2755
2756    def test_time_dependent_rainfall_restricted_by_polygon_with_default(self):
2757        """test_time_dependent_rainfall_restricted_by_polygon_with_default
2758
2759        Test that default rainfall can be used when given rate runs out of data.
2760        """
2761        a = [0.0, 0.0]
2762        b = [0.0, 2.0]
2763        c = [2.0, 0.0]
2764        d = [0.0, 4.0]
2765        e = [2.0, 2.0]
2766        f = [4.0, 0.0]
2767
2768        points = [a, b, c, d, e, f]
2769        #bac, bce, ecf, dbe
2770        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2771
2772
2773        domain = Domain(points, vertices)
2774
2775        #Flat surface with 1m of water
2776        domain.set_quantity('elevation', 0)
2777        domain.set_quantity('stage', 1.0)
2778        domain.set_quantity('friction', 0)
2779
2780        Br = Reflective_boundary(domain)
2781        domain.set_boundary({'exterior': Br})
2782
2783        # Setup only one forcing term, time dependent rainfall that expires at t==20
2784        from anuga.fit_interpolate.interpolate import Modeltime_too_late
2785        def main_rate(t):
2786            if t > 20:
2787                msg = 'Model time exceeded.'
2788                raise Modeltime_too_late, msg
2789            else:
2790                return 3*t + 7
2791       
2792        domain.forcing_terms = []
2793        R = Rainfall(domain,
2794                     rate=main_rate,
2795                     polygon = [[1,1], [2,1], [2,2], [1,2]],
2796                     default_rate=5.0)
2797
2798        assert num.allclose(R.exchange_area, 1)
2799       
2800        domain.forcing_terms.append(R)
2801
2802
2803        domain.time = 10.
2804
2805        domain.compute_forcing_terms()
2806        #print domain.quantities['stage'].explicit_update
2807       
2808        assert num.allclose(domain.quantities['stage'].explicit_update[1], (3*domain.time+7)/1000)
2809        assert num.allclose(domain.quantities['stage'].explicit_update[0], 0)
2810        assert num.allclose(domain.quantities['stage'].explicit_update[2:], 0)       
2811
2812
2813        domain.time = 100.
2814        domain.quantities['stage'].explicit_update[:] = 0.0  # Reset
2815        domain.compute_forcing_terms()
2816        #print domain.quantities['stage'].explicit_update
2817       
2818        assert num.allclose(domain.quantities['stage'].explicit_update[1], 5.0/1000) # Default value
2819        assert num.allclose(domain.quantities['stage'].explicit_update[0], 0)
2820        assert num.allclose(domain.quantities['stage'].explicit_update[2:], 0)       
2821       
2822
2823
2824
2825       
2826
2827
2828    def test_rainfall_forcing_with_evolve(self):
2829        """test_rainfall_forcing_with_evolve
2830
2831        Test how forcing terms are called within evolve
2832        """
2833       
2834        # FIXME(Ole): This test is just to experiment
2835       
2836        a = [0.0, 0.0]
2837        b = [0.0, 2.0]
2838        c = [2.0, 0.0]
2839        d = [0.0, 4.0]
2840        e = [2.0, 2.0]
2841        f = [4.0, 0.0]
2842
2843        points = [a, b, c, d, e, f]
2844        #bac, bce, ecf, dbe
2845        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2846
2847
2848        domain = Domain(points, vertices)
2849
2850        #Flat surface with 1m of water
2851        domain.set_quantity('elevation', 0)
2852        domain.set_quantity('stage', 1.0)
2853        domain.set_quantity('friction', 0)
2854
2855        Br = Reflective_boundary(domain)
2856        domain.set_boundary({'exterior': Br})
2857
2858        # Setup only one forcing term, time dependent rainfall that expires at t==20
2859        from anuga.fit_interpolate.interpolate import Modeltime_too_late
2860        def main_rate(t):
2861            if t > 20:
2862                msg = 'Model time exceeded.'
2863                raise Modeltime_too_late, msg
2864            else:
2865                return 3*t + 7
2866       
2867        domain.forcing_terms = []
2868        R = Rainfall(domain,
2869                     rate=main_rate,
2870                     polygon=[[1,1], [2,1], [2,2], [1,2]],
2871                     default_rate=5.0)
2872
2873        assert num.allclose(R.exchange_area, 1)
2874       
2875        domain.forcing_terms.append(R)
2876
2877        for t in domain.evolve(yieldstep=1, finaltime=25):
2878            pass
2879           
2880            #print t, domain.quantities['stage'].explicit_update, (3*t+7)/1000
2881           
2882            #FIXME(Ole):  A test here is hard because explicit_update also
2883            # receives updates from the flux calculation.
2884
2885       
2886       
2887
2888    def test_inflow_using_circle(self):
2889        from math import pi, cos, sin
2890
2891        a = [0.0, 0.0]
2892        b = [0.0, 2.0]
2893        c = [2.0, 0.0]
2894        d = [0.0, 4.0]
2895        e = [2.0, 2.0]
2896        f = [4.0, 0.0]
2897
2898        points = [a, b, c, d, e, f]
2899        #bac, bce, ecf, dbe
2900        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2901
2902
2903        domain = Domain(points, vertices)
2904
2905        # Flat surface with 1m of water
2906        domain.set_quantity('elevation', 0)
2907        domain.set_quantity('stage', 1.0)
2908        domain.set_quantity('friction', 0)
2909
2910        Br = Reflective_boundary(domain)
2911        domain.set_boundary({'exterior': Br})
2912
2913        # Setup only one forcing term, constant inflow of 2 m^3/s on a circle affecting triangles #0 and #1 (bac and bce)
2914        domain.forcing_terms = []
2915        domain.forcing_terms.append( Inflow(domain, rate=2.0, center=(1,1), radius=1) )
2916
2917        domain.compute_forcing_terms()
2918        #print domain.quantities['stage'].explicit_update
2919       
2920        assert num.allclose(domain.quantities['stage'].explicit_update[1], 2.0/pi)
2921        assert num.allclose(domain.quantities['stage'].explicit_update[0], 2.0/pi)
2922        assert num.allclose(domain.quantities['stage'].explicit_update[2:], 0)       
2923
2924
2925    def test_inflow_using_circle_function(self):
2926        from math import pi, cos, sin
2927
2928        a = [0.0, 0.0]
2929        b = [0.0, 2.0]
2930        c = [2.0, 0.0]
2931        d = [0.0, 4.0]
2932        e = [2.0, 2.0]
2933        f = [4.0, 0.0]
2934
2935        points = [a, b, c, d, e, f]
2936        #bac, bce, ecf, dbe
2937        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2938
2939
2940        domain = Domain(points, vertices)
2941
2942        # Flat surface with 1m of water
2943        domain.set_quantity('elevation', 0)
2944        domain.set_quantity('stage', 1.0)
2945        domain.set_quantity('friction', 0)
2946
2947        Br = Reflective_boundary(domain)
2948        domain.set_boundary({'exterior': Br})
2949
2950        # Setup only one forcing term, time dependent inflow of 2 m^3/s on a circle affecting triangles #0 and #1 (bac and bce)
2951        domain.forcing_terms = []
2952        domain.forcing_terms.append( Inflow(domain, rate=lambda t: 2., center=(1,1), radius=1) )
2953
2954        domain.compute_forcing_terms()
2955       
2956        assert num.allclose(domain.quantities['stage'].explicit_update[1], 2.0/pi)
2957        assert num.allclose(domain.quantities['stage'].explicit_update[0], 2.0/pi)
2958        assert num.allclose(domain.quantities['stage'].explicit_update[2:], 0)       
2959       
2960
2961
2962
2963    def test_inflow_catch_too_few_triangles(self):
2964        """test_inflow_catch_too_few_triangles
2965       
2966        Test that exception is thrown if no triangles are covered by the inflow area
2967        """
2968        from math import pi, cos, sin
2969
2970        a = [0.0, 0.0]
2971        b = [0.0, 2.0]
2972        c = [2.0, 0.0]
2973        d = [0.0, 4.0]
2974        e = [2.0, 2.0]
2975        f = [4.0, 0.0]
2976
2977        points = [a, b, c, d, e, f]
2978        #bac, bce, ecf, dbe
2979        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
2980
2981
2982        domain = Domain(points, vertices)
2983
2984        # Flat surface with 1m of water
2985        domain.set_quantity('elevation', 0)
2986        domain.set_quantity('stage', 1.0)
2987        domain.set_quantity('friction', 0)
2988
2989        Br = Reflective_boundary(domain)
2990        domain.set_boundary({'exterior': Br})
2991
2992        # Setup only one forcing term, constant inflow of 2 m^3/s on a circle affecting triangles #0 and #1 (bac and bce)
2993
2994        try:
2995            Inflow(domain, rate=2.0, center=(1,1.1), radius=0.01)
2996        except:
2997            pass
2998        else:
2999            msg = 'Should have raised exception'
3000            raise Exception, msg
3001
3002
3003
3004
3005    def Xtest_inflow_outflow_conservation(self):
3006        """test_inflow_outflow_conservation
3007       
3008        Test what happens if water is abstracted from one area and
3009        injected into another - especially if there is not enough
3010        water to match the abstraction.
3011        This tests that the total volume is kept constant under a range of
3012        scenarios.
3013       
3014        This test will fail as the problem was only fixed for culverts.
3015        """
3016       
3017        from math import pi, cos, sin
3018       
3019        length = 20.
3020        width = 10.
3021
3022        dx = dy = 2  # 1 or 2 OK
3023        points, vertices, boundary = rectangular_cross(int(length/dx),
3024                                                       int(width/dy),
3025                                                       len1=length, 
3026                                                       len2=width)
3027        domain = Domain(points, vertices, boundary)   
3028        domain.set_name('test_inflow_conservation')  # Output name
3029        domain.set_default_order(2)
3030       
3031
3032        # Flat surface with 1m of water
3033        stage = 1.0
3034        domain.set_quantity('elevation', 0)
3035        domain.set_quantity('stage', stage)
3036        domain.set_quantity('friction', 0)
3037
3038        Br = Reflective_boundary(domain)
3039        domain.set_boundary({'left': Br, 'right': Br, 'bottom': Br, 'top': Br})
3040
3041        # Setup one forcing term, constant inflow of 2 m^3/s on a circle
3042        domain.forcing_terms = []
3043        domain.forcing_terms.append(Inflow(domain, rate=2.0, center=(5,5), radius=1))
3044
3045        domain.compute_forcing_terms()
3046        #print domain.quantities['stage'].explicit_update
3047       
3048        # Check that update values are correct
3049        for x in domain.quantities['stage'].explicit_update:
3050            assert num.allclose(x, 2.0/pi) or num.allclose(x, 0.0)
3051
3052       
3053        # Check volumes without inflow
3054        domain.forcing_terms = []       
3055        initial_volume = domain.quantities['stage'].get_integral()
3056       
3057        assert num.allclose(initial_volume, width*length*stage)
3058       
3059        for t in domain.evolve(yieldstep = 0.05, finaltime = 5.0):
3060            volume =  domain.quantities['stage'].get_integral()
3061            assert num.allclose (volume, initial_volume)
3062           
3063           
3064        # Now apply the inflow and check volumes for a range of stage values
3065        for stage in [2.0, 1.0, 0.5, 0.25, 0.1, 0.0]:
3066            domain.time = 0.0
3067            domain.set_quantity('stage', stage)       
3068                   
3069            domain.forcing_terms = []       
3070            domain.forcing_terms.append(Inflow(domain, rate=2.0, center=(5,5), radius=1))       
3071            initial_volume = domain.quantities['stage'].get_integral()
3072            predicted_volume = initial_volume
3073            dt = 0.05
3074            for t in domain.evolve(yieldstep = dt, finaltime = 5.0):
3075                volume = domain.quantities['stage'].get_integral()
3076               
3077                assert num.allclose (volume, predicted_volume)           
3078                predicted_volume = predicted_volume + 2.0/pi/100/dt # Why 100?
3079           
3080           
3081        # Apply equivalent outflow only and check volumes for a range of stage values
3082        for stage in [2.0, 1.0, 0.5, 0.25, 0.1, 0.0]:
3083            print stage
3084           
3085            domain.time = 0.0
3086            domain.set_quantity('stage', stage)       
3087            domain.forcing_terms = []       
3088            domain.forcing_terms.append(Inflow(domain, rate=-2.0, center=(15,5), radius=1))       
3089            initial_volume = domain.quantities['stage'].get_integral()
3090            predicted_volume = initial_volume
3091            dt = 0.05
3092            for t in domain.evolve(yieldstep = dt, finaltime = 5.0):
3093                volume = domain.quantities['stage'].get_integral()
3094               
3095                print t, volume, predicted_volume
3096                assert num.allclose (volume, predicted_volume)           
3097                predicted_volume = predicted_volume - 2.0/pi/100/dt # Why 100?           
3098           
3099           
3100        # Apply both inflow and outflow and check volumes being constant for a
3101        # range of stage values
3102        for stage in [2.0, 1.0, 0.5, 0.25, 0.1, 0.0]:       
3103            print stage
3104           
3105            domain.time = 0.0
3106            domain.set_quantity('stage', stage)       
3107            domain.forcing_terms = []       
3108            domain.forcing_terms.append(Inflow(domain, rate=2.0, center=(5,5), radius=1))       
3109            domain.forcing_terms.append(Inflow(domain, rate=-2.0, center=(15,5), radius=1))               
3110            initial_volume = domain.quantities['stage'].get_integral()
3111
3112            dt = 0.05
3113            for t in domain.evolve(yieldstep = dt, finaltime = 5.0):
3114                volume = domain.quantities['stage'].get_integral()
3115               
3116                print t, volume
3117                assert num.allclose (volume, initial_volume)           
3118
3119           
3120           
3121
3122    #####################################################
3123    def test_first_order_extrapolator_const_z(self):
3124
3125        a = [0.0, 0.0]
3126        b = [0.0, 2.0]
3127        c = [2.0, 0.0]
3128        d = [0.0, 4.0]
3129        e = [2.0, 2.0]
3130        f = [4.0, 0.0]
3131
3132        points = [a, b, c, d, e, f]
3133        #bac, bce, ecf, dbe
3134        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
3135
3136        domain = Domain(points, vertices)
3137        val0 = 2.+2.0/3
3138        val1 = 4.+4.0/3
3139        val2 = 8.+2.0/3
3140        val3 = 2.+8.0/3
3141
3142        zl=zr=-3.75 #Assume constant bed (must be less than stage)
3143        domain.set_quantity('elevation', zl*num.ones( (4,3), num.int )) #array default#
3144        domain.set_quantity('stage', [[val0, val0-1, val0-2],
3145                                      [val1, val1+1, val1],
3146                                      [val2, val2-2, val2],
3147                                      [val3-0.5, val3, val3]])
3148
3149
3150
3151        domain._order_ = 1
3152        domain.distribute_to_vertices_and_edges()
3153
3154        #Check that centroid values were distributed to vertices
3155        C = domain.quantities['stage'].centroid_values
3156        for i in range(3):
3157            assert num.allclose( domain.quantities['stage'].vertex_values[:,i], C)
3158
3159
3160    def test_first_order_limiter_variable_z(self):
3161        #Check that first order limiter follows bed_slope
3162        from anuga.config import epsilon
3163
3164        a = [0.0, 0.0]
3165        b = [0.0, 2.0]
3166        c = [2.0,0.0]
3167        d = [0.0, 4.0]
3168        e = [2.0, 2.0]
3169        f = [4.0,0.0]
3170
3171        points = [a, b, c, d, e, f]
3172        #bac, bce, ecf, dbe
3173        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
3174
3175        domain = Domain(points, vertices)
3176        val0 = 2.+2.0/3
3177        val1 = 4.+4.0/3
3178        val2 = 8.+2.0/3
3179        val3 = 2.+8.0/3
3180
3181        domain.set_quantity('elevation', [[0,0,0], [6,0,0],
3182                                          [6,6,6], [6,6,6]])
3183        domain.set_quantity('stage', [[val0, val0, val0],
3184                                      [val1, val1, val1],
3185                                      [val2, val2, val2],
3186                                      [val3, val3, val3]])
3187
3188        E = domain.quantities['elevation'].vertex_values
3189        L = domain.quantities['stage'].vertex_values
3190
3191
3192        #Check that some stages are not above elevation (within eps)
3193        #- so that the limiter has something to work with
3194        assert not num.alltrue(num.alltrue(num.greater_equal(L,E-epsilon)))
3195
3196        domain._order_ = 1
3197        domain.distribute_to_vertices_and_edges()
3198
3199        #Check that all stages are above elevation (within eps)
3200        assert num.alltrue(num.alltrue(num.greater_equal(L,E-epsilon)))
3201
3202
3203    #####################################################
3204    def test_distribute_basic(self):
3205        #Using test data generated by abstract_2d_finite_volumes-2
3206        #Assuming no friction and flat bed (0.0)
3207
3208        a = [0.0, 0.0]
3209        b = [0.0, 2.0]
3210        c = [2.0, 0.0]
3211        d = [0.0, 4.0]
3212        e = [2.0, 2.0]
3213        f = [4.0, 0.0]
3214
3215        points = [a, b, c, d, e, f]
3216        #bac, bce, ecf, dbe
3217        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
3218
3219        domain = Domain(points, vertices)
3220
3221        val0 = 2.
3222        val1 = 4.
3223        val2 = 8.
3224        val3 = 2.
3225
3226        domain.set_quantity('stage', [val0, val1, val2, val3],
3227                            location='centroids')
3228        L = domain.quantities['stage'].vertex_values
3229
3230        #First order
3231        domain._order_ = 1
3232        domain.distribute_to_vertices_and_edges()
3233        assert num.allclose(L[1], val1)
3234
3235        #Second order
3236        domain._order_ = 2
3237        domain.beta_w      = 0.9
3238        domain.beta_w_dry  = 0.9
3239        domain.beta_uh     = 0.9
3240        domain.beta_uh_dry = 0.9
3241        domain.beta_vh     = 0.9
3242        domain.beta_vh_dry = 0.9
3243        domain.distribute_to_vertices_and_edges()
3244        assert num.allclose(L[1], [2.2, 4.9, 4.9])
3245
3246
3247
3248    def test_distribute_away_from_bed(self):
3249        #Using test data generated by abstract_2d_finite_volumes-2
3250        #Assuming no friction and flat bed (0.0)
3251
3252        a = [0.0, 0.0]
3253        b = [0.0, 2.0]
3254        c = [2.0, 0.0]
3255        d = [0.0, 4.0]
3256        e = [2.0, 2.0]
3257        f = [4.0, 0.0]
3258
3259        points = [a, b, c, d, e, f]
3260        #bac, bce, ecf, dbe
3261        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
3262
3263        domain = Domain(points, vertices)
3264        L = domain.quantities['stage'].vertex_values
3265
3266        def stage(x,y):
3267            return x**2
3268
3269        domain.set_quantity('stage', stage, location='centroids')
3270
3271        domain.quantities['stage'].compute_gradients()
3272
3273        a, b = domain.quantities['stage'].get_gradients()
3274               
3275        assert num.allclose(a[1], 3.33333334)
3276        assert num.allclose(b[1], 0.0)
3277
3278        domain._order_ = 1
3279        domain.distribute_to_vertices_and_edges()
3280        assert num.allclose(L[1], 1.77777778)
3281
3282        domain._order_ = 2
3283        domain.beta_w      = 0.9
3284        domain.beta_w_dry  = 0.9
3285        domain.beta_uh     = 0.9
3286        domain.beta_uh_dry = 0.9
3287        domain.beta_vh     = 0.9
3288        domain.beta_vh_dry = 0.9
3289        domain.distribute_to_vertices_and_edges()
3290        assert num.allclose(L[1], [0.57777777, 2.37777778, 2.37777778])
3291
3292
3293
3294    def test_distribute_away_from_bed1(self):
3295        #Using test data generated by abstract_2d_finite_volumes-2
3296        #Assuming no friction and flat bed (0.0)
3297
3298        a = [0.0, 0.0]
3299        b = [0.0, 2.0]
3300        c = [2.0, 0.0]
3301        d = [0.0, 4.0]
3302        e = [2.0, 2.0]
3303        f = [4.0, 0.0]
3304
3305        points = [a, b, c, d, e, f]
3306        #bac, bce, ecf, dbe
3307        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
3308
3309        domain = Domain(points, vertices)
3310        L = domain.quantities['stage'].vertex_values
3311
3312        def stage(x,y):
3313            return x**4+y**2
3314
3315        domain.set_quantity('stage', stage, location='centroids')
3316        #print domain.quantities['stage'].centroid_values
3317
3318        domain.quantities['stage'].compute_gradients()
3319        a, b = domain.quantities['stage'].get_gradients()
3320        assert num.allclose(a[1], 25.18518519)
3321        assert num.allclose(b[1], 3.33333333)
3322
3323        domain._order_ = 1
3324        domain.distribute_to_vertices_and_edges()
3325        assert num.allclose(L[1], 4.9382716)
3326
3327        domain._order_ = 2
3328        domain.beta_w      = 0.9
3329        domain.beta_w_dry  = 0.9
3330        domain.beta_uh     = 0.9
3331        domain.beta_uh_dry = 0.9
3332        domain.beta_vh     = 0.9
3333        domain.beta_vh_dry = 0.9
3334        domain.distribute_to_vertices_and_edges()
3335        assert num.allclose(L[1], [1.07160494, 6.46058131, 7.28262855])
3336
3337
3338
3339    def test_distribute_near_bed(self):
3340
3341        a = [0.0, 0.0]
3342        b = [0.0, 2.0]
3343        c = [2.0, 0.0]
3344        d = [0.0, 4.0]
3345        e = [2.0, 2.0]
3346        f = [4.0, 0.0]
3347
3348        points = [a, b, c, d, e, f]
3349        #bac, bce, ecf, dbe
3350        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
3351
3352        domain = Domain(points, vertices)
3353
3354
3355        #Set up for a gradient of (10,0) at mid triangle (bce)
3356        def slope(x, y):
3357            return 10*x
3358
3359        h = 0.1
3360        def stage(x, y):
3361            return slope(x, y) + h
3362
3363        domain.set_quantity('elevation', slope)
3364        domain.set_quantity('stage', stage, location='centroids')
3365
3366        #print domain.quantities['elevation'].centroid_values
3367        #print domain.quantities['stage'].centroid_values
3368
3369        E = domain.quantities['elevation'].vertex_values
3370        L = domain.quantities['stage'].vertex_values
3371
3372        # Get reference values
3373        volumes = []
3374        for i in range(len(L)):
3375            volumes.append(num.sum(L[i])/3)
3376            assert num.allclose(volumes[i], domain.quantities['stage'].centroid_values[i]) 
3377       
3378       
3379        domain._order_ = 1
3380       
3381        domain.tight_slope_limiters = 0
3382        domain.distribute_to_vertices_and_edges()
3383        assert num.allclose(L[1], [0.1, 20.1, 20.1])
3384        for i in range(len(L)):
3385            assert num.allclose(volumes[i], num.sum(L[i])/3)                   
3386       
3387        domain.tight_slope_limiters = 1 # Allow triangle to be flatter (closer to bed)
3388        domain.distribute_to_vertices_and_edges()
3389        assert num.allclose(L[1], [0.298, 20.001, 20.001])
3390        for i in range(len(L)):
3391            assert num.allclose(volumes[i], num.sum(L[i])/3)   
3392
3393        domain._order_ = 2
3394       
3395        domain.tight_slope_limiters = 0
3396        domain.distribute_to_vertices_and_edges()
3397        assert num.allclose(L[1], [0.1, 20.1, 20.1])       
3398        for i in range(len(L)):
3399            assert num.allclose(volumes[i], num.sum(L[i])/3)           
3400       
3401        domain.tight_slope_limiters = 1 # Allow triangle to be flatter (closer to bed)
3402        domain.distribute_to_vertices_and_edges()
3403        assert num.allclose(L[1], [0.298, 20.001, 20.001])
3404        for i in range(len(L)):
3405            assert num.allclose(volumes[i], num.sum(L[i])/3)   
3406       
3407
3408
3409    def test_distribute_near_bed1(self):
3410
3411        a = [0.0, 0.0]
3412        b = [0.0, 2.0]
3413        c = [2.0, 0.0]
3414        d = [0.0, 4.0]
3415        e = [2.0, 2.0]
3416        f = [4.0, 0.0]
3417
3418        points = [a, b, c, d, e, f]
3419        #bac, bce, ecf, dbe
3420        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
3421
3422        domain = Domain(points, vertices)
3423
3424
3425        #Set up for a gradient of (8,2) at mid triangle (bce)
3426        def slope(x, y):
3427            return x**4+y**2
3428
3429        h = 0.1
3430        def stage(x,y):
3431            return slope(x,y)+h
3432
3433        domain.set_quantity('elevation', slope)
3434        domain.set_quantity('stage', stage)
3435
3436        #print domain.quantities['elevation'].centroid_values
3437        #print domain.quantities['stage'].centroid_values
3438
3439        E = domain.quantities['elevation'].vertex_values
3440        L = domain.quantities['stage'].vertex_values
3441
3442        # Get reference values
3443        volumes = []
3444        for i in range(len(L)):
3445            volumes.append(num.sum(L[i])/3)
3446            assert num.allclose(volumes[i], domain.quantities['stage'].centroid_values[i]) 
3447       
3448        #print E
3449        domain._order_ = 1
3450       
3451        domain.tight_slope_limiters = 0
3452        domain.distribute_to_vertices_and_edges()
3453        assert num.allclose(L[1], [4.1, 16.1, 20.1])       
3454        for i in range(len(L)):
3455            assert num.allclose(volumes[i], num.sum(L[i])/3)
3456       
3457               
3458        domain.tight_slope_limiters = 1 # Allow triangle to be flatter (closer to bed)
3459        domain.distribute_to_vertices_and_edges()
3460        assert num.allclose(L[1], [4.2386, 16.0604, 20.001])
3461        for i in range(len(L)):
3462            assert num.allclose(volumes[i], num.sum(L[i])/3)   
3463       
3464
3465        domain._order_ = 2
3466       
3467        domain.tight_slope_limiters = 0   
3468        domain.distribute_to_vertices_and_edges()
3469        assert num.allclose(L[1], [4.1, 16.1, 20.1])
3470        for i in range(len(L)):
3471            assert num.allclose(volumes[i], num.sum(L[i])/3)   
3472       
3473        domain.tight_slope_limiters = 1 # Allow triangle to be flatter (closer to bed)
3474        domain.distribute_to_vertices_and_edges()
3475        #print L[1]
3476        assert num.allclose(L[1], [4.23370103, 16.06529897, 20.001]) or\
3477               num.allclose(L[1], [4.18944138, 16.10955862, 20.001]) or\
3478               num.allclose(L[1], [4.19351461, 16.10548539, 20.001]) # old limiters
3479       
3480        for i in range(len(L)):
3481            assert num.allclose(volumes[i], num.sum(L[i])/3)
3482
3483
3484    def test_second_order_distribute_real_data(self):
3485        #Using test data generated by abstract_2d_finite_volumes-2
3486        #Assuming no friction and flat bed (0.0)
3487
3488        a = [0.0, 0.0]
3489        b = [0.0, 1.0/5]
3490        c = [0.0, 2.0/5]
3491        d = [1.0/5, 0.0]
3492        e = [1.0/5, 1.0/5]
3493        f = [1.0/5, 2.0/5]
3494        g = [2.0/5, 2.0/5]
3495
3496        points = [a, b, c, d, e, f, g]
3497        #bae, efb, cbf, feg
3498        vertices = [ [1,0,4], [4,5,1], [2,1,5], [5,4,6]]
3499
3500        domain = Domain(points, vertices)
3501
3502        def slope(x, y):
3503            return -x/3
3504
3505        domain.set_quantity('elevation', slope)
3506        domain.set_quantity('stage',
3507                            [0.01298164, 0.00365611,
3508                             0.01440365, -0.0381856437096],
3509                            location='centroids')
3510        domain.set_quantity('xmomentum',
3511                            [0.00670439, 0.01263789,
3512                             0.00647805, 0.0178180740668],
3513                            location='centroids')
3514        domain.set_quantity('ymomentum',
3515                            [-7.23510980e-004, -6.30413883e-005,
3516                             6.30413883e-005, 0.000200907255866],
3517                            location='centroids')
3518
3519        E = domain.quantities['elevation'].vertex_values
3520        L = domain.quantities['stage'].vertex_values
3521        X = domain.quantities['xmomentum'].vertex_values
3522        Y = domain.quantities['ymomentum'].vertex_values
3523
3524        #print E
3525        domain._order_ = 2
3526        domain.beta_w      = 0.9
3527        domain.beta_w_dry  = 0.9
3528        domain.beta_uh     = 0.9
3529        domain.beta_uh_dry = 0.9
3530        domain.beta_vh     = 0.9
3531        domain.beta_vh_dry = 0.9
3532       
3533        # FIXME (Ole): Need tests where this is commented out
3534        domain.tight_slope_limiters = 0 # Backwards compatibility (14/4/7)                 
3535        domain.use_centroid_velocities = 0 # Backwards compatibility (7/5/8)
3536       
3537               
3538        domain.distribute_to_vertices_and_edges()
3539
3540        #print L[1,:]
3541        #print X[1,:]
3542        #print Y[1,:]
3543
3544        assert num.allclose(L[1,:], [-0.00825735775384,
3545                                     -0.00801881482869,
3546                                     0.0272445025825])
3547        assert num.allclose(X[1,:], [0.0143507718962,
3548                                     0.0142502147066,
3549                                     0.00931268339717])
3550        assert num.allclose(Y[1,:], [-0.000117062180693,
3551                                     7.94434448109e-005,
3552                                     -0.000151505429018])
3553
3554
3555
3556    def test_balance_deep_and_shallow(self):
3557        """Test that balanced limiters preserve conserved quantites.
3558        This test is using old depth based balanced limiters
3559        """
3560        import copy
3561
3562        a = [0.0, 0.0]
3563        b = [0.0, 2.0]
3564        c = [2.0, 0.0]
3565        d = [0.0, 4.0]
3566        e = [2.0, 2.0]
3567        f = [4.0, 0.0]
3568
3569        points = [a, b, c, d, e, f]
3570
3571        #bac, bce, ecf, dbe
3572        elements = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
3573
3574        domain = Domain(points, elements)
3575        domain.check_integrity()
3576
3577        #Create a deliberate overshoot
3578        domain.set_quantity('stage', [[3,0,3], [2,2,6], [5,3,8], [8,3,5]])
3579        domain.set_quantity('elevation', 0) #Flat bed
3580        stage = domain.quantities['stage']
3581
3582        ref_centroid_values = copy.copy(stage.centroid_values[:]) #Copy
3583
3584        #Limit
3585        domain.tight_slope_limiters = 0               
3586        domain.distribute_to_vertices_and_edges()
3587
3588        #Assert that quantities are conserved
3589        for k in range(len(domain)):
3590            assert num.allclose (ref_centroid_values[k],
3591                                 num.sum(stage.vertex_values[k,:])/3)
3592
3593
3594        #Now try with a non-flat bed - closely hugging initial stage in places
3595        #This will create alphas in the range [0, 0.478260, 1]
3596        domain.set_quantity('stage', [[3,0,3], [2,2,6], [5,3,8], [8,3,5]])
3597        domain.set_quantity('elevation', [[0,0,0],
3598                                        [1.8,1.9,5.9],
3599                                        [4.6,0,0],
3600                                        [0,2,4]])
3601        stage = domain.quantities['stage']
3602
3603        ref_centroid_values = copy.copy(stage.centroid_values[:]) #Copy
3604        ref_vertex_values = copy.copy(stage.vertex_values[:]) #Copy
3605
3606        #Limit
3607        domain.tight_slope_limiters = 0       
3608        domain.distribute_to_vertices_and_edges()
3609
3610
3611        #Assert that all vertex quantities have changed
3612        for k in range(len(domain)):
3613            #print ref_vertex_values[k,:], stage.vertex_values[k,:]
3614            assert not num.allclose (ref_vertex_values[k,:], stage.vertex_values[k,:])
3615        #and assert that quantities are still conserved
3616        for k in range(len(domain)):
3617            assert num.allclose (ref_centroid_values[k],
3618                                 num.sum(stage.vertex_values[k,:])/3)
3619
3620
3621        # Check actual results
3622        assert num.allclose (stage.vertex_values,
3623                             [[2,2,2],
3624                              [1.93333333, 2.03333333, 6.03333333],
3625                              [6.93333333, 4.53333333, 4.53333333],
3626                              [5.33333333, 5.33333333, 5.33333333]])
3627
3628
3629    def test_balance_deep_and_shallow_tight_SL(self):
3630        """Test that balanced limiters preserve conserved quantites.
3631        This test is using Tight Slope Limiters
3632        """
3633        import copy
3634
3635        a = [0.0, 0.0]
3636        b = [0.0, 2.0]
3637        c = [2.0, 0.0]
3638        d = [0.0, 4.0]
3639        e = [2.0, 2.0]
3640        f = [4.0, 0.0]
3641
3642        points = [a, b, c, d, e, f]
3643
3644        #bac, bce, ecf, dbe
3645        elements = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
3646
3647        domain = Domain(points, elements)
3648        domain.check_integrity()
3649
3650        #Create a deliberate overshoot
3651        domain.set_quantity('stage', [[3,0,3], [2,2,6], [5,3,8], [8,3,5]])
3652        domain.set_quantity('elevation', 0) #Flat bed
3653        stage = domain.quantities['stage']
3654
3655        ref_centroid_values = copy.copy(stage.centroid_values[:]) #Copy
3656
3657        #Limit
3658        domain.tight_slope_limiters = 1               
3659        domain.distribute_to_vertices_and_edges()
3660
3661        #Assert that quantities are conserved
3662        for k in range(len(domain)):
3663            assert num.allclose (ref_centroid_values[k],
3664                                 num.sum(stage.vertex_values[k,:])/3)
3665
3666
3667        #Now try with a non-flat bed - closely hugging initial stage in places
3668        #This will create alphas in the range [0, 0.478260, 1]
3669        domain.set_quantity('stage', [[3,0,3], [2,2,6], [5,3,8], [8,3,5]])
3670        domain.set_quantity('elevation', [[0,0,0],
3671                                        [1.8,1.9,5.9],
3672                                        [4.6,0,0],
3673                                        [0,2,4]])
3674        stage = domain.quantities['stage']
3675
3676        ref_centroid_values = copy.copy(stage.centroid_values[:]) #Copy
3677        ref_vertex_values = copy.copy(stage.vertex_values[:]) #Copy
3678
3679        #Limit
3680        domain.tight_slope_limiters = 1       
3681        domain.distribute_to_vertices_and_edges()
3682
3683
3684        #Assert that all vertex quantities have changed
3685        for k in range(len(domain)):
3686            #print ref_vertex_values[k,:], stage.vertex_values[k,:]
3687            assert not num.allclose (ref_vertex_values[k,:], stage.vertex_values[k,:])
3688        #and assert that quantities are still conserved
3689        for k in range(len(domain)):
3690            assert num.allclose (ref_centroid_values[k],
3691                                 num.sum(stage.vertex_values[k,:])/3)
3692
3693
3694        #Also check that Python and C version produce the same
3695        # No longer applicable if tight_slope_limiters == 1
3696        #print stage.vertex_values
3697        #assert allclose (stage.vertex_values,
3698        #                 [[2,2,2],
3699        #                  [1.93333333, 2.03333333, 6.03333333],
3700        #                  [6.93333333, 4.53333333, 4.53333333],
3701        #                  [5.33333333, 5.33333333, 5.33333333]])
3702
3703
3704
3705    def test_balance_deep_and_shallow_Froude(self):
3706        """Test that balanced limiters preserve conserved quantites -
3707        and also that excessive Froude numbers are dealt with.
3708        This test is using tight slope limiters.
3709        """
3710        import copy
3711
3712        a = [0.0, 0.0]
3713        b = [0.0, 2.0]
3714        c = [2.0, 0.0]
3715        d = [0.0, 4.0]
3716        e = [2.0, 2.0]
3717        f = [4.0, 0.0]
3718
3719        points = [a, b, c, d, e, f]
3720
3721        # bac, bce, ecf, dbe
3722        elements = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
3723
3724        domain = Domain(points, elements)
3725        domain.check_integrity()
3726        domain.tight_slope_limiters = True
3727        domain.use_centroid_velocities = True               
3728
3729        # Create non-flat bed - closely hugging initial stage in places
3730        # This will create alphas in the range [0, 0.478260, 1]
3731        domain.set_quantity('stage', [[3,0,3], [2,2,6], [5,3,8], [8,3,5]])
3732        domain.set_quantity('elevation', [[0,0,0],
3733                                        [1.8,1.999,5.999],
3734                                        [4.6,0,0],
3735                                        [0,2,4]])
3736
3737        # Create small momenta, that nonetheless will generate large speeds
3738        # due to shallow depth at isolated vertices
3739        domain.set_quantity('xmomentum', -0.0058)
3740        domain.set_quantity('ymomentum', 0.0890)
3741
3742
3743
3744       
3745        stage = domain.quantities['stage']
3746        elevation = domain.quantities['elevation']
3747        xmomentum = domain.quantities['xmomentum']
3748        ymomentum = domain.quantities['ymomentum']       
3749
3750        # Setup triangle #1 to mimick real Froude explosion observed
3751        # in the Onslow example 13 Nov 2007.
3752
3753        stage.vertex_values[1,:] = [1.6385, 1.6361, 1.2953]
3754        elevation.vertex_values[1,:] = [1.6375, 1.6336, 0.4647]       
3755        xmomentum.vertex_values[1,:] = [-0.0058, -0.0050, -0.0066]
3756        ymomentum.vertex_values[1,:] = [0.0890, 0.0890, 0.0890]
3757
3758        xmomentum.interpolate()
3759        ymomentum.interpolate()       
3760        stage.interpolate()       
3761        elevation.interpolate()
3762
3763        # Verify interpolation
3764        assert num.allclose(stage.centroid_values[1], 1.5233)
3765        assert num.allclose(elevation.centroid_values[1], 1.2452667)
3766        assert num.allclose(xmomentum.centroid_values[1], -0.0058)
3767        assert num.allclose(ymomentum.centroid_values[1], 0.089)
3768
3769        # Derived quantities
3770        depth = stage-elevation
3771        u = xmomentum/depth
3772        v = ymomentum/depth
3773
3774        denom = (depth*g)**0.5 
3775        Fx = u/denom
3776        Fy = v/denom
3777       
3778   
3779        # Verify against Onslow example (14 Nov 2007)
3780        assert num.allclose(depth.centroid_values[1], 0.278033)
3781        assert num.allclose(u.centroid_values[1], -0.0208608)
3782        assert num.allclose(v.centroid_values[1], 0.3201055)
3783
3784        assert num.allclose(denom.centroid_values[1],
3785                            num.sqrt(depth.centroid_values[1]*g))
3786
3787        assert num.allclose(u.centroid_values[1]/denom.centroid_values[1],
3788                            -0.012637746977)
3789        assert num.allclose(Fx.centroid_values[1],
3790                            u.centroid_values[1]/denom.centroid_values[1])
3791
3792        # Check that Froude numbers are small at centroids.
3793        assert num.allclose(Fx.centroid_values[1], -0.012637746977)
3794        assert num.allclose(Fy.centroid_values[1], 0.193924048435)
3795
3796
3797        # But Froude numbers are huge at some vertices and edges
3798        assert num.allclose(Fx.vertex_values[1,:], [-5.85888475e+01,
3799                                                    -1.27775313e+01,
3800                                                    -2.78511420e-03])
3801
3802        assert num.allclose(Fx.edge_values[1,:], [-6.89150773e-03,
3803                                                  -7.38672488e-03,
3804                                                  -2.35626238e+01])
3805
3806        assert num.allclose(Fy.vertex_values[1,:], [8.99035764e+02,
3807                                                    2.27440057e+02,
3808                                                    3.75568430e-02])
3809
3810        assert num.allclose(Fy.edge_values[1,:], [1.05748998e-01,
3811                                                  1.06035244e-01,
3812                                                  3.88346947e+02])
3813       
3814       
3815        # The task is now to arrange the limiters such that Froude numbers
3816        # remain under control whil at the same time obeying the conservation
3817        # laws.
3818
3819       
3820        ref_centroid_values = copy.copy(stage.centroid_values[:]) #Copy
3821        ref_vertex_values = copy.copy(stage.vertex_values[:]) #Copy
3822
3823        # Limit (and invoke balance_deep_and_shallow)
3824        domain.tight_slope_limiters = 1
3825        domain.distribute_to_vertices_and_edges()
3826
3827        # Redo derived quantities
3828        depth = stage-elevation
3829        u = xmomentum/depth
3830        v = ymomentum/depth
3831
3832        # Assert that all vertex velocities stay within one
3833        # order of magnitude of centroid velocities.
3834        #print u.vertex_values[1,:]
3835        #print u.centroid_values[1]
3836       
3837        assert num.alltrue(num.absolute(u.vertex_values[1,:]) <= num.absolute(u.centroid_values[1])*10)
3838        assert num.alltrue(num.absolute(v.vertex_values[1,:]) <= num.absolute(v.centroid_values[1])*10) 
3839
3840        denom = (depth*g)**0.5 
3841        Fx = u/denom
3842        Fy = v/denom
3843
3844
3845        # Assert that Froude numbers are less than max value (TBA)
3846        # at vertices, edges and centroids.
3847        from anuga.config import maximum_froude_number
3848        assert num.alltrue(num.absolute(Fx.vertex_values[1,:]) < maximum_froude_number)
3849        assert num.alltrue(num.absolute(Fy.vertex_values[1,:]) < maximum_froude_number)
3850
3851
3852        # Assert that all vertex quantities have changed
3853        for k in range(len(domain)):
3854            #print ref_vertex_values[k,:], stage.vertex_values[k,:]
3855            assert not num.allclose (ref_vertex_values[k,:],
3856                                     stage.vertex_values[k,:])
3857           
3858        # Assert that quantities are still conserved
3859        for k in range(len(domain)):
3860            assert num.allclose (ref_centroid_values[k],
3861                                 num.sum(stage.vertex_values[k,:])/3)
3862
3863
3864       
3865        return
3866   
3867        qwidth = 12
3868        for k in [1]: #range(len(domain)):
3869            print 'Triangle %d (C, V, E)' %k
3870           
3871            print 'stage'.ljust(qwidth), stage.centroid_values[k],\
3872                  stage.vertex_values[k,:], stage.edge_values[k,:]
3873            print 'elevation'.ljust(qwidth), elevation.centroid_values[k],\
3874                  elevation.vertex_values[k,:], elevation.edge_values[k,:]
3875            print 'depth'.ljust(qwidth), depth.centroid_values[k],\
3876                  depth.vertex_values[k,:], depth.edge_values[k,:]
3877            print 'xmomentum'.ljust(qwidth), xmomentum.centroid_values[k],\
3878                  xmomentum.vertex_values[k,:], xmomentum.edge_values[k,:]
3879            print 'ymomentum'.ljust(qwidth), ymomentum.centroid_values[k],\
3880                  ymomentum.vertex_values[k,:], ymomentum.edge_values[k,:]
3881            print 'u'.ljust(qwidth),u.centroid_values[k],\
3882                  u.vertex_values[k,:], u.edge_values[k,:]
3883            print 'v'.ljust(qwidth), v.centroid_values[k],\
3884                  v.vertex_values[k,:], v.edge_values[k,:]
3885            print 'Fx'.ljust(qwidth), Fx.centroid_values[k],\
3886                  Fx.vertex_values[k,:], Fx.edge_values[k,:]
3887            print 'Fy'.ljust(qwidth), Fy.centroid_values[k],\
3888                  Fy.vertex_values[k,:], Fy.edge_values[k,:]
3889           
3890           
3891       
3892
3893
3894
3895    def test_conservation_1(self):
3896        """Test that stage is conserved globally
3897
3898        This one uses a flat bed, reflective bdries and a suitable
3899        initial condition
3900        """
3901        from mesh_factory import rectangular
3902
3903        #Create basic mesh
3904        points, vertices, boundary = rectangular(6, 6)
3905
3906        #Create shallow water domain
3907        domain = Domain(points, vertices, boundary)
3908        domain.smooth = False
3909        domain.default_order=2
3910
3911        #IC
3912        def x_slope(x, y):
3913            return x/3
3914
3915        domain.set_quantity('elevation', 0)
3916        domain.set_quantity('friction', 0)
3917        domain.set_quantity('stage', x_slope)
3918
3919        # Boundary conditions (reflective everywhere)
3920        Br = Reflective_boundary(domain)
3921        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
3922
3923        domain.check_integrity()
3924
3925        initial_volume = domain.quantities['stage'].get_integral()
3926        initial_xmom = domain.quantities['xmomentum'].get_integral()
3927
3928        #print initial_xmom
3929
3930        #Evolution
3931        for t in domain.evolve(yieldstep = 0.05, finaltime = 5.0):
3932            volume =  domain.quantities['stage'].get_integral()
3933            assert num.allclose (volume, initial_volume)
3934
3935            #I don't believe that the total momentum should be the same
3936            #It starts with zero and ends with zero though
3937            #xmom = domain.quantities['xmomentum'].get_integral()
3938            #print xmom
3939            #assert allclose (xmom, initial_xmom)
3940
3941        os.remove(domain.get_name() + '.sww')
3942
3943
3944    def test_conservation_2(self):
3945        """Test that stage is conserved globally
3946
3947        This one uses a slopy bed, reflective bdries and a suitable
3948        initial condition
3949        """
3950        from mesh_factory import rectangular
3951
3952        #Create basic mesh
3953        points, vertices, boundary = rectangular(6, 6)
3954
3955        #Create shallow water domain
3956        domain = Domain(points, vertices, boundary)
3957        domain.smooth = False
3958        domain.default_order=2
3959
3960        #IC
3961        def x_slope(x, y):
3962            return x/3
3963
3964        domain.set_quantity('elevation', x_slope)
3965        domain.set_quantity('friction', 0)
3966        domain.set_quantity('stage', 0.4) #Steady
3967
3968        # Boundary conditions (reflective everywhere)
3969        Br = Reflective_boundary(domain)
3970        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
3971
3972        domain.check_integrity()
3973
3974        initial_volume = domain.quantities['stage'].get_integral()
3975        initial_xmom = domain.quantities['xmomentum'].get_integral()
3976
3977        #print initial_xmom
3978
3979        #Evolution
3980        for t in domain.evolve(yieldstep = 0.05, finaltime = 5.0):
3981            volume =  domain.quantities['stage'].get_integral()
3982            assert num.allclose (volume, initial_volume)
3983
3984            #FIXME: What would we expect from momentum
3985            #xmom = domain.quantities['xmomentum'].get_integral()
3986            #print xmom
3987            #assert allclose (xmom, initial_xmom)
3988
3989        os.remove(domain.get_name() + '.sww')
3990
3991    def test_conservation_3(self):
3992        """Test that stage is conserved globally
3993
3994        This one uses a larger grid, convoluted bed, reflective bdries and a suitable
3995        initial condition
3996        """
3997        from mesh_factory import rectangular
3998
3999        #Create basic mesh
4000        points, vertices, boundary = rectangular(2, 1)
4001
4002        #Create shallow water domain
4003        domain = Domain(points, vertices, boundary)
4004        domain.smooth = False
4005        domain.default_order = 2
4006        domain.set_quantities_to_be_stored(['stage', 'xmomentum', 'ymomentum'])
4007
4008        #IC
4009        def x_slope(x, y):
4010            z = 0*x
4011            for i in range(len(x)):
4012                if x[i] < 0.3:
4013                    z[i] = x[i]/3
4014                if 0.3 <= x[i] < 0.5:
4015                    z[i] = -0.5
4016                if 0.5 <= x[i] < 0.7:
4017                    z[i] = 0.39
4018                if 0.7 <= x[i]:
4019                    z[i] = x[i]/3
4020            return z
4021
4022
4023
4024        domain.set_quantity('elevation', x_slope)
4025        domain.set_quantity('friction', 0)
4026        domain.set_quantity('stage', 0.4) #Steady
4027
4028        # Boundary conditions (reflective everywhere)
4029        Br = Reflective_boundary(domain)
4030        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
4031
4032        domain.check_integrity()
4033
4034        initial_volume = domain.quantities['stage'].get_integral()
4035        initial_xmom = domain.quantities['xmomentum'].get_integral()
4036
4037        import copy
4038        ref_centroid_values =\
4039                 copy.copy(domain.quantities['stage'].centroid_values)
4040
4041        #print 'ORG', domain.quantities['stage'].centroid_values
4042        domain.distribute_to_vertices_and_edges()
4043
4044
4045        #print domain.quantities['stage'].centroid_values
4046        assert num.allclose(domain.quantities['stage'].centroid_values,
4047                            ref_centroid_values)
4048
4049
4050        #Check that initial limiter doesn't violate cons quan
4051        assert num.allclose(domain.quantities['stage'].get_integral(),
4052                            initial_volume)
4053
4054        #Evolution
4055        for t in domain.evolve(yieldstep = 0.05, finaltime = 10):
4056            volume =  domain.quantities['stage'].get_integral()
4057            #print t, volume, initial_volume
4058            assert num.allclose (volume, initial_volume)
4059
4060        os.remove(domain.get_name() + '.sww')
4061
4062    def test_conservation_4(self):
4063        """Test that stage is conserved globally
4064
4065        This one uses a larger grid, convoluted bed, reflective bdries and a suitable
4066        initial condition
4067        """
4068        from mesh_factory import rectangular
4069
4070        #Create basic mesh
4071        points, vertices, boundary = rectangular(6, 6)
4072
4073        #Create shallow water domain
4074        domain = Domain(points, vertices, boundary)
4075        domain.smooth = False
4076        domain.default_order=2
4077
4078        #IC
4079        def x_slope(x, y):
4080            z = 0*x
4081            for i in range(len(x)):
4082                if x[i] < 0.3:
4083                    z[i] = x[i]/3
4084                if 0.3 <= x[i] < 0.5:
4085                    z[i] = -0.5
4086                if 0.5 <= x[i] < 0.7:
4087                    #z[i] = 0.3 #OK with beta == 0.2
4088                    z[i] = 0.34 #OK with beta == 0.0
4089                    #z[i] = 0.35#Fails after 80 timesteps with an error
4090                                #of the order 1.0e-5
4091                if 0.7 <= x[i]:
4092                    z[i] = x[i]/3
4093            return z
4094
4095
4096
4097        domain.set_quantity('elevation', x_slope)
4098        domain.set_quantity('friction', 0)
4099        domain.set_quantity('stage', 0.4) #Steady
4100
4101        # Boundary conditions (reflective everywhere)
4102        Br = Reflective_boundary(domain)
4103        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
4104
4105        domain.check_integrity()
4106
4107        initial_volume = domain.quantities['stage'].get_integral()
4108        initial_xmom = domain.quantities['xmomentum'].get_integral()
4109
4110        import copy
4111        ref_centroid_values =\
4112                 copy.copy(domain.quantities['stage'].centroid_values)
4113
4114        #Test limiter by itself
4115        domain.distribute_to_vertices_and_edges()
4116
4117        #Check that initial limiter doesn't violate cons quan
4118        assert num.allclose (domain.quantities['stage'].get_integral(),
4119                             initial_volume)
4120        #NOTE: This would fail if any initial stage was less than the
4121        #corresponding bed elevation - but that is reasonable.
4122
4123
4124        #Evolution
4125        for t in domain.evolve(yieldstep = 0.05, finaltime = 10.0):
4126            volume =  domain.quantities['stage'].get_integral()
4127
4128            #print t, volume, initial_volume
4129
4130            assert num.allclose (volume, initial_volume)
4131
4132
4133        os.remove(domain.get_name() + '.sww')
4134
4135
4136    def test_conservation_5(self):
4137        """Test that momentum is conserved globally in
4138        steady state scenario
4139
4140        This one uses a slopy bed, dirichlet and reflective bdries
4141        """
4142        from mesh_factory import rectangular
4143
4144        # Create basic mesh
4145        points, vertices, boundary = rectangular(6, 6)
4146
4147        # Create shallow water domain
4148        domain = Domain(points, vertices, boundary)
4149        domain.smooth = False
4150        domain.default_order = 2
4151
4152        # IC
4153        def x_slope(x, y):
4154            return x/3
4155
4156        domain.set_quantity('elevation', x_slope)
4157        domain.set_quantity('friction', 0)
4158        domain.set_quantity('stage', 0.4) # Steady
4159
4160        # Boundary conditions (reflective everywhere)
4161        Br = Reflective_boundary(domain)
4162        Bleft = Dirichlet_boundary([0.5,0,0])
4163        Bright = Dirichlet_boundary([0.1,0,0])
4164        domain.set_boundary({'left': Bleft, 'right': Bright,
4165                             'top': Br, 'bottom': Br})
4166
4167        domain.check_integrity()
4168
4169        initial_volume = domain.quantities['stage'].get_integral()
4170        initial_xmom = domain.quantities['xmomentum'].get_integral()
4171
4172
4173        # Evolution
4174        for t in domain.evolve(yieldstep = 0.05, finaltime = 15.0):
4175            stage =  domain.quantities['stage'].get_integral()
4176            xmom = domain.quantities['xmomentum'].get_integral()
4177            ymom = domain.quantities['ymomentum'].get_integral()
4178
4179            if num.allclose(t, 6):  # Steady state reached
4180                steady_xmom = domain.quantities['xmomentum'].get_integral()
4181                steady_ymom = domain.quantities['ymomentum'].get_integral()
4182                steady_stage = domain.quantities['stage'].get_integral()
4183
4184            if t > 6:
4185                #print '%.2f %14.8f %14.8f' %(t, ymom, steady_ymom)
4186                msg = 'xmom=%.2f, steady_xmom=%.2f' %(xmom, steady_xmom)
4187                assert num.allclose(xmom, steady_xmom), msg
4188                assert num.allclose(ymom, steady_ymom)
4189                assert num.allclose(stage, steady_stage)
4190
4191
4192        os.remove(domain.get_name() + '.sww')
4193
4194
4195
4196
4197
4198    def test_conservation_real(self):
4199        """Test that momentum is conserved globally
4200       
4201        Stephen finally made a test that revealed the problem.
4202        This test failed with code prior to 25 July 2005
4203        """
4204
4205        yieldstep = 0.01
4206        finaltime = 0.05
4207        min_depth = 1.0e-2
4208
4209
4210        import sys
4211        from os import sep; sys.path.append('..'+sep+'abstract_2d_finite_volumes')
4212        from mesh_factory import rectangular
4213
4214
4215        #Create shallow water domain
4216        points, vertices, boundary = rectangular(10, 10, len1=500, len2=500)
4217        domain = Domain(points, vertices, boundary)
4218        domain.smooth = False
4219        domain.default_order = 1
4220        domain.minimum_allowed_height = min_depth
4221
4222        # Set initial condition
4223        class Set_IC:
4224            """Set an initial condition with a constant value, for x0<x<x1
4225            """
4226
4227            def __init__(self, x0=0.25, x1=0.5, h=1.0):
4228                self.x0 = x0
4229                self.x1 = x1
4230                self.= h
4231
4232            def __call__(self, x, y):
4233                return self.h*((x>self.x0)&(x<self.x1))
4234
4235
4236        domain.set_quantity('stage', Set_IC(200.0,300.0,5.0))
4237
4238
4239        #Boundaries
4240        R = Reflective_boundary(domain)
4241        domain.set_boundary( {'left': R, 'right': R, 'top':R, 'bottom': R})
4242
4243        ref = domain.quantities['stage'].get_integral()
4244
4245        # Evolution
4246        for t in domain.evolve(yieldstep = yieldstep, finaltime = finaltime):
4247            pass
4248            #print 'Integral stage = ',\
4249            #      domain.quantities['stage'].get_integral(),\
4250            #      ' Time = ',domain.time
4251
4252
4253        now = domain.quantities['stage'].get_integral()
4254
4255        msg = 'Stage not conserved: was %f, now %f' %(ref, now)
4256        assert num.allclose(ref, now), msg
4257
4258        os.remove(domain.get_name() + '.sww')
4259
4260    def test_second_order_flat_bed_onestep(self):
4261
4262        from mesh_factory import rectangular
4263
4264        #Create basic mesh
4265        points, vertices, boundary = rectangular(6, 6)
4266
4267        #Create shallow water domain
4268        domain = Domain(points, vertices, boundary)
4269        domain.smooth = False
4270        domain.default_order = 2
4271        domain.beta_w      = 0.9
4272        domain.beta_w_dry  = 0.9
4273        domain.beta_uh     = 0.9
4274        domain.beta_uh_dry = 0.9
4275        domain.beta_vh     = 0.9
4276        domain.beta_vh_dry = 0.9
4277        domain.H0 = 0 # Backwards compatibility (6/2/7)       
4278       
4279        # Boundary conditions
4280        Br = Reflective_boundary(domain)
4281        Bd = Dirichlet_boundary([0.1, 0., 0.])
4282        domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
4283
4284        domain.check_integrity()
4285
4286        # Evolution
4287        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.05):
4288            pass# domain.write_time()
4289
4290        # Data from earlier version of abstract_2d_finite_volumes
4291        assert num.allclose(domain.min_timestep, 0.0396825396825)
4292        assert num.allclose(domain.max_timestep, 0.0396825396825)
4293
4294        assert num.allclose(domain.quantities['stage'].centroid_values[:12],
4295                            [0.00171396, 0.02656103, 0.00241523, 0.02656103,
4296                             0.00241523, 0.02656103, 0.00241523, 0.02656103,
4297                             0.00241523, 0.02656103, 0.00241523, 0.0272623])
4298
4299        domain.distribute_to_vertices_and_edges()
4300
4301        assert num.allclose(domain.quantities['stage'].vertex_values[:12,0],
4302                            [0.0001714, 0.02656103, 0.00024152,
4303                             0.02656103, 0.00024152, 0.02656103,
4304                             0.00024152, 0.02656103, 0.00024152,
4305                             0.02656103, 0.00024152, 0.0272623])
4306
4307        assert num.allclose(domain.quantities['stage'].vertex_values[:12,1],
4308                            [0.00315012, 0.02656103, 0.00024152, 0.02656103,
4309                             0.00024152, 0.02656103, 0.00024152, 0.02656103,
4310                             0.00024152, 0.02656103, 0.00040506, 0.0272623])
4311
4312        assert num.allclose(domain.quantities['stage'].vertex_values[:12,2],
4313                            [0.00182037, 0.02656103, 0.00676264,
4314                             0.02656103, 0.00676264, 0.02656103,
4315                             0.00676264, 0.02656103, 0.00676264,
4316                             0.02656103, 0.0065991, 0.0272623])
4317
4318        assert num.allclose(domain.quantities['xmomentum'].centroid_values[:12],
4319                            [0.00113961, 0.01302432, 0.00148672,
4320                             0.01302432, 0.00148672, 0.01302432,
4321                             0.00148672, 0.01302432, 0.00148672 ,
4322                             0.01302432, 0.00148672, 0.01337143])
4323
4324        assert num.allclose(domain.quantities['ymomentum'].centroid_values[:12],
4325                            [-2.91240050e-004 , 1.22721531e-004,
4326                             -1.22721531e-004, 1.22721531e-004 ,
4327                             -1.22721531e-004, 1.22721531e-004,
4328                             -1.22721531e-004 , 1.22721531e-004,
4329                             -1.22721531e-004, 1.22721531e-004,
4330                             -1.22721531e-004, -4.57969873e-005])
4331
4332        os.remove(domain.get_name() + '.sww')
4333
4334
4335    def test_second_order_flat_bed_moresteps(self):
4336
4337        from mesh_factory import rectangular
4338
4339        #Create basic mesh
4340        points, vertices, boundary = rectangular(6, 6)
4341
4342        #Create shallow water domain
4343        domain = Domain(points, vertices, boundary)
4344        domain.smooth = False
4345        domain.default_order=2
4346
4347        # Boundary conditions
4348        Br = Reflective_boundary(domain)
4349        Bd = Dirichlet_boundary([0.1, 0., 0.])
4350        domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
4351
4352        domain.check_integrity()
4353
4354        #Evolution
4355        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.1):
4356            pass
4357
4358        #Data from earlier version of abstract_2d_finite_volumes
4359        #assert allclose(domain.min_timestep, 0.0396825396825)
4360        #assert allclose(domain.max_timestep, 0.0396825396825)
4361        #print domain.quantities['stage'].centroid_values
4362
4363        os.remove(domain.get_name() + '.sww')       
4364
4365
4366    def test_flatbed_first_order(self):
4367        from mesh_factory import rectangular
4368
4369        #Create basic mesh
4370        N = 8
4371        points, vertices, boundary = rectangular(N, N)
4372
4373        #Create shallow water domain
4374        domain = Domain(points, vertices, boundary)
4375        domain.smooth = False
4376        domain.default_order=1
4377        domain.H0 = 0 # Backwards compatibility (6/2/7)       
4378
4379        # Boundary conditions
4380        Br = Reflective_boundary(domain)
4381        Bd = Dirichlet_boundary([0.2,0.,0.])
4382
4383        domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
4384        domain.check_integrity()
4385
4386
4387        #Evolution
4388        for t in domain.evolve(yieldstep = 0.02, finaltime = 0.5):
4389            pass
4390            #domain.write_time()
4391
4392        #FIXME: These numbers were from version before 25/10
4393        #assert allclose(domain.min_timestep, 0.0140413643926)
4394        #assert allclose(domain.max_timestep, 0.0140947355753)
4395
4396        for i in range(3):
4397            #assert allclose(domain.quantities['stage'].edge_values[:4,i],
4398            #                [0.10730244,0.12337617,0.11200126,0.12605666])
4399
4400            assert num.allclose(domain.quantities['xmomentum'].edge_values[:4,i],
4401                                [0.07610894,0.06901572,0.07284461,0.06819712])
4402
4403            #assert allclose(domain.quantities['ymomentum'].edge_values[:4,i],
4404            #                [-0.0060238, -0.00157404, -0.00309633, -0.0001637])
4405
4406
4407        os.remove(domain.get_name() + '.sww')           
4408
4409    def test_flatbed_second_order(self):
4410        from mesh_factory import rectangular
4411
4412        #Create basic mesh
4413        N = 8
4414        points, vertices, boundary = rectangular(N, N)
4415
4416        #Create shallow water domain
4417        domain = Domain(points, vertices, boundary)
4418        domain.smooth = False
4419        domain.default_order=2
4420        domain.beta_w      = 0.9
4421        domain.beta_w_dry  = 0.9
4422        domain.beta_uh     = 0.9
4423        domain.beta_uh_dry = 0.9
4424        domain.beta_vh     = 0.9
4425        domain.beta_vh_dry = 0.9       
4426        #domain.minimum_allowed_height = 0.0 #Makes it like the 'oldstyle' balance
4427        domain.H0 = 0 # Backwards compatibility (6/2/7)
4428        domain.use_centroid_velocities = False # Backwards compatibility (8/5/8)
4429        domain.set_maximum_allowed_speed(1.0)       
4430
4431        # Boundary conditions
4432        Br = Reflective_boundary(domain)
4433        Bd = Dirichlet_boundary([0.2,0.,0.])
4434
4435        domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
4436        domain.check_integrity()
4437
4438        # Evolution
4439        for t in domain.evolve(yieldstep = 0.01, finaltime = 0.03):
4440            pass
4441
4442        msg = 'min step was %f instead of %f' %(domain.min_timestep,
4443                                                0.0210448446782) 
4444
4445        assert num.allclose(domain.min_timestep, 0.0210448446782), msg
4446        assert num.allclose(domain.max_timestep, 0.0210448446782)
4447
4448        #print domain.quantities['stage'].vertex_values[:4,0]
4449        #print domain.quantities['xmomentum'].vertex_values[:4,0]
4450        #print domain.quantities['ymomentum'].vertex_values[:4,0]
4451
4452        #FIXME: These numbers were from version before 25/10
4453        #assert allclose(domain.quantities['stage'].vertex_values[:4,0],
4454        #                [0.00101913,0.05352143,0.00104852,0.05354394])
4455
4456        #FIXME: These numbers were from version before 21/3/6 -
4457        #could be recreated by setting maximum_allowed_speed to 0 maybe
4458        #assert allclose(domain.quantities['xmomentum'].vertex_values[:4,0],
4459        #                [ 0.00064835, 0.03685719, 0.00085073, 0.03687313])
4460       
4461        assert num.allclose(domain.quantities['xmomentum'].vertex_values[:4,0],
4462                            [ 0.00090581, 0.03685719, 0.00088303, 0.03687313])
4463                       
4464                       
4465
4466        #assert allclose(domain.quantities['xmomentum'].vertex_values[:4,0],
4467        #                [0.00090581,0.03685719,0.00088303,0.03687313])
4468
4469        assert num.allclose(domain.quantities['ymomentum'].vertex_values[:4,0],
4470                            [-0.00139463,0.0006156,-0.00060364,0.00061827])
4471
4472
4473        os.remove(domain.get_name() + '.sww')
4474
4475       
4476    def test_flatbed_second_order_vmax_0(self):
4477        from mesh_factory import rectangular
4478
4479        #Create basic mesh
4480        N = 8
4481        points, vertices, boundary = rectangular(N, N)
4482
4483        #Create shallow water domain
4484        domain = Domain(points, vertices, boundary)
4485        domain.smooth = False
4486        domain.default_order=2
4487        domain.beta_w      = 0.9
4488        domain.beta_w_dry  = 0.9
4489        domain.beta_uh     = 0.9
4490        domain.beta_uh_dry = 0.9
4491        domain.beta_vh     = 0.9
4492        domain.beta_vh_dry = 0.9       
4493        domain.maximum_allowed_speed = 0.0 #Makes it like the 'oldstyle'
4494        domain.H0 = 0 # Backwards compatibility (6/2/7)
4495        domain.use_centroid_velocities = False # Backwards compatibility (8/5/8)       
4496
4497        # Boundary conditions
4498        Br = Reflective_boundary(domain)
4499        Bd = Dirichlet_boundary([0.2,0.,0.])
4500
4501        domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
4502        domain.check_integrity()
4503
4504        #Evolution
4505        for t in domain.evolve(yieldstep = 0.01, finaltime = 0.03):
4506            pass
4507
4508
4509        assert num.allclose(domain.min_timestep, 0.0210448446782)
4510        assert num.allclose(domain.max_timestep, 0.0210448446782)
4511
4512        #FIXME: These numbers were from version before 21/3/6 -
4513        #could be recreated by setting maximum_allowed_speed to 0 maybe
4514        assert num.allclose(domain.quantities['xmomentum'].vertex_values[:4,0],
4515                            [ 0.00064835, 0.03685719, 0.00085073, 0.03687313]) 
4516       
4517
4518        assert num.allclose(domain.quantities['ymomentum'].vertex_values[:4,0],
4519                            [-0.00139463,0.0006156,-0.00060364,0.00061827])
4520
4521
4522        os.remove(domain.get_name() + '.sww')
4523
4524       
4525
4526    def test_flatbed_second_order_distribute(self):
4527        #Use real data from anuga.abstract_2d_finite_volumes 2
4528        #painfully setup and extracted.
4529        from mesh_factory import rectangular
4530
4531        #Create basic mesh
4532        N = 8
4533        points, vertices, boundary = rectangular(N, N)
4534
4535        #Create shallow water domain
4536        domain = Domain(points, vertices, boundary)
4537        domain.smooth = False
4538        domain.default_order=domain._order_=2
4539        domain.beta_w      = 0.9
4540        domain.beta_w_dry  = 0.9
4541        domain.beta_uh     = 0.9
4542        domain.beta_uh_dry = 0.9
4543        domain.beta_vh     = 0.9
4544        domain.beta_vh_dry = 0.9
4545        domain.H0 = 0 # Backwards compatibility (6/2/7)
4546        domain.use_centroid_velocities = False # Backwards compatibility (8/5/8)       
4547        domain.set_maximum_allowed_speed(1.0)       
4548
4549        # Boundary conditions
4550        Br = Reflective_boundary(domain)
4551        Bd = Dirichlet_boundary([0.2,0.,0.])
4552
4553        domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
4554        domain.check_integrity()
4555
4556
4557
4558        for V in [False, True]:
4559            if V:
4560                #Set centroids as if system had been evolved
4561                L = num.zeros(2*N*N, num.float)
4562                L[:32] = [7.21205592e-003, 5.35214298e-002, 1.00910824e-002,
4563                          5.35439433e-002, 1.00910824e-002, 5.35439433e-002,
4564                          1.00910824e-002, 5.35439433e-002, 1.00910824e-002,
4565                          5.35439433e-002, 1.00910824e-002, 5.35439433e-002,
4566                          1.00910824e-002, 5.35393928e-002, 1.02344264e-002,
4567                          5.59605058e-002, 0.00000000e+000, 3.31027800e-004,
4568                          0.00000000e+000, 4.37962142e-005, 0.00000000e+000,
4569                          4.37962142e-005, 0.00000000e+000, 4.37962142e-005,
4570                          0.00000000e+000, 4.37962142e-005, 0.00000000e+000,
4571                          4.37962142e-005, 0.00000000e+000, 4.37962142e-005,
4572                          0.00000000e+000, 5.57305948e-005]
4573
4574                X = num.zeros(2*N*N, num.float)
4575                X[:32] = [6.48351607e-003, 3.68571894e-002, 8.50733285e-003,
4576                          3.68731327e-002, 8.50733285e-003, 3.68731327e-002,
4577                          8.50733285e-003, 3.68731327e-002, 8.50733285e-003,
4578                          3.68731327e-002, 8.50733285e-003, 3.68731327e-002,
4579                          8.50733285e-003, 3.68693861e-002, 8.65220973e-003,
4580                          3.85055387e-002, 0.00000000e+000, 2.86060840e-004,
4581                          0.00000000e+000, 3.58905503e-005, 0.00000000e+000,
4582                          3.58905503e-005, 0.00000000e+000, 3.58905503e-005,
4583                          0.00000000e+000, 3.58905503e-005, 0.00000000e+000,
4584                          3.58905503e-005, 0.00000000e+000, 3.58905503e-005,
4585                          0.00000000e+000, 4.57662812e-005]
4586
4587                Y = num.zeros(2*N*N, num.float)
4588                Y[:32]=[-1.39463104e-003, 6.15600298e-004, -6.03637382e-004,
4589                        6.18272251e-004, -6.03637382e-004, 6.18272251e-004,
4590                        -6.03637382e-004, 6.18272251e-004, -6.03637382e-004,
4591                        6.18272251e-004, -6.03637382e-004, 6.18272251e-004,
4592                        -6.03637382e-004, 6.18599320e-004, -6.74622797e-004,
4593                        -1.48934756e-004, 0.00000000e+000, -5.35079969e-005,
4594                        0.00000000e+000, -2.57264987e-005, 0.00000000e+000,
4595                        -2.57264987e-005, 0.00000000e+000, -2.57264987e-005,
4596                        0.00000000e+000, -2.57264987e-005, 0.00000000e+000,
4597                        -2.57264987e-005, 0.00000000e+000, -2.57264987e-005,
4598                        0.00000000e+000, -2.57635178e-005]
4599
4600
4601                domain.set_quantity('stage', L, location='centroids')
4602                domain.set_quantity('xmomentum', X, location='centroids')
4603                domain.set_quantity('ymomentum', Y, location='centroids')
4604
4605                domain.check_integrity()
4606            else:
4607                #Evolution
4608                for t in domain.evolve(yieldstep = 0.01, finaltime = 0.03):
4609                    pass
4610                assert num.allclose(domain.min_timestep, 0.0210448446782)
4611                assert num.allclose(domain.max_timestep, 0.0210448446782)
4612
4613
4614            #Centroids were correct but not vertices.
4615            #Hence the check of distribute below.
4616            assert num.allclose(domain.quantities['stage'].centroid_values[:4],
4617                                [0.00721206,0.05352143,0.01009108,0.05354394])
4618
4619            assert num.allclose(domain.quantities['xmomentum'].centroid_values[:4],
4620                                [0.00648352,0.03685719,0.00850733,0.03687313])
4621
4622            assert num.allclose(domain.quantities['ymomentum'].centroid_values[:4],
4623                                [-0.00139463,0.0006156,-0.00060364,0.00061827])
4624
4625            #print 'C17=', domain.quantities['xmomentum'].centroid_values[17]
4626            #print 'C19=', domain.quantities['xmomentum'].centroid_values[19]
4627
4628            #assert allclose(domain.quantities['xmomentum'].centroid_values[17],0.00028606084)
4629            ##print domain.quantities['xmomentum'].centroid_values[17], V
4630            ##print
4631            if not V:
4632                #FIXME: These numbers were from version before 21/3/6 -
4633                #could be recreated by setting maximum_allowed_speed to 0 maybe           
4634               
4635                #assert allclose(domain.quantities['xmomentum'].centroid_values[17], 0.0)               
4636                assert num.allclose(domain.quantities['xmomentum'].centroid_values[17], 0.000286060839592)                         
4637
4638            else:
4639                assert num.allclose(domain.quantities['xmomentum'].centroid_values[17], 0.00028606084)
4640
4641            import copy
4642            XX = copy.copy(domain.quantities['xmomentum'].centroid_values)
4643            assert num.allclose(domain.quantities['xmomentum'].centroid_values, XX)
4644
4645            domain.distribute_to_vertices_and_edges()
4646
4647            #assert allclose(domain.quantities['xmomentum'].centroid_values, XX)
4648
4649            #assert allclose(domain.quantities['xmomentum'].centroid_values[17],
4650            #                0.0)
4651            assert num.allclose(domain.quantities['xmomentum'].centroid_values[17], 0.000286060839592)                                                 
4652
4653
4654            #FIXME: These numbers were from version before 25/10
4655            #assert allclose(domain.quantities['stage'].vertex_values[:4,0],
4656            #                [0.00101913,0.05352143,0.00104852,0.05354394])
4657
4658            assert num.allclose(domain.quantities['ymomentum'].vertex_values[:4,0],
4659                                [-0.00139463,0.0006156,-0.00060364,0.00061827])
4660
4661
4662            assert num.allclose(domain.quantities['xmomentum'].vertex_values[:4,0],
4663                                [0.00090581,0.03685719,0.00088303,0.03687313])
4664
4665
4666            #NB NO longer relvant:
4667
4668            #This was the culprit. First triangles vertex 0 had an
4669            #x-momentum of 0.0064835 instead of 0.00090581 and
4670            #third triangle had 0.00850733 instead of 0.00088303
4671            #print domain.quantities['xmomentum'].vertex_values[:4,0]
4672
4673            #print domain.quantities['xmomentum'].vertex_values[:4,0]
4674            #assert allclose(domain.quantities['xmomentum'].vertex_values[:4,0],
4675            #                [0.00090581,0.03685719,0.00088303,0.03687313])
4676
4677        os.remove(domain.get_name() + '.sww')
4678
4679
4680
4681    def test_bedslope_problem_first_order(self):
4682
4683        from mesh_factory import rectangular
4684
4685        #Create basic mesh
4686        points, vertices, boundary = rectangular(6, 6)
4687
4688        #Create shallow water domain
4689        domain = Domain(points, vertices, boundary)
4690        domain.smooth = False
4691        domain.default_order = 1
4692
4693        #Bed-slope and friction
4694        def x_slope(x, y):
4695            return -x/3
4696
4697        domain.set_quantity('elevation', x_slope)
4698
4699        # Boundary conditions
4700        Br = Reflective_boundary(domain)
4701        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
4702
4703        #Initial condition
4704        #domain.set_quantity('stage', Constant_height(x_slope, 0.05))
4705        domain.set_quantity('stage', expression='elevation+0.05')
4706        domain.check_integrity()
4707
4708        #Evolution
4709        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.05):
4710            pass# domain.write_time()
4711
4712        # FIXME (Ole): Need some other assertion here!
4713        #print domain.min_timestep, domain.max_timestep   
4714        #assert allclose(domain.min_timestep, 0.050010003001)
4715        #assert allclose(domain.max_timestep, 0.050010003001)
4716
4717
4718        os.remove(domain.get_name() + '.sww')
4719       
4720    def test_bedslope_problem_first_order_moresteps(self):
4721
4722        from mesh_factory import rectangular
4723
4724        #Create basic mesh
4725        points, vertices, boundary = rectangular(6, 6)
4726
4727        #Create shallow water domain
4728        domain = Domain(points, vertices, boundary)
4729        domain.smooth = False
4730        domain.default_order = 1
4731       
4732        # FIXME (Ole): Need tests where these two are commented out
4733        domain.H0 = 0        # Backwards compatibility (6/2/7)       
4734        domain.tight_slope_limiters = 0 # Backwards compatibility (14/4/7)
4735        domain.use_centroid_velocities = 0 # Backwards compatibility (7/5/8)                 
4736
4737        #Bed-slope and friction
4738        def x_slope(x, y):
4739            return -x/3
4740
4741        domain.set_quantity('elevation', x_slope)
4742
4743        # Boundary conditions
4744        Br = Reflective_boundary(domain)
4745        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
4746
4747        #Initial condition
4748        domain.set_quantity('stage', expression='elevation+0.05')
4749        domain.check_integrity()
4750
4751        #Evolution
4752        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.5):
4753            pass# domain.write_time()
4754
4755        #Data from earlier version of abstract_2d_finite_volumes
4756        #print domain.quantities['stage'].centroid_values
4757
4758        assert num.allclose(domain.quantities['stage'].centroid_values,
4759                            [-0.02998628, -0.01520652, -0.03043492,
4760                             -0.0149132, -0.03004706, -0.01476251,
4761                             -0.0298215, -0.01467976, -0.02988158,
4762                             -0.01474662, -0.03036161, -0.01442995,
4763                             -0.07624583, -0.06297061, -0.07733792,
4764                             -0.06342237, -0.07695439, -0.06289595,
4765                             -0.07635559, -0.0626065, -0.07633628,
4766                             -0.06280072, -0.07739632, -0.06386738,
4767                             -0.12161738, -0.11028239, -0.1223796,
4768                             -0.11095953, -0.12189744, -0.11048616,
4769                             -0.12074535, -0.10987605, -0.12014311,
4770                             -0.10976691, -0.12096859, -0.11087692,
4771                             -0.16868259, -0.15868061, -0.16801135,
4772                             -0.1588003, -0.16674343, -0.15813323,
4773                             -0.16457595, -0.15693826, -0.16281096,
4774                             -0.15585154, -0.16283873, -0.15540068,
4775                             -0.17450362, -0.19919913, -0.18062882,
4776                             -0.19764131, -0.17783111, -0.19407213,
4777                             -0.1736915, -0.19053624, -0.17228678,
4778                             -0.19105634, -0.17920133, -0.1968828,
4779                             -0.14244395, -0.14604641, -0.14473537,
4780                             -0.1506107, -0.14510055, -0.14919522,
4781                             -0.14175896, -0.14560798, -0.13911658,
4782                             -0.14439383, -0.13924047, -0.14829043])
4783
4784        os.remove(domain.get_name() + '.sww')
4785       
4786    def test_bedslope_problem_second_order_one_step(self):
4787
4788        from mesh_factory import rectangular
4789
4790        #Create basic mesh
4791        points, vertices, boundary = rectangular(6, 6)
4792
4793        #Create shallow water domain
4794        domain = Domain(points, vertices, boundary)
4795        domain.smooth = False
4796        domain.default_order=2
4797        domain.beta_w      = 0.9
4798        domain.beta_w_dry  = 0.9
4799        domain.beta_uh     = 0.9
4800        domain.beta_uh_dry = 0.9
4801        domain.beta_vh     = 0.9
4802        domain.beta_vh_dry = 0.9
4803
4804       
4805        # FIXME (Ole): Need tests where this is commented out
4806        domain.tight_slope_limiters = 0 # Backwards compatibility (14/4/7)
4807        domain.use_centroid_velocities = 0 # Backwards compatibility (7/5/8)     
4808       
4809        #Bed-slope and friction at vertices (and interpolated elsewhere)
4810        def x_slope(x, y):
4811            return -x/3
4812
4813        domain.set_quantity('elevation', x_slope)
4814
4815        # Boundary conditions
4816        Br = Reflective_boundary(domain)
4817        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
4818
4819        #Initial condition
4820        domain.set_quantity('stage', expression='elevation+0.05')
4821        domain.check_integrity()
4822
4823        assert num.allclose(domain.quantities['stage'].centroid_values,
4824                            [ 0.01296296,  0.03148148,  0.01296296,
4825                              0.03148148,  0.01296296,  0.03148148,
4826                              0.01296296,  0.03148148,  0.01296296,
4827                              0.03148148,  0.01296296,  0.03148148,
4828                             -0.04259259, -0.02407407, -0.04259259,
4829                             -0.02407407, -0.04259259, -0.02407407,
4830                             -0.04259259, -0.02407407, -0.04259259,
4831                             -0.02407407, -0.04259259, -0.02407407,
4832                             -0.09814815, -0.07962963, -0.09814815,
4833                             -0.07962963, -0.09814815, -0.07962963,
4834                             -0.09814815, -0.07962963, -0.09814815,
4835                             -0.07962963, -0.09814815, -0.07962963,
4836                             -0.1537037,  -0.13518519, -0.1537037,
4837                             -0.13518519, -0.1537037,  -0.13518519,
4838                             -0.1537037 , -0.13518519, -0.1537037,
4839                             -0.13518519, -0.1537037,  -0.13518519,
4840                             -0.20925926, -0.19074074, -0.20925926,
4841                             -0.19074074, -0.20925926, -0.19074074,
4842                             -0.20925926, -0.19074074, -0.20925926,
4843                             -0.19074074, -0.20925926, -0.19074074,
4844                             -0.26481481, -0.2462963,  -0.26481481,
4845                             -0.2462963,  -0.26481481, -0.2462963,
4846                             -0.26481481, -0.2462963,  -0.26481481,
4847                             -0.2462963,  -0.26481481, -0.2462963])
4848
4849
4850        #print domain.quantities['stage'].extrapolate_second_order()
4851        #domain.distribute_to_vertices_and_edges()
4852        #print domain.quantities['stage'].vertex_values[:,0]
4853
4854        #Evolution
4855        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.05):
4856            #domain.write_time()
4857            pass
4858
4859
4860        #print domain.quantities['stage'].centroid_values
4861        assert num.allclose(domain.quantities['stage'].centroid_values,
4862                            [ 0.01290985,  0.02356019,  0.01619096,  0.02356019,  0.01619096,
4863                              0.02356019,  0.01619096,  0.02356019,  0.01619096,  0.02356019,
4864                              0.01619096,  0.0268413,  -0.04411074, -0.0248011,  -0.04186556,
4865                             -0.0248011,  -0.04186556, -0.0248011,  -0.04186556, -0.0248011,
4866                             -0.04186556, -0.0248011,  -0.04186556, -0.02255593,
4867                             -0.09966629, -0.08035666, -0.09742112, -0.08035666,
4868                             -0.09742112, -0.08035666, -0.09742112, -0.08035666,
4869                             -0.09742112, -0.08035666, -0.09742112, -0.07811149,
4870                             -0.15522185, -0.13591222, -0.15297667, -0.13591222,
4871                             -0.15297667, -0.13591222, -0.15297667, -0.13591222,
4872                             -0.15297667, -0.13591222, -0.15297667, -0.13366704,
4873                             -0.2107774,  -0.19146777, -0.20853223, -0.19146777,
4874                             -0.20853223, -0.19146777, -0.20853223, -0.19146777,
4875                             -0.20853223, -0.19146777, -0.20853223, -0.1892226,
4876                             -0.26120669, -0.24776246, -0.25865535, -0.24776246,
4877                             -0.25865535, -0.24776246, -0.25865535, -0.24776246,
4878                             -0.25865535, -0.24776246, -0.25865535, -0.24521113])
4879
4880        os.remove(domain.get_name() + '.sww')
4881
4882    def test_bedslope_problem_second_order_two_steps(self):
4883
4884        from mesh_factory import rectangular
4885
4886        #Create basic mesh
4887        points, vertices, boundary = rectangular(6, 6)
4888
4889        #Create shallow water domain
4890        domain = Domain(points, vertices, boundary)
4891        domain.smooth = False
4892        domain.default_order=2
4893        domain.beta_w      = 0.9
4894        domain.beta_w_dry  = 0.9
4895        domain.beta_uh     = 0.9
4896        domain.beta_uh_dry = 0.9
4897        domain.beta_vh     = 0.9
4898        domain.beta_vh_dry = 0.9
4899       
4900        # FIXME (Ole): Need tests where this is commented out
4901        domain.tight_slope_limiters = 0 # Backwards compatibility (14/4/7)                 
4902        domain.H0 = 0 # Backwards compatibility (6/2/7)
4903        domain.use_centroid_velocities = 0 # Backwards compatibility (7/5/8)
4904       
4905
4906        #Bed-slope and friction at vertices (and interpolated elsewhere)
4907        def x_slope(x, y):
4908            return -x/3
4909
4910        domain.set_quantity('elevation', x_slope)
4911
4912        # Boundary conditions
4913        Br = Reflective_boundary(domain)
4914        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
4915
4916        #Initial condition
4917        domain.set_quantity('stage', expression='elevation+0.05')
4918        domain.check_integrity()
4919
4920        assert num.allclose(domain.quantities['stage'].centroid_values,
4921                            [ 0.01296296,  0.03148148,  0.01296296,
4922                              0.03148148,  0.01296296,  0.03148148,
4923                              0.01296296,  0.03148148,  0.01296296,
4924                              0.03148148,  0.01296296,  0.03148148,
4925                             -0.04259259, -0.02407407, -0.04259259,
4926                             -0.02407407, -0.04259259, -0.02407407,
4927                             -0.04259259, -0.02407407, -0.04259259,
4928                             -0.02407407, -0.04259259, -0.02407407,
4929                             -0.09814815, -0.07962963, -0.09814815,
4930                             -0.07962963, -0.09814815, -0.07962963,
4931                             -0.09814815, -0.07962963, -0.09814815,
4932                             -0.07962963, -0.09814815, -0.07962963,
4933                             -0.1537037 , -0.13518519, -0.1537037,
4934                             -0.13518519, -0.1537037,  -0.13518519,
4935                             -0.1537037 , -0.13518519, -0.1537037,
4936                             -0.13518519, -0.1537037,  -0.13518519,
4937                             -0.20925926, -0.19074074, -0.20925926,
4938                             -0.19074074, -0.20925926, -0.19074074,
4939                             -0.20925926, -0.19074074, -0.20925926,
4940                             -0.19074074, -0.20925926, -0.19074074,
4941                             -0.26481481, -0.2462963,  -0.26481481,
4942                             -0.2462963,  -0.26481481, -0.2462963,
4943                             -0.26481481, -0.2462963,  -0.26481481,
4944                             -0.2462963,  -0.26481481, -0.2462963])
4945
4946
4947        #print domain.quantities['stage'].extrapolate_second_order()
4948        #domain.distribute_to_vertices_and_edges()
4949        #print domain.quantities['stage'].vertex_values[:,0]
4950
4951        #Evolution
4952        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.1):
4953            pass
4954
4955
4956        #Data from earlier version of abstract_2d_finite_volumes ft=0.1
4957        assert num.allclose(domain.min_timestep, 0.0376895634803)
4958        assert num.allclose(domain.max_timestep, 0.0415635655309)
4959
4960
4961        assert num.allclose(domain.quantities['stage'].centroid_values,
4962                            [ 0.00855788,  0.01575204,  0.00994606,  0.01717072,
4963                              0.01005985,  0.01716362,  0.01005985,  0.01716299,
4964                              0.01007098,  0.01736248,  0.01216452,  0.02026776,
4965                             -0.04462374, -0.02479045, -0.04199789, -0.0229465,
4966                             -0.04184033, -0.02295693, -0.04184013, -0.02295675,
4967                             -0.04184486, -0.0228168,  -0.04028876, -0.02036486,
4968                             -0.10029444, -0.08170809, -0.09772846, -0.08021704,
4969                             -0.09760006, -0.08022143, -0.09759984, -0.08022124,
4970                             -0.09760261, -0.08008893, -0.09603914, -0.07758209,
4971                             -0.15584152, -0.13723138, -0.15327266, -0.13572906,
4972                             -0.15314427, -0.13573349, -0.15314405, -0.13573331,
4973                             -0.15314679, -0.13560104, -0.15158523, -0.13310701,
4974                             -0.21208605, -0.19283913, -0.20955631, -0.19134189,
4975                             -0.20942821, -0.19134598, -0.20942799, -0.1913458,
4976                             -0.20943005, -0.19120952, -0.20781177, -0.18869401,
4977                             -0.25384082, -0.2463294,  -0.25047649, -0.24464654,
4978                             -0.25031159, -0.24464253, -0.25031112, -0.24464253,
4979                             -0.25031463, -0.24454764, -0.24885323, -0.24286438])
4980
4981
4982        os.remove(domain.get_name() + '.sww')
4983
4984    def test_bedslope_problem_second_order_two_yieldsteps(self):
4985
4986        from mesh_factory import rectangular
4987
4988        #Create basic mesh
4989        points, vertices, boundary = rectangular(6, 6)
4990
4991        #Create shallow water domain
4992        domain = Domain(points, vertices, boundary)
4993        domain.smooth = False
4994        domain.default_order=2
4995        domain.beta_w      = 0.9
4996        domain.beta_w_dry  = 0.9
4997        domain.beta_uh     = 0.9
4998        domain.beta_uh_dry = 0.9
4999        domain.beta_vh     = 0.9
5000        domain.beta_vh_dry = 0.9
5001       
5002        # FIXME (Ole): Need tests where this is commented out
5003        domain.tight_slope_limiters = 0 # Backwards compatibility (14/4/7)                 
5004        domain.H0 = 0 # Backwards compatibility (6/2/7)
5005        domain.use_centroid_velocities = 0 # Backwards compatibility (7/5/8)
5006       
5007
5008        #Bed-slope and friction at vertices (and interpolated elsewhere)
5009        def x_slope(x, y):
5010            return -x/3
5011
5012        domain.set_quantity('elevation', x_slope)
5013
5014        # Boundary conditions
5015        Br = Reflective_boundary(domain)
5016        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
5017
5018        #Initial condition
5019        domain.set_quantity('stage', expression='elevation+0.05')
5020        domain.check_integrity()
5021
5022        assert num.allclose(domain.quantities['stage'].centroid_values,
5023                            [ 0.01296296,  0.03148148,  0.01296296,
5024                              0.03148148,  0.01296296,  0.03148148,
5025                              0.01296296,  0.03148148,  0.01296296,
5026                              0.03148148,  0.01296296,  0.03148148,
5027                             -0.04259259, -0.02407407, -0.04259259,
5028                             -0.02407407, -0.04259259, -0.02407407,
5029                             -0.04259259, -0.02407407, -0.04259259,
5030                             -0.02407407, -0.04259259, -0.02407407,
5031                             -0.09814815, -0.07962963, -0.09814815,
5032                             -0.07962963, -0.09814815, -0.07962963,
5033                             -0.09814815, -0.07962963, -0.09814815,
5034                             -0.07962963, -0.09814815, -0.07962963,
5035                             -0.1537037 , -0.13518519, -0.1537037,
5036                             -0.13518519, -0.1537037,  -0.13518519,
5037                             -0.1537037 , -0.13518519, -0.1537037,
5038                             -0.13518519, -0.1537037,  -0.13518519,
5039                             -0.20925926, -0.19074074, -0.20925926,
5040                             -0.19074074, -0.20925926, -0.19074074,
5041                             -0.20925926, -0.19074074, -0.20925926,
5042                             -0.19074074, -0.20925926, -0.19074074,
5043                             -0.26481481, -0.2462963,  -0.26481481,
5044                             -0.2462963,  -0.26481481, -0.2462963,
5045                             -0.26481481, -0.2462963,  -0.26481481,
5046                             -0.2462963,  -0.26481481, -0.2462963])
5047
5048
5049        #print domain.quantities['stage'].extrapolate_second_order()
5050        #domain.distribute_to_vertices_and_edges()
5051        #print domain.quantities['stage'].vertex_values[:,0]
5052
5053        #Evolution
5054        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.1):   #0.05??
5055            #domain.write_time()
5056            pass
5057
5058
5059
5060        assert num.allclose(domain.quantities['stage'].centroid_values,
5061                            [ 0.00855788,  0.01575204,  0.00994606,  0.01717072,  0.01005985,
5062                              0.01716362,  0.01005985,  0.01716299,  0.01007098,  0.01736248,
5063                              0.01216452,  0.02026776, -0.04462374, -0.02479045, -0.04199789,
5064                             -0.0229465,  -0.04184033, -0.02295693, -0.04184013,
5065                             -0.02295675, -0.04184486, -0.0228168,  -0.04028876,
5066                             -0.02036486, -0.10029444, -0.08170809, -0.09772846,
5067                             -0.08021704, -0.09760006, -0.08022143, -0.09759984,
5068                             -0.08022124, -0.09760261, -0.08008893, -0.09603914,
5069                             -0.07758209, -0.15584152, -0.13723138, -0.15327266,
5070                             -0.13572906, -0.15314427, -0.13573349, -0.15314405,
5071                             -0.13573331, -0.15314679, -0.13560104, -0.15158523,
5072                             -0.13310701, -0.21208605, -0.19283913, -0.20955631,
5073                             -0.19134189, -0.20942821, -0.19134598, -0.20942799,
5074                             -0.1913458,  -0.20943005, -0.19120952, -0.20781177,
5075                             -0.18869401, -0.25384082, -0.2463294,  -0.25047649,
5076                             -0.24464654, -0.25031159, -0.24464253, -0.25031112,
5077                             -0.24464253, -0.25031463, -0.24454764, -0.24885323,
5078                             -0.24286438])
5079
5080        os.remove(domain.get_name() + '.sww')
5081
5082    def test_bedslope_problem_second_order_more_steps(self):
5083
5084        from mesh_factory import rectangular
5085
5086        #Create basic mesh
5087        points, vertices, boundary = rectangular(6, 6)
5088
5089        #Create shallow water domain
5090        domain = Domain(points, vertices, boundary)
5091        domain.smooth = False
5092        domain.default_order=2
5093        domain.beta_w      = 0.9
5094        domain.beta_w_dry  = 0.9
5095        domain.beta_uh     = 0.9
5096        domain.beta_uh_dry = 0.9
5097        domain.beta_vh     = 0.9
5098        domain.beta_vh_dry = 0.9
5099       
5100       
5101        # FIXME (Ole): Need tests where these two are commented out
5102        domain.H0 = 0        # Backwards compatibility (6/2/7)       
5103        domain.tight_slope_limiters = 0 # Backwards compatibility (14/4/7)                 
5104        domain.use_centroid_velocities = 0 # Backwards compatibility (7/5/8)
5105       
5106               
5107
5108        #Bed-slope and friction at vertices (and interpolated elsewhere)
5109        def x_slope(x, y):
5110            return -x/3
5111
5112        domain.set_quantity('elevation', x_slope)
5113
5114        # Boundary conditions
5115        Br = Reflective_boundary(domain)
5116        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
5117
5118        #Initial condition
5119        domain.set_quantity('stage', expression = 'elevation + 0.05')
5120        domain.check_integrity()
5121
5122        assert num.allclose(domain.quantities['stage'].centroid_values,
5123                            [ 0.01296296,  0.03148148,  0.01296296,
5124                              0.03148148,  0.01296296,  0.03148148,
5125                              0.01296296,  0.03148148,  0.01296296,
5126                              0.03148148,  0.01296296,  0.03148148,
5127                             -0.04259259, -0.02407407, -0.04259259,
5128                             -0.02407407, -0.04259259, -0.02407407,
5129                             -0.04259259, -0.02407407, -0.04259259,
5130                             -0.02407407, -0.04259259, -0.02407407,
5131                             -0.09814815, -0.07962963, -0.09814815,
5132                             -0.07962963, -0.09814815, -0.07962963,
5133                             -0.09814815, -0.07962963, -0.09814815,
5134                             -0.07962963, -0.09814815, -0.07962963,
5135                             -0.1537037 , -0.13518519, -0.1537037,
5136                             -0.13518519, -0.1537037,  -0.13518519,
5137                             -0.1537037 , -0.13518519, -0.1537037,
5138                             -0.13518519, -0.1537037,  -0.13518519,
5139                             -0.20925926, -0.19074074, -0.20925926,
5140                             -0.19074074, -0.20925926, -0.19074074,
5141                             -0.20925926, -0.19074074, -0.20925926,
5142                             -0.19074074, -0.20925926, -0.19074074,
5143                             -0.26481481, -0.2462963,  -0.26481481,
5144                             -0.2462963,  -0.26481481, -0.2462963,
5145                             -0.26481481, -0.2462963,  -0.26481481,
5146                             -0.2462963,  -0.26481481, -0.2462963])
5147
5148
5149        #print domain.quantities['stage'].extrapolate_second_order()
5150        #domain.distribute_to_vertices_and_edges()
5151        #print domain.quantities['stage'].vertex_values[:,0]
5152
5153        #Evolution
5154        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.5):
5155
5156            # Check that diagnostics works
5157            msg = domain.timestepping_statistics(track_speeds=True)
5158            #FIXME(Ole): One might check the contents of msg here.
5159
5160
5161
5162        assert num.allclose(domain.quantities['stage'].centroid_values,
5163     [-0.02907028, -0.01475478, -0.02973417, -0.01447186, -0.02932665, -0.01428285,
5164      -0.02901975, -0.0141361,  -0.02898816, -0.01418135, -0.02961409, -0.01403487,
5165      -0.07597998, -0.06252591, -0.07664854, -0.06312532, -0.07638287, -0.06265139,
5166      -0.07571145, -0.06235231, -0.0756817,  -0.06245309, -0.07652292, -0.06289946,
5167      -0.12367464, -0.11088981, -0.12237277, -0.11115338, -0.1218934,  -0.1107174,
5168      -0.12081485, -0.11000491, -0.12038451, -0.11010335, -0.12102113, -0.11012105,
5169      -0.16909116, -0.15831543, -0.16730214, -0.15786249, -0.1665493,  -0.15697919,
5170      -0.16496618, -0.15559852, -0.16338679, -0.15509088, -0.16364092, -0.15424423,
5171      -0.18771107, -0.19903904, -0.18903759, -0.19858437, -0.18701552, -0.19697797,
5172      -0.1833593,  -0.19505871, -0.1818806,  -0.19418042, -0.18586159, -0.19576946,
5173      -0.13986873, -0.14170053, -0.14132188, -0.14560674, -0.14095617, -0.14373292,
5174      -0.13785933, -0.14033364, -0.13592955, -0.13936356, -0.13596008, -0.14216296])
5175
5176        assert num.allclose(domain.quantities['xmomentum'].centroid_values,
5177     [ 0.00831121,  0.00317948,  0.00731797,  0.00334939,  0.00764717,  0.00348053,
5178       0.00788729,  0.00356522,  0.00780649,  0.00341919,  0.00693525,  0.00310375,
5179       0.02166196,  0.01421475,  0.02017737,  0.01316839,  0.02037015,  0.01368659,
5180       0.02106,     0.01399161,  0.02074514,  0.01354935,  0.01887407,  0.0123113,
5181       0.03775083,  0.02855197,  0.03689337,  0.02759782,  0.03732848,  0.02812072,
5182       0.03872545,  0.02913348,  0.03880939,  0.02803804,  0.03546499,  0.0260039,
5183       0.0632131,   0.04730634,  0.0576324,   0.04592336,  0.05790921,  0.04690514,
5184       0.05986467,  0.04871165,  0.06170068,  0.04811572,  0.05657041,  0.04416292,
5185       0.08489642,  0.07188097,  0.07835261,  0.06843406,  0.07986412,  0.0698247,
5186       0.08201071,  0.07216756,  0.08378418,  0.07273624,  0.080399,    0.06645841,
5187       0.01631548,  0.04691608,  0.0206632,   0.044409,    0.02115518,  0.04560305,
5188       0.02160608,  0.04663725,  0.02174734,  0.04795559,  0.02281427,  0.05667111])
5189
5190
5191        assert num.allclose(domain.quantities['ymomentum'].centroid_values,
5192     [ 1.45876601e-004, -3.24627393e-004, -1.57572719e-004, -2.92790187e-004,
5193      -9.90988382e-005, -3.06677335e-004, -1.62493106e-004, -3.71310004e-004,
5194      -1.99445058e-004, -3.28493467e-004,  6.68217349e-005, -8.42042805e-006,
5195       5.05093371e-004, -1.42842214e-004, -6.81454718e-005, -5.02084057e-004,
5196      -8.50583861e-005, -4.65443981e-004, -1.96406564e-004, -5.88889562e-004,
5197      -2.70160173e-004, -5.35485454e-004,  2.60780997e-004,  3.12145471e-005,
5198       5.16189608e-004,  1.07069062e-004,  9.29989252e-005, -3.71211119e-004,
5199       1.16350246e-004, -3.82407830e-004, -1.62077969e-004, -6.30906636e-004,
5200      -4.74025708e-004, -6.94463009e-004,  6.15092843e-005,  2.22106820e-004,
5201      -6.29589294e-004,  2.43611937e-004, -5.88125094e-004, -6.94293192e-005,
5202      -4.17914641e-004,  6.64609019e-005, -7.68334577e-004, -3.40232101e-004,
5203      -1.67424308e-003, -7.39485066e-004, -1.59966988e-003,  5.68262838e-005,
5204      -1.48470633e-003, -1.84554882e-003, -2.27200099e-003, -1.67506848e-003,
5205      -1.95610258e-003, -1.47638801e-003, -1.73779477e-003, -1.85498791e-003,
5206      -2.01357843e-003, -2.17675471e-003, -1.65783870e-003, -1.15818681e-003,
5207      -1.18663036e-003, -2.94229849e-003, -3.59309018e-003, -5.13496584e-003,
5208      -6.17359400e-003, -5.98761937e-003, -6.00540116e-003, -5.01121966e-003,
5209      -4.50964850e-003, -3.06319963e-003,  6.08950810e-004, -4.79537921e-004])
5210
5211        os.remove(domain.get_name() + '.sww')
5212
5213
5214
5215    def NOtest_bedslope_problem_second_order_more_steps_feb_2007(self):
5216        """test_bedslope_problem_second_order_more_steps_feb_2007
5217
5218        Test shallow water finite volumes, using parameters from
5219        feb 2007 rather than backward compatibility ad infinitum
5220       
5221        """
5222        from mesh_factory import rectangular
5223
5224        #Create basic mesh
5225        points, vertices, boundary = rectangular(6, 6)
5226
5227        #Create shallow water domain
5228        domain = Domain(points, vertices, boundary)
5229        domain.smooth = False
5230        domain.default_order = 2
5231        domain.beta_w      = 0.9
5232        domain.beta_w_dry  = 0.9
5233        domain.beta_uh     = 0.9
5234        domain.beta_uh_dry = 0.9
5235        domain.beta_vh     = 0.9
5236        domain.beta_vh_dry = 0.9
5237        domain.H0 = 0.001
5238        domain.tight_slope_limiters = 1
5239
5240        #Bed-slope and friction at vertices (and interpolated elsewhere)
5241        def x_slope(x, y):
5242            return -x/3
5243
5244        domain.set_quantity('elevation', x_slope)
5245
5246        # Boundary conditions
5247        Br = Reflective_boundary(domain)
5248        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
5249
5250        #Initial condition
5251        domain.set_quantity('stage', expression = 'elevation + 0.05')
5252        domain.check_integrity()
5253
5254        assert num.allclose(domain.quantities['stage'].centroid_values,
5255                            [ 0.01296296,  0.03148148,  0.01296296,
5256                              0.03148148,  0.01296296,  0.03148148,
5257                              0.01296296,  0.03148148,  0.01296296,
5258                              0.03148148,  0.01296296,  0.03148148,
5259                             -0.04259259, -0.02407407, -0.04259259,
5260                             -0.02407407, -0.04259259, -0.02407407,
5261                             -0.04259259, -0.02407407, -0.04259259,
5262                             -0.02407407, -0.04259259, -0.02407407,
5263                             -0.09814815, -0.07962963, -0.09814815,
5264                             -0.07962963, -0.09814815, -0.07962963,
5265                             -0.09814815, -0.07962963, -0.09814815,
5266                             -0.07962963, -0.09814815, -0.07962963,
5267                             -0.1537037 , -0.13518519, -0.1537037,
5268                             -0.13518519, -0.1537037,  -0.13518519,
5269                             -0.1537037 , -0.13518519, -0.1537037,
5270                             -0.13518519, -0.1537037,  -0.13518519,
5271                             -0.20925926, -0.19074074, -0.20925926,
5272                             -0.19074074, -0.20925926, -0.19074074,
5273                             -0.20925926, -0.19074074, -0.20925926,
5274                             -0.19074074, -0.20925926, -0.19074074,
5275                             -0.26481481, -0.2462963,  -0.26481481,
5276                             -0.2462963,  -0.26481481, -0.2462963,
5277                             -0.26481481, -0.2462963,  -0.26481481,
5278                             -0.2462963,  -0.26481481, -0.2462963])
5279
5280
5281        #print domain.quantities['stage'].extrapolate_second_order()
5282        #domain.distribute_to_vertices_and_edges()
5283        #print domain.quantities['stage'].vertex_values[:,0]
5284
5285        #Evolution
5286        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.5):
5287            pass
5288
5289
5290        #print domain.quantities['stage'].centroid_values
5291           
5292        assert num.allclose(domain.quantities['stage'].centroid_values,
5293         [-0.03348416, -0.01749303, -0.03299091, -0.01739241, -0.03246447, -0.01732016,
5294          -0.03205390, -0.01717833, -0.03146383, -0.01699831, -0.03076577, -0.01671795,
5295          -0.07952656, -0.06684763, -0.07721455, -0.06668388, -0.07632976, -0.06600113,
5296          -0.07523678, -0.06546373, -0.07447040, -0.06508861, -0.07438723, -0.06359288,
5297          -0.12526729, -0.11205668, -0.12179433, -0.11068104, -0.12048395, -0.10968948,
5298          -0.11912023, -0.10862628, -0.11784090, -0.10803744, -0.11790629, -0.10742354,
5299          -0.16859613, -0.15427413, -0.16664444, -0.15464452, -0.16570816, -0.15327556,
5300          -0.16409162, -0.15204092, -0.16264608, -0.15102139, -0.16162736, -0.14969205,
5301          -0.18736511, -0.19874036, -0.18811230, -0.19758289, -0.18590182, -0.19580301,
5302          -0.18234588, -0.19423215, -0.18100376, -0.19380116, -0.18509710, -0.19501636,
5303          -0.13982382, -0.14166819, -0.14132775, -0.14528694, -0.14096905, -0.14351126,
5304          -0.13800356, -0.14027920, -0.13613538, -0.13936795, -0.13621902, -0.14204982])
5305
5306                     
5307        assert num.allclose(domain.quantities['xmomentum'].centroid_values,
5308      [0.00600290,  0.00175780,  0.00591905,  0.00190903,  0.00644462,  0.00203095,
5309       0.00684561,  0.00225089,  0.00708208,  0.00236235,  0.00649095,  0.00222343,
5310       0.02068693,  0.01164034,  0.01983343,  0.01159526,  0.02044611,  0.01233252,
5311       0.02135685,  0.01301289,  0.02161290,  0.01260280,  0.01867612,  0.01133078,
5312       0.04091313,  0.02668283,  0.03634781,  0.02733469,  0.03767692,  0.02836840,
5313       0.03906338,  0.02958073,  0.04025669,  0.02953292,  0.03665616,  0.02583565,
5314       0.06314558,  0.04830935,  0.05663609,  0.04564362,  0.05756200,  0.04739673,
5315       0.05967379,  0.04919083,  0.06124330,  0.04965808,  0.05879240,  0.04629319,
5316       0.08220739,  0.06924725,  0.07713556,  0.06782640,  0.07909499,  0.06992544,
5317       0.08116621,  0.07210181,  0.08281548,  0.07222669,  0.07941059,  0.06755612,
5318       0.01581588,  0.04533609,  0.02017939,  0.04342565,  0.02073232,  0.04476108,
5319       0.02117439,  0.04573358,  0.02129473,  0.04694267,  0.02220398,  0.05533458])
5320
5321       
5322        assert num.allclose(domain.quantities['ymomentum'].centroid_values,
5323     [-7.65882069e-005, -1.46087080e-004, -1.09630102e-004, -7.80950424e-005,
5324      -1.15922807e-005, -9.09134899e-005, -1.35994542e-004, -1.95673476e-004,
5325      -4.25779199e-004, -2.95890312e-004, -4.00060341e-004, -9.42021290e-005,
5326      -3.41372596e-004, -1.54560195e-004, -2.94810038e-004, -1.08844546e-004,
5327      -6.97240892e-005,  3.50299623e-005, -2.40159184e-004, -2.01805883e-004,
5328      -7.60732405e-004, -5.10897642e-004, -1.00940001e-003, -1.38037759e-004,
5329      -1.06169131e-003, -3.12307760e-004, -9.90602307e-004, -4.21634250e-005,
5330      -6.02424239e-004,  1.52230578e-004, -7.63833035e-004, -1.10273481e-004,
5331      -1.40187071e-003, -5.57831837e-004, -1.63988285e-003, -2.48018092e-004,
5332      -1.83309840e-003, -6.19360836e-004, -1.29955242e-003, -3.76237145e-004,
5333      -1.00613007e-003, -8.63641918e-005, -1.13604124e-003, -3.90589728e-004,
5334      -1.91457355e-003, -9.43783961e-004, -2.28090840e-003, -5.79107025e-004,
5335      -1.54091533e-003, -2.39785792e-003, -2.47947427e-003, -2.02694009e-003,
5336      -2.10441194e-003, -1.82082650e-003, -1.80229336e-003, -2.10418336e-003,
5337      -1.93104408e-003, -2.23200334e-003, -1.57239706e-003, -1.31486358e-003,
5338      -1.17564993e-003, -2.85846494e-003, -3.52956754e-003, -5.12658193e-003,
5339      -6.24238960e-003, -6.01820113e-003, -6.09602201e-003, -5.04787190e-003,
5340      -4.59373845e-003, -3.01393146e-003,  5.08550095e-004, -4.35896549e-004])
5341
5342        os.remove(domain.get_name() + '.sww')
5343
5344
5345    def test_temp_play(self):
5346
5347        from mesh_factory import rectangular
5348
5349        #Create basic mesh
5350        points, vertices, boundary = rectangular(5, 5)
5351
5352        #Create shallow water domain
5353        domain = Domain(points, vertices, boundary)
5354        domain.smooth = False
5355        domain.default_order=2
5356        domain.beta_w      = 0.9
5357        domain.beta_w_dry  = 0.9
5358        domain.beta_uh     = 0.9
5359        domain.beta_uh_dry = 0.9
5360        domain.beta_vh     = 0.9
5361        domain.beta_vh_dry = 0.9
5362       
5363        # FIXME (Ole): Need tests where these two are commented out
5364        domain.H0 = 0        # Backwards compatibility (6/2/7)       
5365        domain.tight_slope_limiters = False # Backwards compatibility (14/4/7)
5366        domain.use_centroid_velocities = False # Backwards compatibility (7/5/8)
5367        domain.use_edge_limiter = False # Backwards compatibility (9/5/8)       
5368       
5369
5370        #Bed-slope and friction at vertices (and interpolated elsewhere)
5371        def x_slope(x, y):
5372            return -x/3
5373
5374        domain.set_quantity('elevation', x_slope)
5375
5376        # Boundary conditions
5377        Br = Reflective_boundary(domain)
5378        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
5379
5380        #Initial condition
5381        domain.set_quantity('stage', expression='elevation+0.05')
5382        domain.check_integrity()
5383
5384        #Evolution
5385        for t in domain.evolve(yieldstep = 0.05, finaltime = 0.1):
5386            pass
5387
5388        assert num.allclose(domain.quantities['stage'].centroid_values[:4],
5389                            [0.00206836, 0.01296714, 0.00363415, 0.01438924])
5390        #print domain.quantities['xmomentum'].centroid_values[:4]
5391        assert num.allclose(domain.quantities['xmomentum'].centroid_values[:4],
5392                            [0.01360154, 0.00671133, 0.01264578, 0.00648503])
5393        assert num.allclose(domain.quantities['ymomentum'].centroid_values[:4],
5394                            [-1.19201077e-003, -7.23647546e-004,
5395                            -6.39083123e-005, 6.29815168e-005])
5396
5397        os.remove(domain.get_name() + '.sww')
5398
5399    def test_complex_bed(self):
5400        #No friction is tested here
5401
5402        from mesh_factory import rectangular
5403
5404        N = 12
5405        points, vertices, boundary = rectangular(N, N/2, len1=1.2,len2=0.6,
5406                                                 origin=(-0.07, 0))
5407
5408
5409        domain = Domain(points, vertices, boundary)
5410        domain.smooth = False
5411        domain.default_order=2
5412
5413
5414        inflow_stage = 0.1
5415        Z = Weir(inflow_stage)
5416        domain.set_quantity('elevation', Z)
5417
5418        Br = Reflective_boundary(domain)
5419        Bd = Dirichlet_boundary([inflow_stage, 0.0, 0.0])
5420        domain.set_boundary({'left': Bd, 'right': Br, 'bottom': Br, 'top': Br})
5421
5422        domain.set_quantity('stage', expression='elevation')
5423
5424        for t in domain.evolve(yieldstep = 0.02, finaltime = 0.2):
5425            pass
5426
5427
5428        #print domain.quantities['stage'].centroid_values
5429
5430        #FIXME: These numbers were from version before 25/10
5431        #assert allclose(domain.quantities['stage'].centroid_values,
5432# [3.95822638e-002,  5.61022588e-002,  4.66437868e-002,  5.73081011e-002,
5433#  4.72394613e-002,  5.74684939e-002,  4.74309483e-002,  5.77458084e-002,
5434#  4.80628177e-002,  5.85656225e-002,  4.90498542e-002,  6.02609831e-002,
5435#  1.18470315e-002,  1.75136443e-002,  1.18035266e-002,  2.15565695e-002,
5436#  1.31620268e-002,  2.14351640e-002,  1.32351076e-002,  2.15450687e-002,
5437#  1.36414028e-002,  2.24274619e-002,  1.51689511e-002,  2.21789655e-002,
5438# -7.54337535e-003, -6.86362021e-004, -7.74146760e-003, -1.83756530e-003,
5439# -8.16773628e-003, -4.49916813e-004, -8.08202599e-003, -3.91118720e-004,
5440# -8.10292716e-003, -3.88584984e-004, -7.35226124e-003,  2.73985295e-004,
5441#  1.86166683e-001,  8.74070369e-002,  1.86166712e-001,  8.74035875e-002,
5442#  6.11666935e-002, -3.76173225e-002, -6.38333276e-002, -3.76147365e-002,
5443#  6.11666725e-002,  8.73846774e-002,  1.86166697e-001,  8.74171550e-002,
5444# -4.83333333e-002,  1.18333333e-001, -4.83333333e-002,  1.18333333e-001,
5445# -4.83333333e-002, -6.66666667e-003, -1.73333333e-001, -1.31666667e-001,
5446# -1.73333333e-001, -6.66666667e-003, -4.83333333e-002,  1.18333333e-001,
5447# -2.48333333e-001, -2.31666667e-001, -2.48333333e-001, -2.31666667e-001,
5448# -2.48333333e-001, -2.31666667e-001, -2.48333333e-001, -2.31666667e-001,
5449# -2.48333333e-001, -2.31666667e-001, -2.48333333e-001, -2.31666667e-001,
5450# -4.65000000e-001, -3.65000000e-001, -4.65000000e-001, -3.65000000e-001,
5451# -4.65000000e-001, -3.65000000e-001, -4.65000000e-001, -3.65000000e-001,
5452# -4.65000000e-001, -3.65000000e-001, -4.65000000e-001, -3.65000000e-001,
5453# -5.98333333e-001, -5.81666667e-001, -5.98333333e-001, -5.81666667e-001,
5454# -5.98333333e-001, -5.81666667e-001, -5.98333333e-001, -5.81666667e-001,
5455# -5.98333333e-001, -5.81666667e-001, -5.98333333e-001, -5.81666667e-001,
5456# -6.48333333e-001, -6.31666667e-001, -6.48333333e-001, -6.31666667e-001,
5457# -6.48333333e-001, -6.31666667e-001, -6.48333333e-001, -6.31666667e-001,
5458# -6.48333333e-001, -6.31666667e-001, -6.48333333e-001, -6.31666667e-001,
5459# -5.31666667e-001, -5.98333333e-001, -5.31666667e-001, -5.98333333e-001,
5460# -5.31666667e-001, -5.98333333e-001, -5.31666667e-001, -5.98333333e-001,
5461# -5.31666667e-001, -5.98333333e-001, -5.31666667e-001, -5.98333333e-001,
5462# -4.98333333e-001, -4.81666667e-001, -4.98333333e-001, -4.81666667e-001,
5463# -4.98333333e-001, -4.81666667e-001, -4.98333333e-001, -4.81666667e-001,
5464# -4.98333333e-001, -4.81666667e-001, -4.98333333e-001, -4.81666667e-001,
5465# -5.48333333e-001, -5.31666667e-001, -5.48333333e-001, -5.31666667e-001,
5466# -5.48333333e-001, -5.31666667e-001, -5.48333333e-001, -5.31666667e-001,
5467# -5.48333333e-001, -5.31666667e-001, -5.48333333e-001, -5.31666667e-001])
5468
5469        os.remove(domain.get_name() + '.sww')
5470
5471    def test_spatio_temporal_boundary_1(self):
5472        """Test that boundary values can be read from file and interpolated
5473        in both time and space.
5474
5475        Verify that the same steady state solution is arrived at and that
5476        time interpolation works.
5477
5478        The full solution history is not exactly the same as
5479        file boundary must read and interpolate from *smoothed* version
5480        as stored in sww.
5481        """
5482        import time
5483
5484        #Create sww file of simple propagation from left to right
5485        #through rectangular domain
5486
5487        from mesh_factory import rectangular
5488
5489        #Create basic mesh
5490        points, vertices, boundary = rectangular(3, 3)
5491
5492        #Create shallow water domain
5493        domain1 = Domain(points, vertices, boundary)
5494
5495        domain1.reduction = mean
5496        domain1.smooth = False  #Exact result
5497
5498        domain1.default_order = 2
5499        domain1.store = True
5500        domain1.set_datadir('.')
5501        domain1.set_name('spatio_temporal_boundary_source' + str(time.time()))
5502
5503        #FIXME: This is extremely important!
5504        #How can we test if they weren't stored?
5505        domain1.quantities_to_be_stored = ['stage', 'xmomentum', 'ymomentum']
5506
5507
5508        #Bed-slope and friction at vertices (and interpolated elsewhere)
5509        domain1.set_quantity('elevation', 0)
5510        domain1.set_quantity('friction', 0)
5511
5512        # Boundary conditions
5513        Br = Reflective_boundary(domain1)
5514        Bd = Dirichlet_boundary([0.3,0,0])
5515        domain1.set_boundary({'left': Bd, 'top': Bd, 'right': Br, 'bottom': Br})
5516        #Initial condition
5517        domain1.set_quantity('stage', 0)
5518        domain1.check_integrity()
5519
5520        finaltime = 5
5521        #Evolution  (full domain - large steps)
5522        for t in domain1.evolve(yieldstep = 0.671, finaltime = finaltime):
5523            pass
5524            #domain1.write_time()
5525
5526        cv1 = domain1.quantities['stage'].centroid_values
5527
5528
5529        #Create a triangle shaped domain (reusing coordinates from domain 1),
5530        #formed from the lower and right hand  boundaries and
5531        #the sw-ne diagonal
5532        #from domain 1. Call it domain2
5533
5534        points = [ [0,0], [1.0/3,0], [1.0/3,1.0/3],
5535                   [2.0/3,0], [2.0/3,1.0/3], [2.0/3,2.0/3],
5536                   [1,0], [1,1.0/3], [1,2.0/3], [1,1]]
5537
5538        vertices = [ [1,2,0], [3,4,1], [2,1,4], [4,5,2],
5539                     [6,7,3], [4,3,7], [7,8,4], [5,4,8], [8,9,5]]
5540
5541        boundary = { (0,1):'bottom', (1,1):'bottom', (4,1): 'bottom',
5542                     (4,2):'right', (6,2):'right', (8,2):'right',
5543                     (0,0):'diagonal', (3,0):'diagonal', (8,0):'diagonal'}
5544
5545        domain2 = Domain(points, vertices, boundary)
5546
5547        domain2.reduction = domain1.reduction
5548        domain2.smooth = False
5549        domain2.default_order = 2
5550
5551        #Bed-slope and friction at vertices (and interpolated elsewhere)
5552        domain2.set_quantity('elevation', 0)
5553        domain2.set_quantity('friction', 0)
5554        domain2.set_quantity('stage', 0)
5555
5556        # Boundary conditions
5557        Br = Reflective_boundary(domain2)
5558        #Bf = Spatio_temporal_boundary(domain1.get_name() + '.' +\
5559        #                              domain1.format, domain2)
5560        Bf = Field_boundary(domain1.get_name() + '.' +\
5561                            domain1.format, domain2)       
5562        domain2.set_boundary({'right':Br, 'bottom':Br, 'diagonal':Bf})
5563        domain2.check_integrity()
5564
5565
5566
5567        #Evolution (small steps)
5568        for t in domain2.evolve(yieldstep = 0.0711, finaltime = finaltime):
5569            pass
5570
5571
5572        #Use output from domain1 as spatio-temporal boundary for domain2
5573        #and verify that results at right hand side are close.
5574
5575        cv2 = domain2.quantities['stage'].centroid_values
5576
5577        #print take(cv1, (12,14,16))  #Right
5578        #print take(cv2, (4,6,8))
5579        #print take(cv1, (0,6,12))  #Bottom
5580        #print take(cv2, (0,1,4))
5581        #print take(cv1, (0,8,16))  #Diag
5582        #print take(cv2, (0,3,8))
5583
5584        assert num.allclose( num.take(cv1, (0,8,16)), num.take(cv2, (0,3,8))) #Diag
5585        assert num.allclose( num.take(cv1, (0,6,12)), num.take(cv2, (0,1,4))) #Bottom
5586        assert num.allclose( num.take(cv1, (12,14,16)), num.take(cv2, (4,6,8))) #RHS
5587
5588        #Cleanup
5589        os.remove(domain1.get_name() + '.' + domain1.format)
5590        os.remove(domain2.get_name() + '.' + domain2.format)       
5591
5592
5593
5594    def test_spatio_temporal_boundary_2(self):
5595        """Test that boundary values can be read from file and interpolated
5596        in both time and space.
5597        This is a more basic test, verifying that boundary object
5598        produces the expected results
5599
5600
5601        """
5602        import time
5603
5604        #Create sww file of simple propagation from left to right
5605        #through rectangular domain
5606
5607        from mesh_factory import rectangular
5608
5609        #Create basic mesh
5610        points, vertices, boundary = rectangular(3, 3)
5611
5612        #Create shallow water domain
5613        domain1 = Domain(points, vertices, boundary)
5614
5615        domain1.reduction = mean
5616        domain1.smooth = True #To mimic MOST output
5617
5618        domain1.default_order = 2
5619        domain1.store = True
5620        domain1.set_datadir('.')
5621        domain1.set_name('spatio_temporal_boundary_source' + str(time.time()))
5622
5623        #FIXME: This is extremely important!
5624        #How can we test if they weren't stored?
5625        domain1.quantities_to_be_stored = ['stage', 'xmomentum', 'ymomentum']
5626
5627
5628        #Bed-slope and friction at vertices (and interpolated elsewhere)
5629        domain1.set_quantity('elevation', 0)
5630        domain1.set_quantity('friction', 0)
5631
5632        # Boundary conditions
5633        Br = Reflective_boundary(domain1)
5634        Bd = Dirichlet_boundary([0.3,0,0])
5635        domain1.set_boundary({'left': Bd, 'top': Bd, 'right': Br, 'bottom': Br})
5636        #Initial condition
5637        domain1.set_quantity('stage', 0)
5638        domain1.check_integrity()
5639
5640        finaltime = 5
5641        #Evolution  (full domain - large steps)
5642        for t in domain1.evolve(yieldstep = 1, finaltime = finaltime):
5643            pass
5644            #domain1.write_time()
5645
5646
5647        #Create an triangle shaped domain (coinciding with some
5648        #coordinates from domain 1),
5649        #formed from the lower and right hand  boundaries and
5650        #the sw-ne diagonal
5651        #from domain 1. Call it domain2
5652
5653        points = [ [0,0], [1.0/3,0], [1.0/3,1.0/3],
5654                   [2.0/3,0], [2.0/3,1.0/3], [2.0/3,2.0/3],
5655                   [1,0], [1,1.0/3], [1,2.0/3], [1,1]]
5656
5657        vertices = [ [1,2,0],
5658                     [3,4,1], [2,1,4], [4,5,2],
5659                     [6,7,3], [4,3,7], [7,8,4], [5,4,8], [8,9,5]]
5660
5661        boundary = { (0,1):'bottom', (1,1):'bottom', (4,1): 'bottom',
5662                     (4,2):'right', (6,2):'right', (8,2):'right',
5663                     (0,0):'diagonal', (3,0):'diagonal', (8,0):'diagonal'}
5664
5665        domain2 = Domain(points, vertices, boundary)
5666
5667        domain2.reduction = domain1.reduction
5668        domain2.smooth = False
5669        domain2.default_order = 2
5670
5671        #Bed-slope and friction at vertices (and interpolated elsewhere)
5672        domain2.set_quantity('elevation', 0)
5673        domain2.set_quantity('friction', 0)
5674        domain2.set_quantity('stage', 0)
5675
5676
5677        #Read results for specific timesteps t=1 and t=2
5678        from Scientific.IO.NetCDF import NetCDFFile
5679        fid = NetCDFFile(domain1.get_name() + '.' + domain1.format)
5680
5681        x = fid.variables['x'][:]
5682        y = fid.variables['y'][:]
5683        s1 = fid.variables['stage'][1,:]
5684        s2 = fid.variables['stage'][2,:]
5685        fid.close()
5686
5687        shp = (len(x), 1)
5688        points = num.concatenate( (num.reshape(x, shp), num.reshape(y, shp)), axis=1)
5689        #The diagonal points of domain 1 are 0, 5, 10, 15
5690
5691        #print points[0], points[5], points[10], points[15]
5692        msg = ('value was %s,\nshould be [[0,0], [1.0/3, 1.0/3], '
5693               '[2.0/3, 2.0/3], [1,1]]' % str(num.take(points, [0,5,10,15])))
5694        assert num.allclose(num.take(points, [0,5,10,15]),
5695                            [[0,0], [1.0/3, 1.0/3], [2.0/3, 2.0/3], [1,1]]), msg
5696
5697
5698        # Boundary conditions
5699        Br = Reflective_boundary(domain2)
5700        #Bf = Spatio_temporal_boundary(domain1.get_name() + '.' + domain1.format,
5701        #                              domain2)
5702        Bf = Field_boundary(domain1.get_name() + '.' + domain1.format,
5703                            domain2, verbose=False)       
5704        domain2.set_boundary({'right':Br, 'bottom':Br, 'diagonal':Bf})
5705        domain2.check_integrity()
5706
5707        #Test that interpolation points are the mid points of the all boundary
5708        #segments
5709
5710        boundary_midpoints = [[1.0/6, 0], [1.0/2, 0], [5.0/6,0],
5711                              [1.0, 1.0/6], [1.0, 1.0/2], [1.0, 5.0/6],
5712                              [1.0/6, 1.0/6], [0.5, 0.5], [5.0/6, 5.0/6]]
5713
5714        boundary_midpoints.sort()
5715        R = Bf.F.interpolation_points.tolist()
5716        R.sort()
5717        assert num.allclose(boundary_midpoints, R)
5718
5719        #Check spatially interpolated output at time == 1
5720        domain2.time = 1
5721
5722        #First diagonal midpoint
5723        R0 = Bf.evaluate(0,0)
5724        assert num.allclose(R0[0], (s1[0] + s1[5])/2)
5725
5726        #Second diagonal midpoint
5727        R0 = Bf.evaluate(3,0)
5728        assert num.allclose(R0[0], (s1[5] + s1[10])/2)
5729
5730        #First diagonal midpoint
5731        R0 = Bf.evaluate(8,0)
5732        assert num.allclose(R0[0], (s1[10] + s1[15])/2)
5733
5734        #Check spatially interpolated output at time == 2
5735        domain2.time = 2
5736
5737        #First diagonal midpoint
5738        R0 = Bf.evaluate(0,0)
5739        assert num.allclose(R0[0], (s2[0] + s2[5])/2)
5740
5741        #Second diagonal midpoint
5742        R0 = Bf.evaluate(3,0)
5743        assert num.allclose(R0[0], (s2[5] + s2[10])/2)
5744
5745        #First diagonal midpoint
5746        R0 = Bf.evaluate(8,0)
5747        assert num.allclose(R0[0], (s2[10] + s2[15])/2)
5748
5749
5750        #Now check temporal interpolation
5751
5752        domain2.time = 1 + 2.0/3
5753
5754        #First diagonal midpoint
5755        R0 = Bf.evaluate(0,0)
5756        assert num.allclose(R0[0], ((s1[0] + s1[5])/2 + 2.0*(s2[0] + s2[5])/2)/3)
5757
5758        #Second diagonal midpoint
5759        R0 = Bf.evaluate(3,0)
5760        assert num.allclose(R0[0], ((s1[5] + s1[10])/2 + 2.0*(s2[5] + s2[10])/2)/3)
5761
5762        #First diagonal midpoint
5763        R0 = Bf.evaluate(8,0)
5764        assert num.allclose(R0[0], ((s1[10] + s1[15])/2 + 2.0*(s2[10] + s2[15])/2)/3)
5765
5766
5767
5768        #Cleanup
5769        os.remove(domain1.get_name() + '.' + domain1.format)
5770
5771
5772    def test_spatio_temporal_boundary_3(self):
5773        """Test that boundary values can be read from file and interpolated
5774        in both time and space.
5775        This is a more basic test, verifying that boundary object
5776        produces the expected results
5777
5778        This tests adjusting using mean_stage
5779
5780        """
5781
5782        import time
5783
5784        mean_stage = 5.2 # Adjust stage by this amount in boundary
5785
5786        #Create sww file of simple propagation from left to right
5787        #through rectangular domain
5788
5789        from mesh_factory import rectangular
5790
5791        #Create basic mesh
5792        points, vertices, boundary = rectangular(3, 3)
5793
5794        #Create shallow water domain
5795        domain1 = Domain(points, vertices, boundary)
5796
5797        domain1.reduction = mean
5798        domain1.smooth = True #To mimic MOST output
5799
5800        domain1.default_order = 2
5801        domain1.store = True
5802        domain1.set_datadir('.')
5803        domain1.set_name('spatio_temporal_boundary_source' + str(time.time()))
5804
5805        #FIXME: This is extremely important!
5806        #How can we test if they weren't stored?
5807        domain1.quantities_to_be_stored = ['stage', 'xmomentum', 'ymomentum']
5808
5809
5810        #Bed-slope and friction at vertices (and interpolated elsewhere)
5811        domain1.set_quantity('elevation', 0)
5812        domain1.set_quantity('friction', 0)
5813
5814        # Boundary conditions
5815        Br = Reflective_boundary(domain1)
5816        Bd = Dirichlet_boundary([0.3,0,0])
5817        domain1.set_boundary({'left': Bd, 'top': Bd, 'right': Br, 'bottom': Br})
5818        #Initial condition
5819        domain1.set_quantity('stage', 0)
5820        domain1.check_integrity()
5821
5822        finaltime = 5
5823        #Evolution  (full domain - large steps)
5824        for t in domain1.evolve(yieldstep = 1, finaltime = finaltime):
5825            pass
5826            #domain1.write_time()
5827
5828
5829        #Create an triangle shaped domain (coinciding with some
5830        #coordinates from domain 1),
5831        #formed from the lower and right hand  boundaries and
5832        #the sw-ne diagonal
5833        #from domain 1. Call it domain2
5834
5835        points = [ [0,0],
5836                   [1.0/3,0], [1.0/3,1.0/3],
5837                   [2.0/3,0], [2.0/3,1.0/3], [2.0/3,2.0/3],
5838                   [1,0],     [1,1.0/3],     [1,2.0/3],     [1,1]] 
5839                   
5840        vertices = [ [1,2,0],
5841                     [3,4,1], [2,1,4], [4,5,2],
5842                     [6,7,3], [4,3,7], [7,8,4], [5,4,8], [8,9,5]]
5843
5844        boundary = { (0,1):'bottom', (1,1):'bottom', (4,1): 'bottom',
5845                     (4,2):'right', (6,2):'right', (8,2):'right',
5846                     (0,0):'diagonal', (3,0):'diagonal', (8,0):'diagonal'}
5847
5848        domain2 = Domain(points, vertices, boundary)
5849
5850        domain2.reduction = domain1.reduction
5851        domain2.smooth = False
5852        domain2.default_order = 2
5853
5854        #Bed-slope and friction at vertices (and interpolated elsewhere)
5855        domain2.set_quantity('elevation', 0)
5856        domain2.set_quantity('friction', 0)
5857        domain2.set_quantity('stage', 0)
5858
5859
5860        #Read results for specific timesteps t=1 and t=2
5861        from Scientific.IO.NetCDF import NetCDFFile
5862        fid = NetCDFFile(domain1.get_name() + '.' + domain1.format)
5863
5864        x = fid.variables['x'][:]
5865        y = fid.variables['y'][:]
5866        s1 = fid.variables['stage'][1,:]
5867        s2 = fid.variables['stage'][2,:]
5868        fid.close()
5869
5870        shp = (len(x), 1)
5871        points = num.concatenate( (num.reshape(x, shp), num.reshape(y, shp)), axis=1)
5872        #The diagonal points of domain 1 are 0, 5, 10, 15
5873
5874        #print points[0], points[5], points[10], points[15]
5875        msg = ('values was %s,\nshould be [[0,0], [1.0/3, 1.0/3], '
5876               '[2.0/3, 2.0/3], [1,1]]' % str(num.take(points, [0,5,10,15])))
5877        assert num.allclose(num.take(points, [0,5,10,15]),
5878                            [[0,0], [1.0/3, 1.0/3], [2.0/3, 2.0/3], [1,1]]), msg
5879
5880
5881        # Boundary conditions
5882        Br = Reflective_boundary(domain2)
5883        #Bf = Spatio_temporal_boundary(domain1.get_name() + '.' + domain1.format,
5884        #                              domain2)
5885        Bf = Field_boundary(domain1.get_name() + '.' + domain1.format,
5886                            domain2, mean_stage=mean_stage, verbose=False)
5887       
5888        domain2.set_boundary({'right':Br, 'bottom':Br, 'diagonal':Bf})
5889        domain2.check_integrity()
5890
5891        #Test that interpolation points are the mid points of the all boundary
5892        #segments
5893
5894        boundary_midpoints = [[1.0/6, 0], [1.0/2, 0], [5.0/6,0],
5895                              [1.0, 1.0/6], [1.0, 1.0/2], [1.0, 5.0/6],
5896                              [1.0/6, 1.0/6], [0.5, 0.5], [5.0/6, 5.0/6]]
5897
5898        boundary_midpoints.sort()
5899        R = Bf.F.interpolation_points.tolist()
5900        R.sort()
5901        assert num.allclose(boundary_midpoints, R)
5902
5903        #Check spatially interpolated output at time == 1
5904        domain2.time = 1
5905
5906        #First diagonal midpoint
5907        R0 = Bf.evaluate(0,0)
5908        assert num.allclose(R0[0], (s1[0] + s1[5])/2 + mean_stage)
5909
5910        #Second diagonal midpoint
5911        R0 = Bf.evaluate(3,0)
5912        assert num.allclose(R0[0], (s1[5] + s1[10])/2 + mean_stage)
5913
5914        #First diagonal midpoint
5915        R0 = Bf.evaluate(8,0)
5916        assert num.allclose(R0[0], (s1[10] + s1[15])/2 + mean_stage)
5917
5918        #Check spatially interpolated output at time == 2
5919        domain2.time = 2
5920
5921        #First diagonal midpoint
5922        R0 = Bf.evaluate(0,0)
5923        assert num.allclose(R0[0], (s2[0] + s2[5])/2 + mean_stage)
5924
5925        #Second diagonal midpoint
5926        R0 = Bf.evaluate(3,0)
5927        assert num.allclose(R0[0], (s2[5] + s2[10])/2 + mean_stage)
5928
5929        #First diagonal midpoint
5930        R0 = Bf.evaluate(8,0)
5931        assert num.allclose(R0[0], (s2[10] + s2[15])/2 + mean_stage)
5932
5933
5934        #Now check temporal interpolation
5935
5936        domain2.time = 1 + 2.0/3
5937
5938        #First diagonal midpoint
5939        R0 = Bf.evaluate(0,0)
5940        assert num.allclose(R0[0], ((s1[0] + s1[5])/2 + 2.0*(s2[0] + s2[5])/2)/3 + mean_stage)
5941
5942        #Second diagonal midpoint
5943        R0 = Bf.evaluate(3,0)
5944        assert num.allclose(R0[0], ((s1[5] + s1[10])/2 + 2.0*(s2[5] + s2[10])/2)/3 + mean_stage)
5945
5946        #First diagonal midpoint
5947        R0 = Bf.evaluate(8,0)
5948        assert num.allclose(R0[0], ((s1[10] + s1[15])/2 + 2.0*(s2[10] + s2[15])/2)/3 + mean_stage)
5949
5950
5951        #Cleanup
5952        os.remove(domain1.get_name() + '.' + domain1.format)
5953
5954
5955    def test_spatio_temporal_boundary_outside(self):
5956        """Test that field_boundary catches if a point is outside the sww that defines it
5957        """
5958
5959        import time
5960        #Create sww file of simple propagation from left to right
5961        #through rectangular domain
5962
5963        from mesh_factory import rectangular
5964
5965        #Create basic mesh
5966        points, vertices, boundary = rectangular(3, 3)
5967
5968        #Create shallow water domain
5969        domain1 = Domain(points, vertices, boundary)
5970
5971        domain1.reduction = mean
5972        domain1.smooth = True #To mimic MOST output
5973
5974        domain1.default_order = 2
5975        domain1.store = True
5976        domain1.set_datadir('.')
5977        domain1.set_name('spatio_temporal_boundary_source' + str(time.time()))
5978
5979        #FIXME: This is extremely important!
5980        #How can we test if they weren't stored?
5981        domain1.quantities_to_be_stored = ['stage', 'xmomentum', 'ymomentum']
5982
5983
5984        #Bed-slope and friction at vertices (and interpolated elsewhere)
5985        domain1.set_quantity('elevation', 0)
5986        domain1.set_quantity('friction', 0)
5987
5988        # Boundary conditions
5989        Br = Reflective_boundary(domain1)
5990        Bd = Dirichlet_boundary([0.3,0,0])
5991        domain1.set_boundary({'left': Bd, 'top': Bd, 'right': Br, 'bottom': Br})
5992        #Initial condition
5993        domain1.set_quantity('stage', 0)
5994        domain1.check_integrity()
5995
5996        finaltime = 5
5997        #Evolution  (full domain - large steps)
5998        for t in domain1.evolve(yieldstep = 1, finaltime = finaltime):
5999            pass
6000            #domain1.write_time()
6001
6002
6003        #Create an triangle shaped domain (coinciding with some
6004        #coordinates from domain 1, but one edge outside!),
6005        #formed from the lower and right hand  boundaries and
6006        #the sw-ne diagonal as in the previous test but scaled
6007        #in the x direction by a factor of 2
6008
6009        points = [ [0,0],
6010                   [2.0/3,0], [2.0/3,1.0/3],
6011                   [4.0/3,0], [4.0/3,1.0/3], [4.0/3,2.0/3],
6012                   [2,0],     [2,1.0/3],     [2,2.0/3],     [2,1] 
6013                   ]
6014
6015        vertices = [ [1,2,0],
6016                     [3,4,1], [2,1,4], [4,5,2],
6017                     [6,7,3], [4,3,7], [7,8,4], [5,4,8], [8,9,5]]
6018
6019        boundary = { (0,1):'bottom', (1,1):'bottom', (4,1): 'bottom',
6020                     (4,2):'right', (6,2):'right', (8,2):'right',
6021                     (0,0):'diagonal', (3,0):'diagonal', (8,0):'diagonal'}
6022
6023        domain2 = Domain(points, vertices, boundary)
6024
6025        domain2.reduction = domain1.reduction
6026        domain2.smooth = False
6027        domain2.default_order = 2
6028
6029        #Bed-slope and friction at vertices (and interpolated elsewhere)
6030        domain2.set_quantity('elevation', 0)
6031        domain2.set_quantity('friction', 0)
6032        domain2.set_quantity('stage', 0)
6033
6034
6035        #Read results for specific timesteps t=1 and t=2
6036        from Scientific.IO.NetCDF import NetCDFFile
6037        fid = NetCDFFile(domain1.get_name() + '.' + domain1.format)
6038
6039        x = fid.variables['x'][:]
6040        y = fid.variables['y'][:]
6041        s1 = fid.variables['stage'][1,:]
6042        s2 = fid.variables['stage'][2,:]
6043        fid.close()
6044
6045        shp = (len(x), 1)
6046        points = num.concatenate( (num.reshape(x, shp), num.reshape(y, shp)), axis=1)
6047        #The diagonal points of domain 1 are 0, 5, 10, 15
6048
6049        #print points[0], points[5], points[10], points[15]
6050        msg = ('value was %s,\nshould be [[0,0], [1.0/3, 1.0/3], '
6051               '[2.0/3, 2.0/3], [1,1]]' % str(num.take(points, [0,5,10,15])))
6052        assert num.allclose(num.take(points, [0,5,10,15]),
6053                            [[0,0], [1.0/3, 1.0/3], [2.0/3, 2.0/3], [1,1]]), msg
6054
6055
6056
6057        # Boundary conditions
6058        Br = Reflective_boundary(domain2)
6059        #Bf = Spatio_temporal_boundary(domain1.get_name() + '.' + domain1.format,
6060        #                              domain2)
6061        Bf = Field_boundary(domain1.get_name() + '.' + domain1.format,
6062                            domain2, mean_stage=1, verbose=False)
6063       
6064        domain2.set_boundary({'right':Br, 'bottom':Br, 'diagonal':Bf})
6065        domain2.check_integrity()
6066
6067        try:
6068            for t in domain2.evolve(yieldstep = 1, finaltime = finaltime):
6069                pass
6070        except:
6071            pass
6072        else:
6073            msg = 'This should have caught NAN at boundary'
6074            raise Exception, msg
6075
6076
6077        #Cleanup
6078        os.remove(domain1.get_name() + '.' + domain1.format)
6079
6080
6081
6082
6083    def test_extrema(self):
6084        """Test that extrema of quantities are computed correctly
6085        Extrema are updated at every *internal* timestep
6086        """
6087
6088        from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross
6089
6090        initial_runup_height = -0.4
6091        final_runup_height = -0.3
6092
6093
6094        #--------------------------------------------------------------
6095        # Setup computational domain
6096        #--------------------------------------------------------------
6097        N = 5
6098        points, vertices, boundary = rectangular_cross(N, N) 
6099        domain = Domain(points, vertices, boundary)
6100        domain.set_name('extrema_test')
6101
6102        #--------------------------------------------------------------
6103        # Setup initial conditions
6104        #--------------------------------------------------------------
6105        def topography(x,y):
6106            return -x/2                             # linear bed slope
6107           
6108
6109        domain.set_quantity('elevation', topography)       # Use function for elevation
6110        domain.set_quantity('friction', 0.)                # Zero friction
6111        domain.set_quantity('stage', initial_runup_height) # Constant negative initial stage
6112        domain.set_quantities_to_be_monitored(['stage', 'stage-elevation'],
6113                                              time_interval = [0.5, 2.7],
6114                                              polygon = [[0,0], [0,1], [1,1], [1,0]])
6115       
6116        assert len(domain.quantities_to_be_monitored) == 2
6117        assert domain.quantities_to_be_monitored.has_key('stage')
6118        assert domain.quantities_to_be_monitored.has_key('stage-elevation')
6119        for key in domain.quantities_to_be_monitored['stage'].keys():
6120            assert domain.quantities_to_be_monitored['stage'][key] is None       
6121
6122
6123        #--------------------------------------------------------------
6124        # Setup boundary conditions
6125        #--------------------------------------------------------------
6126        Br = Reflective_boundary(domain)              # Reflective wall
6127        Bd = Dirichlet_boundary([final_runup_height,  # Constant inflow
6128                                 0,
6129                                 0])
6130
6131        # All reflective to begin with (still water)
6132        domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
6133
6134
6135        #--------------------------------------------------------------
6136        # Let triangles adjust and check extrema
6137        #--------------------------------------------------------------
6138        for t in domain.evolve(yieldstep = 0.1, finaltime = 1.0):
6139            domain.quantity_statistics() # Run it silently
6140
6141
6142
6143        #--------------------------------------------------------------
6144        # Test extrema
6145        #--------------------------------------------------------------
6146
6147        stage = domain.quantities_to_be_monitored['stage']
6148        assert stage['min'] <= stage['max']
6149
6150        #print stage['min'], stage['max']
6151        assert num.allclose(stage['min'], initial_runup_height,
6152                            rtol = 1.0/N) # First order accuracy
6153
6154
6155        depth = domain.quantities_to_be_monitored['stage-elevation']
6156        assert depth['min'] <= depth['max'] 
6157        assert depth['min'] >= 0.0
6158        assert depth['max'] >= 0.0       
6159        ##assert depth[1] <= ?? initial_runup_height       
6160
6161
6162        #--------------------------------------------------------------
6163        # Update boundary to allow inflow
6164        #--------------------------------------------------------------
6165        domain.set_boundary({'right': Bd})
6166
6167       
6168        #--------------------------------------------------------------
6169        # Evolve system through time
6170        #--------------------------------------------------------------
6171        for t in domain.evolve(yieldstep = 0.1, finaltime = 3.0):
6172            #domain.write_time()
6173            domain.quantity_statistics() # Run it silently           
6174           
6175   
6176        #--------------------------------------------------------------
6177        # Test extrema again
6178        #--------------------------------------------------------------
6179
6180        stage = domain.quantities_to_be_monitored['stage']
6181        assert stage['min'] <= stage['max']
6182
6183        assert num.allclose(stage['min'], initial_runup_height,
6184                            rtol = 1.0/N) # First order accuracy       
6185
6186        depth = domain.quantities_to_be_monitored['stage-elevation']
6187        assert depth['min'] <= depth['max'] 
6188        assert depth['min'] >= 0.0
6189        assert depth['max'] >= 0.0       
6190
6191        #Cleanup
6192        os.remove(domain.get_name() + '.' + domain.format)
6193       
6194
6195
6196    def test_tight_slope_limiters(self):
6197        """Test that new slope limiters (Feb 2007) don't induce extremely
6198        small timesteps. This test actually reveals the problem as it
6199        was in March-April 2007
6200        """
6201
6202        import time, os
6203        from Scientific.IO.NetCDF import NetCDFFile
6204        from data_manager import get_dataobject, extent_sww
6205        from mesh_factory import rectangular
6206
6207       
6208        #Create basic mesh
6209        points, vertices, boundary = rectangular(2, 2)
6210
6211        #Create shallow water domain
6212        domain = Domain(points, vertices, boundary)
6213        domain.default_order = 2
6214
6215        # This will pass
6216        #domain.tight_slope_limiters = 1
6217        #domain.H0 = 0.01
6218       
6219        # This will fail
6220        #domain.tight_slope_limiters = 1
6221        #domain.H0 = 0.001
6222
6223        # This will pass provided C extension implements limiting of
6224        # momentum in _compute_speeds
6225        domain.tight_slope_limiters = 1
6226        domain.H0 = 0.001       
6227        domain.protect_against_isolated_degenerate_timesteps = True       
6228
6229        #Set some field values
6230        domain.set_quantity('elevation', lambda x,y: -x)
6231        domain.set_quantity('friction', 0.03)
6232
6233
6234        ######################
6235        # Boundary conditions
6236        B = Transmissive_boundary(domain)
6237        domain.set_boundary( {'left': B, 'right': B, 'top': B, 'bottom': B})
6238
6239
6240        ######################
6241        #Initial condition - with jumps
6242
6243
6244        bed = domain.quantities['elevation'].vertex_values
6245        stage = num.zeros(bed.shape, num.float)
6246
6247        h = 0.3
6248        for i in range(stage.shape[0]):
6249            if i % 2 == 0:
6250                stage[i,:] = bed[i,:] + h
6251            else:
6252                stage[i,:] = bed[i,:]
6253
6254        domain.set_quantity('stage', stage)
6255
6256
6257        domain.distribute_to_vertices_and_edges()               
6258
6259       
6260
6261        domain.set_name('tight_limiters')
6262        domain.format = 'sww'
6263        domain.smooth = True
6264        domain.reduction = mean
6265        domain.set_datadir('.')
6266        domain.smooth = False
6267        domain.store = True
6268       
6269
6270        #Evolution
6271        for t in domain.evolve(yieldstep = 0.1, finaltime = 0.3):
6272           
6273            #domain.write_time(track_speeds=True)
6274            stage = domain.quantities['stage'].vertex_values
6275
6276            #Get NetCDF
6277            fid = NetCDFFile(domain.writer.filename, netcdf_mode_r)
6278            stage_file = fid.variables['stage']
6279           
6280            fid.close()
6281
6282        os.remove(domain.writer.filename)
6283
6284
6285    def test_pmesh2Domain(self):
6286         import os
6287         import tempfile
6288
6289         fileName = tempfile.mktemp(".tsh")
6290         file = open(fileName,"w")
6291         file.write("4 3 # <vertex #> <x> <y> [attributes]\n \
62920 0.0 0.0 0.0 0.0 0.01 \n \
62931 1.0 0.0 10.0 10.0 0.02  \n \
62942 0.0 1.0 0.0 10.0 0.03  \n \
62953 0.5 0.25 8.0 12.0 0.04  \n \
6296# Vert att title  \n \
6297elevation  \n \
6298stage  \n \
6299friction  \n \
63002 # <triangle #> [<vertex #>] [<neigbouring triangle #>]  \n\
63010 0 3 2 -1  -1  1 dsg\n\
63021 0 1 3 -1  0 -1   ole nielsen\n\
63034 # <segment #> <vertex #>  <vertex #> [boundary tag] \n\
63040 1 0 2 \n\
63051 0 2 3 \n\
63062 2 3 \n\
63073 3 1 1 \n\
63083 0 # <x> <y> [attributes] ...Mesh Vertices... \n \
63090 216.0 -86.0 \n \
63101 160.0 -167.0 \n \
63112 114.0 -91.0 \n \
63123 # <vertex #>  <vertex #> [boundary tag] ...Mesh Segments... \n \
63130 0 1 0 \n \
63141 1 2 0 \n \
63152 2 0 0 \n \
63160 # <x> <y> ...Mesh Holes... \n \
63170 # <x> <y> <attribute>...Mesh Regions... \n \
63180 # <x> <y> <attribute>...Mesh Regions, area... \n\
6319#Geo reference \n \
632056 \n \
6321140 \n \
6322120 \n")
6323         file.close()
6324
6325         tags = {}
6326         b1 =  Dirichlet_boundary(conserved_quantities = num.array([0.0]))
6327         b2 =  Dirichlet_boundary(conserved_quantities = num.array([1.0]))
6328         b3 =  Dirichlet_boundary(conserved_quantities = num.array([2.0]))
6329         tags["1"] = b1
6330         tags["2"] = b2
6331         tags["3"] = b3
6332
6333         #from anuga.abstract_2d_finite_volumes.pmesh2domain import pmesh_to_domain_instance
6334         #domain = pmesh_to_domain_instance(fileName, Domain)
6335
6336         domain = Domain(mesh_filename=fileName)
6337                         #verbose=True, use_cache=True)
6338         
6339         #print "domain.tagged_elements", domain.tagged_elements
6340         ## check the quantities
6341         #print domain.quantities['elevation'].vertex_values
6342         answer = [[0., 8., 0.],
6343                   [0., 10., 8.]]
6344         assert num.allclose(domain.quantities['elevation'].vertex_values,
6345                             answer)
6346
6347         #print domain.quantities['stage'].vertex_values
6348         answer = [[0., 12., 10.],
6349                   [0., 10., 12.]]
6350         assert num.allclose(domain.quantities['stage'].vertex_values,
6351                             answer)
6352
6353         #print domain.quantities['friction'].vertex_values
6354         answer = [[0.01, 0.04, 0.03],
6355                   [0.01, 0.02, 0.04]]
6356         assert num.allclose(domain.quantities['friction'].vertex_values,
6357                             answer)
6358
6359         #print domain.quantities['friction'].vertex_values
6360         tagged_elements = domain.get_tagged_elements()
6361         assert num.allclose(tagged_elements['dsg'][0],0)
6362         assert num.allclose(tagged_elements['ole nielsen'][0],1)
6363
6364         self.failUnless( domain.boundary[(1, 0)]  == '1',
6365                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
6366         self.failUnless( domain.boundary[(1, 2)]  == '2',
6367                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
6368         self.failUnless( domain.boundary[(0, 1)]  == '3',
6369                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
6370         self.failUnless( domain.boundary[(0, 0)]  == 'exterior',
6371                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
6372         #print "domain.boundary",domain.boundary
6373         self.failUnless( len(domain.boundary)  == 4,
6374                          "test_pmesh2Domain Too many boundaries")
6375         #FIXME change to use get_xllcorner
6376         #print "d.geo_reference.xllcorner",domain.geo_reference.xllcorner
6377         self.failUnless(domain.geo_reference.xllcorner  == 140.0,
6378                          "bad geo_referece")
6379
6380
6381         #************
6382
6383   
6384         domain = Domain(fileName)
6385         
6386         #print "domain.tagged_elements", domain.tagged_elements
6387         ## check the quantities
6388         #print domain.quantities['elevation'].vertex_values
6389         answer = [[0., 8., 0.],
6390                   [0., 10., 8.]]
6391         assert num.allclose(domain.quantities['elevation'].vertex_values,
6392                             answer)
6393
6394         #print domain.quantities['stage'].vertex_values
6395         answer = [[0., 12., 10.],
6396                   [0., 10., 12.]]
6397         assert num.allclose(domain.quantities['stage'].vertex_values,
6398                             answer)
6399
6400         #print domain.quantities['friction'].vertex_values
6401         answer = [[0.01, 0.04, 0.03],
6402                   [0.01, 0.02, 0.04]]
6403         assert num.allclose(domain.quantities['friction'].vertex_values,
6404                             answer)
6405
6406         #print domain.quantities['friction'].vertex_values
6407         tagged_elements = domain.get_tagged_elements()         
6408         assert num.allclose(tagged_elements['dsg'][0],0)
6409         assert num.allclose(tagged_elements['ole nielsen'][0],1)
6410
6411         self.failUnless( domain.boundary[(1, 0)]  == '1',
6412                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
6413         self.failUnless( domain.boundary[(1, 2)]  == '2',
6414                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
6415         self.failUnless( domain.boundary[(0, 1)]  == '3',
6416                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
6417         self.failUnless( domain.boundary[(0, 0)]  == 'exterior',
6418                          "test_tags_to_boundaries  failed. Single boundary wasn't added.")
6419         #print "domain.boundary",domain.boundary
6420         self.failUnless( len(domain.boundary)  == 4,
6421                          "test_pmesh2Domain Too many boundaries")
6422         #FIXME change to use get_xllcorner
6423         #print "d.geo_reference.xllcorner",domain.geo_reference.xllcorner
6424         self.failUnless(domain.geo_reference.xllcorner  == 140.0,
6425                          "bad geo_referece")
6426         #************
6427         os.remove(fileName)
6428
6429        #-------------------------------------------------------------
6430
6431    def test_get_lone_vertices(self):
6432       
6433        a = [0.0, 0.0]
6434        b = [0.0, 2.0]
6435        c = [2.0,0.0]
6436        d = [0.0, 4.0]
6437        e = [2.0, 2.0]
6438        f = [4.0,0.0]
6439
6440        points = [a, b, c, d, e, f]
6441        #bac, bce, ecf, dbe
6442        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
6443        boundary = { (0, 0): 'Third',
6444                     (0, 2): 'First',
6445                     (2, 0): 'Second',
6446                     (2, 1): 'Second',
6447                     (3, 1): 'Second',
6448                     (3, 2): 'Third'}
6449
6450
6451        domain = Domain(points, vertices, boundary)
6452        #domain.check_integrity()
6453        domain.get_lone_vertices()
6454
6455       
6456    def test_fitting_using_shallow_water_domain(self):
6457       
6458        #Mesh in zone 56 (absolute coords)
6459
6460        x0 = 314036.58727982
6461        y0 = 6224951.2960092
6462
6463        a = [x0+0.0, y0+0.0]
6464        b = [x0+0.0, y0+2.0]
6465        c = [x0+2.0, y0+0.0]
6466        d = [x0+0.0, y0+4.0]
6467        e = [x0+2.0, y0+2.0]
6468        f = [x0+4.0, y0+0.0]
6469
6470        points = [a, b, c, d, e, f]
6471
6472        #bac, bce, ecf, dbe
6473        elements = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4] ]
6474
6475        #absolute going in ..
6476        mesh4 = Domain(points, elements,
6477                       geo_reference = Geo_reference(56, 0, 0))
6478        mesh4.check_integrity()
6479        quantity = Quantity(mesh4)
6480
6481        #Get (enough) datapoints (relative to georef)
6482        data_points_rel = [[ 0.66666667, 0.66666667],
6483                       [ 1.33333333, 1.33333333],
6484                       [ 2.66666667, 0.66666667],
6485                       [ 0.66666667, 2.66666667],
6486                       [ 0.0, 1.0],
6487                       [ 0.0, 3.0],
6488                       [ 1.0, 0.0],
6489                       [ 1.0, 1.0],
6490                       [ 1.0, 2.0],
6491                       [ 1.0, 3.0],
6492                       [ 2.0, 1.0],
6493                       [ 3.0, 0.0],
6494                       [ 3.0, 1.0]]
6495
6496        data_geo_spatial = Geospatial_data(data_points_rel,
6497                                           geo_reference = Geo_reference(56, x0, y0))
6498        data_points_absolute = data_geo_spatial.get_data_points(absolute=True)
6499        attributes = linear_function(data_points_absolute)
6500        att = 'spam_and_eggs'
6501       
6502        #Create .txt file
6503        ptsfile = tempfile.mktemp(".txt")
6504        file = open(ptsfile,"w")
6505        file.write(" x,y," + att + " \n")
6506        for data_point, attribute in map(None, data_points_absolute
6507                                         ,attributes):
6508            row = str(data_point[0]) + ',' + str(data_point[1]) \
6509                  + ',' + str(attribute)
6510            file.write(row + "\n")
6511        file.close()
6512
6513        #file = open(ptsfile, 'r')
6514        #lines = file.readlines()
6515        #file.close()
6516     
6517
6518        #Check that values can be set from file
6519        quantity.set_values(filename = ptsfile,
6520                            attribute_name = att, alpha = 0)
6521        answer = linear_function(quantity.domain.get_vertex_coordinates())
6522
6523        assert num.allclose(quantity.vertex_values.flat, answer)
6524
6525
6526        #Check that values can be set from file using default attribute
6527        quantity.set_values(filename = ptsfile, alpha = 0)
6528        assert num.allclose(quantity.vertex_values.flat, answer)
6529
6530        #Cleanup
6531        import os
6532        os.remove(ptsfile)
6533
6534    def test_fitting_example_that_crashed(self):
6535        """test_fitting_example_that_crashed
6536       
6537        This unit test has been derived from a real world example (the Towradgi '98 rainstorm simulation).
6538       
6539        It shows a condition where fitting as called from set_quantity crashes when ANUGA mesh
6540        is reused. The test passes in the case where a new mesh is created.
6541       
6542        See ticket:314
6543        """
6544
6545        verbose = False       
6546
6547        from anuga.shallow_water import Domain
6548        from anuga.pmesh.mesh_interface import create_mesh_from_regions
6549        from anuga.geospatial_data.geospatial_data import Geospatial_data
6550
6551
6552        #------------------------------------------------------------------------------
6553        # Create domain
6554        #------------------------------------------------------------------------------
6555
6556        W=303400
6557        N=6195800
6558        E=308640
6559        S=6193120
6560        bounding_polygon = [[W, S], [E, S], [E, N], [W, N]]
6561
6562
6563        offending_regions = []
6564        # From culvert 8
6565        offending_regions.append([[307611.43896231, 6193631.6894806],
6566                                 [307600.11394969, 6193608.2855474],
6567                                 [307597.41349586, 6193609.59227963],
6568                                 [307608.73850848, 6193632.99621282]])
6569        offending_regions.append([[307633.69143231, 6193620.9216536],
6570                                 [307622.36641969, 6193597.5177204],
6571                                 [307625.06687352, 6193596.21098818],
6572                                 [307636.39188614, 6193619.61492137]])
6573        # From culvert 9
6574        offending_regions.append([[306326.69660524, 6194818.62900522],
6575                                 [306324.67939476, 6194804.37099478],
6576                                 [306323.75856492, 6194804.50127295],
6577                                 [306325.7757754, 6194818.7592834]])
6578        offending_regions.append([[306365.57160524, 6194813.12900522],
6579                                 [306363.55439476, 6194798.87099478],
6580                                 [306364.4752246, 6194798.7407166],
6581                                 [306366.49243508, 6194812.99872705]])
6582        # From culvert 10                         
6583        offending_regions.append([[306955.071019428608, 6194465.704096679576],
6584                                 [306951.616980571358, 6194457.295903320424],
6585                                 [306950.044491164153, 6194457.941873183474],
6586                                 [306953.498530021403, 6194466.350066542625]])
6587        offending_regions.append([[307002.540019428649, 6194446.204096679576],
6588                                 [306999.085980571399, 6194437.795903320424],
6589                                 [307000.658469978604, 6194437.149933457375],
6590                                 [307004.112508835853, 6194445.558126816526]])
6591
6592        interior_regions = []
6593        for polygon in offending_regions:
6594            interior_regions.append( [polygon, 100] ) 
6595
6596        meshname = 'offending_mesh.msh'
6597        create_mesh_from_regions(bounding_polygon,
6598                                 boundary_tags={'south': [0], 'east': [1], 'north': [2], 'west': [3]},
6599                                 maximum_triangle_area=1000000,
6600                                 interior_regions=interior_regions,
6601                                 filename=meshname,
6602                                 use_cache=False,
6603                                 verbose=verbose)
6604
6605        domain = Domain(meshname, use_cache=False, verbose=verbose)
6606
6607
6608        #------------------------------------------------------------------------------
6609        # Fit data point to mesh
6610        #------------------------------------------------------------------------------
6611
6612        points_file = 'offending_point.pts'
6613
6614        G=Geospatial_data(data_points=[[306953.344, 6194461.5]], # Offending point
6615                          attributes=[1])
6616        G.export_points_file(points_file)
6617
6618        domain.set_quantity('elevation', 
6619                            filename=points_file,
6620                            use_cache=False,
6621                            verbose=verbose,
6622                            alpha=0.01)
6623
6624       
6625
6626       
6627if __name__ == "__main__":
6628
6629    suite = unittest.makeSuite(Test_Shallow_Water, 'test')
6630    #suite = unittest.makeSuite(Test_Shallow_Water, 'test_rainfall_forcing_with_evolve')
6631    #suite = unittest.makeSuite(Test_Shallow_Water,'test_get_energy_through_cross_section_with_g')   
6632    #suite = unittest.makeSuite(Test_Shallow_Water,'test_fitting_using_shallow_water_domain')   
6633    #suite = unittest.makeSuite(Test_Shallow_Water,'test_tight_slope_limiters')
6634    #suite = unittest.makeSuite(Test_Shallow_Water,'test_inflow_outflow_conservation')
6635    #suite = unittest.makeSuite(Test_Shallow_Water,'test_outflow_conservation_problem_temp')   
6636   
6637
6638   
6639    runner = unittest.TextTestRunner(verbosity=1)   
6640    runner.run(suite)
Note: See TracBrowser for help on using the repository browser.