25 #include "libmesh/mesh_base.h" 26 #include "libmesh/elem_range.h" 27 #include "libmesh/parallel_algebra.h" 28 #include "libmesh/remote_elem.h" 29 #include "metaphysicl/metaphysicl_version.h" 30 #include "metaphysicl/dualsemidynamicsparsenumberarray.h" 31 #include "metaphysicl/parallel_dualnumber.h" 32 #if METAPHYSICL_MAJOR_VERSION < 2 33 #include "metaphysicl/parallel_dynamic_std_array_wrapper.h" 35 #include "metaphysicl/parallel_dynamic_array_wrapper.h" 37 #include "metaphysicl/parallel_semidynamicsparsenumberarray.h" 48 params.addParam<
bool>(
49 "pull_all_nonlocal_a",
51 "Whether to pull all nonlocal 'a' coefficient data to our process. Note that 'nonlocal' " 52 "means elements that we have access to (this may not be all the elements in the mesh if the " 53 "mesh is distributed) but that we do not own.");
54 params.addParamNamesToGroup(
"pull_all_nonlocal_a",
"Parallel Execution Tuning");
56 params.addParam<
bool>(
57 "correct_volumetric_force",
false,
"Flag to activate volume force corrections.");
58 MooseEnum volume_force_correction_method(
"force-consistent pressure-consistent",
61 "volume_force_correction_method",
62 volume_force_correction_method,
63 "The method used for correcting the Rhie-Chow coefficients for a volume force.");
64 params.addParam<std::vector<MooseFunctorName>>(
65 "volumetric_force_functors",
"The names of the functors with the volumetric force sources.");
69 std::vector<std::string>
72 return {
"pull_all_nonlocal_a",
73 "correct_volumetric_force",
74 "volume_force_correction_method",
75 "volumetric_force_functors"};
84 params.addClassDescription(
85 "Computes the Rhie-Chow velocity based on gathered 'a' coefficient data.");
92 params.addParam<MooseFunctorName>(
94 "For simulations in which the advecting velocities are aux variables, this parameter must be " 95 "supplied. It represents the on-diagonal coefficients for the 'x' component velocity, solved " 96 "via the Navier-Stokes equations.");
97 params.addParam<MooseFunctorName>(
99 "For simulations in which the advecting velocities are aux variables, this parameter must be " 100 "supplied when the mesh dimension is greater than 1. It represents the on-diagonal " 101 "coefficients for the 'y' component velocity, solved via the Navier-Stokes equations.");
102 params.addParam<MooseFunctorName>(
104 "For simulations in which the advecting velocities are aux variables, this parameter must be " 105 "supplied when the mesh dimension is greater than 2. It represents the on-diagonal " 106 "coefficients for the 'z' component velocity, solved via the Navier-Stokes equations.");
107 params.addParam<VariableName>(
"disp_x",
"The x-component of displacement");
108 params.addParam<VariableName>(
"disp_y",
"The y-component of displacement");
109 params.addParam<VariableName>(
"disp_z",
"The z-component of displacement");
116 _a(_moose_mesh, blockIDs(),
"a", true),
120 _momentum_sys_number(_fe_problem.systemNumForVariable(getParam<VariableName>(
"u"))),
122 _a_data_provided(false),
123 _pull_all_nonlocal(getParam<bool>(
"pull_all_nonlocal_a")),
124 _bool_correct_vf(getParam<bool>(
"correct_volumetric_force")),
125 _volume_force_correction_method(getParam<
MooseEnum>(
"volume_force_correction_method")),
126 _volumetric_force_functors(
127 isParamValid(
"volumetric_force_functors")
128 ? &getParam<
std::vector<MooseFunctorName>>(
"volumetric_force_functors")
131 auto process_displacement = [
this](
const auto & disp_name,
auto & disp_container)
135 "Displacement provided but we are not running on the displaced mesh. If you " 136 "really want this object to run on the displaced mesh, then set " 137 "'use_displaced_mesh = true', otherwise remove this displacement parameter");
144 process_displacement(
"disp_x",
_disp_xs);
149 process_displacement(
"disp_y",
_disp_ys);
151 paramError(
"disp_y",
"If 'disp_x' is provided, then 'disp_y' must be as well");
157 process_displacement(
"disp_z",
_disp_zs);
159 paramError(
"disp_z",
"If 'disp_x' is provided, then 'disp_z' must be as well");
164 _vel[tid] = std::make_unique<PiecewiseByBlockLambdaFunctor<ADRealVectorValue>>(
165 name() + std::to_string(tid),
181 name() +
"_disp_" + std::to_string(tid),
191 "Rhie Chow coefficients may not be specified for average velocity interpolation");
198 "At least one volumetric force functor must be specified if " 199 "'correct_volumetric_force' is true.");
204 const unsigned int num_volume_forces = (*_volumetric_force_functors).size();
206 for (
const auto i :
make_range(num_volume_forces))
219 mooseError(
"If a_u is provided, then a_v must be provided");
222 mooseError(
"If a_u is provided, then a_w must be provided");
228 paramError(
"a_v",
"If the a_v coefficients are provided, then a_u must be provided");
230 paramError(
"a_w",
"If the a_w coefficients are provided, then a_u must be provided");
248 _a_aux[tid] = std::make_unique<Moose::VectorCompositeFunctor<ADReal>>(
278 std::vector<MooseObject *> var_objects;
281 .template condition<AttribVar>(
static_cast<int>(var_num))
282 .template condition<AttribResidualObject>(
true)
283 .
template condition<AttribSysNum>(
_u->
sys().
number())
284 .queryInto(var_objects);
285 for (
auto *
const var_object : var_objects)
288 if (!dynamic_cast<INSFVMomentumResidualObject *>(var_object) &&
289 !dynamic_cast<FVElementalKernel *>(var_object))
292 " is not a INSFVMomentumResidualObject. Make sure that all the objects applied " 293 "to the momentum equation are INSFV or derived objects.");
294 else if (!dynamic_cast<INSFVMomentumResidualObject *>(var_object) &&
299 " is not a INSFVMomentumResidualObject. Make sure that all the objects applied " 300 "to the momentum equation are INSFV or derived objects.");
304 mooseError(
"No INSFVKernels detected for the velocity variables. If you are trying to use " 305 "auxiliary variables for advection, please specify the a_u/v/w coefficients. If " 306 "not, please specify INSFVKernels for the momentum equations.");
315 Real elem_value = 0.0;
332 std::make_unique<ConstElemRange>(
_mesh.active_local_subdomain_set_elements_begin(
blockIDs()),
359 for (
auto & pair :
_a)
362 for (
auto & pair :
_a)
364 auto & a_val = pair.second;
378 "a-coefficient data should not be provided if the velocity variables are in the " 379 "nonlinear system and we are running kernels that compute said a-coefficients");
386 TIME_SECTION(
"execute", 1,
"Computing Rhie-Chow coefficients");
392 const auto saved_do_derivatives = ADReal::do_derivatives;
393 ADReal::do_derivatives =
true;
408 Threads::parallel_reduce(faces, fvr);
412 ADReal::do_derivatives = saved_do_derivatives;
426 using Datum = std::pair<dof_id_type, VectorValue<ADReal>>;
427 std::unordered_map<processor_id_type, std::vector<Datum>> push_data;
428 std::unordered_map<processor_id_type, std::vector<dof_id_type>> pull_requests;
434 const auto id = elem->id();
435 const auto pid = elem->processor_id();
436 auto it =
_a.find(
id);
437 mooseAssert(it !=
_a.end(),
"We definitely should have found something");
438 push_data[pid].push_back(std::make_pair(
id, it->second));
444 for (
const auto *
const elem :
445 as_range(
_mesh.active_not_local_elements_begin(),
_mesh.active_not_local_elements_end()))
446 if (
blockIDs().count(elem->subdomain_id()))
447 pull_requests[elem->processor_id()].push_back(elem->id());
452 pull_requests[elem->processor_id()].push_back(elem->id());
457 auto action_functor =
458 [
this](
const processor_id_type libmesh_dbg_var(pid),
const std::vector<Datum> & sent_data)
460 mooseAssert(pid != this->
processor_id(),
"We do not send messages to ourself here");
461 for (
const auto & pr : sent_data)
462 _a[pr.first] += pr.second;
470 const std::vector<dof_id_type> & elem_ids,
471 std::vector<VectorValue<ADReal>> & data_to_fill)
473 mooseAssert(pid != this->
processor_id(),
"We shouldn't be gathering from ourselves.");
474 data_to_fill.resize(elem_ids.size());
477 const auto id = elem_ids[i];
478 auto it =
_a.find(
id);
479 mooseAssert(it !=
_a.end(),
"We should hold the value for this locally");
480 data_to_fill[i] = it->second;
485 const std::vector<dof_id_type> & elem_ids,
486 const std::vector<VectorValue<ADReal>> & filled_data)
488 mooseAssert(pid != this->
processor_id(),
"The request filler shouldn't have been ourselves");
489 mooseAssert(elem_ids.size() == filled_data.size(),
"I think these should be the same size");
491 _a[elem_ids[i]] = filled_data[i];
494 _communicator, pull_requests, gather_functor, action_functor, &example);
531 const bool subtract_mesh_velocity)
const 533 const Elem *
const elem = &fi.
elem();
536 auto & p = *
_ps[tid];
537 auto *
const u =
_us[tid];
542 auto incorporate_mesh_velocity =
543 [
this, tid, subtract_mesh_velocity, &time](
const auto & space,
auto &
velocity)
545 if (
_disps.size() && subtract_mesh_velocity)
559 incorporate_mesh_velocity(boundary_face,
velocity);
579 incorporate_mesh_velocity(face,
velocity);
593 mooseDoOnce(
mooseWarning(
"Cannot compute Rhie Chow coefficients on initial. Returning linearly " 594 "interpolated velocities"););
599 mooseDoOnce(
mooseWarning(
"Cannot compute Rhie Chow coefficients if not solving. Returning " 600 "linearly interpolated velocities"););
607 "The 'a' coefficients have not been generated or provided for " 608 "Rhie Chow velocity interpolation.");
611 "We should be on an internal face...");
616 const auto & grad_p = p.adGradSln(fi, time, correct_skewness_p);
620 const auto & unc_grad_p = p.uncorrectedAdGradSln(fi, time, correct_skewness_p);
628 auto vf_indicator_pressure_based =
629 [
this, &elem, &neighbor, &time, &fi, &correct_skewness](
const Point & unit_basis_vector)
633 Real uncorrected_interp_vf;
647 Real elem_value = 0.0;
648 Real neigh_value = 0.0;
652 Real coord_multiplier;
654 const unsigned int rz_radial_coord =
669 elem->
vertex_average(), coord_multiplier, coord_type, rz_radial_coord);
684 elem_value += (*this->
_volumetric_force[i])(loc_face, time) * face_volume_contribution *
685 (fi_loc->
normal() * unit_basis_vector);
688 elem_value = elem_value / elem->
volume();
692 for (
const auto side :
make_range(neighbor->n_sides()))
704 neighbor->vertex_average(), coord_multiplier, coord_type, rz_radial_coord);
717 neigh_value += (*this->
_volumetric_force[i])(loc_face, time) * face_volume_contribution *
718 (fi_loc->
normal() * unit_basis_vector);
721 neigh_value = neigh_value / neighbor->
volume();
726 fi.faceCentroid(), coord_multiplier, coord_type, rz_radial_coord);
731 return MooseUtils::relativeFuzzyEqual(interp_vf, uncorrected_interp_vf, 1e-10) ? 0.0 : 1.0;
738 auto vf_indicator_force_based = [
this, &time, &fi, &correct_skewness](
Point & face_normal)
752 const Point & elem_centroid = fi.elemCentroid();
753 const Point & neighbor_centroid = fi.neighborCentroid();
754 Real elem_volume = fi.elemVolume();
755 Real neighbor_volume = fi.neighborVolume();
762 "Coordinate systems must be the same between the two elements");
767 elem_volume *= coord;
772 mooseAssert(elem_a(i).
value() != 0,
"We should not be dividing by zero");
773 elem_D(i) = elem_volume / elem_a(i);
781 neighbor_volume *= coord;
786 mooseAssert(neighbor_a(i).
value() != 0,
"We should not be dividing by zero");
787 neighbor_D(i) = neighbor_volume / neighbor_a(i);
799 const auto face_eps =
epsilon(tid)(face, time);
807 velocity(i) -= face_D(i) * face_eps * (grad_p(i) - unc_grad_p(i));
813 Point unit_basis_vector;
814 unit_basis_vector(i) = 1.0;
817 Real correction_indicator;
819 correction_indicator = vf_indicator_force_based(unit_basis_vector);
821 correction_indicator = vf_indicator_pressure_based(unit_basis_vector);
824 velocity(i) += face_D(i) * face_eps * (grad_p(i) - unc_grad_p(i)) * correction_indicator;
A class that gathers body force data from elemental kernels contributing to the Navier-Stokes momentu...
unsigned int getAxisymmetricRadialCoord() const
void pull_parallel_vector_data(const Communicator &comm, const MapToVectors &queries, GatherFunctor &gather_data, const ActionFunctor &act_on_data, const datum *example)
virtual void initialize() override
bool elemHasFaceInfo(const Elem &elem, const Elem *const neighbor)
bool needAComputation() const
Whether we need 'a' coefficient computation.
std::vector< MooseVariableFVReal * > _ps
All the thread copies of the pressure variable.
std::vector< const Moose::Functor< Real > * > _volumetric_force
Values of the functors storing the volumetric forces.
CellCenteredMapFunctor< ADRealVectorValue, std::unordered_map< dof_id_type, ADRealVectorValue > > _a
A map from element IDs to 'a' coefficient data.
std::unordered_set< dof_id_type > getBoundaryActiveSemiLocalElemIds(BoundaryID bid) const
const Moose::Functor< T > & getFunctor(const std::string &name, const THREAD_ID tid, const std::string &requestor_name, bool requestor_is_ad)
virtual void execute() override
const unsigned int invalid_uint
void paramError(const std::string ¶m, Args... args) const
virtual void ghostADataOnBoundary(const BoundaryID boundary_id) override
makes sure coefficient data gets communicated on both sides of a given boundary
virtual Elem * elemPtr(const dof_id_type i)
MooseMesh & _moose_mesh
The MooseMesh that this user object operates on.
face_info_iterator ownedFaceInfoBegin()
virtual const Moose::FunctorBase< ADReal > & epsilon(THREAD_ID tid) const
A virtual method that allows us to only implement getVelocity once for free and porous flows...
INSFVVelocityVariable *const _u
The thread 0 copy of the x-velocity variable.
void coordTransformFactor(const P &point, C &factor, const Moose::CoordinateSystemType coord_type, const unsigned int rz_radial_coord=libMesh::invalid_uint)
INSFVVelocityVariable *const _v
The thread 0 copy of the y-velocity variable (null if the problem is 1D)
const ExecFlagType & getCurrentExecuteOnFlag() const
const Elem & elem() const
std::vector< MooseVariableField< Real > * > _disp_xs
All the thread copies of the x-displacement variable.
Moose::StateArg determineState() const
void coordTransformFactor(const SubProblem &s, SubdomainID sub_id, const P &point, C &factor, SubdomainID neighbor_sub_id=libMesh::Elem::invalid_subdomain_id)
std::vector< MooseVariableField< Real > * > _disp_ys
All the thread copies of the y-displacement variable.
void addFunctor(const std::string &name, const Moose::FunctorBase< T > &functor, const THREAD_ID tid)
const Moose::ConstantFunctor< ADReal > _zero_functor
A zero functor potentially used in _a_read.
bool _pull_all_nonlocal
Whether we want to pull all nonlocal 'a' coefficient data.
Moose::VectorComponentFunctor< ADReal > _az
The z-component of 'a'.
const bool _displaced
Whether this object is operating on the displaced mesh.
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
const std::vector< MooseFunctorName > * _volumetric_force_functors
Names of the functors storing the volumetric forces.
const Parallel::Communicator & _communicator
virtual const std::set< SubdomainID > & blockIDs() const
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
const ExecFlagType EXEC_ALWAYS
A class that gathers 'a' coefficient data from flux kernels, boundary conditions, and interface kerne...
virtual Elem * queryElemPtr(const dof_id_type i)
std::vector< MooseVariableFVReal * > _us
All the thread copies of the x-velocity variable.
Moose::ElemArg makeElemArg(const Elem *elem, bool correct_skewnewss=false) const
bool pressureSkewCorrection(THREAD_ID tid) const
Whether central differencing face interpolations of pressure should include a skewness correction...
void push_parallel_vector_data(const Communicator &comm, MapToVectors &&data, const ActionFunctor &act_on_data)
uint8_t processor_id_type
virtual VectorValue< ADReal > getVelocity(const Moose::FV::InterpMethod m, const FaceInfo &fi, const Moose::StateArg &time, const THREAD_ID tid, bool subtract_mesh_velocity) const override
Retrieve a face velocity.
const std::vector< const FaceInfo *> & faceInfo() const
processor_id_type n_processors() const
const std::string & name() const
static InputParameters uniqueParams()
Parameters of this object that should be added to the NSFV action that are unique to this object...
registerMooseObject("NavierStokesApp", INSFVRhieChowInterpolator)
const Elem * neighborPtr() const
std::unordered_set< dof_id_type > getBoundaryActiveNeighborElemIds(BoundaryID bid) const
virtual void addToA(const libMesh::Elem *elem, unsigned int component, const ADReal &value) override
API that momentum residual objects that have on-diagonals for velocity call.
Moose::VectorComponentFunctor< ADReal > _ay
The y-component of 'a'.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void min(const T &r, T &o, Request &req) const
TheWarehouse & theWarehouse() const
static InputParameters validParams()
unsigned int which_neighbor_am_i(const Elem *e) const
boundary_id_type BoundaryID
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
virtual unsigned int currentNlSysNum() const override
void insfvSetup()
perform the setup of this object
std::unordered_set< const Elem * > _elements_to_push_pull
Non-local elements that we should push and pull data for across processes.
const unsigned int _dim
The dimension of the mesh, e.g. 3 for hexes and tets, 2 for quads and tris.
const Point & normal() const
unsigned int number() const
void fillARead()
Fills the _a_read data member at construction time with the appropriate functors. ...
Moose::FV::InterpMethod _velocity_interp_method
The interpolation method to use for the velocity.
void fillContainer(const std::string &var_name, Container &container)
Fill the passed-in variable container with the thread copies of var_name.
const libMesh::MeshBase & _mesh
The libMesh mesh that this object acts on.
const Elem * elemPtr() const
const MooseEnum _volume_force_correction_method
– Method used for computing the properties average
static std::vector< std::string > listOfCommonParams()
bool onBoundary(const SubdomainRestrictable &obj, const FaceInfo &fi)
void checkBlocks(const VarType &var) const
Check the block consistency between the passed in var and us.
virtual unsigned int n_sides() const=0
const Elem * neighbor_ptr(unsigned int i) const
const INSFVVelocityVariable * vel() const
std::vector< const Moose::FunctorBase< VectorValue< ADReal > > * > _a_read
A vector sized according to the number of threads that holds the 'a' data we will read from when comp...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string v
virtual void meshChanged() override
subdomain_id_type subdomain_id() const
INSFVVelocityVariable *const _w
The thread 0 copy of the z-velocity variable (null if the problem is not 3D)
std::tuple< bool, T, T > isPorosityJumpFace(const Moose::FunctorBase< T > &porosity, const FaceInfo &fi, const Moose::StateArg &time)
Checks to see whether the porosity value jumps from one side to the other of the provided face...
Real _baseline_volume_force
Minimum absolute RC force over the domain.
FEProblemBase & _fe_problem
std::vector< unsigned int > _var_numbers
The velocity variable numbers.
std::unique_ptr< ConstElemRange > _elem_range
All the active and elements local to this process that exist on this object's subdomains.
void mooseWarning(Args &&... args) const
virtual Real volume() const
IntRange< T > make_range(T beg, T end)
std::vector< std::unique_ptr< Moose::VectorCompositeFunctor< ADReal > > > _disps
A functor for computing the displacement.
std::vector< MooseVariableField< Real > * > _disp_zs
All the thread copies of the z-displacement variable.
const bool & _bool_correct_vf
Correct Rhie-Chow coefficients for volumetric force flag.
void mooseError(Args &&... args) const
virtual void initialSetup() override
std::vector< MooseVariableFVReal * > _ws
All the thread copies of the z-velocity variable.
This user-object gathers 'a' (on-diagonal velocity coefficients) data.
Moose::CoordinateSystemType getCoordSystem(SubdomainID sid) const
static const std::string velocity
const ExecFlagType EXEC_PRE_KERNELS
Moose::VectorComponentFunctor< ADReal > _ax
bool isParamValid(const std::string &name) const
bool _a_data_provided
Whether 'a' data has been provided by the user.
face_info_iterator ownedFaceInfoEnd()
bool velocitySkewCorrection(THREAD_ID tid) const
Whether central differencing face interpolations of velocity should include a skewness correction Als...
bool hasBlocks(const SubdomainName &name) const
virtual void finalize() override
processor_id_type processor_id() const
void interpolate(InterpMethod m, T &result, const T2 &value1, const T3 &value2, const FaceInfo &fi, const bool one_is_elem)
INSFVRhieChowInterpolator(const InputParameters ¶ms)
std::vector< std::unique_ptr< Moose::FunctorBase< VectorValue< ADReal > > > > _a_aux
A vector sized according to the number of threads that holds vector composites of 'a' component funct...
std::vector< MooseVariableFVReal * > _vs
All the thread copies of the y-velocity variable.
auto index_range(const T &sizable)
static InputParameters validParams()
Point vertex_average() const
static std::string deduceFunctorName(const std::string &name, const InputParameters ¶ms)
std::vector< std::unique_ptr< PiecewiseByBlockLambdaFunctor< ADRealVectorValue > > > _vel
A functor for computing the (non-RC corrected) velocity.
const unsigned int _momentum_sys_number
The number of the nonlinear system in which the monolithic momentum and continuity equations are loca...
const ExecFlagType EXEC_INITIAL