1 | from anuga.abstract_2d_finite_volumes.generic_boundary_conditions\ |
---|
2 | import Boundary |
---|
3 | |
---|
4 | import numpy as num |
---|
5 | |
---|
6 | from anuga.shallow_water.shallow_water_ext import rotate |
---|
7 | |
---|
8 | |
---|
9 | ################################################################################ |
---|
10 | # Boundary conditions - specific to the shallow water wave equation |
---|
11 | ################################################################################ |
---|
12 | |
---|
13 | ## |
---|
14 | # @brief Class for a reflective boundary. |
---|
15 | # @note Inherits from Boundary. |
---|
16 | class Reflective_boundary(Boundary): |
---|
17 | """Reflective boundary returns same conserved quantities as |
---|
18 | those present in its neighbour volume but reflected. |
---|
19 | |
---|
20 | This class is specific to the shallow water equation as it |
---|
21 | works with the momentum quantities assumed to be the second |
---|
22 | and third conserved quantities. |
---|
23 | """ |
---|
24 | |
---|
25 | ## |
---|
26 | # @brief Instantiate a Reflective_boundary. |
---|
27 | # @param domain |
---|
28 | def __init__(self, model=None): |
---|
29 | Boundary.__init__(self) |
---|
30 | |
---|
31 | if model is None: |
---|
32 | msg = 'Model must be specified for reflective boundary' |
---|
33 | raise Exception, msg |
---|
34 | |
---|
35 | self.conserved_quantities = num.zeros(3, num.float) |
---|
36 | |
---|
37 | self.model = model |
---|
38 | |
---|
39 | ## |
---|
40 | # @brief Return a representation of this instance. |
---|
41 | def __repr__(self): |
---|
42 | return 'Reflective_boundary' |
---|
43 | |
---|
44 | ## |
---|
45 | # @brief Calculate reflections (reverse outward momentum). |
---|
46 | # @param vol_id |
---|
47 | # @param edge_id |
---|
48 | def evaluate(self, vol_id, edge_id): |
---|
49 | """Reflective boundaries reverses the outward momentum |
---|
50 | of the volume they serve. |
---|
51 | """ |
---|
52 | |
---|
53 | # FIXME - arbitrary model construction time means we have to do these in the |
---|
54 | # RUN state. |
---|
55 | stage = self.model.domain.quantities['stage'].edge_values |
---|
56 | xmom = self.model.domain.quantities['xmomentum'].edge_values |
---|
57 | ymom = self.model.domain.quantities['ymomentum'].edge_values |
---|
58 | normals = self.model.domain.normals |
---|
59 | |
---|
60 | q = self.conserved_quantities |
---|
61 | q[0] = stage[vol_id, edge_id] |
---|
62 | q[1] = xmom[vol_id, edge_id] |
---|
63 | q[2] = ymom[vol_id, edge_id] |
---|
64 | |
---|
65 | normal = normals[vol_id, 2*edge_id:2*edge_id+2] |
---|
66 | |
---|
67 | r = rotate(q, normal, direction = 1) |
---|
68 | r[1] = -r[1] |
---|
69 | q = rotate(r, normal, direction = -1) |
---|
70 | |
---|
71 | return q |
---|
72 | |
---|
73 | |
---|
74 | ## |
---|
75 | # @brief A transmissive boundary, momentum set to zero. |
---|
76 | # @note Inherits from Bouondary. |
---|
77 | class Transmissive_stage_zero_momentum_boundary(Boundary): |
---|
78 | """Return same stage as those present in its neighbour volume. |
---|
79 | Set momentum to zero. |
---|
80 | |
---|
81 | Underlying domain must be specified when boundary is instantiated |
---|
82 | """ |
---|
83 | |
---|
84 | ## |
---|
85 | # @brief Instantiate a Transmissive (zero momentum) boundary. |
---|
86 | # @param domain |
---|
87 | def __init__(self, model=None): |
---|
88 | Boundary.__init__(self) |
---|
89 | |
---|
90 | if model is None: |
---|
91 | msg = ('Domain must be specified for ' |
---|
92 | 'Transmissive_stage_zero_momentum boundary') |
---|
93 | raise Exception, msg |
---|
94 | |
---|
95 | self.model = model |
---|
96 | |
---|
97 | ## |
---|
98 | # @brief Return a representation of this instance. |
---|
99 | def __repr__(self): |
---|
100 | return 'Transmissive_stage_zero_momentum_boundary(%s)' % self.domain |
---|
101 | |
---|
102 | ## |
---|
103 | # @brief Calculate transmissive (zero momentum) results. |
---|
104 | # @param vol_id |
---|
105 | # @param edge_id |
---|
106 | def evaluate(self, vol_id, edge_id): |
---|
107 | """Transmissive boundaries return the edge values |
---|
108 | of the volume they serve. |
---|
109 | """ |
---|
110 | |
---|
111 | q = self.model.domain.get_conserved_quantities(vol_id, edge=edge_id) |
---|
112 | |
---|
113 | q[1] = q[2] = 0.0 |
---|
114 | return q |
---|