36 "Rhie-Chow mass flux object specialized for porous flow/baffle cases.");
39 NS::porosity,
"1",
"Porosity functor (defaults to 1 for non-porous calculations).");
40 params.
addParam<std::vector<UserObjectName>>(
41 "pressure_jump_models", {},
"Pressure jump models applied by this object.");
44 "0.0<pressure_jump_relaxation<=1.0",
45 "Under-relaxation factor for pressure jump updates.");
51 _eps(getFunctor<
Real>(
NS::porosity)),
52 _pressure_jump_relaxation(getParam<
Real>(
"pressure_jump_relaxation")),
55 "baffle_jump", _moose_mesh, blockIDs(),
"baffle_jump"))
62 "Pressure variable '",
64 "' must have the same block restriction as this object. Variable blocks: ",
66 "; this object's blocks: ",
69 for (
const auto *
const velocity :
_vel)
70 if (velocity->blockIDs() !=
blockIDs())
72 "Velocity variable '",
74 "' must have the same block restriction as this object. Variable blocks: ",
76 "; this object's blocks: ",
80 std::unordered_set<BoundaryID> pressure_jump_boundary_ids;
81 for (
const auto & model_name : getParam<std::vector<UserObjectName>>(
"pressure_jump_models"))
83 const auto &
model = getUserObjectByName<PressureJumpModel>(model_name);
84 for (
const auto boundary_id :
model.boundaryIDs())
85 if (!pressure_jump_boundary_ids.insert(boundary_id).second)
87 "Pressure jump models must not act on overlapping boundaries.");
92 for (
const auto & [model_param, rc_param] :
94 if (
model.parameters().have_parameter<MooseFunctorName>(model_param) &&
95 model.getParam<MooseFunctorName>(model_param) != getParam<MooseFunctorName>(rc_param))
97 "Pressure jump model '",
102 model.getParam<MooseFunctorName>(model_param),
103 "' but this object uses '",
104 getParam<MooseFunctorName>(rc_param),
111 const std::vector<LinearSystem *> & momentum_systems,
113 const std::vector<unsigned int> & momentum_system_numbers)
116 momentum_systems, pressure_system, momentum_system_numbers);
122 for (
const auto boundary_id :
model->boundaryIDs())
125 "Pressure jump model '",
129 "' is not internal to this object's blocks. Pressure-jump baffles must lie "
130 "strictly inside the flow domain.");
134 for (
const auto system_number : momentum_system_numbers)
136 std::vector<LinearFVElementalKernel *> kernels;
139 .template condition<AttribThread>(
_tid)
140 .template condition<AttribSystem>(
"LinearFVElementalKernel")
141 .template condition<AttribSysNum>(system_number)
144 for (
const auto *
const kernel : kernels)
145 if (
const auto *
const pressure_kernel =
147 pressure_kernel && MooseUtils::setsIntersect(pressure_kernel->blockIDs(),
blockIDs()) &&
151 "Momentum pressure kernel '",
152 pressure_kernel->name(),
154 pressure_kernel->getParam<MooseFunctorName>(
NS::porosity),
155 "' but this object uses '",
163 "Pressure jump models require LinearFVPressureCorrectionDiffusionJump.");
165 auto *
const pressure_var =
167 mooseAssert(pressure_var,
"The pressure variable type was checked by RhieChowMassFlux.");
168 const auto & solution_gradient_reader = pressure_var->requestCellGradients();
174 if (!jump_gradient_method)
176 pressure_var->name(),
177 "' must use FVPressureJumpGreenGaussGradient as its default gradient method "
178 "when this object has pressure baffles.");
180 jump_gradient_method->linkFlowSystem(*
this, solution_gradient_reader);
185 mooseError(
"FVReconstructedPressureGradient '",
187 "' must use the pressure variable's FVPressureJumpGreenGaussGradient as its "
188 "base_gradient_method when this object has pressure baffles.");
192 "Momentum pressure kernels coupled to this object must use the pressure "
193 "variable's FVPressureJumpGreenGaussGradient or an FVReconstructedPressureGradient "
194 "based on it when pressure baffles are present.");
199 for (
auto *
const velocity :
_vel)
201 const auto & velocity_gradient = velocity->requestCellGradients();
204 if (!velocity_gradient_method)
207 "' must use FVVelocityJumpGreenGaussGradient as its default gradient method "
208 "when this object has pressure baffles.");
210 velocity_gradient_method->linkFlowSystem(*
this);
259 if (
hasBlocks(elem_info->subdomain_id()))
262 const Real cell_volume = elem_info->volume() * elem_info->coordFactor();
295 if (!pressure_jump_model)
299 const bool elem_is_owner = pressure_jump_model->elemIsOwner(fi);
301 return (elem_side == elem_is_owner) ? -J : J;
313 if (!pressure_jump_model || !fi->neighborPtr())
315 if (!
hasBlocks(fi->elemPtr()->subdomain_id()) || !
hasBlocks(fi->neighborPtr()->subdomain_id()))
318 const Real new_jump =
340 velocity(component) =
_vel[component]->getElemValue(cell_info, state);
346 const auto cell_to_face = fi.
faceCentroid() - cell_info.centroid();
361 if (elem_rho <= 0.0 || neighbor_rho <= 0.0)
362 mooseError(
"density must be positive on pressure-jump face ", fi.
id(),
".");
370 Moose::FV::InterpMethod::Average, face_rho, elem_rho, neighbor_rho, fi,
true);
376 const unsigned int component)
const
378 mooseAssert(component <
_Ainv_raw.size(),
"Invalid pressure-diffusion component.");
382 return density * (*
_Ainv_raw[component])(momentum_dof);
402 const Real face_area)
const
409 "Pressure-diffusion data must be ready before constructing a baffle face operator.");
411 const auto & elem_info = *fi.
elemInfo();
425 elem_rho_hbya(component) =
426 elem_rho * (*
_HbyA_raw[component])(elem_info.dofIndices()[system_number][0]);
427 neighbor_rho_hbya(component) =
428 neighbor_rho * (*
_HbyA_raw[component])(neighbor_info.dofIndices()[system_number][0]);
446 mooseAssert(data.
valid,
447 "Cannot construct the pressure-jump operator on face " + std::to_string(fi.
id()) +
448 ": the half-cell distances, normal pressure diffusion coefficients, face area, "
449 "and conductances must be finite and positive, and the corrections finite.");
459 if (
model->appliesTo(fi))
463 mooseAssert(!face_model,
464 "Pressure-jump face " + std::to_string(fi.
id()) +
465 " lies on boundaries of more than one pressure jump model.");
const PertinentGeochemicalSystem model(database, {"H2O", "H+", "HCO3-", "O2(aq)", "Ca++", ">(s)FeOH", "radius_neg1", "radius_neg1.5"}, {"Calcite"}, {}, {"Calcite_asdf"}, {"CH4(aq)"}, {">(s)FeOCa+"}, "O2(aq)", "e-")
registerMooseObject("NavierStokesApp", PorousRhieChowMassFlux)
bool hasBlocks(const SubdomainName &name) const
virtual const std::set< SubdomainID > & blockIDs() const
const Elem * elem() const
const std::vector< std::vector< dof_id_type > > & dofIndices() const
FVGradientMethod & getFVGradientMethod(const GradientMethodName &name, const THREAD_ID tid=0)
virtual MooseMesh & mesh() override
TheWarehouse & theWarehouse() const
Green-Gauss pressure gradient that removes prescribed jumps before interpolating across baffles.
Green-Gauss velocity gradient that uses the one-sided baffle face states of a porous Rhie-Chow object...
A functor whose evaluation relies on querying a map where the keys are face info ids and the values c...
ValueType evaluate(const FaceInfo *const fi) const
Evaluate the face functor using a FaceInfo argument.
const Point & normal() const
const Elem * neighborPtr() const
const ElemInfo * elemInfo() const
const ElemInfo * neighborInfo() const
const Elem * elemPtr() const
const Point & faceCentroid() const
Moose::ElemArg makeElemArg(const Elem *elem, bool correct_skewnewss=false) const
bool useNonorthogonalCorrection() const
const FVGradientMethod & method() const
Pressure-correction diffusion kernel that enforces modeled jumps on internal baffle faces.
Adds the porosity-weighted pressure gradient to the right hand side of the momentum equation written ...
void updateFVGradient(const LinearFVGradientReader &reader)
const std::string & name() const
void paramError(const std::string ¶m, Args... args) const
void mooseError(Args &&... args) const
const T & getParam(const std::string &name) const
const std::string & getBoundaryName(const BoundaryID boundary_id) const
const std::vector< const FaceInfo * > & faceInfo() const
const std::vector< const ElemInfo * > & elemInfoVector() const
bool isBoundaryFullyExternalToSubdomains(BoundaryID bid, const std::set< SubdomainID > &blk_group) const
unsigned int number() const
Computes Rhie-Chow face mass fluxes for porous flow with optional internal pressure jumps.
const Moose::Functor< Real > & _eps
Porosity functor.
bool pressureDiffusionDataReady() const
Whether the pressure-diffusion kernel and cell coefficients are ready for interface use.
const Real _pressure_jump_relaxation
Under-relaxation factor applied when updating pressure jumps.
bool pressureDiffusionUsesNonorthogonalCorrection() const
Whether the linked pressure-diffusion kernel applies a nonorthogonal correction.
void linkMomentumPressureSystems(const std::vector< LinearSystem * > &momentum_systems, LinearSystem &pressure_system, const std::vector< unsigned int > &momentum_system_numbers) override
Update the momentum system-related information.
bool hasPressureBaffles() const
Whether at least one pressure-jump model is configured.
bool faceIsBaffle(const FaceInfo &fi) const
Whether a face is governed by a pressure-jump model.
void setupPorousMeshInformation()
Overwrite the cached cell fluid volumes with cell volume times porosity.
const PressureJumpModel * getPressureJumpModel(const FaceInfo &fi) const
Return the pressure-jump model that applies to the face, or null if there is none.
Real baffleNormalVelocity(const FaceInfo &fi) const
Return the normal superficial velocity at a baffle face, recovered from the shared face mass flux and...
Real getFaceSidePorosity(const FaceInfo &fi, bool elem_side, const Moose::StateArg &time) const
Return the porosity on one side of a face.
std::vector< const PressureJumpModel * > _pressure_jump_models
Pressure-jump models with mutually disjoint boundary sets.
PorousRhieChowMassFlux(const InputParameters ¶ms)
Construct the porous Rhie-Chow mass flux object.
static InputParameters validParams()
std::vector< const LinearFVGradientReader * > _velocity_gradients
Published velocity gradients, one per component, read by the baffle face states.
void updateBaffleJumps()
Recompute and relax the pressure jumps using the current face mass fluxes.
void meshChanged() override
Clear face-indexed baffle-jump data after a mesh change.
void computeHbyA(bool verbose) override
Computes the inverse of the diagonal (1/A) of the system matrix plus the H/A components for the press...
FaceCenteredMapFunctor< Real, std::unordered_map< dof_id_type, Real > > & _baffle_jump
Restartable face field storing pressure as non-owner minus owner.
NS::FV::PressureJumpInterfaceData pressureJumpInterfaceData(const FaceInfo &fi, const RealVectorValue &elem_gradient, const RealVectorValue &neighbor_gradient, Real face_area) const
Construct the complete pressure-jump operator for a face.
void initCouplingField() override
Populate baffle-jump storage after initializing the pressure coupling field.
RealVectorValue baffleFaceVelocity(const FaceInfo &fi, bool elem_side) const
Return the superficial velocity at a baffle face as seen from one side.
Real getSignedBaffleJump(const FaceInfo &fi, bool elem_side) const
Return the pressure jump seen from one side of a baffle face.
Real cellPressureDiffusionCoefficient(const ElemInfo &elem_info, unsigned int component) const
Cell coefficient whose face interpolation forms the pressure-diffusion tensor.
Interface for pressure-jump models evaluated by PorousRhieChowMassFlux.
User object responsible for determining the face fluxes using the Rhie-Chow interpolation in a segreg...
const MooseMesh & _moose_mesh
The MooseMesh that this user object operates on.
const LinearFVGradientReader & basePressureGradientField() const
Get the base pressure gradient field used to seed reconstructed gradient updates.
virtual void computeHbyA(bool verbose)
Computes the inverse of the diagonal (1/A) of the system matrix plus the H/A components for the press...
virtual void linkMomentumPressureSystems(const std::vector< LinearSystem * > &momentum_systems, LinearSystem &pressure_system, const std::vector< unsigned int > &momentum_system_numbers)
Update the momentum system-related information.
LinearFVPressureCorrectionDiffusion * _p_diffusion_kernel
Pointer to the pressure diffusion term in the pressure Poisson equation.
unsigned int _global_pressure_system_number
Global number of the pressure system.
const MooseLinearVariableFVReal *const _p
The thread 0 copy of the pressure variable.
virtual void meshChanged() override
std::vector< MooseLinearVariableFVReal * > _vel
Thread 0 copies of the velocity variables; non-const to allow writing cell velocities in updateCellVe...
LinearSystem * _pressure_system
Pointer to the pressure system.
std::vector< std::unique_ptr< NumericVector< Number > > > _Ainv_raw
We hold on to the cell-based 1/A vectors so that we can easily reconstruct the cell velocities as wel...
std::vector< const FaceInfo * > _flow_face_info
The subset of the FaceInfo objects that actually cover the subdomains which the flow field is defined...
std::vector< std::unique_ptr< NumericVector< Number > > > _HbyA_raw
We hold on to the cell-based HbyA vectors so that we can easily reconstruct the cell velocities as we...
FVReconstructedPressureGradient & reconstructedGradientMethod()
Access the reconstructed gradient method when it is selected.
const Moose::Functor< Real > & _rho
Functor describing the density of the fluid.
virtual void initCouplingField()
Initialize the coupling fields (HbyA and Ainv)
bool usingReconstructedPressureGradientMethod() const
Whether the registered pressure gradient field is produced by the reconstructed method.
FaceCenteredMapFunctor< Real, std::unordered_map< dof_id_type, Real > > & _face_mass_flux
A map functor from faces to mass fluxes which are used in the advection terms.
const LinearFVGradientReader & pressureGradientField() const
Get the registered pressure gradient field used by compatible momentum pressure kernels.
static InputParameters validParams()
FaceCenteredMapFunctor< Real, std::unordered_map< dof_id_type, Real > > _HbyA_flux
A map functor from faces to $HbyA_{ij} = (A_{offdiag}*\mathrm{(predicted~velocity)} - \mathrm{Source}...
std::unique_ptr< NumericVector< Number > > _cell_fluid_volumes
Fluid volume of each cell, used to rapidly scale the pressure-gradient force in H/A and 1/A.
unsigned int dimension() const
Number of spatial dimensions of the coupled momentum/pressure systems.
std::vector< unsigned int > _global_momentum_system_numbers
Global numbers of the momentum system(s)
MooseVariableFieldBase & getVariable(THREAD_ID tid, const std::string &var_name) const
FEProblemBase & _fe_problem
void interpolate(InterpMethod m, T &result, const T2 &value1, const T3 &value2, const FaceInfo &fi, const bool one_is_elem)
std::string stringify(const T &t)
PressureJumpInterfaceData pressureJumpInterfaceData(const RealVectorValue &normal, const Point &elem_to_face, const Point &face_to_neighbor, const RealVectorValue &elem_diffusion, const RealVectorValue &neighbor_diffusion, const RealVectorValue &elem_gradient, const RealVectorValue &neighbor_gradient, const RealVectorValue &elem_rho_hbya, const RealVectorValue &neighbor_rho_hbya, const Real face_area, const bool use_nonorthogonal_correction, const Real elem_jump)
Construct the conservative half-cell interface coefficients for a diagonal diffusion tensor.
Real pressureJumpHbyAFlux(const PressureJumpInterfaceData &data)
Compute the H/A part of the face mass flux after eliminating the interface pressures.
static const std::string density
static const std::string porosity
static const std::string pressure
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
auto index_range(const T &sizable)
VectorValue< Real > RealVectorValue
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
Complete face operator obtained by eliminating the two one-sided interface pressures.