Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiphase hybrid #915

Merged
merged 49 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
a54f5ef
option to sharpen nalu vof field or not
mbkuhn Sep 5, 2023
8ff02df
putting previous commit into practice
mbkuhn Sep 5, 2023
3e9a12c
important options for sharpening and masking
mbkuhn Sep 5, 2023
52a4e95
able to turn off mac projection
mbkuhn Sep 6, 2023
9237d9f
getting toward a working sharpening
mbkuhn Sep 21, 2023
4310f94
provides stability for very small epsilon (interface thickness)
mbkuhn Sep 21, 2023
a942e53
removing unnecessary things, clean up
mbkuhn Sep 21, 2023
86970fd
more unnecessary
mbkuhn Sep 21, 2023
746fb05
default to a smaller interface thickness
mbkuhn Sep 21, 2023
d286fd8
masking fluxes is sufficient, no need to mask whole term
mbkuhn Sep 21, 2023
d078139
density fluxes and update (to make sure it works)
mbkuhn Sep 21, 2023
6f4e8fc
best upwinding approach so far
mbkuhn Sep 21, 2023
e8069a5
begin to look at the rest of the iteration
mbkuhn Sep 21, 2023
12d383f
ability to turn off strong overset coupling to nodal projection
mbkuhn Sep 21, 2023
05d963f
initialize pressure in sloshing tank case
mbkuhn Sep 21, 2023
27e65f9
modify pressure by hydrostatic source term
mbkuhn Sep 22, 2023
5283029
momentum sharpening as included in paper
mbkuhn Sep 25, 2023
fcf6d14
to go with last change
mbkuhn Sep 25, 2023
dc32b8b
ability to specify tolerance for convergence, not just steps
mbkuhn Sep 25, 2023
dec0538
to go with previous commit
mbkuhn Sep 25, 2023
6deee3f
keep vof bounded
mbkuhn Sep 25, 2023
5084989
initialize pressure field for other cases (like waves)
mbkuhn Sep 25, 2023
5cbf8e7
specify relative length scale by input argument
mbkuhn Sep 25, 2023
6185496
move copy to old, misc
mbkuhn Sep 26, 2023
ab6bdde
Neumann version of youngs normal
mbkuhn Sep 26, 2023
22bfd6b
discrete sharpening, much improved from other one
mbkuhn Sep 27, 2023
5b99df1
likely unused stuff, add for history
mbkuhn Sep 27, 2023
4d9ed9a
more reasonable asdf function, better for small nalu domains
mbkuhn Sep 27, 2023
62dbde5
more flexible flux computation and commented debugging stuff
mbkuhn Sep 27, 2023
0ffd600
populate ghost cells for iblank fields
mbkuhn Sep 27, 2023
78cda3e
making vof margin for flux upwinding/downwinding an input argument
mbkuhn Sep 27, 2023
9c0e634
changing defaults of sharpening tool
mbkuhn Sep 27, 2023
309cd1f
commented print statements for debugging
mbkuhn Sep 27, 2023
23483fd
include boundedness of vof and recalc of density
mbkuhn Sep 27, 2023
1102fee
new FuzzyInterface case
mbkuhn Sep 27, 2023
514c8e1
calculate face velocity in the upwinding/downwinding form like the vo…
mbkuhn Sep 29, 2023
e97e9d4
changing the sharpen margin default
mbkuhn Oct 2, 2023
f105213
do density adjustment as intended
mbkuhn Oct 2, 2023
4868108
options to ignore nalu pressure and to turn off pressure source term …
mbkuhn Oct 2, 2023
246b05f
cleaning up the code and putting in more options
mbkuhn Oct 2, 2023
842feb1
replacing the pressure gradient with hydrostatic
mbkuhn Oct 3, 2023
18a0bb8
reapply hydrostatic guess of pressure gradient
mbkuhn Oct 3, 2023
de1603e
turning latest commits into input options
mbkuhn Oct 3, 2023
5c86476
switching to full upwinding for velocity sharpening
mbkuhn Oct 3, 2023
4cce542
ramping the pseudo-time seems to work better
mbkuhn Oct 3, 2023
e244444
ability to sharpen pressure gradient
mbkuhn Oct 4, 2023
f1bba36
3 big changes
mbkuhn Oct 5, 2023
e5d1b16
set current working version of options as default
mbkuhn Oct 5, 2023
c28d8aa
Merge branch 'multiphase_dev' into mphase_hybrid
mbkuhn Oct 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions amr-wind/core/SimTime.H
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public:
*/
bool new_timestep();

void increment_timestep() {++m_time_index;}

/** Return true if simulation should continue
*/
bool continue_simulation() const;
Expand Down
5 changes: 5 additions & 0 deletions amr-wind/equation_systems/icns/icns_advection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ MacProjOp::MacProjOp(
{
amrex::ParmParse pp("incflo");
pp.query("density", m_rho_0);
bool disable_omac{true};
pp.query("disable_overset_mac", disable_omac);
if (m_has_overset && disable_omac) {
m_has_overset = false;
}
}

void MacProjOp::init_projector(const MacProjOp::FaceFabPtrVec& beta) noexcept
Expand Down
69 changes: 50 additions & 19 deletions amr-wind/equation_systems/vof/vof_advection.H
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ struct AdvectionOp<VOF, fvm::Godunov>
{
amrex::ParmParse pp_multiphase("VOF");
pp_multiphase.query("remove_debris", m_rm_debris);
pp_multiphase.query("sharpen_acq_field", m_sharpen_acq);
pp_multiphase.query("sharpen_dest_field", m_sharpen_dest);
pp_multiphase.query("replace_masked", m_replace_mask);

// Setup density factor arrays for multiplying velocity flux
fields_in.repo.declare_face_normal_field(
Expand All @@ -34,7 +37,9 @@ struct AdvectionOp<VOF, fvm::Godunov>
const FieldState /*unused*/,
const amrex::Real /*unused*/,
const amrex::Real /*unused*/)
{}
{
// Would be best to sharpen old vof and update old density here
}

void operator()(const FieldState /*unused*/, const amrex::Real dt)
{
Expand All @@ -43,13 +48,38 @@ struct AdvectionOp<VOF, fvm::Godunov>

auto& repo = fields.repo;
const auto& geom = repo.mesh().Geom();
const int nlevels = repo.num_active_levels();

auto& aa_x = repo.get_field("advalpha_x");
auto& aa_y = repo.get_field("advalpha_y");
auto& aa_z = repo.get_field("advalpha_z");

// cppcheck-suppress constVariable
auto& dof_field = fields.field;
// Old and new states
auto& dof_old = fields.field.state(amr_wind::FieldState::Old);
auto& dof_new = fields.field;
// Working state of vof is nph, to keep others untouched during step
auto& dof_field = fields.field.state(amr_wind::FieldState::NPH);

// Sharpen starting vof field if hybrid solver is being used
if (repo.int_field_exists("iblank_cell") && m_sharpen_acq) {
auto& f_iblank = repo.get_int_field("iblank_cell");
amr_wind::multiphase::sharpen_acquired_vof(
nlevels, f_iblank, dof_old);
}
// Sharpen future vof field if hybrid solver is being used
if (repo.int_field_exists("iblank_cell") && m_sharpen_dest) {
auto& f_iblank = repo.get_int_field("iblank_cell");
amr_wind::multiphase::sharpen_acquired_vof(
nlevels, f_iblank, dof_new);
}

// Initialize as old state values
for (int lev = 0; lev < repo.num_active_levels(); ++lev) {
amrex::MultiFab::Copy(
dof_field(lev), dof_old(lev), 0, 0, dof_field.num_comp(),
dof_field.num_grow());
}

//
// Advect volume using Implicit Eulerian Sweeping method with PLIC
// reconstruction
Expand All @@ -71,8 +101,6 @@ struct AdvectionOp<VOF, fvm::Godunov>
isweep = 1;
}

const int nlevels = repo.num_active_levels();

amrex::Vector<amrex::Array<amrex::MultiFab*, AMREX_SPACEDIM>> fluxes(
nlevels);
amrex::Vector<amrex::Array<amrex::MultiFab*, AMREX_SPACEDIM>> advas(
Expand All @@ -86,20 +114,6 @@ struct AdvectionOp<VOF, fvm::Godunov>
advas[lev][2] = &aa_z(lev);
}

// Sharpen acquired vof field if hybrid solver is being used
if (repo.int_field_exists("iblank_cell")) {
auto& f_iblank = repo.get_int_field("iblank_cell");
amr_wind::multiphase::sharpen_acquired_vof(
nlevels, f_iblank, dof_field);
// Update old vof so that old density can be updated
// cppcheck-suppress constVariableReference
auto& old_dof_field = dof_field.state(amr_wind::FieldState::Old);
for (int lev = 0; lev < repo.num_active_levels(); ++lev) {
amrex::MultiFab::Copy(
old_dof_field(lev), dof_field(lev), 0, 0,
dof_field.num_comp(), dof_field.num_grow());
}
}
// Split advection step 1, with cmask calculation
multiphase::split_advection_step(
isweep, 0, nlevels, dof_field, fluxes, (*fluxC), advas, u_mac,
Expand All @@ -112,6 +126,20 @@ struct AdvectionOp<VOF, fvm::Godunov>
multiphase::split_advection_step(
isweep, 2, nlevels, dof_field, fluxes, (*fluxC), advas, u_mac,
v_mac, w_mac, dof_field.bc_type(), geom, dt, m_rm_debris);

// Replace masked cells using overset
if (repo.int_field_exists("iblank_cell") && m_replace_mask) {
auto& f_iblank = repo.get_int_field("iblank_cell");
amr_wind::multiphase::replace_masked_vof(
nlevels, f_iblank, dof_field, dof_new);
}

// Copy working version of vof to new state
for (int lev = 0; lev < repo.num_active_levels(); ++lev) {
amrex::MultiFab::Copy(
dof_new(lev), dof_field(lev), 0, 0, dof_field.num_comp(),
dof_field.num_grow());
}
}

PDEFields& fields;
Expand All @@ -120,6 +148,9 @@ struct AdvectionOp<VOF, fvm::Godunov>
Field& w_mac;
int isweep = 0;
bool m_rm_debris{true};
bool m_sharpen_acq{false};
bool m_sharpen_dest{false};
bool m_replace_mask{true};
// Lagrangian transport is deprecated, only Eulerian is supported
};

Expand Down
30 changes: 30 additions & 0 deletions amr-wind/equation_systems/vof/vof_hybridsolver_ops.H
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,36 @@ static void sharpen_acquired_vof(
}
}

static void replace_masked_vof(
const int nlevels,
amr_wind::IntField& f_iblank,
amr_wind::Field& f_vof,
amr_wind::Field& f_vof_new)
{
// Sharpen data from nalu-wind (in iblank regions)
for (int lev = 0; lev < nlevels; ++lev) {
auto& iblank = f_iblank(lev);
auto& vof = f_vof(lev);
const auto& vof_new = f_vof_new(lev);

for (amrex::MFIter mfi(iblank); mfi.isValid(); ++mfi) {
const auto& gbx = mfi.growntilebox();
const amrex::Array4<const int>& native_flag =
iblank.const_array(mfi);
const amrex::Array4<amrex::Real>& volfrac = vof.array(mfi);
const amrex::Array4<const amrex::Real>& vfmasked =
vof_new.const_array(mfi);
amrex::ParallelFor(
gbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept {
// In iblanked regions, sharpen VOF and limit it
volfrac(i, j, k) = (native_flag(i, j, k) > 0)
? volfrac(i, j, k)
: vfmasked(i, j, k);
});
}
}
}

} // namespace amr_wind::multiphase

#endif // VOF_HYBRIDSOLVER_OPS.H
59 changes: 59 additions & 0 deletions amr-wind/equation_systems/vof/volume_fractions.H
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,65 @@ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void youngs_fd_normal(
mz = mm1 - mm2;
}

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void youngs_fd_normal_neumann(
int i,
int j,
int k,
int ibdy,
int jbdy,
int kbdy,
amrex::Array4<amrex::Real const> const& volfrac,
amrex::Real& mx,
amrex::Real& my,
amrex::Real& mz) noexcept
{
amrex::Real mm1, mm2;

// Do neumann condition via indices
int im1 = ibdy == -1 ? i : i - 1;
int jm1 = jbdy == -1 ? j : j - 1;
int km1 = kbdy == -1 ? k : k - 1;
int ip1 = ibdy == +1 ? i : i + 1;
int jp1 = jbdy == +1 ? j : j + 1;
int kp1 = kbdy == +1 ? k : k + 1;

mm1 = volfrac(im1, jm1, km1) + volfrac(im1, jm1, kp1) +
volfrac(im1, jp1, km1) + volfrac(im1, jp1, kp1) +
2.0 * (volfrac(im1, jm1, k) + volfrac(im1, jp1, k) +
volfrac(im1, j, km1) + volfrac(im1, j, kp1)) +
4.0 * volfrac(im1, j, k);
mm2 = volfrac(ip1, jm1, km1) + volfrac(ip1, jm1, kp1) +
volfrac(ip1, jp1, km1) + volfrac(ip1, jp1, kp1) +
2.0 * (volfrac(ip1, jm1, k) + volfrac(ip1, jp1, k) +
volfrac(ip1, j, km1) + volfrac(ip1, j, kp1)) +
4.0 * volfrac(ip1, j, k);
mx = mm1 - mm2;

mm1 = volfrac(im1, jm1, km1) + volfrac(im1, jm1, kp1) +
volfrac(ip1, jm1, km1) + volfrac(ip1, jm1, kp1) +
2.0 * (volfrac(im1, jm1, k) + volfrac(ip1, jm1, k) +
volfrac(i, jm1, km1) + volfrac(i, jm1, kp1)) +
4.0 * volfrac(i, jm1, k);
mm2 = volfrac(im1, jp1, km1) + volfrac(im1, jp1, kp1) +
volfrac(ip1, jp1, km1) + volfrac(ip1, jp1, kp1) +
2.0 * (volfrac(im1, jp1, k) + volfrac(ip1, jp1, k) +
volfrac(i, jp1, km1) + volfrac(i, jp1, kp1)) +
4.0 * volfrac(i, jp1, k);
my = mm1 - mm2;

mm1 = volfrac(im1, jm1, km1) + volfrac(im1, jp1, km1) +
volfrac(ip1, jm1, km1) + volfrac(ip1, jp1, km1) +
2.0 * (volfrac(im1, j, km1) + volfrac(ip1, j, km1) +
volfrac(i, jm1, km1) + volfrac(i, jp1, km1)) +
4.0 * volfrac(i, j, km1);
mm2 = volfrac(im1, jm1, kp1) + volfrac(im1, jp1, kp1) +
volfrac(ip1, jm1, kp1) + volfrac(ip1, jp1, kp1) +
2.0 * (volfrac(im1, j, kp1) + volfrac(ip1, j, kp1) +
volfrac(i, jm1, kp1) + volfrac(i, jp1, kp1)) +
4.0 * volfrac(i, j, kp1);
mz = mm1 - mm2;
}

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void mixed_youngs_central_normal(
int i,
int j,
Expand Down
15 changes: 15 additions & 0 deletions amr-wind/incflo.H
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,25 @@ private:
bool m_do_initial_proj = true;
int m_initial_iterations = 3;

// Sharpening multiphase for overset
int m_sharpen_iterations = 10;
amrex::Real m_sharpen_tolerance = 1e-12;
int m_sharpen_calctolniter = 1;
amrex::Real m_sharpen_rlscale = 1.5;
amrex::Real m_sharpen_margin = 0.1;
amrex::Real m_sharpen_proctg_tol = 0.0;
bool m_sharpen_hs_pressure = false;
bool m_sharpen_hsp_guess = true;
bool m_sharpen_hsp_replace = true;
bool m_sharpen_gradp = false;

bool m_constant_density = true;

bool m_use_godunov = true;

// Other choices for overset
bool m_disable_onodal = true;

// Prescribe advection velocity
bool m_prescribe_vel = false;

Expand Down
15 changes: 15 additions & 0 deletions amr-wind/incflo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,21 @@ void incflo::init_physics_and_pde()
// Check for if velocity is prescribed
amrex::ParmParse pp("incflo");
pp.query("prescribe_velocity", m_prescribe_vel);

// Check for sharpening iterations (overset feature)
pp.query("sharpen_iterations", m_sharpen_iterations);
pp.query("sharpen_tolerance", m_sharpen_tolerance);
pp.query("sharpen_calctol_niter", m_sharpen_calctolniter);
pp.query("sharpen_rlscale", m_sharpen_rlscale);
pp.query("sharpen_margin", m_sharpen_margin);
pp.query("sharpen_targetvof_tol", m_sharpen_proctg_tol);
pp.query("sharpen_hs_pressure", m_sharpen_hs_pressure);
pp.query("sharpen_guess_hsp", m_sharpen_hsp_guess);
pp.query("sharpen_replace_hsp", m_sharpen_hsp_replace);
pp.query("sharpen_pressure_grad", m_sharpen_gradp);

// Determine if overset values should be forced into projection
pp.query("disable_overset_nodal", m_disable_onodal);
}
m_sim.create_turbulence_model();

Expand Down
39 changes: 35 additions & 4 deletions amr-wind/incflo_advance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "amr-wind/utilities/console_io.H"
#include "amr-wind/utilities/PostProcessing.H"
#include "AMReX_MultiFabUtil.H"
#include "amr-wind/overset/sharpen_nalu_data.H"

using namespace amrex;

Expand Down Expand Up @@ -190,11 +191,30 @@ void incflo::ApplyPredictor(bool incremental_projection)
const auto& density_old = density_new.state(amr_wind::FieldState::Old);
auto& density_nph = density_new.state(amr_wind::FieldState::NPH);

// Recalculate incoming pressure gradient field if overset
auto gp_copy = density().repo().create_scratch_field(3);
auto& gp = density().repo().get_field("gp");

// Process data for overset multiphase
if (sim().has_overset()) {
UpdateGradP(
(density_old).vec_const_ptrs(), m_time.current_time(),
m_time.deltaT());
// Sharpen nalu fields
amr_wind::overset::SharpenNaluDataDiscrete(
sim(), m_sharpen_iterations, m_sharpen_tolerance,
m_sharpen_calctolniter, m_sharpen_rlscale, m_sharpen_margin,
m_sharpen_proctg_tol, m_sharpen_hs_pressure, m_sharpen_gradp);
// Recalculate pressure gradient with incoming sharpened field
if (!m_sharpen_gradp || sim().time().current_time() == 0.0) {
UpdateGradP(
(density_old).vec_const_ptrs(), m_time.current_time(),
m_time.deltaT());
}
if (m_sharpen_hsp_guess ||
(m_sharpen_gradp && sim().time().current_time() == 0.0)) {
amr_wind::overset::ReplaceMaskedGradP(sim());
}
if (m_sharpen_gradp) {
amr_wind::overset::CopyGradP(
*gp_copy, gp, sim().repo().num_active_levels());
}
}

// *************************************************************************************
Expand Down Expand Up @@ -269,6 +289,10 @@ void incflo::ApplyPredictor(bool incremental_projection)
}
}

if (m_verbose > 2) {
PrintMaxVelLocations("before pre advection");
}

// Extrapolate and apply MAC projection for advection velocities
icns().pre_advection_actions(amr_wind::FieldState::Old);

Expand Down Expand Up @@ -396,6 +420,13 @@ void incflo::ApplyPredictor(bool incremental_projection)
(density_new).vec_const_ptrs(), new_time, m_time.deltaT(),
incremental_projection);

if (m_sharpen_hsp_replace) {
amr_wind::overset::ReapplyModifiedGradP(sim());
}
if (m_sharpen_gradp) {
amr_wind::overset::ReapplyOversetGradP(*gp_copy, sim());
}

if (m_verbose > 2) {
PrintMaxVelLocations("after nodal projection");
}
Expand Down
2 changes: 2 additions & 0 deletions amr-wind/overset/TiogaInterface.H
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ private:

CFDSim& m_sim;

bool m_disable_pressure_from_nalu{true};

//! IBLANK on cell centered fields
IntField& m_iblank_cell;

Expand Down
Loading