Tsunami Project Lab
Loading...
Searching...
No Matches
WavePropagation2d.h
Go to the documentation of this file.
1
29#ifndef TSUNAMI_LAB_PATCHES_WAVE_PROPAGATION_2D
30#define TSUNAMI_LAB_PATCHES_WAVE_PROPAGATION_2D
31
32#include "WavePropagation.h"
33
34namespace tsunami_lab {
35 namespace patches {
36 template<class T>
37 class WavePropagation2d;
38 }
39}
40
41template<class T>
43 private:
45 unsigned short m_step = 0;
46
48 t_idx m_nx = 0;
49
51 t_idx m_ny = 0;
52
54 t_idx m_stride = 0;
55
57 t_idx m_innerOffset = 0;
58
60 t_real * m_h[2] = { nullptr, nullptr };
61
63 t_real * m_hu[2] = { nullptr, nullptr };
64
66 t_real * m_hv[2] = { nullptr, nullptr };
67
69 t_real * m_bm = nullptr;
70
74 inline t_idx idx( t_idx i_ix, t_idx i_iy ) const {
75 return ( i_ix + 1 ) + ( i_iy + 1 ) * m_stride;
76 }
77
78 public:
86 m_nx = i_nx;
87 m_ny = i_ny;
88 m_stride = i_nx + 2;
89 m_innerOffset = m_stride + 1;
90
91 const t_idx l_total = m_stride * ( m_ny + 2 );
92
93 // allocate state buffers (zero-initialised, including ghosts)
94 for( unsigned short l_st = 0; l_st < 2; l_st++ ) {
95 m_h [l_st] = new t_real[ l_total ]();
96 m_hu[l_st] = new t_real[ l_total ]();
97 m_hv[l_st] = new t_real[ l_total ]();
98 }
99
100 // bathymetry (zero-initialised)
101 m_bm = new t_real[ l_total ]();
102 }
103
108 for( unsigned short l_st = 0; l_st < 2; l_st++ ) {
109 delete[] m_h [l_st];
110 delete[] m_hu[l_st];
111 delete[] m_hv[l_st];
112 }
113 delete[] m_bm;
114 }
115
139 void timeStep( t_real i_scaling ) {
140 // pointers to old (Q^n) and new (Q^{n+1}) state
141 t_real * l_hOld = m_h [m_step];
142 t_real * l_huOld = m_hu[m_step];
143 t_real * l_hvOld = m_hv[m_step];
144
145 m_step = ( m_step + 1 ) % 2;
146 t_real * l_hNew = m_h [m_step];
147 t_real * l_huNew = m_hu[m_step];
148 t_real * l_hvNew = m_hv[m_step];
149
150 const t_idx l_s = m_stride;
151
152 // initialise Q^{n+1} = Q^n on the interior
153 for( t_idx l_j = 1; l_j <= m_ny; l_j++ ) {
154 for( t_idx l_i = 1; l_i <= m_nx; l_i++ ) {
155 const t_idx l_id = l_i + l_j * l_s;
156 l_hNew [l_id] = l_hOld [l_id];
157 l_huNew[l_id] = l_huOld[l_id];
158 l_hvNew[l_id] = l_hvOld[l_id];
159 }
160 }
161
162 // x-sweep: vertical edges between cells (i, j) and (i+1, j)
163 // for i ∈ [0, m_nx], j ∈ [1, m_ny] — touches the left/right ghosts
164 for( t_idx l_j = 1; l_j <= m_ny; l_j++ ) {
165 for( t_idx l_i = 0; l_i <= m_nx; l_i++ ) {
166 const t_idx l_idL = l_i + l_j * l_s;
167 const t_idx l_idR = ( l_i+1 ) + l_j * l_s;
168
169 t_real l_hL = l_hOld [l_idL];
170 t_real l_hR = l_hOld [l_idR];
171 t_real l_huL = l_huOld[l_idL];
172 t_real l_huR = l_huOld[l_idR];
173 t_real l_bL = m_bm [l_idL];
174 t_real l_bR = m_bm [l_idR];
175
176 const bool l_dryL = l_hL <= 0;
177 const bool l_dryR = l_hR <= 0;
178 if( l_dryL && l_dryR ) continue;
179
180 // wet-dry edge: mirror dry side from wet partner (Spec 3.2.1)
181 if( l_dryL ) {
182 l_hL = l_hR; l_huL = -l_huR; l_bL = l_bR;
183 } else if( l_dryR ) {
184 l_hR = l_hL; l_huR = -l_huL; l_bR = l_bL;
185 }
186
187 t_real l_netUpdates[2][2];
188 this->solver.netUpdates( l_hL, l_hR,
189 l_huL, l_huR,
190 l_bL, l_bR,
191 l_netUpdates[0], l_netUpdates[1] );
192
193 if( !l_dryL ) {
194 l_hNew [l_idL] -= i_scaling * l_netUpdates[0][0];
195 l_huNew[l_idL] -= i_scaling * l_netUpdates[0][1];
196 }
197 if( !l_dryR ) {
198 l_hNew [l_idR] -= i_scaling * l_netUpdates[1][0];
199 l_huNew[l_idR] -= i_scaling * l_netUpdates[1][1];
200 }
201 }
202 }
203
204 // y-sweep: horizontal edges between cells (i, j) and (i, j+1)
205 // for i ∈ [1, m_nx], j ∈ [0, m_ny] — touches the bottom/top ghosts.
206 // hv plays the role of the normal momentum here; hu is untouched.
207 for( t_idx l_j = 0; l_j <= m_ny; l_j++ ) {
208 for( t_idx l_i = 1; l_i <= m_nx; l_i++ ) {
209 const t_idx l_idB = l_i + l_j * l_s; // below
210 const t_idx l_idT = l_i + ( l_j+1 ) * l_s; // above (top)
211
212 t_real l_hB = l_hOld [l_idB];
213 t_real l_hT = l_hOld [l_idT];
214 t_real l_hvB = l_hvOld[l_idB];
215 t_real l_hvT = l_hvOld[l_idT];
216 t_real l_bB = m_bm [l_idB];
217 t_real l_bT = m_bm [l_idT];
218
219 const bool l_dryB = l_hB <= 0;
220 const bool l_dryT = l_hT <= 0;
221 if( l_dryB && l_dryT ) continue;
222
223 if( l_dryB ) {
224 l_hB = l_hT; l_hvB = -l_hvT; l_bB = l_bT;
225 } else if( l_dryT ) {
226 l_hT = l_hB; l_hvT = -l_hvB; l_bT = l_bB;
227 }
228
229 t_real l_netUpdates[2][2];
230 this->solver.netUpdates( l_hB, l_hT,
231 l_hvB, l_hvT,
232 l_bB, l_bT,
233 l_netUpdates[0], l_netUpdates[1] );
234
235 if( !l_dryB ) {
236 l_hNew [l_idB] -= i_scaling * l_netUpdates[0][0];
237 l_hvNew[l_idB] -= i_scaling * l_netUpdates[0][1];
238 }
239 if( !l_dryT ) {
240 l_hNew [l_idT] -= i_scaling * l_netUpdates[1][0];
241 l_hvNew[l_idT] -= i_scaling * l_netUpdates[1][1];
242 }
243 }
244 }
245 }
246
259 BoundaryCondition i_right,
260 BoundaryCondition i_bottom,
261 BoundaryCondition i_top ) {
262 t_real * l_h = m_h [m_step];
263 t_real * l_hu = m_hu[m_step];
264 t_real * l_hv = m_hv[m_step];
265 const t_idx l_s = m_stride;
266
267 // Note: the four corner ghost cells (i ∈ {0, m_nx+1} ∧ j ∈ {0, m_ny+1})
268 // are intentionally not written — see class docstring. A future
269 // CTU/transverse extension would have to fill them in addition.
270
271 // left edge: i = 0 mirrors i = 1
272 for( t_idx l_j = 1; l_j <= m_ny; l_j++ ) {
273 l_h [ l_j*l_s] = l_h [1 + l_j*l_s];
274 l_hu[ l_j*l_s] = ( i_left == BoundaryCondition::REFLECTING )
275 ? -l_hu[1 + l_j*l_s] : l_hu[1 + l_j*l_s];
276 l_hv[ l_j*l_s] = l_hv[1 + l_j*l_s];
277 m_bm[ l_j*l_s] = m_bm[1 + l_j*l_s];
278 }
279
280 // right edge: i = m_nx + 1 mirrors i = m_nx
281 for( t_idx l_j = 1; l_j <= m_ny; l_j++ ) {
282 l_h [(m_nx+1) + l_j*l_s] = l_h [m_nx + l_j*l_s];
283 l_hu[(m_nx+1) + l_j*l_s] = ( i_right == BoundaryCondition::REFLECTING )
284 ? -l_hu[m_nx + l_j*l_s] : l_hu[m_nx + l_j*l_s];
285 l_hv[(m_nx+1) + l_j*l_s] = l_hv[m_nx + l_j*l_s];
286 m_bm[(m_nx+1) + l_j*l_s] = m_bm[m_nx + l_j*l_s];
287 }
288
289 // bottom edge: j = 0 mirrors j = 1
290 for( t_idx l_i = 1; l_i <= m_nx; l_i++ ) {
291 l_h [l_i ] = l_h [l_i + l_s];
292 l_hu[l_i ] = l_hu[l_i + l_s];
293 l_hv[l_i ] = ( i_bottom == BoundaryCondition::REFLECTING )
294 ? -l_hv[l_i + l_s] : l_hv[l_i + l_s];
295 m_bm[l_i ] = m_bm[l_i + l_s];
296 }
297
298 // top edge: j = m_ny + 1 mirrors j = m_ny
299 for( t_idx l_i = 1; l_i <= m_nx; l_i++ ) {
300 l_h [l_i + (m_ny+1)*l_s] = l_h [l_i + m_ny*l_s];
301 l_hu[l_i + (m_ny+1)*l_s] = l_hu[l_i + m_ny*l_s];
302 l_hv[l_i + (m_ny+1)*l_s] = ( i_top == BoundaryCondition::REFLECTING )
303 ? -l_hv[l_i + m_ny*l_s] : l_hv[l_i + m_ny*l_s];
304 m_bm[l_i + (m_ny+1)*l_s] = m_bm[l_i + m_ny*l_s];
305 }
306 }
307
315
323
330 return m_stride;
331 }
332
339 t_real const * getHeight() {
340 return m_h[m_step] + m_innerOffset;
341 }
342
349 return m_hu[m_step] + m_innerOffset;
350 }
351
358 return m_hv[m_step] + m_innerOffset;
359 }
360
367 return m_bm + m_innerOffset;
368 }
369
377 void setHeight( t_idx i_ix,
378 t_idx i_iy,
379 t_real i_h ) {
380 m_h[m_step][ idx( i_ix, i_iy ) ] = i_h;
381 }
382
390 void setMomentumX( t_idx i_ix,
391 t_idx i_iy,
392 t_real i_hu ) {
393 m_hu[m_step][ idx( i_ix, i_iy ) ] = i_hu;
394 }
395
403 void setMomentumY( t_idx i_ix,
404 t_idx i_iy,
405 t_real i_hv ) {
406 m_hv[m_step][ idx( i_ix, i_iy ) ] = i_hv;
407 }
408
417 t_idx i_iy,
418 t_real i_b ) {
419 m_bm[ idx( i_ix, i_iy ) ] = i_b;
420 }
421};
422
423#endif
Definition WavePropagation2d.h:42
void setBathymetry(t_idx i_ix, t_idx i_iy, t_real i_b)
Definition WavePropagation2d.h:416
void setHeight(t_idx i_ix, t_idx i_iy, t_real i_h)
Definition WavePropagation2d.h:377
t_idx getStride()
Definition WavePropagation2d.h:329
void timeStep(t_real i_scaling)
Definition WavePropagation2d.h:139
t_real const * getBathymetry()
Definition WavePropagation2d.h:366
WavePropagation2d(t_idx i_nx, t_idx i_ny)
Definition WavePropagation2d.h:85
void setGhostBoundary(BoundaryCondition i_left, BoundaryCondition i_right, BoundaryCondition i_bottom, BoundaryCondition i_top)
Definition WavePropagation2d.h:258
t_real const * getMomentumY()
Definition WavePropagation2d.h:357
void setMomentumX(t_idx i_ix, t_idx i_iy, t_real i_hu)
Definition WavePropagation2d.h:390
~WavePropagation2d()
Definition WavePropagation2d.h:107
t_real const * getMomentumX()
Definition WavePropagation2d.h:348
void setMomentumY(t_idx i_ix, t_idx i_iy, t_real i_hv)
Definition WavePropagation2d.h:403
void setGhostReflection()
Definition WavePropagation2d.h:319
t_real const * getHeight()
Definition WavePropagation2d.h:339
void setGhostOutflow()
Definition WavePropagation2d.h:311
Definition WavePropagation.h:31
T solver
Definition WavePropagation.h:32
BoundaryCondition
Definition WavePropagation.h:19
@ OUTFLOW
zero-gradient: copy the inner cell into the ghost cell
Definition constants.h:12
float t_real
floating point type
Definition constants.h:17
std::size_t t_idx
integral type for cell-ids, pointer arithmetic, etc.
Definition constants.h:14