source: anuga_core/source/anuga/shallow_water_balanced/swb_domain.py @ 7573

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

Committing a version of shallow_water_balanced which passes it unit test
using a version of edge limiting which doesn't limit boundary edges. THis
is useful to allow linear functions to be reconstructed.

Had to play with the transmissive BC and use centroid values which is
set via domain set_centroid_transmissive_bc

File size: 9.1 KB
Line 
1
2from anuga.shallow_water.shallow_water_domain import *
3from anuga.shallow_water.shallow_water_domain import Domain as Sww_domain
4
5from swb_boundary_conditions import Transmissive_boundary
6
7##############################################################################
8# Shallow Water Balanced Domain
9#
10# Uses extra evolved quantities height, elevation, xvelocity, yvelocity
11##############################################################################
12
13##
14# @brief Class for a shallow water balanced domain.
15class Domain(Sww_domain):
16
17    ##
18    # @brief Instantiate a shallow water balanced domain.
19    # @param coordinates
20    # @param vertices
21    # @param boundary
22    # @param tagged_elements
23    # @param geo_reference
24    # @param use_inscribed_circle
25    # @param mesh_filename
26    # @param use_cache
27    # @param verbose
28    # @param full_send_dict
29    # @param ghost_recv_dict
30    # @param processor
31    # @param numproc
32    # @param number_of_full_nodes
33    # @param number_of_full_triangles
34    def __init__(self,
35                 coordinates=None,
36                 vertices=None,
37                 boundary=None,
38                 tagged_elements=None,
39                 geo_reference=None,
40                 use_inscribed_circle=False,
41                 mesh_filename=None,
42                 use_cache=False,
43                 verbose=False,
44                 full_send_dict=None,
45                 ghost_recv_dict=None,
46                 processor=0,
47                 numproc=1,
48                 number_of_full_nodes=None,
49                 number_of_full_triangles=None):
50
51        conserved_quantities = [ 'stage', 'xmomentum', 'ymomentum']
52
53        evolved_quantities = [ 'stage', 'xmomentum', 'ymomentum', \
54                               'height', 'elevation', 'xvelocity', 'yvelocity']
55       
56        other_quantities = [ 'friction' ]
57
58
59        Sww_domain.__init__(self,
60                            coordinates = coordinates,
61                            vertices = vertices,
62                            boundary = boundary,
63                            tagged_elements = tagged_elements,
64                            geo_reference = geo_reference,
65                            use_inscribed_circle = use_inscribed_circle,
66                            mesh_filename = mesh_filename,
67                            use_cache = use_cache,
68                            verbose = verbose,
69                            conserved_quantities = conserved_quantities,
70                            evolved_quantities = evolved_quantities,
71                            other_quantities = other_quantities,
72                            full_send_dict = full_send_dict,
73                            ghost_recv_dict = ghost_recv_dict,
74                            processor = processor,
75                            numproc = numproc,
76                            number_of_full_nodes = number_of_full_nodes,
77                            number_of_full_triangles = number_of_full_triangles)
78       
79        #---------------------
80        # set some defaults
81        #---------------------
82        self.set_timestepping_method(1)
83        self.set_default_order(2)
84        self.set_new_mannings_function(True)
85        self.set_centroid_transmissive_bc(True)
86
87    ##
88    # @brief Run integrity checks on shallow water balanced domain.
89    def check_integrity(self):
90        Sww_domain.check_integrity(self)
91
92        #Check that the evolved quantities are correct (order)
93        msg = 'First evolved quantity must be "stage"'
94        assert self.evolved_quantities[0] == 'stage', msg
95        msg = 'Second evolved quantity must be "xmomentum"'
96        assert self.evolved_quantities[1] == 'xmomentum', msg
97        msg = 'Third evolved quantity must be "ymomentum"'
98        assert self.evolved_quantities[2] == 'ymomentum', msg
99        msg = 'Fourth evolved quantity must be "height"'
100        assert self.evolved_quantities[3] == 'height', msg
101        msg = 'Fifth evolved quantity must be "elevation"'
102        assert self.evolved_quantities[4] == 'elevation', msg
103        msg = 'Sixth evolved quantity must be "xvelocity"'
104        assert self.evolved_quantities[5] == 'xvelocity', msg       
105        msg = 'Seventh evolved quantity must be "yvelocity"'
106        assert self.evolved_quantities[6] == 'yvelocity', msg       
107
108        msg = 'First other quantity must be "friction"'
109        assert self.other_quantities[0] == 'friction', msg
110
111    ##
112    # @brief
113    def compute_fluxes(self):
114        #Call correct module function (either from this module or C-extension)
115        compute_fluxes(self)
116
117    ##
118    # @brief
119    def distribute_to_vertices_and_edges(self):
120        """Distribution from centroids to edges specific to the SWW eqn.
121
122        It will ensure that h (w-z) is always non-negative even in the
123        presence of steep bed-slopes by taking a weighted average between shallow
124        and deep cases.
125
126        In addition, all conserved quantities get distributed as per either a
127        constant (order==1) or a piecewise linear function (order==2).
128       
129
130        Precondition:
131        All conserved quantities defined at centroids and bed elevation defined at
132        edges.
133       
134        Postcondition
135        Evolved quantities defined at vertices and edges
136        """
137
138
139        #Shortcuts
140        Stage  = self.quantities['stage']
141        Xmom   = self.quantities['xmomentum']
142        Ymom   = self.quantities['ymomentum']
143        Elev   = self.quantities['elevation']
144        Height = self.quantities['height']
145        Xvel   = self.quantities['xvelocity']
146        Yvel   = self.quantities['yvelocity']
147
148        #Arrays   
149        w_C   = Stage.centroid_values   
150        uh_C  = Xmom.centroid_values
151        vh_C  = Ymom.centroid_values   
152        z_C   = Elev.centroid_values
153        h_C   = Height.centroid_values
154        u_C   = Xvel.centroid_values
155        v_C   = Yvel.centroid_values
156
157        w_C[:] = num.maximum(w_C, z_C)
158       
159        h_C[:] = w_C - z_C
160
161
162        assert num.min(h_C) >= 0
163               
164        num.putmask(uh_C, h_C < 1.0e-15, 0.0)
165        num.putmask(vh_C, h_C < 1.0e-15, 0.0)
166        num.putmask(h_C, h_C < 1.0e-15, 1.0e-15)       
167       
168        u_C[:]  = uh_C/h_C
169        v_C[:]  = vh_C/h_C
170       
171        for name in [ 'height', 'xvelocity', 'yvelocity' ]:
172            Q = self.quantities[name]
173            if self._order_ == 1:
174                Q.extrapolate_first_order()
175            elif self._order_ == 2:
176                Q.extrapolate_second_order_and_limit_by_edge()
177            else:
178                raise 'Unknown order'
179
180
181        w_E     = Stage.edge_values
182        uh_E    = Xmom.edge_values
183        vh_E    = Ymom.edge_values     
184        z_E     = Elev.edge_values     
185        h_E     = Height.edge_values
186        u_E     = Xvel.edge_values
187        v_E     = Yvel.edge_values             
188
189
190        w_E[:]   = z_E + h_E
191
192        #num.putmask(u_E, h_temp <= 0.0, 0.0)
193        #num.putmask(v_E, h_temp <= 0.0, 0.0)
194        #num.putmask(w_E, h_temp <= 0.0, z_E+h_E)
195        #num.putmask(h_E, h_E <= 0.0, 0.0)
196       
197        uh_E[:] = u_E * h_E
198        vh_E[:] = v_E * h_E
199
200        """
201        print '=========================================================='
202        print 'Time ', self.get_time()
203        print h_E
204        print uh_E
205        print vh_E
206        """
207       
208        # Compute vertex values by interpolation
209        for name in self.evolved_quantities:
210            Q = self.quantities[name]
211            Q.interpolate_from_edges_to_vertices()
212
213
214        w_V     = Stage.vertex_values
215        uh_V    = Xmom.vertex_values
216        vh_V    = Ymom.vertex_values   
217        z_V     = Elev.vertex_values   
218        h_V     = Height.vertex_values
219        u_V     = Xvel.vertex_values
220        v_V     = Yvel.vertex_values           
221
222
223        #w_V[:]    = z_V + h_V
224
225        #num.putmask(u_V, h_V <= 0.0, 0.0)
226        #num.putmask(v_V, h_V <= 0.0, 0.0)
227        #num.putmask(w_V, h_V <= 0.0, z_V)       
228        #num.putmask(h_V, h_V <= 0.0, 0.0)
229       
230        uh_V[:] = u_V * h_V
231        vh_V[:] = v_V * h_V
232
233
234    ##
235    # @brief Code to let us use old shallow water domain BCs
236    def conserved_values_to_evolved_values(self, q_cons, q_evol):
237        """Mapping between conserved quantities and the evolved quantities.
238        Used where we have a boundary condition which works with conserved
239        quantities and we now want to use them for the new well balanced
240        code using the evolved quantities
241
242        Typically the old boundary condition will set the values in q_cons,
243
244        q_evol on input will have the values of the evolved quantities at the
245        edge point (useful as it provides values for evlevation).
246        """
247
248        wc  = q_cons[0]
249        uhc = q_cons[1]
250        vhc = q_cons[2]
251
252        we  = q_evol[0]
253        uhe = q_evol[1]
254        vhe = q_evol[2]
255
256        he  = q_evol[3]
257        be  = q_evol[4]
258        ue  = q_evol[5]
259        ve  = q_evol[6]
260
261
262        hc = wc - be
263
264        if hc <= 0.0:
265            hc = 0.0
266            uc = 0.0
267            vc = 0.0
268        else:
269            uc = uhc/hc
270            vc = vhc/hc
271
272        q_evol[0]  = wc
273        q_evol[1]  = uhc
274        q_evol[2]  = vhc
275
276        q_evol[3]  = hc
277        q_evol[4]  = be
278        q_evol[5]  = uc
279        q_evol[6]  = vc
280
281
282        return q_evol
283
284 
Note: See TracBrowser for help on using the repository browser.