22 #include "libmesh/mesh_base.h" 23 #include "libmesh/elem_range.h" 24 #include "metaphysicl/dualsemidynamicsparsenumberarray.h" 27 #include "libmesh/petsc_matrix.h" 28 #include "libmesh/petsc_vector.h" 39 params.addClassDescription(
"Computes H/A and 1/A together with face velocities for segregated " 40 "momentum-pressure equations.");
55 _HbyA(_moose_mesh, blockIDs(),
"HbyA"),
56 _Ainv(_moose_mesh, blockIDs(),
"Ainv", false),
71 _face_velocity(_moose_mesh, blockIDs(),
"face_values")
74 paramError(
"use_displaced_mesh",
75 "The segregated Rhie-Chow user object does not currently support operation on a " 86 paramError(
"velocity_interp_method",
87 "Segregated momentum-pressure solvers do not allow average interpolation methods!");
89 if (!dynamic_cast<SIMPLENonlinearAssembly *>(getMooseApp().getExecutioner()))
90 mooseError(this->
name(),
" should only be used with a segregated thermal-hydraulics solver!");
95 std::vector<NonlinearSystemBase *> momentum_systems,
96 const std::vector<unsigned int> & momentum_system_numbers,
97 const TagID pressure_gradient_tag)
106 dynamic_cast<NonlinearImplicitSystem *>(&system->system()));
120 for (
const auto & pair :
_HbyA)
121 _HbyA[pair.first] = 0;
123 for (
const auto & pair :
_Ainv)
124 _Ainv[pair.first] = 0;
132 if (
hasBlocks(fi->elemPtr()->subdomain_id()) ||
133 (fi->neighborPtr() &&
hasBlocks(fi->neighborPtr()->subdomain_id())))
146 const Elem *
const boundary_elem =
147 hasBlocks(fi->elemPtr()->subdomain_id()) ? fi->elemPtr() : fi->neighborPtr();
167 mooseError(
"Segregated solution algorithms only support Rhie-Chow interpolation!");
178 if (
hasBlocks(fi->elemPtr()->subdomain_id()) ||
179 (fi->neighborPtr() &&
hasBlocks(fi->neighborPtr()->subdomain_id())))
203 -HbyA(comp_index) - Ainv(comp_index) * grad_p(comp_index);
207 const Elem *
const boundary_elem =
208 hasBlocks(fi->elemPtr()->subdomain_id()) ? fi->elemPtr() : fi->neighborPtr();
224 -HbyA(comp_index) - Ainv(comp_index) * grad_p(comp_index);
256 const auto index = elem->dof_number(system_number, var_nums[comp_index], 0);
261 index, -(*
_HbyA_raw[comp_index])(index)-Ainv(comp_index) * grad_p(comp_index));
278 const std::vector<unsigned int> & var_nums)
282 if (
hasBlocks(fi->elemPtr()->subdomain_id()) ||
283 (fi->neighborPtr() &&
hasBlocks(fi->neighborPtr()->subdomain_id())))
290 const Elem * elem = fi->elemPtr();
291 const Elem * neighbor = fi->neighborPtr();
295 const auto dof_index_elem = elem->
dof_number(system_number, var_nums[comp_index], 0);
296 const auto dof_index_neighbor =
297 neighbor->
dof_number(system_number, var_nums[comp_index], 0);
300 _HbyA[fi->id()](comp_index),
301 (*raw_hbya[comp_index])(dof_index_elem),
302 (*raw_hbya[comp_index])(dof_index_neighbor),
309 const Elem *
const boundary_elem =
310 hasBlocks(fi->elemPtr()->subdomain_id()) ? fi->elemPtr() : fi->neighborPtr();
321 const auto dof_index_elem =
322 boundary_elem->
dof_number(system_number, var_nums[comp_index], 0);
323 _HbyA[fi->id()](comp_index) = (*raw_hbya[comp_index])(dof_index_elem);
335 _console <<
"************************************" << std::endl;
336 _console <<
"Computing HbyA" << std::endl;
337 _console <<
"************************************" << std::endl;
340 "The momentum system shall be linked before calling this function!");
362 "The matrices used in the segregated INSFVRhieChow objects need to be convertable " 367 _console <<
"Matrix in rc object" << std::endl;
371 auto Ainv = current_local_solution.
zero_clone();
376 auto working_vector = momentum_system->current_local_solution->zero_clone();
379 mooseAssert(working_vector_petsc,
380 "The vectors used in the segregated INSFVRhieChow objects need to be convertable " 383 *working_vector_petsc = 1.0;
391 _console <<
"Velocity solution in H(u)" << std::endl;
396 auto active_local_begin =
397 _mesh.evaluable_elements_begin(momentum_system->get_dof_map(), var_nums[system_i]);
398 auto active_local_end =
399 _mesh.evaluable_elements_end(momentum_system->get_dof_map(), var_nums[system_i]);
402 for (
auto it = active_local_begin; it != active_local_end; ++it)
404 const Elem * elem = *it;
408 Real coord_multiplier;
410 const unsigned int rz_radial_coord =
414 elem->
vertex_average(), coord_multiplier, coord_type, rz_radial_coord);
417 const auto dof_index = elem->
dof_number(momentum_system->number(), var_nums[system_i], 0);
419 (*Ainv_petsc)(dof_index)*
volume * coord_multiplier;
425 *working_vector_petsc = 0.0;
426 LibmeshPetscCall(MatDiagonalSet(mmat->
mat(), working_vector_petsc->
vec(), INSERT_VALUES));
449 _console <<
"total RHS" << std::endl;
451 _console <<
"pressure RHS" << std::endl;
466 mmat->
vector_mult(*working_vector_petsc, solution);
471 working_vector_petsc->
print();
475 HbyA.
add(*working_vector_petsc);
479 _console <<
" H(u)-rhs-relaxation_source" << std::endl;
488 _console <<
" (H(u)-rhs)/A" << std::endl;
497 _console <<
"************************************" << std::endl;
498 _console <<
"DONE Computing HbyA " << std::endl;
499 _console <<
"************************************" << std::endl;
unsigned int getAxisymmetricRadialCoord() const
registerMooseObject("NavierStokesApp", INSFVRhieChowInterpolatorSegregated)
INSFVPressureVariable *const _p
The thread 0 copy of the pressure variable.
std::vector< libMesh::NonlinearImplicitSystem * > _momentum_implicit_systems
Pointers to the momentum equation implicit system(s)
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
std::vector< NonlinearSystemBase * > _momentum_systems
Pointers to the nonlinear system(s) corresponding to the momentum equation(s)
std::vector< unsigned int > _momentum_system_numbers
Numbers of the momentum system(s)
const unsigned int invalid_uint
MooseMesh & _moose_mesh
The MooseMesh that this user object operates on.
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...
void mooseError(Args &&... args)
INSFVVelocityVariable *const _u
The thread 0 copy of the x-velocity variable.
void initialize() override
void vector_mult(NumericVector< T > &dest, const NumericVector< T > &arg) const
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)
virtual std::unique_ptr< NumericVector< T > > zero_clone() const=0
const ExecFlagType EXEC_NONE
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
Get the face velocity (used in advection terms)
void addFunctor(const std::string &name, const Moose::FunctorBase< T > &functor, const THREAD_ID tid)
const std::string & name() const override
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
const ExecFlagType EXEC_ALWAYS
virtual void pointwise_divide(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
CellCenteredMapFunctor< RealVectorValue, std::unordered_map< dof_id_type, RealVectorValue > > _Ainv
A map functor from element IDs to $1/A_i$.
virtual bool isDirichletBoundaryFace(const FaceInfo &fi, const Elem *elem, const Moose::StateArg &state) const
Moose::ElemArg makeElemArg(const Elem *elem, bool correct_skewnewss=false) const
virtual void scale(const T factor)=0
void computeFaceVelocity()
Update the values of the face velocities in the containers.
bool isInternalFace(const FaceInfo &) const
const std::vector< const FaceInfo *> & faceInfo() const
void setCurrentNonlinearSystem(const unsigned int nl_sys_num)
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...
FaceCenteredMapFunctor< RealVectorValue, std::unordered_map< dof_id_type, RealVectorValue > > _face_velocity
A map functor from faces to face velocities which are used in the advection terms.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
const unsigned int _dim
The dimension of the mesh, e.g. 3 for hexes and tets, 2 for quads and tris.
virtual void print(std::ostream &os=libMesh::out) const
static InputParameters validParams()
void populateHbyA(const std::vector< std::unique_ptr< NumericVector< Number >>> &raw_hbya, const std::vector< unsigned int > &var_nums)
Populate the face values of the H/A field.
const libMesh::MeshBase & _mesh
The libMesh mesh that this object acts on.
virtual void pointwise_mult(const NumericVector< T > &vec1, const NumericVector< T > &vec2)=0
virtual void get_diagonal(NumericVector< T > &dest) const override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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)
FEProblemBase & _fe_problem
FaceCenteredMapFunctor< RealVectorValue, std::unordered_map< dof_id_type, RealVectorValue > > _HbyA
A map functor from faces to $HbyA_{ij} = (A_{offdiag}*{(predicted~velocity)} - {Source})_{ij}/A_{ij}$...
GradientType gradient(const ElemArg &elem, const StateArg &state) const
IntRange< T > make_range(T beg, T end)
virtual MooseMesh & mesh() override
void computeCellVelocity()
Update the cell values of the velocity variables.
TagID _pressure_gradient_tag
Residual tag corresponding to the pressure gradient contribution.
void mooseError(Args &&... args) const
Moose::CoordinateSystemType getCoordSystem(SubdomainID sid) const
static const std::string velocity
void meshChanged() override
virtual TagName vectorTagName(const TagID tag) const
const ConsoleStream _console
bool hasBlocks(const SubdomainName &name) const
std::unique_ptr< PiecewiseByBlockLambdaFunctor< ADRealVectorValue > > _vel
A functor for computing the (non-RC corrected) velocity.
virtual void add(const numeric_index_type i, const T value)=0
void interpolate(InterpMethod m, T &result, const T2 &value1, const T3 &value2, const FaceInfo &fi, const bool one_is_elem)
INSFVRhieChowInterpolatorSegregated(const InputParameters ¶ms)
void computeHbyA(bool verbose)
Computes the inverse of the digaonal (1/A) of the system matrix plus the H/A components for the press...
auto index_range(const T &sizable)
static InputParameters validParams()
void print(std::ostream &os=libMesh::out, const bool sparse=false) const
const ElemInfo & elemInfo(const dof_id_type id) const
Point vertex_average() const
A user object which implements the Rhie Chow interpolation for segregated momentum-pressure systems...
void linkMomentumSystem(std::vector< NonlinearSystemBase *> momentum_systems, const std::vector< unsigned int > &momentum_system_numbers, const TagID pressure_gradient_tag)
Update the momentum system-related information.
virtual void computeResidualTag(const NumericVector< libMesh::Number > &soln, NumericVector< libMesh::Number > &residual, TagID tag)
void initFaceVelocities()
Initialize the container for face velocities.