23 #include "libmesh/elem.h" 24 #include "libmesh/node.h" 25 #include "libmesh/fe_type.h" 83 std::vector<ADRealTensorValue>
_d2u;
84 std::vector<ADRealTensorValue>
_d2v;
85 std::vector<ADRealTensorValue>
_d2w;
98 using T::_advected_mesh_strong_residual;
99 using T::_advective_strong_residual;
101 using T::_boussinesq_strong_residual;
103 using T::_coupled_force_strong_residual;
104 using T::_current_elem;
105 using T::_disp_x_num;
106 using T::_disp_x_sys_num;
107 using T::_disp_y_num;
108 using T::_disp_y_sys_num;
109 using T::_disp_z_num;
110 using T::_disp_z_sys_num;
112 using T::_fe_problem;
114 using T::_grad_velocity;
115 using T::_gravity_strong_residual;
116 using T::_has_advected_mesh;
117 using T::_has_boussinesq;
118 using T::_has_coupled_force;
119 using T::_has_gravity;
120 using T::_has_transient;
123 using T::_object_tracker;
127 using T::_relative_velocity;
129 using T::_rz_axial_coord;
130 using T::_rz_radial_coord;
131 using T::_td_strong_residual;
132 using T::_use_displaced_mesh;
134 using T::_viscous_form;
135 using T::getVectorVar;
140 template <
typename T>
146 "This is the material class used to compute the stabilization parameter tau.");
147 params.
addParam<
Real>(
"alpha", 1.,
"Multiplicative factor on the stabilization parameter tau.");
151 template <
typename T>
154 _alpha(this->template getParam<
Real>(
"alpha")),
155 _tau(this->template declareADProperty<
Real>(
"tau")),
156 _viscous_strong_residual(
157 this->template declareADProperty<
RealVectorValue>(
"viscous_strong_residual")),
158 _momentum_strong_residual(
159 this->template declareADProperty<
RealVectorValue>(
"momentum_strong_residual")),
160 _velocity_var(getVectorVar(
"velocity", 0)),
162 _assembly.getFE(FEType(_velocity_var->feType().order,
LAGRANGE), _mesh.dimension())),
163 _vel_number(_velocity_var->number()),
164 _vel_sys_number(_velocity_var->sys().number())
169 template <
typename T>
173 return ADReal::do_derivatives &&
174 (_vel_sys_number == _fe_problem.currentNonlinearSystem().number());
177 template <
typename T>
183 _hmax = _current_elem->hmax();
188 std::array<unsigned int, 3> disps = {_disp_x_num, _disp_y_num, _disp_z_num};
189 std::array<unsigned int, 3> disp_sys_nums = {_disp_x_sys_num, _disp_y_sys_num, _disp_z_sys_num};
191 for (
unsigned int n_outer = 0; n_outer < _current_elem->n_vertices(); n_outer++)
192 for (
unsigned int n_inner = n_outer + 1; n_inner < _current_elem->n_vertices(); n_inner++)
194 VectorValue<ADReal> diff = (_current_elem->point(n_outer) - _current_elem->point(n_inner));
197 const auto disp_num = disps[i];
200 const auto sys_num = disp_sys_nums[i];
205 diff(i).derivatives().insert(
206 _current_elem->node_ref(n_outer).dof_number(sys_num, disp_num, 0)) = 1.;
207 diff(i).derivatives().insert(
208 _current_elem->node_ref(n_inner).dof_number(sys_num, disp_num, 0)) = -1.;
211 _hmax = std::max(_hmax, diff.norm_sq());
214 _hmax = std::sqrt(_hmax);
217 template <
typename T>
222 computeViscousStrongResidual();
224 T::computeProperties();
227 template <
typename T>
231 auto resize_and_zero = [
this](
auto & d2vel)
233 d2vel.resize(_qrule->n_points());
234 for (
auto & d2qp : d2vel)
237 resize_and_zero(_d2u);
238 resize_and_zero(_d2v);
239 resize_and_zero(_d2w);
241 auto get_d2 = [
this](
const auto i) -> std::vector<ADRealTensorValue> &
261 const auto & vel_dof_indices = _velocity_var->dofIndices();
265 mooseAssert(_current_elem->dim() == _mesh.dimension(),
266 "Below logic only applicable if element and mesh dimension are the same");
267 const auto dimensional_component = i % _mesh.dimension();
268 auto & d2vel = get_d2(dimensional_component);
269 const auto dof_index = vel_dof_indices[i];
270 ADReal dof_value = (*_velocity_var->sys().currentSolution())(dof_index);
271 if (doVelocityDerivatives())
272 dof_value.derivatives().insert(dof_index) = 1;
273 const auto scalar_i_component = i / _mesh.dimension();
274 for (
const auto qp :
make_range(_qrule->n_points()))
275 d2vel[qp] += dof_value * _scalar_lagrange_fe->get_d2phi()[scalar_i_component][qp];
280 for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
282 _viscous_strong_residual[_qp](0) = -_mu[_qp] * _d2u[_qp].tr();
283 _viscous_strong_residual[_qp](1) =
284 _mesh.dimension() >= 2 ? -_mu[_qp] * _d2v[_qp].tr() :
ADReal(0);
285 _viscous_strong_residual[_qp](2) =
286 _mesh.dimension() == 3 ? -_mu[_qp] * _d2w[_qp].tr() :
ADReal(0);
289 _viscous_strong_residual[_qp] -= _mu[_qp] * _d2u[_qp].row(0);
290 if (_mesh.dimension() >= 2)
291 _viscous_strong_residual[_qp] -= _mu[_qp] * _d2v[_qp].row(1);
292 if (_mesh.dimension() == 3)
293 _viscous_strong_residual[_qp] -= _mu[_qp] * _d2w[_qp].row(2);
300 template <
typename T>
319 const auto & r = _ad_q_point[_qp](_rz_radial_coord);
324 for (
const auto i :
make_range((
unsigned int)2))
325 rz_term(i) = -_mu[_qp] * _grad_velocity[_qp](i, _rz_radial_coord) / r;
326 rz_term(_rz_radial_coord) += _mu[_qp] * _velocity[_qp](_rz_radial_coord) / (r * r);
327 _viscous_strong_residual[_qp] += rz_term;
332 for (
const auto i :
make_range((
unsigned int)2))
334 rz_term(i) = -_mu[_qp] * _grad_velocity[_qp](_rz_radial_coord, i) / r;
336 rz_term(_rz_radial_coord) += _mu[_qp] * _velocity[_qp](_rz_radial_coord) / (r * r);
337 _viscous_strong_residual[_qp] += rz_term;
341 template <
typename T>
345 T::computeQpProperties();
347 const auto nu = _mu[_qp] / _rho[_qp];
348 const auto transient_part = _has_transient ? 4. / (_dt * _dt) : 0.;
350 _tau[_qp] = _alpha / std::sqrt(transient_part + (2. * _speed / _hmax) * (2. * _speed / _hmax) +
351 9. * (4. * nu / (_hmax * _hmax)) * (4. * nu / (_hmax * _hmax)));
353 _momentum_strong_residual[_qp] =
354 _advective_strong_residual[_qp] + _viscous_strong_residual[_qp] + _grad_p[_qp];
357 _momentum_strong_residual[_qp] += _td_strong_residual[_qp];
360 _momentum_strong_residual[_qp] += _gravity_strong_residual[_qp];
363 _momentum_strong_residual[_qp] += _boussinesq_strong_residual[_qp];
365 if (_has_advected_mesh)
366 _momentum_strong_residual[_qp] += _advected_mesh_strong_residual[_qp];
368 if (_has_coupled_force)
369 _momentum_strong_residual[_qp] += _coupled_force_strong_residual[_qp];
std::vector< ADRealTensorValue > _d2u
Containers to hold the matrix of second spatial derivatives of velocity.
void computeHMax()
Compute the maximum dimension of the current element.
const unsigned int invalid_uint
const FEBase *const & _scalar_lagrange_fe
A scalar Lagrange FE data member to compute the velocity second derivatives since they're currently n...
virtual void computeProperties() override
void mooseError(Args &&... args)
INSADTauMaterialTempl< INSADMaterial > INSADTauMaterial
bool doVelocityDerivatives() const
Whether to seed with respect to velocity derivatives.
static InputParameters validParams()
INSADTauMaterialTempl(const InputParameters ¶meters)
DualNumber< Real, DNDerivativeType, true > ADReal
virtual void computeQpProperties() override
ADMaterialProperty< RealVectorValue > & _momentum_strong_residual
The strong residual of the momentum equation.
InputParameters validParams()
ADReal _speed
The speed of the medium.
const unsigned int _vel_number
The velocity variable number.
ADMaterialProperty< RealVectorValue > & _viscous_strong_residual
Strong residual corresponding to the momentum viscous term.
const std::vector< std::vector< OutputTensor > > & get_d2phi() const
void computeViscousStrongResidual()
Compute the viscous strong residual.
const VectorMooseVariable *const _velocity_var
The velocity variable.
ADMaterialProperty< Real > & _tau
const unsigned int _vel_sys_number
The velocity system number.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
ADReal computeSpeed(const ADRealVectorValue &velocity)
Compute the speed (velocity norm) given the supplied velocity.
std::vector< ADRealTensorValue > _d2w
std::vector< ADRealTensorValue > _d2v
auto index_range(const T &sizable)
void viscousTermRZ()
Compute the strong form corresponding to RZ pieces of the viscous term.