Changeset 8446 for trunk/anuga_work/development/gareth/experimental/balanced_dev/swb2_boundary_conditions.py
- Timestamp:
- Jun 14, 2012, 12:31:32 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/anuga_work/development/gareth/experimental/balanced_dev/swb2_boundary_conditions.py
r8396 r8446 6 6 ##### 7 7 8 class zero_mass_flux_transmissive_momentum_flux_boundary(Boundary): 9 """ Boundary which operates directly on the fluxes 10 CAN BE UNSTABLE -- CAREFUL 11 Sets boundary values of h, uh, vh as in transmissive boundary, but 12 also ensures: 13 flux[0] = 0.0, 8 #class zero_mass_flux_transmissive_momentum_flux_boundary(Boundary): 9 # """ Boundary which operates directly on the fluxes 10 # CAN BE UNSTABLE -- CAREFUL 11 # Sets boundary values of h, uh, vh as in transmissive boundary, but 12 # also ensures: 13 # flux[0] = 0.0, 14 # """ 15 # def __init__(self, domain = None): 16 # Boundary.__init__(self) 17 # 18 # if domain is None: 19 # msg = 'Domain must be specified for zero_mass_flux_transmissive_momentum_flux boundary' 20 # raise Exception, msg 21 # 22 # self.domain = domain 23 # 24 # def __repr__(self): 25 # return 'zero_mass_flux_transmissive_momentum_flux_boundary(%s)' %self.domain 26 # 27 # def evaluate(self, vol_id, edge_id): 28 # """Transmissive boundaries return the edge values 29 # of the volume they serve. 30 # """ 31 # 32 # if self.domain.get_centroid_transmissive_bc() : 33 # q = self.domain.get_evolved_quantities(vol_id) 34 # else: 35 # q = self.domain.get_evolved_quantities(vol_id, edge = edge_id) 36 # return q 37 # 38 ###### 39 # 40 #class zero_mass_flux_zero_momentum_boundary(Boundary): 41 # """ Boundary which operates directly on the fluxes 42 # Sets boundary values of h=neighbour_h, uh=0, vh=0. 43 # and ensure that: 44 # flux[0] = 0.0 45 # """ 46 # def __init__(self, domain = None): 47 # Boundary.__init__(self) 48 # 49 # if domain is None: 50 # msg = 'Domain must be specified for zero_mass_flux_zero_momentum_boundary' 51 # raise Exception, msg 52 # 53 # self.domain = domain 54 # 55 # def __repr__(self): 56 # return 'zero_mass_flux_zero_momentum_boundary(%s)' %self.domain 57 # 58 # def evaluate(self, vol_id, edge_id): 59 # """ Apply chosen values to q[1], q[2] 60 # """ 61 # 62 # if self.domain.get_centroid_transmissive_bc() : 63 # q = self.domain.get_evolved_quantities(vol_id) 64 # else: 65 # q = self.domain.get_evolved_quantities(vol_id, edge = edge_id) 66 # 67 # normal = self.domain.normals[vol_id, 2*edge_id:2*edge_id+2] 68 # 69 # r = rotate(q, normal, direction = 1) 70 # #r[1] = -r[1] 71 # tdamp=0.0 72 # ndamp=0.0 73 # r[1]=r[1]*ndamp 74 # r[2]=r[2]*tdamp 75 # q = rotate(r, normal, direction = -1) 76 # 77 # # q[1]=0. 78 # # q[2]=0. 79 # 80 # return q 81 # 82 # 83 #class zero_mass_flux_zero_n_transmissive_t_momentum_boundary(Boundary): 84 # """ Boundary which operates directly on the fluxes 85 # Sets boundary values of h=neighbour_h, uh=0, vh=vh 86 # and ensure that: 87 # flux[0] = 0.0 88 # """ 89 # def __init__(self, domain = None): 90 # Boundary.__init__(self) 91 # 92 # if domain is None: 93 # msg = 'Domain must be specified for zero_mass_flux_zero_n_transmissive_t_momentum_boundary' 94 # raise Exception, msg 95 # 96 # self.domain = domain 97 # 98 # def __repr__(self): 99 # return 'zero_mass_flux_zero_n_transmissive_t_momentum_boundary(%s)' %self.domain 100 # 101 # def evaluate(self, vol_id, edge_id): 102 # """ Apply chosen values to q[1], q[2] 103 # """ 104 # 105 # if self.domain.get_centroid_transmissive_bc() : 106 # q = self.domain.get_evolved_quantities(vol_id) 107 # else: 108 # q = self.domain.get_evolved_quantities(vol_id, edge = edge_id) 109 # 110 # normal = self.domain.normals[vol_id, 2*edge_id:2*edge_id+2] 111 # 112 # r = rotate(q, normal, direction = 1) 113 # #r[1] = -r[1] 114 # tdamp=1.0 115 # ndamp=0.0 116 # r[1]=r[1]*ndamp 117 # r[2]=r[2]*tdamp 118 # q = rotate(r, normal, direction = -1) 119 # 120 # # q[1]=0. 121 # # q[2]=0. 122 # 123 # return q 124 # 125 # 126 #class zero_mass_flux_zero_t_transmissive_n_momentum_boundary(Boundary): 127 # """ Boundary which operates directly on the fluxes 128 # Sets boundary values of h=neighbour_h, uh=neighbour_uh, vh=0. 129 # and ensure that: 130 # flux[0] = 0.0 131 # """ 132 # def __init__(self, domain = None): 133 # Boundary.__init__(self) 134 # 135 # if domain is None: 136 # msg = 'Domain must be specified for zero_mass_flux_zero_t_transmissive_n_momentum_boundary' 137 # raise Exception, msg 138 # 139 # self.domain = domain 140 # 141 # def __repr__(self): 142 # return 'zero_mass_flux_zero_t_transmissive_n_momentum_boundary(%s)' %self.domain 143 # 144 # def evaluate(self, vol_id, edge_id): 145 # """ Apply chosen values to q[1], q[2] 146 # """ 147 # 148 # if self.domain.get_centroid_transmissive_bc() : 149 # q = self.domain.get_evolved_quantities(vol_id) 150 # else: 151 # q = self.domain.get_evolved_quantities(vol_id, edge = edge_id) 152 # 153 # normal = self.domain.normals[vol_id, 2*edge_id:2*edge_id+2] 154 # 155 # r = rotate(q, normal, direction = 1) 156 # #r[1] = -r[1] 157 # tdamp=0.0 158 # ndamp=1.0 159 # r[1]=r[1]*ndamp 160 # r[2]=r[2]*tdamp 161 # q = rotate(r, normal, direction = -1) 162 # 163 # # q[1]=0. 164 # # q[2]=0. 165 # 166 # return q 167 # 168 # 169 class Characteristic_boundary(Boundary): 14 170 """ 15 def __init__(self, domain = None): 171 172 Example: 173 174 def waveform(t): 175 return sea_level + normalized_amplitude/cosh(t-25)**2 176 177 Bf = Nudge_boundary(domain, waveform) 178 179 Underlying domain must be specified when boundary is instantiated 180 """ 181 182 def __init__(self, domain=None, function=None): 183 """ Instantiate a 184 Nudge_boundary. 185 domain is the domain containing the boundary 186 function is the function to apply 187 """ 188 16 189 Boundary.__init__(self) 17 190 18 191 if domain is None: 19 msg = 'Domain must be specified for zero_mass_flux_transmissive_momentum_fluxboundary'192 msg = 'Domain must be specified for this type boundary' 20 193 raise Exception, msg 21 194 195 if function is None: 196 msg = 'Function must be specified for this type boundary' 197 raise Exception, msg 198 22 199 self.domain = domain 200 self.function = function 201 23 202 24 203 def __repr__(self): 25 return 'zero_mass_flux_transmissive_momentum_flux_boundary(%s)' %self.domain 204 """ Return a representation of this instance. """ 205 msg = 'Nudge_boundary' 206 msg += '(%s)' % self.domain 207 return msg 208 26 209 27 210 def evaluate(self, vol_id, edge_id): 28 """Transmissive boundaries return the edge values29 of the volume they serve.30 211 """ 31 32 if self.domain.get_centroid_transmissive_bc() : 33 q = self.domain.get_evolved_quantities(vol_id) 212 """ 213 214 q = self.domain.get_conserved_quantities(vol_id, edge = edge_id) 215 bed = self.domain.quantities['elevation'].centroid_values[vol_id] 216 depth=max(q[0]-bed,0.0) 217 dt=self.domain.timestep 218 219 normal = self.domain.get_normal(vol_id, edge_id) 220 221 222 t = self.domain.get_time() 223 224 if hasattr(self.function, 'time'): 225 # Roll boundary over if time exceeds 226 while t > self.function.time[-1]: 227 msg = 'WARNING: domain time %.2f has exceeded' % t 228 msg += 'time provided in ' 229 msg += 'Flather_boundary object.\n' 230 msg += 'I will continue, reusing the object from t==0' 231 log.critical(msg) 232 t -= self.function.time[-1] 233 234 value = self.function(t) 235 try: 236 x = float(value) 237 except: 238 x = float(value[0]) 239 240 ## 241 ndotq = (normal[0]*q[1] + normal[1]*q[2]) # momentum perpendicular to the boundary 242 243 if(depth==0.): 244 q[0] = x 245 q[1] = 0. 246 q[2] = 0. 247 34 248 else: 35 q = self.domain.get_evolved_quantities(vol_id, edge = edge_id) 249 250 # Asssume sub-critical flow. Set the values of the characteristics as 251 # appropriate, depending on whether we have inflow or outflow 252 tmp = (9.8/depth)**0.5 253 if(ndotq>0.): 254 # Only need to impose one characteristic 255 # Assume zero external velocity (dangerous?) 256 # FIXME: Allow external velocities to be specified in the function 257 # This would be needed to use the boundary for real inflows (e.g. run_wave.py) 258 # At the moment, it seems to work okay as a 'passive' outflow boundary (e.g. run_wave.py) 259 # Here it attenuates the wave at the outflow a bit, but doesn't do too much damage compared 260 # with the other boundary conditions 261 w1 = 0. - tmp*x 262 w2 = (+normal[1]*q[1] -normal[0]*q[2])/depth 263 w3 = ndotq/depth + tmp*q[0] 264 265 else: 266 # Need to set 2 characteristics 267 # Assume zero external velocity (dangerous?) 268 # FIXME: Allow this to be specified with a function 269 w1 = 0. - tmp*x 270 w2 = 0. 271 #w2 = (+normal[1]*q[1] -normal[0]*q[2])/depth 272 w3 = ndotq/depth + tmp*q[0] 273 274 275 q[0] = (w3-w1)/(2*tmp) 276 qperp= (w3+w1)/2. *depth 277 qpar= w2*depth 278 279 # So q[1], q[2] = qperp*(normal[0], normal[1]) + qpar*(-normal[1], normal[0]) 280 281 q[1] = qperp*normal[0] + qpar*normal[1] 282 q[2] = qperp*normal[1] -qpar*normal[0] 283 36 284 return q 37 38 #####39 40 class zero_mass_flux_zero_momentum_boundary(Boundary):41 """ Boundary which operates directly on the fluxes42 Sets boundary values of h=neighbour_h, uh=0, vh=0.43 and ensure that:44 flux[0] = 0.045 """46 def __init__(self, domain = None):47 Boundary.__init__(self)48 49 if domain is None:50 msg = 'Domain must be specified for zero_mass_flux_zero_momentum_boundary'51 raise Exception, msg52 53 self.domain = domain54 55 def __repr__(self):56 return 'zero_mass_flux_zero_momentum_boundary(%s)' %self.domain57 58 def evaluate(self, vol_id, edge_id):59 """ Apply chosen values to q[1], q[2]60 """61 62 if self.domain.get_centroid_transmissive_bc() :63 q = self.domain.get_evolved_quantities(vol_id)64 else:65 q = self.domain.get_evolved_quantities(vol_id, edge = edge_id)66 67 normal = self.domain.normals[vol_id, 2*edge_id:2*edge_id+2]68 69 r = rotate(q, normal, direction = 1)70 #r[1] = -r[1]71 tdamp=0.072 ndamp=0.073 r[1]=r[1]*ndamp74 r[2]=r[2]*tdamp75 q = rotate(r, normal, direction = -1)76 77 # q[1]=0.78 # q[2]=0.79 80 return q81 82 83 class zero_mass_flux_zero_n_transmissive_t_momentum_boundary(Boundary):84 """ Boundary which operates directly on the fluxes85 Sets boundary values of h=neighbour_h, uh=0, vh=vh86 and ensure that:87 flux[0] = 0.088 """89 def __init__(self, domain = None):90 Boundary.__init__(self)91 92 if domain is None:93 msg = 'Domain must be specified for zero_mass_flux_zero_n_transmissive_t_momentum_boundary'94 raise Exception, msg95 96 self.domain = domain97 98 def __repr__(self):99 return 'zero_mass_flux_zero_n_transmissive_t_momentum_boundary(%s)' %self.domain100 101 def evaluate(self, vol_id, edge_id):102 """ Apply chosen values to q[1], q[2]103 """104 105 if self.domain.get_centroid_transmissive_bc() :106 q = self.domain.get_evolved_quantities(vol_id)107 else:108 q = self.domain.get_evolved_quantities(vol_id, edge = edge_id)109 110 normal = self.domain.normals[vol_id, 2*edge_id:2*edge_id+2]111 112 r = rotate(q, normal, direction = 1)113 #r[1] = -r[1]114 tdamp=1.0115 ndamp=0.0116 r[1]=r[1]*ndamp117 r[2]=r[2]*tdamp118 q = rotate(r, normal, direction = -1)119 120 # q[1]=0.121 # q[2]=0.122 123 return q124 125 126 class zero_mass_flux_zero_t_transmissive_n_momentum_boundary(Boundary):127 """ Boundary which operates directly on the fluxes128 Sets boundary values of h=neighbour_h, uh=neighbour_uh, vh=0.129 and ensure that:130 flux[0] = 0.0131 """132 def __init__(self, domain = None):133 Boundary.__init__(self)134 135 if domain is None:136 msg = 'Domain must be specified for zero_mass_flux_zero_t_transmissive_n_momentum_boundary'137 raise Exception, msg138 139 self.domain = domain140 141 def __repr__(self):142 return 'zero_mass_flux_zero_t_transmissive_n_momentum_boundary(%s)' %self.domain143 144 def evaluate(self, vol_id, edge_id):145 """ Apply chosen values to q[1], q[2]146 """147 148 if self.domain.get_centroid_transmissive_bc() :149 q = self.domain.get_evolved_quantities(vol_id)150 else:151 q = self.domain.get_evolved_quantities(vol_id, edge = edge_id)152 153 normal = self.domain.normals[vol_id, 2*edge_id:2*edge_id+2]154 155 r = rotate(q, normal, direction = 1)156 #r[1] = -r[1]157 tdamp=0.0158 ndamp=1.0159 r[1]=r[1]*ndamp160 r[2]=r[2]*tdamp161 q = rotate(r, normal, direction = -1)162 163 # q[1]=0.164 # q[2]=0.165 166 return q167 168 169 285 ### 170 286 def rotate(q,normal,direction=1):
Note: See TracChangeset
for help on using the changeset viewer.