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/dualsemidynamicsparsenumberarray.h" 30 #include "metaphysicl/parallel_dualnumber.h" 31 #include "metaphysicl/parallel_dynamic_std_array_wrapper.h" 32 #include "metaphysicl/parallel_semidynamicsparsenumberarray.h" 43 params.addParam<
bool>(
44 "pull_all_nonlocal_a",
46 "Whether to pull all nonlocal 'a' coefficient data to our process. Note that 'nonlocal' " 47 "means elements that we have access to (this may not be all the elements in the mesh if the " 48 "mesh is distributed) but that we do not own.");
49 params.addParamNamesToGroup(
"pull_all_nonlocal_a",
"Parallel Execution Tuning");
51 params.addParam<
bool>(
52 "correct_volumetric_force",
false,
"Flag to activate volume force corrections.");
53 MooseEnum volume_force_correction_method(
"force-consistent pressure-consistent",
56 "volume_force_correction_method",
57 volume_force_correction_method,
58 "The method used for correcting the Rhie-Chow coefficients for a volume force.");
59 params.addParam<std::vector<MooseFunctorName>>(
60 "volumetric_force_functors",
"The names of the functors with the volumetric force sources.");
64 std::vector<std::string>
67 return {
"pull_all_nonlocal_a",
68 "correct_volumetric_force",
69 "volume_force_correction_method",
70 "volumetric_force_functors"};
79 params.addClassDescription(
80 "Computes the Rhie-Chow velocity based on gathered 'a' coefficient data.");
87 params.addParam<MooseFunctorName>(
89 "For simulations in which the advecting velocities are aux variables, this parameter must be " 90 "supplied. It represents the on-diagonal coefficients for the 'x' component velocity, solved " 91 "via the Navier-Stokes equations.");
92 params.addParam<MooseFunctorName>(
94 "For simulations in which the advecting velocities are aux variables, this parameter must be " 95 "supplied when the mesh dimension is greater than 1. It represents the on-diagonal " 96 "coefficients for the 'y' component velocity, solved 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 2. It represents the on-diagonal " 101 "coefficients for the 'z' component velocity, solved via the Navier-Stokes equations.");
102 params.addParam<VariableName>(
"disp_x",
"The x-component of displacement");
103 params.addParam<VariableName>(
"disp_y",
"The y-component of displacement");
104 params.addParam<VariableName>(
"disp_z",
"The z-component of displacement");
111 _a(_moose_mesh, blockIDs(),
"a", true),
115 _momentum_sys_number(_fe_problem.systemNumForVariable(getParam<VariableName>(
"u"))),
117 _a_data_provided(false),
118 _pull_all_nonlocal(getParam<bool>(
"pull_all_nonlocal_a")),
119 _bool_correct_vf(getParam<bool>(
"correct_volumetric_force")),
120 _volume_force_correction_method(getParam<
MooseEnum>(
"volume_force_correction_method")),
121 _volumetric_force_functors(
122 isParamValid(
"volumetric_force_functors")
123 ? &getParam<
std::vector<MooseFunctorName>>(
"volumetric_force_functors")
126 auto process_displacement = [
this](
const auto & disp_name,
auto & disp_container)
130 "Displacement provided but we are not running on the displaced mesh. If you " 131 "really want this object to run on the displaced mesh, then set " 132 "'use_displaced_mesh = true', otherwise remove this displacement parameter");
139 process_displacement(
"disp_x",
_disp_xs);
144 process_displacement(
"disp_y",
_disp_ys);
146 paramError(
"disp_y",
"If 'disp_x' is provided, then 'disp_y' must be as well");
152 process_displacement(
"disp_z",
_disp_zs);
154 paramError(
"disp_z",
"If 'disp_x' is provided, then 'disp_z' must be as well");
159 _vel[tid] = std::make_unique<PiecewiseByBlockLambdaFunctor<ADRealVectorValue>>(
160 name() + std::to_string(tid),
176 name() +
"_disp_" + std::to_string(tid),
186 "Rhie Chow coefficients may not be specified for average velocity interpolation");
193 "At least one volumetric force functor must be specified if " 194 "'correct_volumetric_force' is true.");
199 const unsigned int num_volume_forces = (*_volumetric_force_functors).size();
201 for (
const auto i :
make_range(num_volume_forces))
214 mooseError(
"If a_u is provided, then a_v must be provided");
217 mooseError(
"If a_u is provided, then a_w must be provided");
223 paramError(
"a_v",
"If the a_v coefficients are provided, then a_u must be provided");
225 paramError(
"a_w",
"If the a_w coefficients are provided, then a_u must be provided");
243 _a_aux[tid] = std::make_unique<Moose::VectorCompositeFunctor<ADReal>>(
273 std::vector<MooseObject *> var_objects;
276 .template condition<AttribVar>(
static_cast<int>(var_num))
277 .template condition<AttribResidualObject>(
true)
278 .
template condition<AttribSysNum>(
_u->
sys().
number())
279 .queryInto(var_objects);
280 for (
auto *
const var_object : var_objects)
283 if (!dynamic_cast<INSFVMomentumResidualObject *>(var_object) &&
284 !dynamic_cast<FVElementalKernel *>(var_object))
287 " is not a INSFVMomentumResidualObject. Make sure that all the objects applied " 288 "to the momentum equation are INSFV or derived objects.");
289 else if (!dynamic_cast<INSFVMomentumResidualObject *>(var_object) &&
294 " is not a INSFVMomentumResidualObject. Make sure that all the objects applied " 295 "to the momentum equation are INSFV or derived objects.");
299 mooseError(
"No INSFVKernels detected for the velocity variables. If you are trying to use " 300 "auxiliary variables for advection, please specify the a_u/v/w coefficients. If " 301 "not, please specify INSFVKernels for the momentum equations.");
310 Real elem_value = 0.0;
327 std::make_unique<ConstElemRange>(
_mesh.active_local_subdomain_set_elements_begin(
blockIDs()),
354 for (
auto & pair :
_a)
357 for (
auto & pair :
_a)
359 auto & a_val = pair.second;
373 "a-coefficient data should not be provided if the velocity variables are in the " 374 "nonlinear system and we are running kernels that compute said a-coefficients");
381 TIME_SECTION(
"execute", 1,
"Computing Rhie-Chow coefficients");
387 const auto saved_do_derivatives = ADReal::do_derivatives;
388 ADReal::do_derivatives =
true;
403 Threads::parallel_reduce(faces, fvr);
407 ADReal::do_derivatives = saved_do_derivatives;
421 using Datum = std::pair<dof_id_type, VectorValue<ADReal>>;
422 std::unordered_map<processor_id_type, std::vector<Datum>> push_data;
423 std::unordered_map<processor_id_type, std::vector<dof_id_type>> pull_requests;
429 const auto id = elem->id();
430 const auto pid = elem->processor_id();
431 auto it =
_a.find(
id);
432 mooseAssert(it !=
_a.end(),
"We definitely should have found something");
433 push_data[pid].push_back(std::make_pair(
id, it->second));
439 for (
const auto *
const elem :
440 as_range(
_mesh.active_not_local_elements_begin(),
_mesh.active_not_local_elements_end()))
441 if (
blockIDs().count(elem->subdomain_id()))
442 pull_requests[elem->processor_id()].push_back(elem->id());
447 pull_requests[elem->processor_id()].push_back(elem->id());
452 auto action_functor =
453 [
this](
const processor_id_type libmesh_dbg_var(pid),
const std::vector<Datum> & sent_data)
455 mooseAssert(pid != this->
processor_id(),
"We do not send messages to ourself here");
456 for (
const auto & pr : sent_data)
457 _a[pr.first] += pr.second;
465 const std::vector<dof_id_type> & elem_ids,
466 std::vector<VectorValue<ADReal>> & data_to_fill)
468 mooseAssert(pid != this->
processor_id(),
"We shouldn't be gathering from ourselves.");
469 data_to_fill.resize(elem_ids.size());
472 const auto id = elem_ids[i];
473 auto it =
_a.find(
id);
474 mooseAssert(it !=
_a.end(),
"We should hold the value for this locally");
475 data_to_fill[i] = it->second;
480 const std::vector<dof_id_type> & elem_ids,
481 const std::vector<VectorValue<ADReal>> & filled_data)
483 mooseAssert(pid != this->
processor_id(),
"The request filler shouldn't have been ourselves");
484 mooseAssert(elem_ids.size() == filled_data.size(),
"I think these should be the same size");
486 _a[elem_ids[i]] = filled_data[i];
489 _communicator, pull_requests, gather_functor, action_functor, &example);
526 const bool subtract_mesh_velocity)
const 528 const Elem *
const elem = &fi.
elem();
531 auto & p = *
_ps[tid];
532 auto *
const u =
_us[tid];
537 auto incorporate_mesh_velocity =
538 [
this, tid, subtract_mesh_velocity, &time](
const auto & space,
auto &
velocity)
540 if (
_disps.size() && subtract_mesh_velocity)
554 incorporate_mesh_velocity(boundary_face,
velocity);
574 incorporate_mesh_velocity(face,
velocity);
588 mooseDoOnce(
mooseWarning(
"Cannot compute Rhie Chow coefficients on initial. Returning linearly " 589 "interpolated velocities"););
594 mooseDoOnce(
mooseWarning(
"Cannot compute Rhie Chow coefficients if not solving. Returning " 595 "linearly interpolated velocities"););
602 "The 'a' coefficients have not been generated or provided for " 603 "Rhie Chow velocity interpolation.");
606 "We should be on an internal face...");
611 const auto & grad_p = p.adGradSln(fi, time, correct_skewness_p);
615 const auto & unc_grad_p = p.uncorrectedAdGradSln(fi, time, correct_skewness_p);
623 auto vf_indicator_pressure_based =
624 [
this, &elem, &neighbor, &time, &fi, &correct_skewness](
const Point & unit_basis_vector)
628 Real uncorrected_interp_vf;
642 Real elem_value = 0.0;
643 Real neigh_value = 0.0;
647 Real coord_multiplier;
649 const unsigned int rz_radial_coord =
664 elem->
vertex_average(), coord_multiplier, coord_type, rz_radial_coord);
679 elem_value += (*this->
_volumetric_force[i])(loc_face, time) * face_volume_contribution *
680 (fi_loc->
normal() * unit_basis_vector);
683 elem_value = elem_value / elem->
volume();
687 for (
const auto side :
make_range(neighbor->n_sides()))
699 neighbor->vertex_average(), coord_multiplier, coord_type, rz_radial_coord);
712 neigh_value += (*this->
_volumetric_force[i])(loc_face, time) * face_volume_contribution *
713 (fi_loc->
normal() * unit_basis_vector);
716 neigh_value = neigh_value / neighbor->
volume();
721 fi.faceCentroid(), coord_multiplier, coord_type, rz_radial_coord);
733 auto vf_indicator_force_based = [
this, &time, &fi, &correct_skewness](
Point & face_normal)
747 const Point & elem_centroid = fi.elemCentroid();
748 const Point & neighbor_centroid = fi.neighborCentroid();
749 Real elem_volume = fi.elemVolume();
750 Real neighbor_volume = fi.neighborVolume();
757 "Coordinate systems must be the same between the two elements");
762 elem_volume *= coord;
767 mooseAssert(elem_a(i).
value() != 0,
"We should not be dividing by zero");
768 elem_D(i) = elem_volume / elem_a(i);
776 neighbor_volume *= coord;
781 mooseAssert(neighbor_a(i).
value() != 0,
"We should not be dividing by zero");
782 neighbor_D(i) = neighbor_volume / neighbor_a(i);
794 const auto face_eps =
epsilon(tid)(face, time);
802 velocity(i) -= face_D(i) * face_eps * (grad_p(i) - unc_grad_p(i));
808 Point unit_basis_vector;
809 unit_basis_vector(i) = 1.0;
812 Real correction_indicator;
814 correction_indicator = vf_indicator_force_based(unit_basis_vector);
816 correction_indicator = vf_indicator_pressure_based(unit_basis_vector);
819 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
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
std::tuple< bool, ADReal, ADReal > isPorosityJumpFace(const Moose::Functor< ADReal > &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...
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
virtual const std::string & name() const
void mooseWarning(Args &&... args) const
A class that gathers 'a' coefficient data from flux kernels, boundary conditions, and interface kerne...
virtual Elem * queryElemPtr(const dof_id_type i)
bool isParamValid(const std::string &name) const
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
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
void paramError(const std::string ¶m, Args... args) 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)
Real _baseline_volume_force
Minimum absolute RC force over the domain.
FEProblemBase & _fe_problem
bool relativeFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
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.
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 _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