1#ifndef ICNS_ADVECTION_H
2#define ICNS_ADVECTION_H
10#include "AMReX_MultiFabUtil.H"
11#include "hydro_MacProjector.H"
13#include "hydro_utils.H"
16#include "AMReX_REAL.H"
18using namespace amrex::literals;
26 amrex::Vector<amrex::Array<const amrex::MultiFab*, ICNS::ndim>>;
45 amrex::Array<amrex::MultiFab*, ICNS::ndim>& ,
56 const amrex::Vector<amrex::Array<amrex::MultiFab*, AMREX_SPACEDIM>>&
62#ifdef KYNEMA_SGF_USE_FFT
63 std::unique_ptr<Hydro::FFTMacProjector> m_fft_mac_proj;
85 bool variable_density,
89 ,
u_mac(fields_in.repo.get_field(
"u_mac"))
90 ,
v_mac(fields_in.repo.get_field(
"v_mac"))
91 ,
w_mac(fields_in.repo.get_field(
"w_mac"))
94 sim.field_boundary_manager(),
99 ,
m_flux_x(fields_in.repo.create_scratch_field(
101 ,
m_flux_y(fields_in.repo.create_scratch_field(
103 ,
m_flux_z(fields_in.repo.create_scratch_field(
105 ,
m_face_x(fields_in.repo.create_scratch_field(
107 ,
m_face_y(fields_in.repo.create_scratch_field(
109 ,
m_face_z(fields_in.repo.create_scratch_field(
113 amrex::ParmParse pp(
"incflo");
116 if (pp.contains(
"use_ppm") || pp.contains(
"use_limiter")) {
118 "Godunov: use_ppm and use_limiter are deprecated. Please "
119 "update input file");
126 }
else if (amrex::toLower(
godunov_type) ==
"ppm_nolim") {
128 amrex::Print() <<
"WARNING: Using advection type ppm_nolim is not "
129 "recommended. Prefer using weno_z."
144 "Invalid godunov_type specified. For godunov_type select "
145 "between plm, ppm, ppm_nolim, bds, weno_js, and weno_z. If no "
146 "godunov_type is specified, the default weno_z is used.");
153 }
else if (amrex::toLower(
mflux_type) ==
"upwind") {
156 amrex::Abort(
"Invalid argument entered for mflux_type.");
161 pp.query(
"icns_conserv",
m_cons);
167 amrex::ParmParse pp_eq(
"ICNS");
173 const FieldState fstate,
const amrex::Real dt,
const amrex::Real time)
176 const auto& repo =
fields.repo;
177 const auto& geom = repo.mesh().Geom();
179 const auto& src_term =
fields.src_term;
180 const auto& dof_field =
fields.field.state(fstate);
181 auto bcrec_device = dof_field.bcrec_device();
192 const bool godunov_use_ppm =
197 limiter_type = PPM::NoLimiter;
199 limiter_type = PPM::WENOZ;
201 limiter_type = PPM::WENO_JS;
203 limiter_type = PPM::default_limiter;
208 const amrex::Real dt_extrap =
210 for (
int lev = 0; lev < repo.num_active_levels(); ++lev) {
211 HydroUtils::ExtrapVelToFaces(
212 dof_field(lev), src_term(lev),
u_mac(lev),
v_mac(lev),
213 w_mac(lev), dof_field.bcrec(), bcrec_device.data(),
214 repo.mesh().Geom(lev), dt_extrap, godunov_use_ppm,
219 amrex::Abort(
"Invalid godunov scheme");
234 amrex::Array<Field*, AMREX_SPACEDIM> mac_vel = {
236 dof_field.fillpatch_sibling_fields(time,
u_mac.num_grow(), mac_vel);
239 for (
int lev = 0; lev < repo.num_active_levels(); ++lev) {
240 u_mac(lev).FillBoundary(geom[lev].periodicity());
241 v_mac(lev).FillBoundary(geom[lev].periodicity());
242 w_mac(lev).FillBoundary(geom[lev].periodicity());
252 const auto& repo =
fields.repo;
253 const auto& geom = repo.mesh().Geom();
255 const auto& src_term =
fields.src_term;
256 auto& conv_term =
fields.conv_term;
257 const auto& dof_field =
fields.field.state(fstate);
269 const auto& rho_nph =
272 const bool mphase_vof = repo.field_exists(
"vof");
277 for (
int lev = 0; lev < repo.num_active_levels(); ++lev) {
281 dof_field(lev).boxArray(), dof_field(lev).DistributionMap(),
283 amrex::MultiFab::Copy(
287 src_term(lev).boxArray(), src_term(lev).DistributionMap(),
289 amrex::MultiFab::Copy(
292 amrex::MultiFab q_nph(
293 dof_field(lev).boxArray(), dof_field(lev).DistributionMap(),
295 amrex::MultiFab::Copy(
302 for (
int idim = 0; idim < dof_field.num_comp(); ++idim) {
303 amrex::MultiFab::Multiply(
306 amrex::MultiFab::Multiply(
309 amrex::MultiFab::Multiply(
310 q_nph, rho_nph(lev), 0, idim, 1,
315 amrex::MFItInfo mfi_info;
316 if (amrex::Gpu::notInLaunchRegion()) {
317 mfi_info.EnableTiling(amrex::IntVect(1024, 1024, 1024))
326 const bool is_velocity =
true;
327 const bool known_edge_state =
false;
328 const bool godunov_use_ppm =
335 limiter_type = PPM::NoLimiter;
337 limiter_type = PPM::WENOZ;
339 limiter_type = PPM::WENO_JS;
341 limiter_type = PPM::default_limiter;
346 const amrex::Real dt_extrap =
349#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
351 for (amrex::MFIter mfi(dof_field(lev), mfi_info); mfi.isValid();
353 const auto& bx = mfi.tilebox();
354 amrex::FArrayBox tmpfab(
355 amrex::grow(bx, 1), 1, amrex::The_Async_Arena());
356 tmpfab.setVal<amrex::RunOn::Device>(0.0_rt);
357 const auto& divu = tmpfab.array();
358 HydroUtils::ComputeFluxesOnBoxFromState(
360 q_nph.const_array(mfi), flux_x(lev).array(mfi),
361 flux_y(lev).array(mfi), flux_z(lev).array(mfi),
362 face_x(lev).array(mfi), face_y(lev).array(mfi),
363 face_z(lev).array(mfi), known_edge_state,
364 u_mac(lev).const_array(mfi),
365 v_mac(lev).const_array(mfi),
366 w_mac(lev).const_array(mfi), divu, fq.const_array(mfi),
367 geom[lev], dt_extrap, dof_field.bcrec(),
368 dof_field.bcrec_device().data(),
iconserv.data(),
375 amrex::Abort(
"Invalid godunov scheme");
385 dof_field.bcrec(), dof_field.bcrec_device().data(),
386 rho_o.bcrec(), rho_o.bcrec_device().data(), dt,
mflux_scheme,
390 amrex::Vector<amrex::Array<amrex::MultiFab*, AMREX_SPACEDIM>> fluxes(
391 repo.num_active_levels());
392 for (
int lev = 0; lev < repo.num_active_levels(); ++lev) {
393 fluxes[lev][0] = &flux_x(lev);
394 fluxes[lev][1] = &flux_y(lev);
395 fluxes[lev][2] = &flux_z(lev);
400 for (
int lev = repo.num_active_levels() - 1; lev > 0; --lev) {
402 geom[lev].Domain().size() / geom[lev - 1].Domain().size();
403 amrex::average_down_faces(
404 GetArrOfConstPtrs(fluxes[lev]), fluxes[lev - 1], rr,
408 for (
int lev = 0; lev < repo.num_active_levels(); ++lev) {
411#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
413 for (amrex::MFIter mfi(dof_field(lev), amrex::TilingIfNotGPU());
414 mfi.isValid(); ++mfi) {
415 const auto& bx = mfi.tilebox();
417 HydroUtils::ComputeDivergence(
418 bx, conv_term(lev).array(mfi), flux_x(lev).array(mfi),
419 flux_y(lev).array(mfi), flux_z(lev).array(mfi),
ICNS::ndim,
420 geom[lev],
static_cast<amrex::Real
>(-1.0_rt),
424 amrex::FArrayBox div_umac(bx, 1, amrex::The_Async_Arena());
425 auto const& divum_arr = div_umac.array();
426 HydroUtils::ComputeDivergence(
427 bx, divum_arr,
u_mac(lev).const_array(mfi),
428 v_mac(lev).const_array(mfi),
429 w_mac(lev).const_array(mfi), 1, geom[lev],
430 static_cast<amrex::Real
>(1.0_rt),
false);
431 HydroUtils::ComputeConvectiveTerm(
432 bx,
ICNS::ndim, mfi, dof_field(lev).const_array(mfi),
433 face_x(lev).const_array(mfi),
434 face_y(lev).const_array(mfi),
435 face_z(lev).const_array(mfi), divum_arr,
436 conv_term(lev).array(mfi),
iconserv.data(),
482 bool variable_density,
486 ,
u_mac(fields_in.repo.get_field(
"u_mac"))
487 ,
v_mac(fields_in.repo.get_field(
"v_mac"))
488 ,
w_mac(fields_in.repo.get_field(
"w_mac"))
492 sim.field_boundary_manager(),
501 const amrex::Real dt,
505 const auto& repo =
fields.repo;
506 auto& dof_field =
fields.field.state(fstate);
511 dof_field.to_stretched_space();
518 for (
int lev = 0; lev < repo.num_active_levels(); ++lev) {
519 MOL::ExtrapVelToFaces(
521 repo.mesh().Geom(lev), dof_field.bcrec(),
522 dof_field.bcrec_device().data());
531 const auto& repo =
fields.repo;
532 const auto& geom = repo.mesh().Geom();
533 auto& conv_term =
fields.conv_term.state(fstate);
534 const auto& dof_field =
fields.field.state(fstate);
535 const auto& rho = repo.get_field(
"density").state(fstate);
541 int nmaxcomp = AMREX_SPACEDIM;
542 for (
int lev = 0; lev < repo.num_active_levels(); ++lev) {
544 amrex::MFItInfo mfi_info;
547 if (amrex::Gpu::notInLaunchRegion()) {
548 mfi_info.EnableTiling(amrex::IntVect(1024, 1024, 1024))
552#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
554 for (amrex::MFIter mfi(dof_field(lev), mfi_info); mfi.isValid();
556 amrex::Box
const& bx = mfi.tilebox();
560 amrex::FArrayBox qfab(
562 const auto& q = qfab.array();
564 auto rho_arr = rho(lev).const_array(mfi);
565 auto vel_arr = dof_field(lev).const_array(mfi);
568 [=] AMREX_GPU_DEVICE(
int i,
int j,
int k,
int n) {
569 q(i, j, k, n) = rho_arr(i, j, k) * vel_arr(i, j, k, n);
575 amrex::Box tmpbox = amrex::surroundingNodes(bx);
576 const int tmpcomp = nmaxcomp * AMREX_SPACEDIM;
578 amrex::FArrayBox tmpfab(
579 tmpbox, tmpcomp, amrex::The_Async_Arena());
581 amrex::Array4<amrex::Real> fx = tmpfab.array(0);
582 amrex::Array4<amrex::Real> fy = tmpfab.array(nmaxcomp);
583 amrex::Array4<amrex::Real> fz = tmpfab.array(nmaxcomp * 2);
586 lev, bx, AMREX_SPACEDIM, fx, fy, fz, q,
587 u_mac(lev).const_array(mfi),
v_mac(lev).const_array(mfi),
588 w_mac(lev).const_array(mfi), dof_field.bcrec().data(),
589 dof_field.bcrec_device().data(), geom);
592 bx, AMREX_SPACEDIM, conv_term(lev).array(mfi), fx, fy, fz,
593 geom[lev].InvCellSizeArray());
Definition FieldBoundary.H:66
Definition FieldRepo.H:86
Definition icns_advection.H:23
MacProjOp(FieldRepo &, FieldBoundaryMgr &, bool, bool, bool, bool)
Definition icns_advection.cpp:45
amrex::Real m_rho_0
Definition icns_advection.H:72
FieldRepo & m_repo
Definition icns_advection.H:59
std::unique_ptr< Hydro::MacProjector > m_mac_proj
Definition icns_advection.H:61
bool m_has_overset
Definition icns_advection.H:67
MLMGOptions m_options
Definition icns_advection.H:66
bool m_need_init
Definition icns_advection.H:68
void operator()(FieldState fstate, amrex::Real dt)
Definition icns_advection.cpp:206
bool m_variable_density
Definition icns_advection.H:69
amrex::Real rho0() const
Definition icns_advection.H:49
bool m_mesh_mapping
Definition icns_advection.H:70
void init_projector(const FaceFabPtrVec &)
Definition icns_advection.cpp:80
FieldBoundaryMgr & m_fb_mgr
Definition icns_advection.H:60
void set_inflow_velocity(amrex::Real time)
Definition icns_advection.cpp:157
static void mac_proj_to_uniform_space(const kynema_sgf::FieldRepo &, kynema_sgf::Field &, kynema_sgf::Field &, kynema_sgf::Field &, amrex::Array< amrex::MultiFab *, ICNS::ndim > &, amrex::Real, int)
Definition icns_advection.cpp:377
void enforce_inout_solvability(const amrex::Vector< amrex::Array< amrex::MultiFab *, AMREX_SPACEDIM > > &a_umac)
Definition icns_advection.cpp:70
amrex::Vector< amrex::Array< const amrex::MultiFab *, ICNS::ndim > > FaceFabPtrVec
Definition icns_advection.H:25
bool m_is_anelastic
Definition icns_advection.H:71
FieldLoc
Definition FieldDescTypes.H:29
FieldState
Definition FieldDescTypes.H:16
@ ZFACE
Face-centered in z-direction.
Definition FieldDescTypes.H:34
@ XFACE
Face-centered in x-direction (e.g., face normal velocity)
Definition FieldDescTypes.H:32
@ YFACE
Face-centered in y-direction.
Definition FieldDescTypes.H:33
@ NPH
State at (n + 1/2) (intermediate) timestep.
Definition FieldDescTypes.H:20
@ Old
Same as FieldState::N.
Definition FieldDescTypes.H:23
scheme
Definition Godunov.H:8
@ BDS
Definition Godunov.H:12
@ PPM
Definition Godunov.H:10
@ UPWIND
Definition Godunov.H:16
@ PLM
Definition Godunov.H:9
@ WENO_JS
Definition Godunov.H:13
@ MINMOD
Definition Godunov.H:15
@ PPM_NOLIM
Definition Godunov.H:11
@ WENOZ
Definition Godunov.H:14
amrex::Array< amrex::Real, 24 > PrintMaxMACVelLocations(const kynema_sgf::FieldRepo &repo, const std::string &header)
Definition diagnostics.cpp:440
Definition SchemeTraits.H:6
static AMREX_INLINE void hybrid_fluxes(const FieldRepo &repo, const int ncomp, const amrex::Gpu::DeviceVector< int > &iconserv, ScratchField &flux_x, ScratchField &flux_y, ScratchField &flux_z, const Field &dof_field, const Field &dof_nph, const Field &src_term, const Field &rho_o, const Field &rho_nph, const Field &u_mac, const Field &v_mac, const Field &w_mac, amrex::Vector< amrex::BCRec > const &velbc, amrex::BCRec const *velbc_d, amrex::Vector< amrex::BCRec > const &rhobc, amrex::BCRec const *rhobc_d, const amrex::Real dt, godunov::scheme mflux_scheme, bool allow_inflow_on_outflow, bool use_forces_in_trans, bool pre_multiplied_src_term=false)
Definition vof_momentum_flux.H:11
Definition AdvOp_Godunov.H:22
This test case is intended as an evaluation of the momentum advection scheme.
Definition BCInterface.cpp:12
void compute_convective_rate(amrex::Box const &bx, int ncomp, amrex::Array4< amrex::Real > const &dUdt, amrex::Array4< amrex::Real const > const &fx, amrex::Array4< amrex::Real const > const &fy, amrex::Array4< amrex::Real const > const &fz, amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > dxi)
Definition incflo_mol_fluxes.cpp:9
void compute_convective_fluxes(int lev, amrex::Box const &bx, int ncomp, amrex::Array4< amrex::Real > const &fx, amrex::Array4< amrex::Real > const &fy, amrex::Array4< amrex::Real > const &fz, amrex::Array4< amrex::Real const > const &q, amrex::Array4< amrex::Real const > const &umac, amrex::Array4< amrex::Real const > const &vmac, amrex::Array4< amrex::Real const > const &wmac, amrex::BCRec const *h_bcrec, amrex::BCRec const *d_bcrec, amrex::Vector< amrex::Geometry > geom)
Definition incflo_mol_fluxes.cpp:29
Definition MLMGOptions.H:27
static constexpr int nghost_src
Number of ghost cells in the source term variable.
Definition SchemeTraits.H:21
static constexpr int nghost_state
Number of ghost in the state variable.
Definition SchemeTraits.H:19
static constexpr int nghost_state
Number of ghost cells in the state variable.
Definition SchemeTraits.H:41
MacProjOp m_macproj_op
Definition icns_advection.H:448
std::unique_ptr< ScratchField > m_face_x
Definition icns_advection.H:453
AdvectionOp(CFDSim &sim, PDEFields &fields_in, bool has_overset, bool variable_density, bool mesh_mapping, bool is_anelastic)
Definition icns_advection.H:81
Field & v_mac
Definition icns_advection.H:445
std::unique_ptr< ScratchField > m_flux_x
Definition icns_advection.H:450
void operator()(const FieldState fstate, const amrex::Real dt)
Definition icns_advection.H:250
Field & w_mac
Definition icns_advection.H:446
void preadvect(const FieldState fstate, const amrex::Real dt, const amrex::Real time)
Definition icns_advection.H:172
amrex::Gpu::DeviceVector< int > iconserv
Definition icns_advection.H:457
godunov::scheme mflux_scheme
Definition icns_advection.H:460
const bool fluxes_are_area_weighted
Definition icns_advection.H:463
bool godunov_use_forces_in_trans
Definition icns_advection.H:464
bool m_allow_inflow_on_outflow
Definition icns_advection.H:467
Field & u_mac
Definition icns_advection.H:444
std::string godunov_type
Definition icns_advection.H:461
PDEFields & fields
Definition icns_advection.H:443
std::unique_ptr< ScratchField > m_flux_y
Definition icns_advection.H:451
int m_cons
Definition icns_advection.H:465
int m_verbose
Definition icns_advection.H:466
std::unique_ptr< ScratchField > m_face_z
Definition icns_advection.H:455
std::unique_ptr< ScratchField > m_flux_z
Definition icns_advection.H:452
std::string postmac_advection_type
Definition icns_advection.H:469
std::string premac_advection_type
Definition icns_advection.H:468
godunov::scheme godunov_scheme
Definition icns_advection.H:459
std::unique_ptr< ScratchField > m_face_y
Definition icns_advection.H:454
std::string mflux_type
Definition icns_advection.H:462
PDEFields & fields
Definition icns_advection.H:598
Field & u_mac
Definition icns_advection.H:599
MacProjOp m_macproj_op
Definition icns_advection.H:605
bool m_mesh_mapping
Definition icns_advection.H:603
void operator()(const FieldState fstate, const amrex::Real)
Definition icns_advection.H:528
AdvectionOp(CFDSim &sim, PDEFields &fields_in, bool has_overset, bool variable_density, bool mesh_mapping, bool is_anelastic)
Definition icns_advection.H:478
void preadvect(const FieldState fstate, const amrex::Real dt, const amrex::Real)
Definition icns_advection.H:499
Field & v_mac
Definition icns_advection.H:600
Field & w_mac
Definition icns_advection.H:601
static constexpr int ndim
Definition icns.H:40
Definition PDEFields.H:27