REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_FillPatch.cpp
Go to the documentation of this file.
1#include <REMORA.H>
5
6using namespace amrex;
7
8PhysBCFunctNoOp null_bc;
9
10/**
11 * Fill valid and ghost data in the MultiFab "mf"
12 * This version fills the MultiFab mf_to_fill in valid regions with
13 * the "state data" at the given time;
14 * values in mf when it is passed in are *not* used.
15 *
16 * @param[in ] lev level to FillPatch on
17 * @param[in ] time current time
18 * @param[inout] mf_to_fill MultiFab to fill
19 * @param[in ] mfs vector over levels of multifabs associated with mf_to_fill
20 * @param[in ] bccomp index into domain_bcs_type
21 * @param[in ] bdy_var_type when filling from NetCDF, which boundary data
22 * @param[in ] icomp component to fill
23 * @param[in ] fill_all whether to fill all components
24 * @param[in ] fill_set whether to use FillPatchers
25 * @param[in ] icomp_calc component to use in RHS boundary calculation
26 * @param[in ] dt_lev time step at this level
27 * @param[in ] mf_calc data to use in RHS boundary calculation
28 */
29void
30REMORA::FillPatch (int lev, Real time, MultiFab& mf_to_fill, Vector<MultiFab*> const& mfs,
31 const int bccomp,
32#ifdef REMORA_USE_NETCDF
33 const int bdy_var_type,
34#else
35 const int /*bdy_var_type*/,
36#endif
37 const int icomp,
38 const bool fill_all,
39 const bool fill_set,
40 const int n_not_fill,
41 const int icomp_calc,
42 const Real dt_lev,
43 const MultiFab& mf_calc)
44{
45 BL_PROFILE_VAR("REMORA::FillPatch()",REMORA_FillPatch);
46 amrex::Interpolater* mapper = nullptr;
47
48 Box mf_box(mf_to_fill.boxArray()[0]);
49 bool is_2d = mf_box.length(2) == 1;
50
51 MultiFab* mask;
52
53 //
54 // ***************************************************************************
55 // The first thing we do is interpolate the momenta on the "valid" faces of
56 // the fine grids (where the interface is coarse/fine not fine/fine) -- this
57 // will not be over-written below because the FillPatch operators see these as
58 // valid faces.
59 // ***************************************************************************
60 if (lev>0 && fill_set) {
61 if (cf_set_width > 0 &&
62 mf_box.ixType() == IndexType(IntVect(0,0,0))) {
63 FPr_c[lev-1].FillSet(mf_to_fill, time, null_bc, domain_bcs_type);
64 } else if (cf_set_width >= 0) {
65 if (!is_2d) {
66 if (mf_box.ixType() == IndexType(IntVect(1,0,0))) {
67 FPr_u[lev-1].FillSet(mf_to_fill, time, null_bc, domain_bcs_type);
68 } else if (mf_box.ixType() == IndexType(IntVect(0,1,0))) {
69 FPr_v[lev-1].FillSet(mf_to_fill, time, null_bc, domain_bcs_type);
70 } else if (mf_box.ixType() == IndexType(IntVect(0,0,1))) {
71 FPr_w[lev-1].FillSet(mf_to_fill, time, null_bc, domain_bcs_type);
72 }
73 } else {
74 if (mf_box.ixType() == IndexType(IntVect(1,0,0))) {
75 FPr_ubar[lev-1].FillSet(mf_to_fill, time, null_bc, domain_bcs_type);
76 } else if (mf_box.ixType() == IndexType(IntVect(0,1,0))) {
77 FPr_vbar[lev-1].FillSet(mf_to_fill, time, null_bc, domain_bcs_type);
78 }
79 }
80 }
81 }
82
83 int ncomp;
84 if (fill_all) {
85 ncomp = mf_to_fill.nComp();
86 } else {
87 ncomp = 1;
88 }
89
90 if (mf_box.ixType() == IndexType(IntVect(0,0,0)))
91 {
92 mapper = &cell_cons_interp;
93 mask = vec_mskr[lev].get();
94 }
95 else if (mf_box.ixType() == IndexType(IntVect(1,0,0)))
96 {
97 mapper = &face_linear_interp;
98 mask = vec_msku[lev].get();
99 }
100 else if (mf_box.ixType() == IndexType(IntVect(0,1,0)))
101 {
102 mapper = &face_linear_interp;
103 mask = vec_mskv[lev].get();
104 }
105 else {
106 mapper = &face_linear_interp;
107 mask = vec_mskr[lev].get();
108 }
109
110 if (lev == 0)
111 {
112 Vector<MultiFab*> fmf = {mfs[lev], mfs[lev]};
113 Vector<Real> ftime = {t_old[lev], t_new[lev]};
114 amrex::FillPatchSingleLevel(mf_to_fill, time, fmf, ftime, icomp, icomp, ncomp,
115 geom[lev], null_bc, bccomp);
116 }
117 else
118 {
119 Vector<MultiFab*> fmf = {mfs[lev], mfs[lev]};
120 Vector<Real> ftime = {t_old[lev], t_new[lev]};
121 Vector<MultiFab*> cmf = {mfs[lev-1], mfs[lev-1]};
122 Vector<Real> ctime = {t_old[lev-1], t_new[lev-1]};
123
124 mfs[lev-1]->FillBoundary(geom[lev-1].periodicity());
125 amrex::FillPatchTwoLevels(mf_to_fill, mf_to_fill.nGrowVect(), IntVect(0,0,0),
126 time, cmf, ctime, fmf, ftime,
127 icomp, icomp, ncomp, geom[lev-1], geom[lev],
128 //null_bc, bccomp, null_bc, bccomp,
129 refRatio(lev-1),
130 mapper, domain_bcs_type, bccomp);
131 } // lev > 0
132
133 // This is currently unconditionally true, but do_bc flag should actually be passed in
134 const bool do_bc=true;
135 if (do_bc) {
136 // ***************************************************************************
137 // Physical bc's at domain boundary
138 // ***************************************************************************
139
140 // Enforce physical boundary conditions
141 (*physbcs[lev])(mf_to_fill,*mask,icomp,ncomp,mf_to_fill.nGrowVect(),time,bccomp,n_not_fill,mf_calc,
142 *vec_msku[lev].get(), *vec_mskv[lev].get());
143
144#ifdef REMORA_USE_NETCDF
145 // Fill the data which is stored in the boundary data read from netcdf files
146 if ( (solverChoice.boundary_from_netcdf) && (lev==0) &&
147 (bdy_var_type != BdyVars::null) )
148 {
149 fill_from_bdyfiles(mf_to_fill,*mask,time,bccomp,bdy_var_type, icomp,icomp_calc,mf_calc,dt_lev);
150 }
151#endif
152 // Fill corners of the domain with periodic data
153 if ( mf_box.ixType() == IndexType(IntVect(0,0,0)) ) {
154 mf_to_fill.EnforcePeriodicity(geom[lev].periodicity());
155 }
156
157 // Also enforce free-slip at top boundary (on xvel or yvel)
158 if ( (mf_box.ixType() == IndexType(IntVect(1,0,0))) ||
159 (mf_box.ixType() == IndexType(IntVect(0,1,0))) )
160 {
161 int khi = geom[lev].Domain().bigEnd(2);
162 for (MFIter mfi(mf_to_fill); mfi.isValid(); ++mfi)
163 {
164 Box gbx = mfi.growntilebox(); // Note this is face-centered since vel is
165 gbx.setSmall(2,khi+1);
166 if (gbx.ok()) {
167 Array4<Real> vel_arr = mf_to_fill.array(mfi);
168 ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
169 {
170 vel_arr(i,j,k) = vel_arr(i,j,khi);
171 });
172 }
173 }
174 }
175 }
176}
177
178/**
179 * Fill valid and ghost data in the MultiFab "mf"
180 * This version fills the MultiFab mf_to_fill in valid regions with
181 * the "state data" at the given time;
182 * values in mf when it is passed in are *not* used.
183 * Unlike FillPatch, FillPatchNoBC does not apply boundary conditions
184 *
185 * @param[in ] lev level to FillPatch on
186 * @param[in ] time current time
187 * @param[inout] mf_to_fill MultiFab to fill
188 * @param[in ] mfs vector over levels of multifabs associated with mf_to_fill
189 * @param[in ] bdy_var_type when filling from NetCDF, which boundary data
190 * @param[in ] icomp component to fill
191 * @param[in ] fill_all whether to fill all components
192 * @param[in ] fill_set whether to use FillPatchers
193 */
194void
195REMORA::FillPatchNoBC (int lev, Real time, MultiFab& mf_to_fill, Vector<MultiFab*> const& mfs,
196#ifdef REMORA_USE_NETCDF
197 const int /*bdy_var_type*/,
198#else
199 const int /*bdy_var_type*/,
200#endif
201 const int icomp,
202 const bool fill_all,
203 const bool fill_set)
204{
205 // HACK: Note that this is hacky; should be able to have a single call to FillPatch with a
206 // flag for bcs, but for some reason it was acting weird, so we're splitting this out into
207 // two functions with repeated code for the time being
208 BL_PROFILE_VAR("REMORA::FillPatch()",REMORA_FillPatch);
209 int bccomp;
210 amrex::Interpolater* mapper = nullptr;
211
212 Box mf_box(mf_to_fill.boxArray()[0]);
213 bool is_2d = mf_box.length(2) == 1;
214
215 //
216 // ***************************************************************************
217 // The first thing we do is interpolate the momenta on the "valid" faces of
218 // the fine grids (where the interface is coarse/fine not fine/fine) -- this
219 // will not be over-written below because the FillPatch operators see these as
220 // valid faces.
221 // ***************************************************************************
222 if (lev>0 && fill_set) {
223 if (cf_set_width > 0 &&
224 mf_box.ixType() == IndexType(IntVect(0,0,0))) {
225 FPr_c[lev-1].FillSet(mf_to_fill, time, null_bc, domain_bcs_type);
226 } else if (cf_set_width >= 0) {
227 if (!is_2d) {
228 if (mf_box.ixType() == IndexType(IntVect(1,0,0))) {
229 FPr_u[lev-1].FillSet(mf_to_fill, time, null_bc, domain_bcs_type);
230 } else if (mf_box.ixType() == IndexType(IntVect(0,1,0))) {
231 FPr_v[lev-1].FillSet(mf_to_fill, time, null_bc, domain_bcs_type);
232 } else if (mf_box.ixType() == IndexType(IntVect(0,0,1))) {
233 FPr_w[lev-1].FillSet(mf_to_fill, time, null_bc, domain_bcs_type);
234 }
235 } else {
236 if (mf_box.ixType() == IndexType(IntVect(1,0,0))) {
237 FPr_ubar[lev-1].FillSet(mf_to_fill, time, null_bc, domain_bcs_type);
238 } else if (mf_box.ixType() == IndexType(IntVect(0,1,0))) {
239 FPr_vbar[lev-1].FillSet(mf_to_fill, time, null_bc, domain_bcs_type);
240 }
241 }
242 }
243 }
244
245 int ncomp;
246 if (fill_all) {
247 ncomp = mf_to_fill.nComp();
248 } else {
249 ncomp = 1;
250 }
251
252 if (mf_box.ixType() == IndexType(IntVect(0,0,0)))
253 {
254 bccomp = 0;
255 mapper = &cell_cons_interp;
256 }
257 else if (mf_box.ixType() == IndexType(IntVect(1,0,0)))
258 {
259 bccomp = BCVars::xvel_bc;
260 mapper = &face_linear_interp;
261 }
262 else if (mf_box.ixType() == IndexType(IntVect(0,1,0)))
263 {
264 bccomp = BCVars::yvel_bc;
265 mapper = &face_linear_interp;
266 }
267 else {
268 bccomp = BCVars::zvel_bc;
269 mapper = &face_linear_interp;
270 }
271
272 if (lev == 0)
273 {
274 Vector<MultiFab*> fmf = {mfs[lev], mfs[lev]};
275 Vector<Real> ftime = {t_old[lev], t_new[lev]};
276 amrex::FillPatchSingleLevel(mf_to_fill, time, fmf, ftime, icomp, icomp, ncomp,
277 geom[lev], null_bc, bccomp);
278 }
279 else
280 {
281 Vector<MultiFab*> fmf = {mfs[lev], mfs[lev]};
282 Vector<Real> ftime = {t_old[lev], t_new[lev]};
283 Vector<MultiFab*> cmf = {mfs[lev-1], mfs[lev-1]};
284 Vector<Real> ctime = {t_old[lev-1], t_new[lev-1]};
285
286 mfs[lev-1]->FillBoundary(geom[lev-1].periodicity());
287 amrex::FillPatchTwoLevels(mf_to_fill, mf_to_fill.nGrowVect(), IntVect(0,0,0),
288 time, cmf, ctime, fmf, ftime,
289 icomp, icomp, ncomp, geom[lev-1], geom[lev],
290 //null_bc, bccomp, null_bc, bccomp,
291 refRatio(lev-1),
292 mapper, domain_bcs_type, bccomp);
293 } // lev > 0
294}
295
296
297// utility to copy in data from old/new data into a struct that holds data for FillPatching
299REMORA::GetDataAtTime (int /*lev*/, Real /*time*/)
300{
301 BL_PROFILE_VAR("GetDataAtTime()",GetDataAtTime);
303
304// HACK HACK HACK
305#if 0
306 const Real teps = (t_new[lev] - t_old[lev]) * 1.e-3_rt;
307
308 if (time > t_new[lev] - teps && time < t_new[lev] + teps)
309 {
310 for (int i = 0; i < Vars::NumTypes; ++i) {
311 data.add_var(&vars_new[lev][i], data.non_owning);
312 }
313 data.set_time(t_new[lev]);
314 }
315 else if (time > t_old[lev] - teps && time < t_old[lev] + teps)
316 {
317 for (int i = 0; i < Vars::NumTypes; ++i) {
318 data.add_var(&vars_old[lev][i], data.non_owning);
319 }
320 data.set_time(t_old[lev]);
321 }
322 else if (time > t_old[lev] && time < t_new[lev])
323 {
324 // do first order interpolation in time between [t_old[lev], t_new[lev]]
325 // time interpolation includes the ghost cells
326 for (int i = 0; i < Vars::NumTypes; ++i) {
327 MultiFab* mf_tmp = new MultiFab(vars_new[lev][i].boxArray(),
328 vars_new[lev][i].DistributionMap(),
329 vars_new[lev][i].nComp(), vars_new[lev][i].nGrowVect());
330 mf_tmp->setVal(0.0_rt);
331
332 const Real dt_fraction = (time - t_old[lev]) / (t_new[lev] - t_old[lev]);
333 MultiFab::Saxpy(*mf_tmp, 1.0_rt - dt_fraction, vars_old[lev][i], 0, 0, mf_tmp->nComp(), mf_tmp->nGrowVect());
334 MultiFab::Saxpy(*mf_tmp, dt_fraction, vars_new[lev][i], 0, 0, mf_tmp->nComp(), mf_tmp->nGrowVect());
335
336 data.add_var(mf_tmp, data.owning);
337 }
338 data.set_time(time);
339 }
340 else
341 {
342 amrex::Error("Requested data at a time outside the interval [t_old, t_new]");
343 }
344
345 // We need to make sure to fill these before we compute the viscosity
346 for (int i = 0; i < Vars::NumTypes; ++i) {
347 data.get_var(Vars::xvel).FillBoundary(geom[lev].periodicity());
348 data.get_var(Vars::yvel).FillBoundary(geom[lev].periodicity());
349 data.get_var(Vars::zvel).FillBoundary(geom[lev].periodicity());
350 data.get_var(Vars::cons).FillBoundary(geom[lev].periodicity());
351 }
352#endif
353 return data;
354}
355
356/**
357 * Fill an entire multifab by interpolating from the coarser level --
358 * this is used only when a new level of refinement is being created
359 * during a run (i.e not at initialization)
360 * This will never be used with static refinement.
361 *
362 * @param[in ] lev level to FillPatch on
363 * @param[in ] time current time
364 * @param[inout] mf_to_fill MultiFab to fill
365 * @param[inout] mf_crse MultiFab of coarse data
366 * @param[in ] icomp component to fill
367 * @param[in ] fill_all whether to fill all components
368 */
369void
370REMORA::FillCoarsePatch (int lev, Real time, MultiFab* mf_to_fill, MultiFab* mf_crse,
371 const int bdy_var_type,
372 const int icomp,
373 const bool fill_all,
374 const int n_not_fill,
375 const int icomp_calc,
376 const Real dt_lev,
377 const MultiFab& mf_calc)
378{
379 BL_PROFILE_VAR("FillCoarsePatch()",FillCoarsePatch);
380 AMREX_ASSERT(lev > 0);
381
382 MultiFab* mask;
383
384 int ncomp;
385 if (fill_all) {
386 ncomp = mf_to_fill->nComp();
387 } else {
388 ncomp = 1;
389 }
390
391 Box mf_box(mf_to_fill->boxArray()[0]);
392
393 int bccomp = 0;
394 amrex::Interpolater* mapper = nullptr;
395
396 Box box_mf(mf_to_fill->boxArray()[0]);
397
398 if (box_mf.ixType() == IndexType(IntVect(0,0,0)))
399 {
400 bccomp = 0;
401 mapper = &cell_cons_interp;
402 mask = vec_mskr[lev].get();
403 }
404 else if (box_mf.ixType() == IndexType(IntVect(1,0,0)))
405 {
406 bccomp = BCVars::xvel_bc;
407 mapper = &face_linear_interp;
408 mask = vec_msku[lev].get();
409 }
410 else if (box_mf.ixType() == IndexType(IntVect(0,1,0)))
411 {
412 bccomp = BCVars::yvel_bc;
413 mapper = &face_linear_interp;
414 mask = vec_mskv[lev].get();
415 }
416 else if (box_mf.ixType() == IndexType(IntVect(0,0,1)))
417 {
418 bccomp = BCVars::zvel_bc;
419 mapper = &face_linear_interp;
420 mask = vec_mskr[lev].get();
421 } else {
422 amrex::Abort("Dont recognize this box type in REMORA_FillPatch");
423 }
424
425#if 0
426 TimeInterpolatedData cdata = GetDataAtTime(lev-1, time);
427 TimeInterpolatedData fdata = GetDataAtTime(lev , time);
428 Vector<Real> ctime = {cdata.get_time()};
429
430 Vector<MultiFab*> cmf = {mf_crse};
431 Vector<Real> ctime = {time};
432
433 REMORAPhysBCFunct cphysbc(lev-1,geom[lev-1],
435 cdata,
437#ifdef REMORA_USE_NETCDF
438 ,ic_type,bdy_data_xlo,bdy_data_xhi,
440#endif
441 );
442 REMORAPhysBCFunct fphysbc(lev,geom[lev],
444 fdata,
446#ifdef REMORA_USE_NETCDF
447 ,ic_type,bdy_data_xlo,bdy_data_xhi,
449#endif
450 );
451#endif
452
453 mf_crse->FillBoundary(geom[lev-1].periodicity());
454 amrex::InterpFromCoarseLevel(*mf_to_fill, mf_to_fill->nGrowVect(), IntVect(0,0,0),
455 *mf_crse, 0, icomp, ncomp, geom[lev-1], geom[lev],
456 refRatio(lev-1),
457 mapper, domain_bcs_type, bccomp);
458
459 // ***************************************************************************
460 // Physical bc's at domain boundary
461 // ***************************************************************************
462
463 // Enforce physical boundary conditions
464 (*physbcs[lev])(*mf_to_fill,*mask,icomp,ncomp,mf_to_fill->nGrowVect(),
465 time,bccomp,n_not_fill,mf_calc,
466 *vec_msku[lev].get(), *vec_mskv[lev].get());
467
468#ifdef REMORA_USE_NETCDF
469 // Fill the data which is stored in the boundary data read from netcdf files
470 if ( (solverChoice.boundary_from_netcdf) && (lev==0) &&
471 (bdy_var_type != BdyVars::null) )
472 {
473 fill_from_bdyfiles(*mf_to_fill,*mask,time,bccomp,bdy_var_type, icomp,icomp_calc,mf_calc,dt_lev);
474 }
475#endif
476 // Fill corners of the domain with periodic data
477 if ( mf_box.ixType() == IndexType(IntVect(0,0,0)) ) {
478 mf_to_fill->EnforcePeriodicity(geom[lev].periodicity());
479 }
480
481 // Also enforce free-slip at top boundary (on xvel or yvel)
482 if ( (mf_box.ixType() == IndexType(IntVect(1,0,0))) ||
483 (mf_box.ixType() == IndexType(IntVect(0,1,0))) )
484 {
485 int khi = geom[lev].Domain().bigEnd(2);
486 for (MFIter mfi(*mf_to_fill); mfi.isValid(); ++mfi)
487 {
488 Box gbx = mfi.growntilebox(); // Note this is face-centered since vel is
489 gbx.setSmall(2,khi+1);
490 if (gbx.ok()) {
491 Array4<Real> vel_arr = mf_to_fill->array(mfi);
492 ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
493 {
494 vel_arr(i,j,k) = vel_arr(i,j,khi);
495 });
496 }
497 }
498 }
499}
500
501/**
502 * @param[in ] lev level to fill at
503 * @param[in ] lev MultiFab of cell-centered velocities
504 */
505void
506REMORA::FillBdyCCVels (int lev, MultiFab& mf_cc_vel)
507{
508 // Impose bc's at domain boundaries
509// for (int lev = 0; lev <= finest_level; ++lev)
510// {
511 Box domain(Geom(lev).Domain());
512
513 int ihi = domain.bigEnd(0);
514 int jhi = domain.bigEnd(1);
515 int khi = domain.bigEnd(2);
516
517 // Impose periodicity first
518 mf_cc_vel.FillBoundary(geom[lev].periodicity());
519
520#ifdef _OPENMP
521#pragma omp parallel if (Gpu::notInLaunchRegion())
522#endif
523 for (MFIter mfi(mf_cc_vel, TilingIfNotGPU()); mfi.isValid(); ++mfi)
524 {
525 // Note that we don't fill corners here -- only the cells that share a face
526 // with interior cells -- this is all that is needed to calculate vorticity
527 const Box& bx = mfi.tilebox();
528 const Array4<Real>& vel_arr = mf_cc_vel.array(mfi);
529
530 if (!Geom(lev).isPeriodic(0)) {
531 // Low-x side
532 if (bx.smallEnd(0) <= domain.smallEnd(0)) {
533 Real mult = (phys_bc_type[BCVars::xvel_bc][0] == REMORA_BC::no_slip_wall) ? -1. : 1.;
534 ParallelFor(makeSlab(bx,0,0), [=] AMREX_GPU_DEVICE(int , int j, int k) noexcept
535 {
536 vel_arr(-1,j,k,1) = mult*vel_arr(0,j,k,1); // v
537 vel_arr(-1,j,k,2) = mult*vel_arr(0,j,k,2); // w
538 });
539 }
540
541 // High-x side
542 if (bx.bigEnd(0) >= domain.bigEnd(0)) {
543 Real mult = (phys_bc_type[BCVars::xvel_bc][3] == REMORA_BC::no_slip_wall) ? -1. : 1.;
544 ParallelFor(makeSlab(bx,0,0), [=] AMREX_GPU_DEVICE(int , int j, int k) noexcept
545 {
546 vel_arr(ihi+1,j,k,1) = mult*vel_arr(ihi,j,k,1); // v
547 vel_arr(ihi+1,j,k,2) = mult*vel_arr(ihi,j,k,2); // w
548 });
549 }
550 } // !periodic
551
552 if (!Geom(lev).isPeriodic(1)) {
553 // Low-y side
554 if (bx.smallEnd(1) <= domain.smallEnd(1)) {
555 Real mult = (phys_bc_type[BCVars::yvel_bc][1] == REMORA_BC::no_slip_wall) ? -1. : 1.;
556 ParallelFor(makeSlab(bx,1,0), [=] AMREX_GPU_DEVICE(int i, int , int k) noexcept
557 {
558 vel_arr(i,-1,k,0) = mult*vel_arr(i,0,k,0); // u
559 vel_arr(i,-1,k,2) = mult*vel_arr(i,0,k,2); // w
560 });
561 }
562
563 // High-y side
564 if (bx.bigEnd(1) >= domain.bigEnd(1)) {
565 Real mult = (phys_bc_type[BCVars::yvel_bc][4] == REMORA_BC::no_slip_wall) ? -1. : 1.;
566 ParallelFor(makeSlab(bx,1,0), [=] AMREX_GPU_DEVICE(int i, int , int k) noexcept
567 {
568 vel_arr(i,jhi+1,k,0) = mult*vel_arr(i,jhi,k,0); // u
569 vel_arr(i,jhi+1,k,2) = mult*-vel_arr(i,jhi,k,2); // w
570 });
571 }
572 } // !periodic
573
574 if (!Geom(lev).isPeriodic(2)) {
575 // Low-z side
576 if (bx.smallEnd(2) <= domain.smallEnd(2)) {
577 Real mult = (phys_bc_type[BCVars::zvel_bc][2] == REMORA_BC::no_slip_wall) ? -1. : 1.;
578 ParallelFor(makeSlab(bx,2,0), [=] AMREX_GPU_DEVICE(int i, int j, int) noexcept
579 {
580 vel_arr(i,j,-1,0) = mult*vel_arr(i,j,0,0); // u
581 vel_arr(i,j,-1,1) = mult*vel_arr(i,j,0,1); // v
582 });
583 }
584
585 // High-z side
586 if (bx.bigEnd(2) >= domain.bigEnd(2)) {
587 Real mult = (phys_bc_type[BCVars::zvel_bc][5] == REMORA_BC::no_slip_wall) ? -1. : 1.;
588 ParallelFor(makeSlab(bx,2,0), [=] AMREX_GPU_DEVICE(int i, int j, int) noexcept
589 {
590 vel_arr(i,j,khi+1,0) = mult*vel_arr(i,j,khi,0); // u
591 vel_arr(i,j,khi+1,1) = mult*vel_arr(i,j,khi,1); // v
592 });
593 }
594 } // !periodic
595 } // MFIter
596
597// } // lev
598}
PhysBCFunctNoOp null_bc
amrex::Vector< amrex::BCRec > domain_bcs_type
vector (over BCVars) of BCRecs
Definition REMORA.H:1136
amrex::Vector< REMORAFillPatcher > FPr_v
Vector over levels of FillPatchers for v (3D)
Definition REMORA.H:1071
amrex::GpuArray< amrex::GpuArray< REMORA_BC, AMREX_SPACEDIM *2 >, BCVars::NumTypes > phys_bc_type
Array holding the "physical" boundary condition types (e.g. "inflow")
Definition REMORA.H:1147
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskr
land/sea mask at cell centers (2D)
Definition REMORA.H:349
amrex::Vector< REMORAFillPatcher > FPr_u
Vector over levels of FillPatchers for u (3D)
Definition REMORA.H:1069
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_msku
land/sea mask at x-faces (2D)
Definition REMORA.H:351
void FillPatchNoBC(int lev, amrex::Real time, amrex::MultiFab &mf_to_be_filled, amrex::Vector< amrex::MultiFab * > const &mfs, const int bdy_var_type=BdyVars::null, const int icomp=0, const bool fill_all=true, const bool fill_set=true)
Fill a new MultiFab by copying in phi from valid region and filling ghost cells without applying boun...
amrex::Vector< amrex::Vector< amrex::FArrayBox > > bdy_data_yhi
Vectors (over time) of Vector (over variables) of FArrayBoxs for holding Northern boundary data from ...
Definition REMORA.H:1012
amrex::Real bdy_time_interval
Interval between boundary data times.
Definition REMORA.H:1017
amrex::Vector< REMORAFillPatcher > FPr_vbar
Vector over levels of FillPatchers for vbar (2D)
Definition REMORA.H:1079
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskv
land/sea mask at y-faces (2D)
Definition REMORA.H:353
amrex::Vector< std::unique_ptr< REMORAPhysBCFunct > > physbcs
Vector (over level) of functors to apply physical boundary conditions.
Definition REMORA.H:1124
void FillPatch(int lev, amrex::Real time, amrex::MultiFab &mf_to_be_filled, amrex::Vector< amrex::MultiFab * > const &mfs, const int bccomp, const int bdy_var_type=BdyVars::null, const int icomp=0, const bool fill_all=true, const bool fill_set=true, const int n_not_fill=0, const int icomp_calc=0, const amrex::Real dt=amrex::Real(0.0), const amrex::MultiFab &mf_calc=amrex::MultiFab())
Fill a new MultiFab by copying in phi from valid region and filling ghost cells.
amrex::Vector< amrex::Vector< amrex::FArrayBox > > bdy_data_ylo
Vectors (over time) of Vector (over variables) of FArrayBoxs for holding Southern boundary data from ...
Definition REMORA.H:1010
void fill_from_bdyfiles(amrex::MultiFab &mf_to_fill, const amrex::MultiFab &mf_mask, const amrex::Real time, const int bccomp, const int bdy_var_type, const int icomp_to_fill, const int icomp_calc=0, const amrex::MultiFab &mf_calc=amrex::MultiFab(), const amrex::Real=amrex::Real(0.0))
Fill boundary data from netcdf file.
void FillBdyCCVels(int lev, amrex::MultiFab &mf_cc_vel)
Fill the physical boundary conditions for cell-centered velocity (diagnostic only)
TimeInterpolatedData GetDataAtTime(int lev, amrex::Real time)
utility to copy in data from old and/or new state into another multifab
amrex::Vector< REMORAFillPatcher > FPr_c
Vector over levels of FillPatchers for scalars.
Definition REMORA.H:1067
amrex::Vector< REMORAFillPatcher > FPr_w
Vector over levels of FillPatchers for w.
Definition REMORA.H:1073
amrex::Vector< amrex::Real > t_new
new time at each level
Definition REMORA.H:1114
static SolverChoice solverChoice
Container for algorithmic choices.
Definition REMORA.H:1237
int cf_set_width
Width for fixing values at coarse-fine interface.
Definition REMORA.H:1064
amrex::Vector< amrex::Vector< amrex::FArrayBox > > bdy_data_xhi
Vectors (over time) of Vector (over variables) of FArrayBoxs for holding Eastern boundary data from f...
Definition REMORA.H:1008
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NCONS+8 > m_bc_extdir_vals
Array holding the Dirichlet values at walls which need them.
Definition REMORA.H:1144
amrex::Vector< REMORAFillPatcher > FPr_ubar
Vector over levels of FillPatchers for ubar (2D)
Definition REMORA.H:1077
amrex::Vector< amrex::Vector< amrex::FArrayBox > > bdy_data_xlo
Vectors (over time) of Vector (over variables) of FArrayBoxs for holding Western boundary data from f...
Definition REMORA.H:1006
void FillCoarsePatch(int lev, amrex::Real time, amrex::MultiFab *mf_fine, amrex::MultiFab *mf_crse, const int bdy_var_type=BdyVars::null, const int icomp=0, const bool fill_all=true, const int n_not_fill=0, const int icomp_calc=0, const amrex::Real dt=amrex::Real(0.0), const amrex::MultiFab &mf_calc=amrex::MultiFab())
fill an entire multifab by interpolating from the coarser level
amrex::Vector< amrex::Real > t_old
old time at each level
Definition REMORA.H:1116
amrex::Gpu::DeviceVector< amrex::BCRec > domain_bcs_type_d
GPU vector (over BCVars) of BCRecs.
Definition REMORA.H:1138
void set_time(amrex::Real time)
void add_var(amrex::MultiFab *var_data, int own_data)
amrex::MultiFab & get_var(int var_idx)