REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_init_bcs.cpp
Go to the documentation of this file.
1#include <AMReX_Vector.H>
2#include <AMReX_BC_TYPES.H>
3#include <AMReX_ParmParse.H>
4
5#include <REMORA.H>
6
7using namespace amrex;
8
10{
11 const int xvel_bc_idx = xvel_bc();
12 const int yvel_bc_idx = yvel_bc();
13 const int zvel_bc_idx = zvel_bc();
14 const int ubar_bc_idx = ubar_bc();
15 const int vbar_bc_idx = vbar_bc();
16 const int zeta_bc_idx = zeta_bc();
17 const int tke_bc_idx = tke_bc();
18 const int foextrap_periodic_bc_idx = foextrap_periodic_bc();
19 const int foextrap_bc_idx = foextrap_bc();
20 const int u2d_simple_bc_idx = u2d_simple_bc();
21 const int v2d_simple_bc_idx = v2d_simple_bc();
22
23 std::vector<std::string> bcvar_names(BCVars::NumTypes(ncons),"");
24 bcvar_names[BCVars::Temp_bc_comp] = "temp";
25 bcvar_names[BCVars::Salt_bc_comp] = "salt";
26 bcvar_names[BCVars::Scalar_bc_comp] = "scalar";
27 bcvar_names[xvel_bc_idx] = "u";
28 bcvar_names[yvel_bc_idx] = "v";
29 bcvar_names[zvel_bc_idx] = "w";
30 bcvar_names[ubar_bc_idx] = "ubar";
31 bcvar_names[vbar_bc_idx] = "vbar";
32 bcvar_names[zeta_bc_idx] = "zeta";
33 bcvar_names[tke_bc_idx] = "tke";
34
35 phys_bc_type.assign(num_bc_vars(), {});
36 m_bc_extdir_vals.assign(num_bc_vars(), {});
37
38 auto uses_velocity_input = [=] (int bcvar_type) noexcept {
39 return bcvar_type == xvel_bc_idx || bcvar_type == yvel_bc_idx || bcvar_type == zvel_bc_idx;
40 };
41
42 auto uses_scalar_input = [=] (int bcvar_type) noexcept {
43 return bcvar_type >= Tracer_comp && bcvar_type < ncons;
44 };
45
46 auto f_set_var_bc = [this, uses_velocity_input, uses_scalar_input, xvel_bc_idx, zeta_bc_idx, ubar_bc_idx, vbar_bc_idx, bcvar_names]
47 (ParmParse& pp, int bcvar_type, Orientation ori, std::string bc_type_string) {
48 // const bool requires_file_data =
49 // (bc_type_string == "clamped") || (bc_type_string == "chapman") ||
50 // (bc_type_string == "flather") || (bc_type_string == "orlanski_rad_nudg");
51
52 // if (bcvar_type > Tracer_comp && requires_file_data) {
53 // amrex::Abort("Additional passive scalars do not yet support NetCDF-driven boundary conditions");
54 // }
55
56 if (bc_type_string == "symmetry")
57 {
58 phys_bc_type[bcvar_type][ori] = REMORA_BC::symmetry;
59 phys_bc_need_data[bdy_index[bcvar_type]][ori] = false;
60 domain_bc_type[ori] = "Symmetry";
61 }
62 else if (bc_type_string == "outflow")
63 {
64 phys_bc_type[bcvar_type][ori] = REMORA_BC::outflow;
65 phys_bc_need_data[bdy_index[bcvar_type]][ori] = false;
66 domain_bc_type[ori] = "Outflow";
67 }
68 else if (bc_type_string == "inflow")
69 {
70 phys_bc_type[bcvar_type][ori] = REMORA_BC::inflow;
71 phys_bc_need_data[bdy_index[bcvar_type]][ori] = false;
72 domain_bc_type[ori] = "Inflow";
73
74 if (uses_velocity_input(bcvar_type)) {
75 std::vector<Real> v;
76 pp.getarr("velocity", v, 0, AMREX_SPACEDIM);
77 m_bc_extdir_vals[bcvar_type][ori] = v[bcvar_type - xvel_bc_idx];
78 } else if (uses_scalar_input(bcvar_type)) {
79 Real scalar_in = 0.;
80 if (pp.queryAdd("scalar", scalar_in)) {
81 m_bc_extdir_vals[bcvar_type][ori] = scalar_in;
82 }
83 }
84 }
85 else if (bc_type_string == "noslipwall")
86 {
87 phys_bc_type[bcvar_type][ori] = REMORA_BC::no_slip_wall;
88 phys_bc_need_data[bdy_index[bcvar_type]][ori] = false;
89 domain_bc_type[ori] = "NoSlipWall";
90
91 if (uses_velocity_input(bcvar_type)) {
92 std::vector<Real> v;
93
94 // The values of m_bc_extdir_vals default to 0.
95 // But if we find "velocity" in the inputs file, use those values instead.
96 if (pp.queryarr("velocity", v, 0, AMREX_SPACEDIM))
97 {
98 v[ori.coordDir()] = 0.0_rt;
99 m_bc_extdir_vals[bcvar_type][ori] = v[bcvar_type - xvel_bc_idx];
100 }
101 }
102 }
103 else if (bc_type_string == "slipwall")
104 {
105 phys_bc_type[bcvar_type][ori] = REMORA_BC::slip_wall;
106 phys_bc_need_data[bdy_index[bcvar_type]][ori] = false;
107 domain_bc_type[ori] = "SlipWall";
108 }
109 else if (bc_type_string == "clamped")
110 {
111 phys_bc_type[bcvar_type][ori] = REMORA_BC::clamped;
112 phys_bc_need_data[bdy_index[bcvar_type]][ori] = true;
113 domain_bc_type[ori] = "Clamped";
115 }
116 else if (bc_type_string == "chapman")
117 {
118 phys_bc_type[bcvar_type][ori] = REMORA_BC::chapman;
119 phys_bc_need_data[bdy_index[bcvar_type]][ori] = true;
120 domain_bc_type[ori] = "Chapman";
122
123 if (bcvar_type != zeta_bc_idx) {
124 amrex::Abort("Chapman BC can only be applied to zeta");
125 }
126 }
127 else if (bc_type_string == "flather")
128 {
129 phys_bc_type[bcvar_type][ori] = REMORA_BC::flather;
130 phys_bc_need_data[bdy_index[bcvar_type]][ori] = true;
131 domain_bc_type[ori] = "Flather";
133
134 if (!(bcvar_type == ubar_bc_idx || bcvar_type == vbar_bc_idx)) {
135 amrex::Abort("Flather BC can only be applied to ubar or vbar");
136 }
137 }
138 else if (bc_type_string == "orlanski_rad")
139 {
140 phys_bc_type[bcvar_type][ori] = REMORA_BC::orlanski_rad;
141 phys_bc_need_data[bdy_index[bcvar_type]][ori] = false;
142 domain_bc_type[ori] = "Orlanski Radiation";
143 }
144 else if (bc_type_string == "orlanski_rad_nudg")
145 {
147 phys_bc_need_data[bdy_index[bcvar_type]][ori] = true;
148 domain_bc_type[ori] = "Orlanski Radiation with nudging";
150 }
151 else if (bc_type_string == "periodic")
152 {
153 if (!geom[0].isPeriodic(ori.coordDir())) {
154 amrex::Abort("Periodic boundary specified in a non-periodic direction");
155 }
156 phys_bc_type[bcvar_type][ori] = REMORA_BC::periodic;
157 phys_bc_need_data[bdy_index[bcvar_type]][ori] = false;
158 domain_bc_type[ori] = "Periodic";
159 }
160 else
161 {
162 phys_bc_type[bcvar_type][ori] = REMORA_BC::undefined;
163 phys_bc_need_data[bdy_index[bcvar_type]][ori] = false;
164 }
165
166 if (geom[0].isPeriodic(ori.coordDir()))
167 {
168 domain_bc_type[ori] = "Periodic";
169 if (phys_bc_type[bcvar_type][ori] == REMORA_BC::undefined)
170 {
171 phys_bc_type[bcvar_type][ori] = REMORA_BC::periodic;
172 phys_bc_need_data[bdy_index[bcvar_type]][ori] = false;
173 } else if (phys_bc_type[bcvar_type][ori] != REMORA_BC::periodic) {
174 amrex::Abort("Wrong BC type for periodic boundary");
175 }
176 }
177
178 if (phys_bc_type[bcvar_type][ori] == REMORA_BC::undefined)
179 {
180 amrex::Print() << "BC Type specified for variable " << bcvar_names[bcvar_type] << " is " << bc_type_string << std::endl;
181 amrex::Abort("This BC type is unknown");
182 }
183 };
184
185 auto f_by_side = [this, &f_set_var_bc] (std::string const& bcid, Orientation ori)
186 {
187 ParmParse pp("remora.bc."+bcid);
188 std::string bc_type_in = "null";
189 // Default z directions to slipwall
190 if (bcid=="zlo" or bcid=="zhi") bc_type_in = "slipwall";
191 pp.queryAdd("type", bc_type_in);
192 std::string bc_type = amrex::toLower(bc_type_in);
193
194 for (int icomp = 0; icomp < num_bc_vars(); ++icomp) {
195 f_set_var_bc(pp, icomp, ori, bc_type);
196 }
197 };
198
199 auto f_by_var = [this, &f_set_var_bc, zvel_bc_idx] (std::string const& varname, int bcvar_type)
200 {
201 amrex::Vector<Orientation> orientations = {Orientation(Direction::x,Orientation::low), Orientation(Direction::y,Orientation::high),Orientation(Direction::x,Orientation::high),Orientation(Direction::y,Orientation::low)}; // west, south, east, north [matches ROMS]
202 std::vector<std::string> bc_types = {"null","null","null","null"};
203 ParmParse pp("remora.bc."+varname);
204 std::string bc_type_in = "null";
205 // default zvel to outflow
206 if (bcvar_type == zvel_bc_idx) {
207 bc_types = {"outflow","outflow","outflow","outflow"};
208 for (int i=0; i<4; i++) {
209 auto ori = orientations[i];
210 if (geom[0].isPeriodic(ori.coordDir())) {
211 bc_types[i] = "periodic";
212 }
213 }
214 }
215 pp.queryarr("type", bc_types);
216 AMREX_ASSERT(bc_types.size() == 4);
217 for (int i=0; i<4; i++) {
218 std::string bc_type = amrex::toLower(bc_types[i]);
219 auto ori = orientations[i];
220 f_set_var_bc(pp, bcvar_type, ori, bc_type);
221 }
222 };
223
227 bdy_index[xvel_bc_idx] = BdyVars::u;
228 bdy_index[yvel_bc_idx] = BdyVars::v;
229 bdy_index[ubar_bc_idx] = BdyVars::ubar;
230 bdy_index[vbar_bc_idx] = BdyVars::vbar;
231 bdy_index[zeta_bc_idx] = BdyVars::zeta;
232
233 for (OrientationIter oit; oit; ++oit) {
234 Orientation ori = oit();
235 // These are simply defaults for Dirichlet faces -- they should be over-written below if needed
236 m_bc_extdir_vals[BCVars::Temp_bc_comp ][ori] = 1.e19_rt;
237 m_bc_extdir_vals[BCVars::Salt_bc_comp ][ori] = 1.e20_rt;
238 for (int icomp = Tracer_comp; icomp < ncons; ++icomp) {
239 m_bc_extdir_vals[icomp][ori] = 1.e21_rt + static_cast<Real>(icomp - Tracer_comp);
240 }
241
242 m_bc_extdir_vals[xvel_bc_idx][ori] = 0.0_rt; // default
243 m_bc_extdir_vals[yvel_bc_idx][ori] = 0.0_rt;
244 m_bc_extdir_vals[zvel_bc_idx][ori] = 0.0_rt;
245
246 m_bc_extdir_vals[ubar_bc_idx][ori] = 0.0_rt; // default
247 m_bc_extdir_vals[vbar_bc_idx][ori] = 0.0_rt;
248 m_bc_extdir_vals[u2d_simple_bc_idx][ori] = 0.0_rt;
249 m_bc_extdir_vals[v2d_simple_bc_idx][ori] = 0.0_rt;
250 }
251
252 // Whether to specify boundary conditions by variable (then side).
253 // Alternative is to do it by side by indicating keywords that indicate multiple variables
254 set_bcs_by_var = false;
255
256 ParmParse pp("remora");
257 pp.queryAdd("boundary_per_variable", set_bcs_by_var);
258 // Check whether variable specification matches flag in inputs file
259 if (!set_bcs_by_var && (pp.contains("bc.temp.type") ||
260 pp.contains("bc.salt.type") ||
261 pp.contains("bc.scalar.type") ||
262 pp.contains("bc.u.type") ||
263 pp.contains("bc.v.type") ||
264 pp.contains("bc.w.type") ||
265 pp.contains("bc.ubar.type") ||
266 pp.contains("bc.vbar.type") ||
267 pp.contains("bc.zeta.type") ||
268 pp.contains("bc.tke.type"))) {
269 amrex::Abort("boundary_per_variable set to false, but per-variable boundary conditions are specified. Use bc.{x,y}{lo,hi}.type instead");
270 }
271 if (set_bcs_by_var && (pp.contains("bc.xlo.type") ||
272 pp.contains("bc.xhi.type") ||
273 pp.contains("bc.ylo.type") ||
274 pp.contains("bc.yhi.type"))) {
275 amrex::Abort("boundary_per_variable set to true, but per-side boundary conditions are specified. Use bc.{temp,salt,etc}.type instead");
276 }
277 if (!set_bcs_by_var) {
278 f_by_side("xlo", Orientation(Direction::x,Orientation::low));
279 f_by_side("xhi", Orientation(Direction::x,Orientation::high));
280 f_by_side("ylo", Orientation(Direction::y,Orientation::low));
281 f_by_side("yhi", Orientation(Direction::y,Orientation::high));
282 } else {
283 f_by_var("temp", BCVars::Temp_bc_comp);
284 f_by_var("salt", BCVars::Salt_bc_comp);
285 for (int icomp = Tracer_comp; icomp < ncons; ++icomp) {
286 f_by_var("scalar", icomp);
287 }
288 f_by_var("u", xvel_bc_idx);
289 f_by_var("v", yvel_bc_idx);
290 f_by_var("w", zvel_bc_idx);
291 f_by_var("ubar", ubar_bc_idx);
292 f_by_var("vbar", vbar_bc_idx);
293 f_by_var("zeta", zeta_bc_idx);
294 f_by_var("tke", tke_bc_idx);
295 }
296
297 // Always specify z direction by side keyword
298 f_by_side("zlo", Orientation(Direction::z,Orientation::low));
299 f_by_side("zhi", Orientation(Direction::z,Orientation::high));
300
301 // *****************************************************************************
302 //
303 // Here we translate the physical boundary conditions -- one type per face --
304 // into logical boundary conditions for each velocity component
305 //
306 // *****************************************************************************
307 {
310
311 for (OrientationIter oit; oit; ++oit) {
312 Orientation ori = oit();
313 int dir = ori.coordDir();
314 Orientation::Side side = ori.faceDir();
315 // only do this for xvel and yvel
316 for (int i = 0; i < 2; i++) {
317 auto const bct = phys_bc_type[xvel_bc_idx+i][ori];
318 if ( bct == REMORA_BC::symmetry )
319 {
320 if (side == Orientation::low) {
321 domain_bcs_type[xvel_bc_idx+i].setLo(dir, REMORABCType::reflect_even);
322 if (i==1)
323 domain_bcs_type[xvel_bc_idx+dir].setLo(dir, REMORABCType::reflect_odd);
324 } else {
325 domain_bcs_type[xvel_bc_idx+i].setHi(dir, REMORABCType::reflect_even);
326 if (i==1)
327 domain_bcs_type[xvel_bc_idx+dir].setHi(dir, REMORABCType::reflect_odd);
328 }
329 }
330 else if (bct == REMORA_BC::outflow)
331 {
332 if (side == Orientation::low) {
333 domain_bcs_type[xvel_bc_idx+i].setLo(dir, REMORABCType::foextrap);
334 } else {
335 domain_bcs_type[xvel_bc_idx+i].setHi(dir, REMORABCType::foextrap);
336 }
337 }
338 else if (bct == REMORA_BC::inflow)
339 {
340 if (side == Orientation::low) {
341 domain_bcs_type[xvel_bc_idx+i].setLo(dir, REMORABCType::ext_dir);
342 } else {
343 domain_bcs_type[xvel_bc_idx+i].setHi(dir, REMORABCType::ext_dir);
344 }
345 }
346 else if (bct == REMORA_BC::no_slip_wall)
347 {
348 if (side == Orientation::low) {
349 domain_bcs_type[xvel_bc_idx+i].setLo(dir, REMORABCType::ext_dir);
350 } else {
351 domain_bcs_type[xvel_bc_idx+i].setHi(dir, REMORABCType::ext_dir);
352 }
353 }
354 else if (bct == REMORA_BC::slip_wall)
355 {
356 if (side == Orientation::low) {
357 domain_bcs_type[xvel_bc_idx+i].setLo(dir, REMORABCType::foextrap);
358 if (i==1) {
359 // Only normal direction has ext_dir
360 domain_bcs_type[xvel_bc_idx+dir].setLo(dir, REMORABCType::ext_dir);
361 }
362
363 } else {
364 domain_bcs_type[xvel_bc_idx+i].setHi(dir, REMORABCType::foextrap);
365 if (i==1) {
366 // Only normal direction has ext_dir
367 domain_bcs_type[xvel_bc_idx+dir].setHi(dir, REMORABCType::ext_dir);
368 }
369 }
370 }
371 else if (bct == REMORA_BC::periodic)
372 {
373 if (side == Orientation::low) {
374 domain_bcs_type[xvel_bc_idx+i].setLo(dir, REMORABCType::int_dir);
375 } else {
376 domain_bcs_type[xvel_bc_idx+i].setHi(dir, REMORABCType::int_dir);
377 }
378 }
379 else if (bct == REMORA_BC::clamped)
380 {
381 if (side == Orientation::low) {
382 domain_bcs_type[xvel_bc_idx+i].setLo(dir, REMORABCType::clamped);
383 } else {
384 domain_bcs_type[xvel_bc_idx+i].setHi(dir, REMORABCType::clamped);
385 }
386 }
387 else if (bct == REMORA_BC::orlanski_rad)
388 {
389 if (side == Orientation::low) {
390 domain_bcs_type[xvel_bc_idx+i].setLo(dir, REMORABCType::orlanski_rad);
391 } else {
392 domain_bcs_type[xvel_bc_idx+i].setHi(dir, REMORABCType::orlanski_rad);
393 }
394 }
395 else if (bct == REMORA_BC::orlanski_rad_nudge)
396 {
397 if (side == Orientation::low) {
398 domain_bcs_type[xvel_bc_idx+i].setLo(dir, REMORABCType::orlanski_rad_nudge);
399 } else {
400 domain_bcs_type[xvel_bc_idx+i].setHi(dir, REMORABCType::orlanski_rad_nudge);
401 }
402 }
403 else
404 {
405 amrex::Abort("Velocity boundary condition not validly specified");
406 }
407 }
408
409 // Always set zvel_bc to foextrap
410 if (side == Orientation::low) {
411 domain_bcs_type[zvel_bc_idx].setLo(dir, REMORABCType::foextrap);
412 } else {
413 domain_bcs_type[zvel_bc_idx].setHi(dir, REMORABCType::foextrap);
414 }
415 }
416 }
417
418 // *****************************************************************************
419 //
420 // Here we translate the physical boundary conditions -- one type per face --
421 // into logical boundary conditions for each cell-centered variable
422 //
423 // *****************************************************************************
424 {
425 for (OrientationIter oit; oit; ++oit) {
426 Orientation ori = oit();
427 int dir = ori.coordDir();
428 Orientation::Side side = ori.faceDir();
429 for (int i = 0; i < ncons; i++) {
430 auto const bct = phys_bc_type[BCVars::cons_bc+i][ori];
431 if ( bct == REMORA_BC::symmetry )
432 {
433 if (side == Orientation::low) {
435 } else {
437 }
438 }
439 else if ( bct == REMORA_BC::outflow)
440 {
441 if (side == Orientation::low) {
443 } else {
445 }
446 }
447 else if ( bct == REMORA_BC::no_slip_wall)
448 {
449 if (side == Orientation::low) {
451 } else {
453 }
454 }
455 else if (bct == REMORA_BC::slip_wall)
456 {
457 if (side == Orientation::low) {
459 } else {
461 }
462 }
463 else if (bct == REMORA_BC::inflow)
464 {
465 if (side == Orientation::low) {
467 } else {
469 }
470 }
471 else if (bct == REMORA_BC::periodic)
472 {
473 if (side == Orientation::low) {
475 } else {
477 }
478 }
479 else if ( bct == REMORA_BC::clamped)
480 {
481 if (side == Orientation::low) {
483 } else {
485 }
486 }
487 else if ( bct == REMORA_BC::orlanski_rad)
488 {
489 if (side == Orientation::low) {
491 } else {
493 }
494 }
495 else if ( bct == REMORA_BC::orlanski_rad_nudge)
496 {
497 if (side == Orientation::low) {
499 } else {
501 }
502 }
503 else
504 {
505 amrex::Abort("Scalar/tracer boundary condition not validly specified");
506 }
507 }
508 }
509 }
510
511 // *****************************************************************************
512 //
513 // Here we translate the physical boundary conditions -- one type per face --
514 // into logical boundary conditions for ubar and vbar. Also add simplified
515 // 2d boundary condition (corresponding to BCs in bc_2d.F
516 //
517 // *****************************************************************************
518 {
519 for (OrientationIter oit; oit; ++oit) {
520 Orientation ori = oit();
521 int dir = ori.coordDir();
522 Orientation::Side side = ori.faceDir();
523 for (int i = 0; i < 2; i++) {
524 auto const bct = phys_bc_type[ubar_bc_idx+i][ori];
525 if ( bct == REMORA_BC::symmetry )
526 {
527 if (side == Orientation::low) {
528 domain_bcs_type[ubar_bc_idx+i].setLo(dir, REMORABCType::reflect_even);
529 domain_bcs_type[u2d_simple_bc_idx+i].setLo(dir, REMORABCType::reflect_even);
530 if (i==1 and dir!=2) {
531 domain_bcs_type[ubar_bc_idx+dir].setLo(dir, REMORABCType::reflect_odd);
532 domain_bcs_type[u2d_simple_bc_idx+dir].setLo(dir, REMORABCType::reflect_odd);
533 }
534 } else {
535 domain_bcs_type[ubar_bc_idx+i].setHi(dir, REMORABCType::reflect_even);
536 domain_bcs_type[u2d_simple_bc_idx+i].setHi(dir, REMORABCType::reflect_even);
537 if (i==1 and dir!=2) {
538 domain_bcs_type[ubar_bc_idx+dir].setHi(dir, REMORABCType::reflect_odd);
539 domain_bcs_type[u2d_simple_bc_idx+dir].setHi(dir, REMORABCType::reflect_odd);
540 }
541 }
542 }
543 else if (bct == REMORA_BC::outflow)
544 {
545 if (side == Orientation::low) {
546 domain_bcs_type[ubar_bc_idx+i].setLo(dir, REMORABCType::foextrap);
547 domain_bcs_type[u2d_simple_bc_idx+i].setLo(dir, REMORABCType::foextrap);
548 } else {
549 domain_bcs_type[ubar_bc_idx+i].setHi(dir, REMORABCType::foextrap);
550 domain_bcs_type[u2d_simple_bc_idx+i].setHi(dir, REMORABCType::foextrap);
551 }
552 }
553 else if (bct == REMORA_BC::inflow)
554 {
555 if (side == Orientation::low) {
556 domain_bcs_type[ubar_bc_idx+i].setLo(dir, REMORABCType::ext_dir);
557 domain_bcs_type[u2d_simple_bc_idx+i].setLo(dir, REMORABCType::ext_dir);
558 } else {
559 domain_bcs_type[ubar_bc_idx+i].setHi(dir, REMORABCType::ext_dir);
560 domain_bcs_type[u2d_simple_bc_idx+i].setHi(dir, REMORABCType::ext_dir);
561 }
562 }
563 else if (bct == REMORA_BC::no_slip_wall)
564 {
565 if (side == Orientation::low) {
566 domain_bcs_type[ubar_bc_idx+i].setLo(dir, REMORABCType::ext_dir);
567 domain_bcs_type[u2d_simple_bc_idx+i].setLo(dir, REMORABCType::ext_dir);
568 } else {
569 domain_bcs_type[ubar_bc_idx+i].setHi(dir, REMORABCType::ext_dir);
570 domain_bcs_type[u2d_simple_bc_idx+i].setHi(dir, REMORABCType::ext_dir);
571 }
572 }
573 else if (bct == REMORA_BC::slip_wall)
574 {
575 if (side == Orientation::low) {
576 domain_bcs_type[ubar_bc_idx+i].setLo(dir, REMORABCType::foextrap);
577 domain_bcs_type[u2d_simple_bc_idx+i].setLo(dir, REMORABCType::foextrap);
578 if (i==1 and dir!=2) {
579 // Only normal direction has ext_dir
580 domain_bcs_type[ubar_bc_idx+dir].setLo(dir, REMORABCType::ext_dir);
581 domain_bcs_type[u2d_simple_bc_idx+dir].setLo(dir, REMORABCType::ext_dir);
582 }
583
584 } else {
585 domain_bcs_type[ubar_bc_idx+i].setHi(dir, REMORABCType::foextrap);
586 domain_bcs_type[u2d_simple_bc_idx+i].setHi(dir, REMORABCType::foextrap);
587 if (i==1 and dir!=2) {
588 // Only normal direction has ext_dir
589 domain_bcs_type[ubar_bc_idx+dir].setHi(dir, REMORABCType::ext_dir);
590 domain_bcs_type[u2d_simple_bc_idx+dir].setHi(dir, REMORABCType::ext_dir);
591 }
592 }
593 }
594 else if (bct == REMORA_BC::periodic)
595 {
596 if (side == Orientation::low) {
597 domain_bcs_type[ubar_bc_idx+i].setLo(dir, REMORABCType::int_dir);
598 domain_bcs_type[u2d_simple_bc_idx+i].setLo(dir, REMORABCType::int_dir);
599 } else {
600 domain_bcs_type[ubar_bc_idx+i].setHi(dir, REMORABCType::int_dir);
601 domain_bcs_type[u2d_simple_bc_idx+i].setHi(dir, REMORABCType::int_dir);
602 }
603 }
604 else if (bct == REMORA_BC::clamped)
605 {
606 if (side == Orientation::low) {
607 domain_bcs_type[ubar_bc_idx+i].setLo(dir, REMORABCType::clamped);
608 domain_bcs_type[u2d_simple_bc_idx+i].setLo(dir, REMORABCType::foextrap);
609 } else {
610 domain_bcs_type[ubar_bc_idx+i].setHi(dir, REMORABCType::clamped);
611 domain_bcs_type[u2d_simple_bc_idx+i].setHi(dir, REMORABCType::foextrap);
612 }
613 }
614 else if (bct == REMORA_BC::flather)
615 {
616 if (side == Orientation::low) {
617 domain_bcs_type[ubar_bc_idx+i].setLo(dir, REMORABCType::chapman);
618 domain_bcs_type[u2d_simple_bc_idx+i].setLo(dir, REMORABCType::foextrap);
619 if (i==1 and dir!=2) {
620 // Only normal direction has Flather
621 domain_bcs_type[ubar_bc_idx+dir].setLo(dir, REMORABCType::flather);
622 domain_bcs_type[u2d_simple_bc_idx+dir].setLo(dir, REMORABCType::foextrap);
623 }
624
625 } else {
626 domain_bcs_type[ubar_bc_idx+i].setHi(dir, REMORABCType::chapman);
627 domain_bcs_type[u2d_simple_bc_idx+i].setHi(dir, REMORABCType::foextrap);
628 if (i==1 and dir!=2) {
629 // Only normal direction has Flather
630 domain_bcs_type[ubar_bc_idx+dir].setHi(dir, REMORABCType::flather);
631 domain_bcs_type[u2d_simple_bc_idx+dir].setHi(dir, REMORABCType::foextrap);
632 }
633 }
634 }
635 else if (bct == REMORA_BC::orlanski_rad)
636 {
637 if (side == Orientation::low) {
638 domain_bcs_type[ubar_bc_idx+i].setLo(dir, REMORABCType::orlanski_rad);
639 domain_bcs_type[u2d_simple_bc_idx+i].setLo(dir, REMORABCType::foextrap);
640 } else {
641 domain_bcs_type[ubar_bc_idx+i].setHi(dir, REMORABCType::orlanski_rad);
642 domain_bcs_type[u2d_simple_bc_idx+i].setHi(dir, REMORABCType::foextrap);
643 }
644 }
645 else if (bct == REMORA_BC::orlanski_rad_nudge)
646 {
647 if (side == Orientation::low) {
648 domain_bcs_type[ubar_bc_idx+i].setLo(dir, REMORABCType::orlanski_rad_nudge);
649 domain_bcs_type[u2d_simple_bc_idx+i].setLo(dir, REMORABCType::foextrap);
650 } else {
651 domain_bcs_type[ubar_bc_idx+i].setHi(dir, REMORABCType::orlanski_rad_nudge);
652 domain_bcs_type[u2d_simple_bc_idx+i].setHi(dir, REMORABCType::foextrap);
653 }
654 }
655 else
656 {
657 amrex::Abort("ubar or vbar boundary condition not validly specified");
658 }
659 }
660 }
661 }
662
663 // *****************************************************************************
664 //
665 // Here we translate the physical boundary conditions -- one type per face --
666 // into logical boundary conditions for zeta and tke
667 //
668 // *****************************************************************************
669 {
670 for (OrientationIter oit; oit; ++oit) {
671 Orientation ori = oit();
672 int dir = ori.coordDir();
673 Orientation::Side side = ori.faceDir();
674 for (int i = 0; i < 2; i++) {
675 auto const bct = phys_bc_type[zeta_bc_idx+i][ori];
676 if ( bct == REMORA_BC::symmetry )
677 {
678 if (side == Orientation::low) {
679 domain_bcs_type[zeta_bc_idx+i].setLo(dir, REMORABCType::reflect_even);
680 } else {
681 domain_bcs_type[zeta_bc_idx+i].setHi(dir, REMORABCType::reflect_even);
682 }
683 }
684 else if ( bct == REMORA_BC::outflow)
685 {
686 if (side == Orientation::low) {
687 domain_bcs_type[zeta_bc_idx+i].setLo(dir, REMORABCType::foextrap);
688 } else {
689 domain_bcs_type[zeta_bc_idx+i].setHi(dir, REMORABCType::foextrap);
690 }
691 }
692 else if ( bct == REMORA_BC::no_slip_wall)
693 {
694 if (side == Orientation::low) {
695 domain_bcs_type[zeta_bc_idx+i].setLo(dir, REMORABCType::foextrap);
696 } else {
697 domain_bcs_type[zeta_bc_idx+i].setHi(dir, REMORABCType::foextrap);
698 }
699 }
700 else if (bct == REMORA_BC::slip_wall)
701 {
702 if (side == Orientation::low) {
703 domain_bcs_type[zeta_bc_idx+i].setLo(dir, REMORABCType::foextrap);
704 } else {
705 domain_bcs_type[zeta_bc_idx+i].setHi(dir, REMORABCType::foextrap);
706 }
707 }
708 else if (bct == REMORA_BC::inflow)
709 {
710 if (side == Orientation::low) {
711 domain_bcs_type[zeta_bc_idx+i].setLo(dir, REMORABCType::ext_dir);
712 } else {
713 domain_bcs_type[zeta_bc_idx+i].setHi(dir, REMORABCType::ext_dir);
714 }
715 }
716 else if (bct == REMORA_BC::periodic)
717 {
718 if (side == Orientation::low) {
719 domain_bcs_type[zeta_bc_idx+i].setLo(dir, REMORABCType::int_dir);
720 } else {
721 domain_bcs_type[zeta_bc_idx+i].setHi(dir, REMORABCType::int_dir);
722 }
723 }
724 else if (bct == REMORA_BC::chapman)
725 {
726 if (side == Orientation::low) {
727 domain_bcs_type[zeta_bc_idx+i].setLo(dir, REMORABCType::chapman);
728 } else {
729 domain_bcs_type[zeta_bc_idx+i].setHi(dir, REMORABCType::chapman);
730 }
731 }
732 else if ( bct == REMORA_BC::clamped)
733 {
734 if (side == Orientation::low) {
735 domain_bcs_type[zeta_bc_idx+i].setLo(dir, REMORABCType::clamped);
736 } else {
737 domain_bcs_type[zeta_bc_idx+i].setHi(dir, REMORABCType::clamped);
738 }
739 }
740 else if ( bct == REMORA_BC::orlanski_rad)
741 {
742 if (side == Orientation::low) {
743 domain_bcs_type[zeta_bc_idx+i].setLo(dir, REMORABCType::orlanski_rad);
744 } else {
745 domain_bcs_type[zeta_bc_idx+i].setHi(dir, REMORABCType::orlanski_rad);
746 }
747 }
748 else if ( bct == REMORA_BC::orlanski_rad_nudge)
749 {
750 if (side == Orientation::low) {
751 domain_bcs_type[zeta_bc_idx+i].setLo(dir, REMORABCType::orlanski_rad_nudge);
752 } else {
753 domain_bcs_type[zeta_bc_idx+i].setHi(dir, REMORABCType::orlanski_rad_nudge);
754 }
755 }
756 else
757 {
758 amrex::Abort("Free surface (zeta) boundary condition not validly specified");
759 }
760 }
761 }
762 }
763
764 // *****************************************************************************
765 //
766 // Here we define a boundary condition that will foextrap while respecting periodicity
767 // This is used as a "null BC"
768 //
769 // *****************************************************************************
770 {
771 for (OrientationIter oit; oit; ++oit) {
772 Orientation ori = oit();
773 int dir = ori.coordDir();
774 Orientation::Side side = ori.faceDir();
775 if (side == Orientation::low) {
776 domain_bcs_type[foextrap_periodic_bc_idx].setLo(dir, REMORABCType::foextrap);
777 } else {
778 domain_bcs_type[foextrap_periodic_bc_idx].setHi(dir, REMORABCType::foextrap);
779 }
780 }
781 }
782
783 // *****************************************************************************
784 //
785 // Here we define a boundary condition that will unconditionally foextrap
786 //
787 // *****************************************************************************
788 {
789 for (OrientationIter oit; oit; ++oit) {
790 Orientation ori = oit();
791 int dir = ori.coordDir();
792 Orientation::Side side = ori.faceDir();
793 if (side == Orientation::low) {
794 domain_bcs_type[foextrap_bc_idx].setLo(dir, REMORABCType::foextrap);
795 } else {
796 domain_bcs_type[foextrap_bc_idx].setHi(dir, REMORABCType::foextrap);
797 }
798 }
799 }
800
801
802#ifdef AMREX_USE_GPU
803 Gpu::htod_memcpy
804 (domain_bcs_type_d.data(), domain_bcs_type.data(),
805 sizeof(amrex::BCRec)*num_bc_vars());
806#else
807 std::memcpy
808 (domain_bcs_type_d.data(), domain_bcs_type.data(),
809 sizeof(amrex::BCRec)*num_bc_vars());
810#endif
811}
@ orlanski_rad_nudge
#define Tracer_comp
int foextrap_periodic_bc() const noexcept
Definition REMORA.H:1145
int ncons
Number of conserved scalars in the state (temperature + salt + passive scalars)
Definition REMORA.H:1437
int zvel_bc() const noexcept
Definition REMORA.H:1140
void init_bcs()
Read in boundary parameters from input file and set up data structures.
int xvel_bc() const noexcept
Definition REMORA.H:1138
amrex::Vector< amrex::BCRec > domain_bcs_type
vector (over BCVars) of BCRecs
Definition REMORA.H:1386
bool set_bcs_by_var
whether to set boundary conditions by variable rather than just by side
Definition REMORA.H:1371
int tke_bc() const noexcept
Definition REMORA.H:1144
int num_bc_vars() const noexcept
Definition REMORA.H:1149
int yvel_bc() const noexcept
Definition REMORA.H:1139
int foextrap_bc() const noexcept
Definition REMORA.H:1146
int v2d_simple_bc() const noexcept
Definition REMORA.H:1148
int zeta_bc() const noexcept
Definition REMORA.H:1143
amrex::Vector< amrex::GpuArray< REMORA_BC, AMREX_SPACEDIM *2 > > phys_bc_type
Array holding the "physical" boundary condition types (e.g. "inflow")
Definition REMORA.H:1397
amrex::Vector< int > bdy_index
Container to connect boundary data being read in boundary condition containers.
Definition REMORA.H:1406
int u2d_simple_bc() const noexcept
Definition REMORA.H:1147
static SolverChoice solverChoice
Container for algorithmic choices.
Definition REMORA.H:1494
int ubar_bc() const noexcept
Definition REMORA.H:1141
int vbar_bc() const noexcept
Definition REMORA.H:1142
amrex::Array< std::string, 2 *AMREX_SPACEDIM > domain_bc_type
Array of strings describing domain boundary conditions.
Definition REMORA.H:1391
amrex::GpuArray< amrex::GpuArray< bool, AMREX_SPACEDIM *2 >, BdyVars::NumTypes+1 > phys_bc_need_data
These are flags that indicate whether we need to read in boundary data from file.
Definition REMORA.H:1400
amrex::Vector< amrex::GpuArray< amrex::Real, AMREX_SPACEDIM *2 > > m_bc_extdir_vals
Array holding the Dirichlet values at walls which need them.
Definition REMORA.H:1394
amrex::Gpu::DeviceVector< amrex::BCRec > domain_bcs_type_d
GPU vector (over BCVars) of BCRecs.
Definition REMORA.H:1388
int NumTypes(int ncons) noexcept
static constexpr int cons_bc
static constexpr int Salt_bc_comp
static constexpr int Temp_bc_comp
static constexpr int Scalar_bc_comp