25 params.addRequiredParam<NonlinearVariableName>(
NS::pressure,
"The pressure variable.");
26 params.addRequiredParam<NonlinearVariableName>(
"v",
"The y-component of velocity");
27 params.addParam<NonlinearVariableName>(
"w",
"The z-component of velocity");
28 params.renameParam(
"gradient_variable",
"grad_u",
"The gradient of the x-component of velocity");
29 params.addRequiredParam<NonlinearVariableName>(
"grad_v",
30 "The gradient of the y-component of velocity");
31 params.addParam<NonlinearVariableName>(
"grad_w",
"The gradient of the z-component of velocity");
32 params.renameParam(
"face_variable",
"face_u",
"The x-component of the face velocity");
33 params.addRequiredParam<NonlinearVariableName>(
"face_v",
"The y-component of the face velocity");
34 params.addParam<NonlinearVariableName>(
"face_w",
"The z-component of the face velocity");
35 params.addParam<NonlinearVariableName>(
37 "For enclosed problems like the lid driven cavity this variable can be provided to remove " 38 "the pressure nullspace");
39 params.renameParam(
"diffusivity",
NS::mu,
"The dynamic viscosity");
55 _v_var(sys.getFieldVariable<
Real>(tid, moose_obj->getParam<NonlinearVariableName>(
"v"))),
56 _w_var(
mesh.dimension() > 2
57 ? &sys.getFieldVariable<
Real>(tid, moose_obj->getParam<NonlinearVariableName>(
"w"))
60 tid, moose_obj->getParam<NonlinearVariableName>(
"grad_v"))),
61 _grad_w_var(
mesh.dimension() > 2
63 tid, moose_obj->getParam<NonlinearVariableName>(
"grad_w"))
66 sys.getFieldVariable<
Real>(tid, moose_obj->getParam<NonlinearVariableName>(
"face_v"))),
69 ? &sys.getFieldVariable<
Real>(tid, moose_obj->getParam<NonlinearVariableName>(
"face_w"))
72 sys.getFieldVariable<
Real>(tid, moose_obj->getParam<NonlinearVariableName>(
NS::
pressure))),
73 _enclosure_lm_var(moose_obj->isParamValid(
"enclosure_lm")
74 ? &sys.getScalarVariable(
75 tid, moose_obj->getParam<NonlinearVariableName>(
"enclosure_lm"))
78 _qv_dof_indices(_grad_v_var.dofIndices()),
79 _v_dof_indices(_v_var.dofIndices()),
80 _lm_v_dof_indices(_v_face_var.dofIndices()),
81 _qw_dof_indices(_grad_w_var ? &_grad_w_var->dofIndices() : nullptr),
82 _w_dof_indices(_w_var ? &_w_var->dofIndices() : nullptr),
83 _lm_w_dof_indices(_w_face_var ? &_w_face_var->dofIndices() : nullptr),
84 _p_dof_indices(_pressure_var.dofIndices()),
85 _global_lm_dof_indices(_enclosure_lm_var ? &_enclosure_lm_var->dofIndices() : nullptr),
87 _qv_sol(_grad_v_var.sln()),
89 _lm_v_sol(_v_face_var.sln()),
90 _qw_sol(_grad_w_var ? &_grad_w_var->sln() : nullptr),
91 _w_sol(_w_var ? &_w_var->sln() : nullptr),
92 _lm_w_sol(_w_face_var ? &_w_face_var->sln() : nullptr),
93 _p_sol(_pressure_var.sln()),
94 _global_lm_dof_value(_enclosure_lm_var ? &_enclosure_lm_var->sln() : nullptr),
97 if (
mesh.dimension() > 2)
106 auto check_type = [&vel_type](
const auto & var)
108 if (vel_type != var.feType())
111 "does not have the same finite element type as the x-component velocity. All scalar " 112 "field finite element types must be the same for the Navier-Stokes L-HDG implementation");
120 auto check_grad_type = [&grad_type](
const auto & var)
122 if (grad_type != var.feType())
125 "does not have the same finite element type as the x-component velocity gradient. All " 126 "vector field finite element types must be the same for the Navier-Stokes L-HDG " 134 auto check_lm_type = [&lm_type](
const auto & var)
136 if (lm_type != var.feType())
138 "does not have the same finite element type as the x-component face variable. All " 139 "face variable finite element types must be the same for the Navier-Stokes L-HDG " 149 const unsigned int vel_component,
153 const Elem *
const current_elem,
158 vel_gradient, body_force, JxW, qrule, current_elem, q_point, scalar_re);
164 qp_p(vel_component) =
_p_sol[qp];
188 for (
const auto i :
make_range(scalar_vector_jac.
m()))
200 mooseAssert(scalar_u_vel_jac.
n() == scalar_v_vel_jac.
n(),
"These must be the same size");
205 const auto rho_vel_cross_vel =
207 scalar_u_vel_jac(i,
j) -= JxW[qp] * (
_grad_scalar_phi[i][qp] * rho_vel_cross_vel);
211 const auto rho_vel_cross_vel =
213 scalar_v_vel_jac(i,
j) -= JxW[qp] * (
_grad_scalar_phi[i][qp] * rho_vel_cross_vel);
224 const Elem *
const current_elem,
232 const auto f = pressure_mms_forcing_function(
247 "There should only be one degree of freedom for removing the pressure nullspace");
248 pressure_re(i) -= JxW[qp] *
_scalar_phi[i][qp] * (*_global_lm_dof_value)[0];
253 global_lm_re(0) -= JxW[qp] *
_p_sol[qp];
281 p_global_lm_jac(i, 0) -= JxW[qp] *
_scalar_phi[i][qp];
295 const unsigned int qp,
296 const unsigned int vel_component)
299 return _rho * U * U(vel_component);
305 const unsigned int qp,
306 const unsigned int vel_component,
307 const unsigned int vel_j_component,
309 const unsigned int j)
313 vector_phi(vel_j_component) = phi[
j][qp];
314 auto ret = vector_phi * U(vel_component);
315 if (vel_component == vel_j_component)
316 ret += U * phi[
j][qp];
323 const QBase & qrule_face,
330 const auto vdotn = vel * normals[qp];
338 const QBase & qrule_face,
343 mooseAssert((p_lm_u_vel_jac.
m() == p_lm_v_vel_jac.
m()) &&
344 (p_lm_u_vel_jac.
n() == p_lm_v_vel_jac.
n()),
345 "We already checked that lm finite element types are the same, so these matrices " 346 "should be the same size");
347 for (
const auto i :
make_range(p_lm_u_vel_jac.
m()))
353 p_lm_u_vel_jac(i,
j) += JxW_face[qp] * phi * normals[qp] *
_scalar_phi_face[i][qp];
357 p_lm_v_vel_jac(i,
j) += JxW_face[qp] * phi * normals[qp] *
_scalar_phi_face[i][qp];
366 const unsigned int vel_component,
368 const QBase & qrule_face,
373 vector_sol, scalar_sol, lm_sol, JxW_face, qrule_face, normals, scalar_re);
378 qp_p(vel_component) =
_p_sol[qp];
384 scalar_re(i) += JxW_face[qp] *
_scalar_phi_face[i][qp] * (qp_p * normals[qp]);
387 scalar_re(i) += JxW_face[qp] *
_scalar_phi_face[i][qp] * rho_vel_cross_vel * normals[qp];
395 const QBase & qrule_face,
406 JxW_face, qrule_face, normals, scalar_vector_jac, scalar_scalar_jac, scalar_lm_jac);
408 for (
const auto i :
make_range(scalar_lm_u_vel_jac.
m()))
416 scalar_p_jac(i,
j) += JxW_face[qp] *
_scalar_phi_face[i][qp] * (p_phi * normals[qp]);
419 for (
const auto j :
make_range(scalar_lm_u_vel_jac.
n()))
427 const auto rho_vel_cross_vel =
429 scalar_lm_u_vel_jac(i,
j) +=
434 const auto rho_vel_cross_vel =
436 scalar_lm_v_vel_jac(i,
j) +=
447 const unsigned int vel_component,
449 const QBase & qrule_face,
451 const Elem *
const neigh,
455 vector_sol, scalar_sol, lm_sol, JxW_face, qrule_face, normals, lm_re);
460 qp_p(vel_component) =
_p_sol[qp];
466 lm_re(i) += JxW_face[qp] *
_lm_phi_face[i][qp] * (qp_p * normals[qp]);
472 lm_re(i) += JxW_face[qp] *
_lm_phi_face[i][qp] * rho_vel_cross_vel * normals[qp];
480 const QBase & qrule_face,
482 const Elem *
const neigh,
491 JxW_face, qrule_face, normals, lm_vec_jac, lm_scalar_jac, lm_lm_jac);
500 lm_p_jac(i,
j) += JxW_face[qp] *
_lm_phi_face[i][qp] * (p_phi * normals[qp]);
508 const auto rho_vel_cross_vel =
510 lm_lm_u_vel_jac(i,
j) +=
511 JxW_face[qp] *
_lm_phi_face[i][qp] * rho_vel_cross_vel * normals[qp];
515 const auto rho_vel_cross_vel =
517 lm_lm_v_vel_jac(i,
j) +=
518 JxW_face[qp] *
_lm_phi_face[i][qp] * rho_vel_cross_vel * normals[qp];
528 const QBase & qrule_face,
530 const Elem *
const current_elem,
531 const unsigned int current_side,
538 current_elem, current_side, qp, &qrule_face, q_point_face[qp]};
540 const RealVectorValue dirichlet_velocity((*dirichlet_vel[0])(elem_side_qp_arg, time_arg),
541 (*dirichlet_vel[1])(elem_side_qp_arg, time_arg),
542 (*dirichlet_vel[2])(elem_side_qp_arg, time_arg));
543 const auto vdotn = dirichlet_velocity * normals[qp];
553 const unsigned int vel_component,
556 const QBase & qrule_face,
558 const Elem *
const current_elem,
559 const unsigned int current_side,
565 *dirichlet_vel[vel_component],
577 qp_p(vel_component) =
_p_sol[qp];
580 current_elem, current_side, qp, &qrule_face, q_point_face[qp]};
582 const RealVectorValue dirichlet_velocity((*dirichlet_vel[0])(elem_side_qp_arg, time_arg),
583 (*dirichlet_vel[1])(elem_side_qp_arg, time_arg),
584 (*dirichlet_vel[2])(elem_side_qp_arg, time_arg));
585 const auto scalar_value = dirichlet_velocity(vel_component);
590 scalar_re(i) += JxW_face[qp] *
_scalar_phi_face[i][qp] * (qp_p * normals[qp]);
594 (
_rho * dirichlet_velocity * normals[qp]) * scalar_value;
602 const QBase & qrule_face,
609 JxW_face, qrule_face, normals, scalar_vector_jac, scalar_scalar_jac);
611 for (
const auto i :
make_range(scalar_pressure_jac.
m()))
612 for (
const auto j :
make_range(scalar_pressure_jac.
n()))
618 scalar_pressure_jac(i,
j) += JxW_face[qp] *
_scalar_phi_face[i][qp] * (p_phi * normals[qp]);
const MooseArray< Number > & _p_sol
void pressureVolumeJacobian(const MooseArray< Real > &JxW, const libMesh::QBase &qrule, DenseMatrix< Number > &p_u_vel_jac, DenseMatrix< Number > &p_v_vel_jac, DenseMatrix< Number > &p_global_lm_jac, DenseMatrix< Number > &global_lm_p_jac)
Compute the volumetric contributions to the pressure Jacobian, e.g.
const MooseArray< Number > & _v_sol
const MooseArray< std::vector< Real > > & _scalar_phi_face
const MooseArray< Number > & _u_sol
const MooseArray< std::vector< Real > > & _scalar_phi
static InputParameters validParams()
void scalarDirichletResidual(const MooseArray< Gradient > &vector_sol, const MooseArray< Number > &scalar_sol, const Moose::Functor< Real > &dirichlet_value, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, const Elem *const current_elem, const unsigned int current_side, const MooseArray< Point > &q_point_face, DenseVector< Number > &scalar_re)
const libMesh::FEType & feType() const
void lmFaceJacobian(const unsigned int vel_component, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, const Elem *const neigh, DenseMatrix< Number > &lm_vec_jac, DenseMatrix< Number > &lm_scalar_jac, DenseMatrix< Number > &lm_lm_jac, DenseMatrix< Number > &lm_p_jac, DenseMatrix< Number > &lm_lm_u_vel_jac, DenseMatrix< Number > &lm_lm_v_vel_jac)
const MooseVariableFE< Real > & _v_var
RealVectorValue rhoVelCrossVelJacobian(const MooseArray< Number > &u_sol, const MooseArray< Number > &v_sol, const unsigned int qp, const unsigned int vel_component, const unsigned int vel_j_component, const MooseArray< std::vector< Real >> &phi, const unsigned int j)
void mooseError(Args &&... args)
void pressureVolumeResidual(const Moose::Functor< Real > &pressure_mms_forcing_function, const MooseArray< Real > &JxW, const libMesh::QBase &qrule, const Elem *const current_elem, const MooseArray< Point > &q_point, DenseVector< Number > &pressure_re, DenseVector< Number > &global_lm_re)
Compute the volumetric contributions to the pressure residual, e.g.
const MooseArray< std::vector< Real > > & _lm_phi_face
const MooseVariableFE< Real > *const _w_var
Moose::StateArg determineState() const
const MooseVariableFE< Real > & _v_face_var
static const std::string density
void pressureFaceJacobian(const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseMatrix< Number > &p_lm_u_vel_jac, DenseMatrix< Number > &p_lm_v_vel_jac)
const MooseArray< std::vector< RealVectorValue > > & _grad_scalar_phi
void scalarFaceResidual(const MooseArray< Gradient > &vector_sol, const MooseArray< Number > &scalar_sol, const MooseArray< Number > &lm_sol, const unsigned int vel_component, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseVector< Number > &scalar_re)
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
void scalarVolumeJacobian(const unsigned int vel_component, const MooseArray< Real > &JxW, const libMesh::QBase &qrule, DenseMatrix< Number > &scalar_vector_jac, DenseMatrix< Number > &scalar_u_vel_jac, DenseMatrix< Number > &scalar_v_vel_jac, DenseMatrix< Number > &scalar_p_jac)
Compute the volumetric contributions to a velocity Jacobian.
RealVectorValue rhoVelCrossVelResidual(const MooseArray< Number > &u_sol, const MooseArray< Number > &v_sol, const unsigned int qp, const unsigned int vel_component)
void scalarFaceJacobian(const unsigned int vel_component, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseMatrix< Number > &scalar_vector_jac, DenseMatrix< Number > &scalar_scalar_jac, DenseMatrix< Number > &scalar_lm_jac, DenseMatrix< Number > &scalar_p_jac, DenseMatrix< Number > &scalar_lm_u_vel_jac, DenseMatrix< Number > &scalar_lm_v_vel_jac)
void scalarDirichletJacobian(const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseMatrix< Number > &scalar_vector_jac, DenseMatrix< Number > &scalar_scalar_jac)
unsigned int size() const
void scalarDirichletResidual(const MooseArray< Gradient > &vector_sol, const MooseArray< Number > &scalar_sol, const unsigned int vel_component, const std::array< const Moose::Functor< Real > *, 3 > &dirichlet_vel, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, const Elem *const current_elem, const unsigned int current_side, const MooseArray< Point > &q_point_face, DenseVector< Number > &scalar_re)
Real f(Real x)
Test function for Brents method.
static const std::string mu
static InputParameters validParams()
void scalarFaceJacobian(const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseMatrix< Number > &scalar_vector_jac, DenseMatrix< Number > &scalar_scalar_jac, DenseMatrix< Number > &scalar_lm_jac)
const MooseVariableFE< RealVectorValue > & _grad_v_var
void lmFaceJacobian(const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseMatrix< Number > &lm_vec_jac, DenseMatrix< Number > &lm_scalar_jac, DenseMatrix< Number > &lm_lm_jac)
void lmFaceResidual(const MooseArray< Gradient > &vector_sol, const MooseArray< Number > &scalar_sol, const MooseArray< Number > &lm_sol, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseVector< Number > &lm_re)
unsigned int n_points() const
const MooseVariableFE< RealVectorValue > *const _grad_w_var
void scalarVolumeResidual(const MooseArray< Gradient > &vector_field, const Moose::Functor< Real > &source, const MooseArray< Real > &JxW, const libMesh::QBase &qrule, const Elem *const current_elem, const MooseArray< Point > &q_point, DenseVector< Number > &scalar_re)
const TransientInterface & _ti
const MooseVariableFE< Real > & _pressure_var
const MooseVariableFE< Real > & _u_face_var
void addMooseVariableDependency(MooseVariableFieldBase *var)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Real _rho
The density.
void pressureDirichletResidual(const std::array< const Moose::Functor< Real > *, 3 > &dirichlet_vel, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, const Elem *const current_elem, const unsigned int current_side, const MooseArray< Point > &q_point_face, DenseVector< Number > &pressure_re)
void pressureFaceResidual(const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseVector< Number > &pressure_re)
const MooseVariableFE< Real > & _u_var
static const std::string pressure
const MooseArray< Number > & _lm_u_sol
IntRange< T > make_range(T beg, T end)
NavierStokesLHDGAssemblyHelper(const MooseObject *moose_obj, MaterialPropertyInterface *mpi, MooseVariableDependencyInterface *mvdi, const TransientInterface *const ti, const FEProblemBase &fe_problem, SystemBase &sys, const MooseMesh &mesh, const THREAD_ID tid)
virtual unsigned int size() const override final
void scalarVolumeJacobian(const MooseArray< Real > &JxW, const libMesh::QBase &qrule, DenseMatrix< Number > &scalar_vector_jac)
const MooseArray< Number > & _lm_v_sol
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
const MooseVariableFE< RealVectorValue > & _grad_u_var
const MooseVariableFE< Real > *const _w_face_var
void scalarFaceResidual(const MooseArray< Gradient > &vector_sol, const MooseArray< Number > &scalar_sol, const MooseArray< Number > &lm_sol, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseVector< Number > &scalar_re)
void lmFaceResidual(const MooseArray< Gradient > &vector_sol, const MooseArray< Number > &scalar_sol, const MooseArray< Number > &lm_sol, const unsigned int vel_component, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, const Elem *const neigh, DenseVector< Number > &lm_re)
void scalarDirichletJacobian(const unsigned int vel_component, const MooseArray< Real > &JxW_face, const libMesh::QBase &qrule_face, const MooseArray< Point > &normals, DenseMatrix< Number > &scalar_vector_jac, DenseMatrix< Number > &scalar_scalar_jac, DenseMatrix< Number > &scalar_pressure_jac)
auto index_range(const T &sizable)
void scalarVolumeResidual(const MooseArray< Gradient > &vel_gradient, const unsigned int vel_component, const Moose::Functor< Real > &body_force, const MooseArray< Real > &JxW, const libMesh::QBase &qrule, const Elem *const current_elem, const MooseArray< Point > &q_point, DenseVector< Number > &scalar_re)
Compute the volumetric contributions to a velocity residual for a provided velocity gradient and stre...
const MooseVariableScalar *const _enclosure_lm_var
const MooseArray< Number > *const _global_lm_dof_value