8#ifndef PECLET_FLOW_FLOW_IBM_CLOSURES_HPP
9#define PECLET_FLOW_FLOW_IBM_CLOSURES_HPP
16 for (
int face = 0; face < 6; ++face)
17 if (bc_[face] != 0 && touchesGlobalFace(face))
33 for (
int c = 0; c < 3; ++c)
47 for (
int face = 0; face < 6; ++face) {
48 const int t = bc_[face];
49 if (t == 0 || !touchesGlobalFace(face))
60 return varRho_ || (porous_ && porousCons_);
65 return varRho_ ? rhoField_ : epsRho_;
73 const double rho = rho_;
75 "peclet::flow::eps_rho", Kokkos::RangePolicy<CCExec>(
space, 0, n_),
82 fp.haveMu = varProps_;
88 fp.harmMu = harmonicMu_;
100 fp.rhoIdtC = rho_ / dt_;
111 Kokkos::parallel_for(
112 "peclet::flow::div_adv",
113 MD(
space, {
G - 1,
G - 1,
G - 1}, {e.x -
G + 1, e.y -
G + 1, e.z -
G + 1}),
115 const long sx = 1, sy = e.x, sz = (
long)e.x * e.y;
116 const long i = (
long)x + (
long)y * sy + (
long)z * sz;
117 dv(i) = (
U(i +
sx) -
U(i)) + (V(i + sy) - V(i)) + (W(i + sz) - W(i));
123 const std::string& in0,
const std::string& in1,
124 const std::vector<double>&
params) {
125 if (
target ==
"mu" && vmgExplicit_ && useVelocityMg_)
145 for (
int k = 0; k < 4 && k < (int)
params.size(); ++k)
149 closures_.push_back(
cl);
162 if (fields_.has(
"rho"))
163 rhoField_ = fields_.at(
"rho").data;
166 Kokkos::deep_copy(rhoField_, rho_);
168 if (rho1_.extent(0) == 0) {
174 ensureCellForceAll();
175 useVelocityMg_ =
false;
188 useChebyshev_ =
true;
189 chebBoundsSet_ =
false;
198 return cutcellPressure_;
203 if constexpr (Grid::collocated) {
205 throw std::runtime_error(
"set_porous_continuity: staggered-only (v1)");
209 if (fields_.has(
"eps"))
210 epsField_ = fields_.at(
"eps").data;
213 Kokkos::deep_copy(epsField_, 1.0);
215 if (epsPrev_.extent(0) == 0) {
216 epsPrev_ =
CCField(
"epsPrev", n_);
217 depsdt_ =
CCField(
"depsdt", n_);
219 if (divAdv_.extent(0) == 0)
220 divAdv_ =
CCField(
"divAdv", n_);
221 if (epsRho_.extent(0) == 0)
222 epsRho_ =
CCField(
"epsRho", n_);
227 ensureCellForceAll();
228 Kokkos::deep_copy(epsPrev_, epsField_);
229 if (eps1_.extent(0) == 0)
231 if (beta1_.extent(0) == 0)
232 beta1_ =
CCField(
"beta1", n1_);
233 if (rho1_.extent(0) == 0) {
248 useChebyshev_ =
true;
249 chebBoundsSet_ =
false;
260 Kokkos::deep_copy(epsPrev_, epsField_);
275 pressUnderRelax_ = w;
282 if (
variable && vmgExplicit_ && useVelocityMg_)
285 harmonicMu_ = harmonic;
287 if (fields_.has(
"mu"))
288 muField_ = fields_.at(
"mu").data;
291 Kokkos::deep_copy(muField_,
301 varRotMode_ = mode < 0 ? 0 : (mode > 2 ? 2 : mode);
302 varRotChi_ =
chi < 0.0 ? 0.0 :
chi;
307 const std::vector<double>& xs,
const std::vector<double>&
ys) {
314 cl.nTab = (int)std::min(xs.size(),
ys.size());
317 auto hx = Kokkos::create_mirror_view(
cl.tabX);
318 auto hy = Kokkos::create_mirror_view(
cl.tabY);
319 for (
int k = 0; k <
cl.nTab; ++k) {
323 Kokkos::deep_copy(
cl.tabX,
hx);
324 Kokkos::deep_copy(
cl.tabY,
hy);
325 cl.tabYPhys.assign(
ys.begin(),
ys.begin() +
cl.nTab);
328 closures_.push_back(
cl);
346 "peclet.flow set_property_model NOTICE: a physical domain is armed and target "
347 "'%s' is not rho/mu/force_x/y/z, so this closure's parameters are taken in "
348 "that field's INTERNAL units (see the `unit_scales` property).\n",
360 auto hy = Kokkos::create_mirror_view(
cl.tabY);
361 for (
int k = 0; k <
cl.nTab; ++k)
362 hy(k) =
cl.tabYPhys[(std::size_t)k] * kp;
363 Kokkos::deep_copy(
cl.tabY,
hy);
368 for (
int k = 0; k < 4; ++k)
374 for (
auto&
cl : closures_)
380 ensureCellForceAll();
385 if (!fields_.has(
"drag_beta"))
388 dragBeta_ = fields_.at(
"drag_beta").data;
389 ensureCellForceAll();
396 if (!(porous_ && hasDrag_))
398 pressGraphAmg_ =
true;
401 if (cutcellPressure_)
403 useChebyshev_ =
false;
404 chebBoundsSet_ =
false;
430 Kokkos::parallel_for(
431 "peclet::flow::add_drag_diag",
MD(
space, {
G,
G,
G}, {e.x -
G, e.y -
G, e.z -
G}),
433 const long i = (
long)x + (
long)y * e.x + (
long)z * (
long)e.x * e.y;
434 const double bd = Grid::atVelocity(beta, i, sc);
void setAgglomerationMode(int mode)
bool hasCutcellPressure() const
void registerBalancedForceState()
void fillDragBetaGhosts()
void fillGhosts(CCField f)
void fillPropGhosts(CCField f, bool edges=false)
void setPropertyMode(bool variable, bool harmonic)
CCField addField(const std::string &name)
void setPropertyModel(const std::string &target, ClosureKind kind, const std::string &in0, const std::string &in1, const std::vector< double > ¶ms)
void applyScalarBcFace(CCField c, int a, int side, int type, double val, bool edges=false)
void addDragDiagonal(int c)
void setVariableRotational(int mode, double chi)
void setPressureUnderRelax(double w)
void closureUnitsNotice(const std::string &target) const
Under a physical domain, say on stderr that a closure on a target of unknown dimension takes its para...
void setPorousDepsDt(bool on)
void closureRefreshUnits(Closure &cl)
Re-derive a closure's internal p / tabY from its physical pPhys / tabYPhys with the current reference...
void setPorousConservative(bool on)
long strideOf(int c) const
void collocatedV8AutoFallback(const char *why)
void throwVelocityMgVariableMu(const char *who) const
void setDensityMode(bool variable)
void fillCellForceGhosts()
Kokkos::View< MReal *, CCMem > FV
void setPropertyTable(const std::string &target, const std::string &in0, const std::vector< double > &xs, const std::vector< double > &ys)
void configurePorousDragSolver()
double closureTargetToInt(const std::string &target) const
The internal-per-physical factor of a closure TARGET: rho, mu, force_x/y/z; 0.0 for any other field (...
VarFaceProps makeFaceProps(int c)
void vofBcPropGhosts(CCField f)
WO-R item 5 — the Neumann property policy at an inflow face.
void setPorousContinuity(bool on)
void fillPorousEpsGhosts()
Kokkos::View< double *, CCMem > CCField
Kokkos::DefaultExecutionSpace CCExec
void applyClosure(const Closure &cl, C3 e, int g)
Kokkos::View< const double *, CCMem > CCConst
double forceToInt(int a) const
bool physical
an extent was given (the scales are armed)
static constexpr double AC
static constexpr double U