32#ifdef REMORA_USE_NETCDF
33 const int bdy_var_type,
41#ifdef REMORA_USE_NETCDF
48 const MultiFab& mf_calc)
50 BL_PROFILE_VAR(
"REMORA::FillPatch()",REMORA_FillPatch);
51 amrex::Interpolater* mapper =
nullptr;
53 Box mf_box(mf_to_fill.boxArray()[0]);
54 bool is_2d = mf_box.length(2) == 1;
65 if (lev>0 && fill_set) {
67 mf_box.ixType() == IndexType(IntVect(0,0,0))) {
71 if (mf_box.ixType() == IndexType(IntVect(1,0,0))) {
73 }
else if (mf_box.ixType() == IndexType(IntVect(0,1,0))) {
75 }
else if (mf_box.ixType() == IndexType(IntVect(0,0,1))) {
79 if (mf_box.ixType() == IndexType(IntVect(1,0,0))) {
81 }
else if (mf_box.ixType() == IndexType(IntVect(0,1,0))) {
90 ncomp = mf_to_fill.nComp();
95 if (mf_box.ixType() == IndexType(IntVect(0,0,0)))
97 mapper = &cell_cons_interp;
100 else if (mf_box.ixType() == IndexType(IntVect(1,0,0)))
102 mapper = &face_linear_interp;
105 else if (mf_box.ixType() == IndexType(IntVect(0,1,0)))
107 mapper = &face_linear_interp;
111 mapper = &face_linear_interp;
117 Vector<MultiFab*> fmf = {mfs[lev], mfs[lev]};
118 Vector<Real> ftime = {
t_old[lev],
t_new[lev]};
119 amrex::FillPatchSingleLevel(mf_to_fill, time, fmf, ftime, icomp, icomp, ncomp,
124 Vector<MultiFab*> fmf = {mfs[lev], mfs[lev]};
125 Vector<Real> ftime = {
t_old[lev],
t_new[lev]};
126 Vector<MultiFab*> cmf = {mfs[lev-1], mfs[lev-1]};
127 Vector<Real> ctime = {
t_old[lev-1],
t_new[lev-1]};
129 mfs[lev-1]->FillBoundary(geom[lev-1].periodicity());
130 amrex::FillPatchTwoLevels(mf_to_fill, mf_to_fill.nGrowVect(), IntVect(0,0,0),
131 time, cmf, ctime, fmf, ftime,
132 icomp, icomp, ncomp, geom[lev-1], geom[lev],
139 const bool do_bc=
true;
146 (*
physbcs[lev])(mf_to_fill,*mask,icomp,ncomp,mf_to_fill.nGrowVect(),time,bccomp,n_not_fill,mf_calc,
149#ifdef REMORA_USE_NETCDF
154 fill_from_bdyfiles(mf_to_fill,*mask,time,bccomp,bdy_var_type, icomp,icomp_calc,mf_calc,dt_lev);
158 if ( mf_box.ixType() == IndexType(IntVect(0,0,0)) ) {
159 mf_to_fill.EnforcePeriodicity(geom[lev].periodicity());
163 if ( (mf_box.ixType() == IndexType(IntVect(1,0,0))) ||
164 (mf_box.ixType() == IndexType(IntVect(0,1,0))) )
166 int khi = geom[lev].Domain().bigEnd(2);
167 for (MFIter mfi(mf_to_fill); mfi.isValid(); ++mfi)
169 Box gbx = mfi.growntilebox();
170 gbx.setSmall(2,khi+1);
172 Array4<Real> vel_arr = mf_to_fill.array(mfi);
173 ParallelFor(gbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
175 vel_arr(i,j,k) = vel_arr(i,j,khi);
201#ifdef REMORA_USE_NETCDF
213 BL_PROFILE_VAR(
"REMORA::FillPatchNoBC()",REMORA_FillPatch);
215 amrex::Interpolater* mapper =
nullptr;
217 Box mf_box(mf_to_fill.boxArray()[0]);
218 bool is_2d = mf_box.length(2) == 1;
227 if (lev>0 && fill_set) {
229 mf_box.ixType() == IndexType(IntVect(0,0,0))) {
233 if (mf_box.ixType() == IndexType(IntVect(1,0,0))) {
235 }
else if (mf_box.ixType() == IndexType(IntVect(0,1,0))) {
237 }
else if (mf_box.ixType() == IndexType(IntVect(0,0,1))) {
241 if (mf_box.ixType() == IndexType(IntVect(1,0,0))) {
243 }
else if (mf_box.ixType() == IndexType(IntVect(0,1,0))) {
252 ncomp = mf_to_fill.nComp();
257 if (mf_box.ixType() == IndexType(IntVect(0,0,0)))
260 mapper = &cell_cons_interp;
262 else if (mf_box.ixType() == IndexType(IntVect(1,0,0)))
265 mapper = &face_linear_interp;
267 else if (mf_box.ixType() == IndexType(IntVect(0,1,0)))
270 mapper = &face_linear_interp;
274 mapper = &face_linear_interp;
279 Vector<MultiFab*> fmf = {mfs[lev], mfs[lev]};
280 Vector<Real> ftime = {
t_old[lev],
t_new[lev]};
281 amrex::FillPatchSingleLevel(mf_to_fill, time, fmf, ftime, icomp, icomp, ncomp,
286 Vector<MultiFab*> fmf = {mfs[lev], mfs[lev]};
287 Vector<Real> ftime = {
t_old[lev],
t_new[lev]};
288 Vector<MultiFab*> cmf = {mfs[lev-1], mfs[lev-1]};
289 Vector<Real> ctime = {
t_old[lev-1],
t_new[lev-1]};
291 mfs[lev-1]->FillBoundary(geom[lev-1].periodicity());
292 amrex::FillPatchTwoLevels(mf_to_fill, mf_to_fill.nGrowVect(), IntVect(0,0,0),
293 time, cmf, ctime, fmf, ftime,
294 icomp, icomp, ncomp, geom[lev-1], geom[lev],
311 const Real teps = (
t_new[lev] -
t_old[lev]) * 1.e-3_rt;
313 if (time >
t_new[lev] - teps && time <
t_new[lev] + teps)
315 for (
int i = 0; i < Vars::NumTypes; ++i) {
320 else if (time >
t_old[lev] - teps && time <
t_old[lev] + teps)
322 for (
int i = 0; i < Vars::NumTypes; ++i) {
327 else if (time >
t_old[lev] && time <
t_new[lev])
331 for (
int i = 0; i < Vars::NumTypes; ++i) {
332 MultiFab* mf_tmp =
new MultiFab(vars_new[lev][i].boxArray(),
333 vars_new[lev][i].DistributionMap(),
334 vars_new[lev][i].nComp(), vars_new[lev][i].nGrowVect());
335 mf_tmp->setVal(0.0_rt);
337 const Real dt_fraction = (time -
t_old[lev]) / (
t_new[lev] -
t_old[lev]);
338 MultiFab::Saxpy(*mf_tmp, 1.0_rt - dt_fraction, vars_old[lev][i], 0, 0, mf_tmp->nComp(), mf_tmp->nGrowVect());
339 MultiFab::Saxpy(*mf_tmp, dt_fraction, vars_new[lev][i], 0, 0, mf_tmp->nComp(), mf_tmp->nGrowVect());
347 amrex::Error(
"Requested data at a time outside the interval [t_old, t_new]");
351 for (
int i = 0; i < Vars::NumTypes; ++i) {
352 data.
get_var(Vars::xvel).FillBoundary(geom[lev].periodicity());
353 data.
get_var(Vars::yvel).FillBoundary(geom[lev].periodicity());
354 data.
get_var(Vars::zvel).FillBoundary(geom[lev].periodicity());
355 data.
get_var(Vars::cons).FillBoundary(geom[lev].periodicity());
381 const int bdy_var_type,
384 const int n_not_fill,
385 const int icomp_calc,
387 const MultiFab& mf_calc) {
388 amrex::Interpolater* mapper = &pc_interp;
390 fill_all, n_not_fill, icomp_calc, dt_lev, mf_calc, mapper);
415 const int bdy_var_type,
418 const int n_not_fill,
419 const int icomp_calc,
421 const MultiFab& mf_calc) {
422 amrex::Interpolater* mapper =
nullptr;
424 fill_all, n_not_fill, icomp_calc, dt_lev, mf_calc, mapper);
448#ifdef REMORA_USE_NETCDF
449 const int bdy_var_type,
455 const int n_not_fill,
456#ifdef REMORA_USE_NETCDF
457 const int icomp_calc,
463 const MultiFab& mf_calc,
464 amrex::Interpolater* mapper)
467 AMREX_ASSERT(lev > 0);
473 ncomp = mf_to_fill->nComp();
478 Box box_mf(mf_to_fill->boxArray()[0]);
480 if (box_mf.ixType() == IndexType(IntVect(0,0,0)))
484 else if (box_mf.ixType() == IndexType(IntVect(1,0,0)))
488 else if (box_mf.ixType() == IndexType(IntVect(0,1,0)))
492 else if (box_mf.ixType() == IndexType(IntVect(0,0,1)))
496 amrex::Abort(
"Dont recognize this box type in REMORA_FillPatch");
499 if (mapper ==
nullptr) {
500 if (box_mf.ixType() == IndexType(IntVect(0,0,0)))
502 mapper = &cell_cons_interp;
504 else if (box_mf.ixType() == IndexType(IntVect(1,0,0)))
506 mapper = &face_linear_interp;
508 else if (box_mf.ixType() == IndexType(IntVect(0,1,0)))
510 mapper = &face_linear_interp;
512 else if (box_mf.ixType() == IndexType(IntVect(0,0,1)))
514 mapper = &face_linear_interp;
516 amrex::Abort(
"Dont recognize this box type in REMORA_FillPatch");
523 Vector<Real> ctime = {cdata.
get_time()};
525 Vector<MultiFab*> cmf = {mf_crse};
526 Vector<Real> ctime = {time};
532#ifdef REMORA_USE_NETCDF
541#ifdef REMORA_USE_NETCDF
549 mf_crse->FillBoundary(geom[lev-1].periodicity());
550 amrex::InterpFromCoarseLevel(*mf_to_fill, mf_to_fill->nGrowVect(), IntVect(0,0,0),
551 *mf_crse, 0, icomp, ncomp, geom[lev-1], geom[lev],
560 (*
physbcs[lev])(*mf_to_fill,*mask,icomp,ncomp,mf_to_fill->nGrowVect(),
561 time,bccomp,n_not_fill,mf_calc,
564#ifdef REMORA_USE_NETCDF
569 fill_from_bdyfiles(*mf_to_fill,*mask,time,bccomp,bdy_var_type, icomp,icomp_calc,mf_calc,dt_lev);
573 if ( box_mf.ixType() == IndexType(IntVect(0,0,0)) ) {
574 mf_to_fill->EnforcePeriodicity(geom[lev].periodicity());
578 if ( (box_mf.ixType() == IndexType(IntVect(1,0,0))) ||
579 (box_mf.ixType() == IndexType(IntVect(0,1,0))) )
581 int khi = geom[lev].Domain().bigEnd(2);
582 for (MFIter mfi(*mf_to_fill); mfi.isValid(); ++mfi)
584 Box gbx = mfi.growntilebox();
585 gbx.setSmall(2,khi+1);
587 Array4<Real> vel_arr = mf_to_fill->array(mfi);
588 ParallelFor(gbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
590 vel_arr(i,j,k) = vel_arr(i,j,khi);
608 Box domain(Geom(lev).Domain());
610 int ihi = domain.bigEnd(0);
611 int jhi = domain.bigEnd(1);
612 int khi = domain.bigEnd(2);
615 mf_cc_vel.FillBoundary(geom[lev].periodicity());
618#pragma omp parallel if (Gpu::notInLaunchRegion())
620 for (MFIter mfi(mf_cc_vel, TilingIfNotGPU()); mfi.isValid(); ++mfi)
624 const Box& bx = mfi.tilebox();
625 const Array4<Real>& vel_arr = mf_cc_vel.array(mfi);
627 if (!Geom(lev).isPeriodic(0)) {
629 if (bx.smallEnd(0) <= domain.smallEnd(0)) {
631 ParallelFor(makeSlab(bx,0,0), [=] AMREX_GPU_DEVICE(
int ,
int j,
int k)
noexcept
633 vel_arr(-1,j,k,1) = mult*vel_arr(0,j,k,1);
634 vel_arr(-1,j,k,2) = mult*vel_arr(0,j,k,2);
639 if (bx.bigEnd(0) >= domain.bigEnd(0)) {
641 ParallelFor(makeSlab(bx,0,0), [=] AMREX_GPU_DEVICE(
int ,
int j,
int k)
noexcept
643 vel_arr(ihi+1,j,k,1) = mult*vel_arr(ihi,j,k,1);
644 vel_arr(ihi+1,j,k,2) = mult*vel_arr(ihi,j,k,2);
649 if (!Geom(lev).isPeriodic(1)) {
651 if (bx.smallEnd(1) <= domain.smallEnd(1)) {
653 ParallelFor(makeSlab(bx,1,0), [=] AMREX_GPU_DEVICE(
int i,
int ,
int k)
noexcept
655 vel_arr(i,-1,k,0) = mult*vel_arr(i,0,k,0);
656 vel_arr(i,-1,k,2) = mult*vel_arr(i,0,k,2);
661 if (bx.bigEnd(1) >= domain.bigEnd(1)) {
663 ParallelFor(makeSlab(bx,1,0), [=] AMREX_GPU_DEVICE(
int i,
int ,
int k)
noexcept
665 vel_arr(i,jhi+1,k,0) = mult*vel_arr(i,jhi,k,0);
666 vel_arr(i,jhi+1,k,2) = mult*-vel_arr(i,jhi,k,2);
671 if (!Geom(lev).isPeriodic(2)) {
673 if (bx.smallEnd(2) <= domain.smallEnd(2)) {
675 ParallelFor(makeSlab(bx,2,0), [=] AMREX_GPU_DEVICE(
int i,
int j,
int)
noexcept
677 vel_arr(i,j,-1,0) = mult*vel_arr(i,j,0,0);
678 vel_arr(i,j,-1,1) = mult*vel_arr(i,j,0,1);
683 if (bx.bigEnd(2) >= domain.bigEnd(2)) {
685 ParallelFor(makeSlab(bx,2,0), [=] AMREX_GPU_DEVICE(
int i,
int j,
int)
noexcept
687 vel_arr(i,j,khi+1,0) = mult*vel_arr(i,j,khi,0);
688 vel_arr(i,j,khi+1,1) = mult*vel_arr(i,j,khi,1);
void FillCoarsePatchPC(int lev, amrex::Real time, amrex::MultiFab *mf_fine, amrex::MultiFab *mf_crse, const int bccomp, 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 using the piecewise constant interpol...
amrex::Vector< amrex::BCRec > domain_bcs_type
vector (over BCVars) of BCRecs
amrex::Vector< REMORAFillPatcher > FPr_v
Vector over levels of FillPatchers for v (3D)
void FillCoarsePatch(int lev, amrex::Real time, amrex::MultiFab *mf_fine, amrex::MultiFab *mf_crse, const int bccomp, 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::GpuArray< amrex::GpuArray< REMORA_BC, AMREX_SPACEDIM *2 >, BCVars::NumTypes > phys_bc_type
Array holding the "physical" boundary condition types (e.g. "inflow")
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskr
land/sea mask at cell centers (2D)
amrex::Vector< REMORAFillPatcher > FPr_u
Vector over levels of FillPatchers for u (3D)
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_msku
land/sea mask at x-faces (2D)
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 ...
amrex::Real bdy_time_interval
Interval between boundary data times.
amrex::Vector< REMORAFillPatcher > FPr_vbar
Vector over levels of FillPatchers for vbar (2D)
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskv
land/sea mask at y-faces (2D)
amrex::Vector< std::unique_ptr< REMORAPhysBCFunct > > physbcs
Vector (over level) of functors to apply physical boundary conditions.
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 ...
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.
amrex::Vector< REMORAFillPatcher > FPr_w
Vector over levels of FillPatchers for w.
amrex::Vector< amrex::Real > t_new
new time at each level
static SolverChoice solverChoice
Container for algorithmic choices.
int cf_set_width
Width for fixing values at coarse-fine interface.
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...
void FillCoarsePatchMap(int lev, amrex::Real time, amrex::MultiFab *mf_fine, amrex::MultiFab *mf_crse, const int bccomp, 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(), amrex::Interpolater *mapper=nullptr)
fill an entire multifab by interpolating from the coarser level, explicitly specifying interpolator t...
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.
amrex::Vector< REMORAFillPatcher > FPr_ubar
Vector over levels of FillPatchers for ubar (2D)
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...
amrex::Vector< amrex::Real > t_old
old time at each level
amrex::Gpu::DeviceVector< amrex::BCRec > domain_bcs_type_d
GPU vector (over BCVars) of BCRecs.
bool boundary_from_netcdf
void set_time(amrex::Real time)
void add_var(amrex::MultiFab *var_data, int own_data)
amrex::MultiFab & get_var(int var_idx)