LCOV - code coverage report
Current view: top level - src/materials - INSADMaterial.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: #32971 (54bef8) with base c6cf66 Lines: 138 142 97.2 %
Date: 2026-05-29 20:37:52 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "INSADMaterial.h"
      11             : #include "Function.h"
      12             : #include "Assembly.h"
      13             : #include "INSADObjectTracker.h"
      14             : #include "FEProblemBase.h"
      15             : #include "NonlinearSystemBase.h"
      16             : #include "NS.h"
      17             : #include "NavierStokesMethods.h"
      18             : 
      19             : registerMooseObject("NavierStokesApp", INSADMaterial);
      20             : 
      21             : InputParameters
      22        2978 : INSADMaterial::validParams()
      23             : {
      24        2978 :   InputParameters params = Material::validParams();
      25        2978 :   params.addClassDescription("This is the material class used to compute some of the strong "
      26             :                              "residuals for the INS equations.");
      27        5956 :   params.addRequiredCoupledVar("velocity", "The velocity");
      28        2978 :   params.addRequiredCoupledVar(NS::pressure, "The pressure");
      29        5956 :   params.addParam<MaterialPropertyName>("mu_name", "mu", "The name of the dynamic viscosity");
      30        5956 :   params.addParam<MaterialPropertyName>("rho_name", "rho", "The name of the density");
      31        2978 :   return params;
      32           0 : }
      33             : 
      34        2307 : INSADMaterial::INSADMaterial(const InputParameters & parameters)
      35             :   : Material(parameters),
      36        2307 :     _velocity(adCoupledVectorValue("velocity")),
      37        2307 :     _grad_velocity(adCoupledVectorGradient("velocity")),
      38        2307 :     _grad_p(adCoupledGradient(NS::pressure)),
      39        4614 :     _mu(getADMaterialProperty<Real>("mu_name")),
      40        4614 :     _rho(getADMaterialProperty<Real>("rho_name")),
      41        2307 :     _velocity_dot(nullptr),
      42        2307 :     _mass_strong_residual(declareADProperty<Real>("mass_strong_residual")),
      43        2307 :     _advective_strong_residual(declareADProperty<RealVectorValue>("advective_strong_residual")),
      44             :     // We have to declare the below strong residuals for integrity check purposes even though we may
      45             :     // not compute them. This may incur some unnecessary cost for a non-sparse derivative container
      46             :     // since when the properties are resized the entire non-sparse derivative containers will be
      47             :     // initialized to zero
      48        2307 :     _td_strong_residual(declareADProperty<RealVectorValue>("td_strong_residual")),
      49        2307 :     _gravity_strong_residual(declareADProperty<RealVectorValue>("gravity_strong_residual")),
      50        2307 :     _boussinesq_strong_residual(declareADProperty<RealVectorValue>("boussinesq_strong_residual")),
      51        2307 :     _coupled_force_strong_residual(
      52        2307 :         declareADProperty<RealVectorValue>("coupled_force_strong_residual")),
      53        2307 :     _mesh_velocity(declareADProperty<RealVectorValue>("mesh_velocity")),
      54        2307 :     _relative_velocity(declareADProperty<RealVectorValue>("relative_velocity")),
      55        2307 :     _advected_mesh_strong_residual(
      56        2307 :         declareADProperty<RealVectorValue>("advected_mesh_strong_residual")),
      57             :     // _mms_function_strong_residual(declareProperty<RealVectorValue>("mms_function_strong_residual")),
      58        4614 :     _use_displaced_mesh(getParam<bool>("use_displaced_mesh")),
      59        2307 :     _ad_q_point(_bnd ? _assembly.adQPointsFace() : _assembly.adQPoints()),
      60        2307 :     _rz_radial_coord(_mesh.getAxisymmetricRadialCoord()),
      61        4794 :     _rz_axial_coord(_rz_radial_coord == 0 ? 1 : 0)
      62             : {
      63        4614 :   if (!_fe_problem.hasUserObject("ins_ad_object_tracker"))
      64             :   {
      65         653 :     InputParameters tracker_params = INSADObjectTracker::validParams();
      66         653 :     tracker_params.addPrivateParam(MooseBase::app_param, &_app);
      67             : 
      68        1306 :     _fe_problem.addUserObject("INSADObjectTracker", "ins_ad_object_tracker", tracker_params);
      69         653 :   }
      70             : 
      71             :   // Bypass the UserObjectInterface method because it requires a UserObjectName param which we
      72             :   // don't need
      73        2307 :   _object_tracker = &_fe_problem.getUserObject<INSADObjectTracker>("ins_ad_object_tracker");
      74        2307 :   const_cast<INSADObjectTracker *>(_object_tracker)->addBlockIDs(this->blockIDs());
      75        2307 : }
      76             : 
      77             : void
      78        2307 : INSADMaterial::resolveOptionalProperties()
      79             : {
      80        2307 :   Material::resolveOptionalProperties();
      81             : 
      82        4644 :   for (const auto sub_id : this->blockIDs())
      83        2337 :     if ((_object_tracker->get<bool>("has_boussinesq", sub_id)))
      84             :     {
      85         564 :       _boussinesq_alphas[sub_id] = &getPossiblyConstantGenericMaterialPropertyByName<Real, true>(
      86         282 :           _object_tracker->get<MaterialPropertyName>("alpha", sub_id), _material_data, 0);
      87         564 :       _ref_temps[sub_id] = &getPossiblyConstantGenericMaterialPropertyByName<Real, false>(
      88         282 :           _object_tracker->get<MaterialPropertyName>("ref_temp", sub_id), _material_data, 0);
      89             :     }
      90        2307 : }
      91             : 
      92             : void
      93      425644 : INSADMaterial::subdomainSetup()
      94             : {
      95      425644 :   if ((_has_transient = _object_tracker->get<bool>("has_transient", _current_subdomain_id)))
      96      113147 :     _velocity_dot = &adCoupledVectorDot("velocity");
      97             :   else
      98      312497 :     _velocity_dot = nullptr;
      99             : 
     100      425644 :   if (auto alpha_it = _boussinesq_alphas.find(_current_subdomain_id);
     101             :       alpha_it != _boussinesq_alphas.end())
     102             :   {
     103      225781 :     _has_boussinesq = true;
     104      225781 :     _boussinesq_alpha = alpha_it->second;
     105      225781 :     auto & temp_var = _subproblem.getStandardVariable(
     106      225781 :         _tid, _object_tracker->get<std::string>("temperature", _current_subdomain_id));
     107      225781 :     addMooseVariableDependency(&temp_var);
     108      225781 :     _temperature = &temp_var.adSln();
     109      225781 :     _ref_temp = libmesh_map_find(_ref_temps, _current_subdomain_id);
     110             :   }
     111             :   else
     112             :   {
     113      199863 :     _has_boussinesq = false;
     114      199863 :     _boussinesq_alpha = nullptr;
     115      199863 :     _temperature = nullptr;
     116      199863 :     _ref_temp = nullptr;
     117             :   }
     118             : 
     119      425644 :   _has_gravity = _object_tracker->get<bool>("has_gravity", _current_subdomain_id);
     120      425644 :   if (_has_gravity || _has_boussinesq)
     121      226010 :     _gravity_vector = _object_tracker->get<RealVectorValue>("gravity", _current_subdomain_id);
     122             :   else
     123             :     _gravity_vector = 0;
     124             : 
     125             :   // Setup data for Arbitrary Lagrangian Eulerian (ALE) simulations in which the simulation domain
     126             :   // is displacing. We will need to subtract the mesh velocity from the velocity solution in order
     127             :   // to get the correct material velocity for the momentum convection term.
     128      425644 :   if ((_has_advected_mesh = _object_tracker->get<bool>("has_advected_mesh", _current_subdomain_id)))
     129             :   {
     130        2852 :     auto & disp_x = _subproblem.getStandardVariable(
     131        2852 :         _tid, _object_tracker->get<VariableName>("disp_x", _current_subdomain_id));
     132        2852 :     addMooseVariableDependency(&disp_x);
     133        2852 :     _disp_x_dot = &disp_x.adUDot();
     134        2852 :     _disp_x_sys_num = disp_x.sys().number();
     135        2852 :     _disp_x_num = (disp_x.kind() == Moose::VarKindType::VAR_SOLVER) &&
     136        2852 :                           (_disp_x_sys_num == _fe_problem.currentNonlinearSystem().number())
     137        2852 :                       ? disp_x.number()
     138             :                       : libMesh::invalid_uint;
     139        5704 :     if (_object_tracker->isTrackerParamValid("disp_y", _current_subdomain_id))
     140             :     {
     141        2852 :       auto & disp_y = _subproblem.getStandardVariable(
     142        2852 :           _tid, _object_tracker->get<VariableName>("disp_y", _current_subdomain_id));
     143        2852 :       addMooseVariableDependency(&disp_y);
     144        2852 :       _disp_y_dot = &disp_y.adUDot();
     145        2852 :       _disp_y_sys_num = disp_y.sys().number();
     146        2852 :       _disp_y_num =
     147             :           disp_y.kind() == (Moose::VarKindType::VAR_SOLVER &&
     148             :                             (_disp_y_sys_num == _fe_problem.currentNonlinearSystem().number()))
     149        2852 :               ? disp_y.number()
     150             :               : libMesh::invalid_uint;
     151             :     }
     152             :     else
     153             :     {
     154           0 :       _disp_y_dot = nullptr;
     155           0 :       _disp_y_sys_num = libMesh::invalid_uint;
     156           0 :       _disp_y_num = libMesh::invalid_uint;
     157             :     }
     158        5704 :     if (_object_tracker->isTrackerParamValid("disp_z", _current_subdomain_id))
     159             :     {
     160        1396 :       auto & disp_z = _subproblem.getStandardVariable(
     161        1396 :           _tid, _object_tracker->get<VariableName>("disp_z", _current_subdomain_id));
     162        1396 :       addMooseVariableDependency(&disp_z);
     163        1396 :       _disp_z_dot = &disp_z.adUDot();
     164        1396 :       _disp_z_sys_num = disp_z.sys().number();
     165        1396 :       _disp_z_num =
     166             :           disp_z.kind() == (Moose::VarKindType::VAR_SOLVER &&
     167             :                             (_disp_z_sys_num == _fe_problem.currentNonlinearSystem().number()))
     168        1396 :               ? disp_z.number()
     169             :               : libMesh::invalid_uint;
     170             :     }
     171             :     else
     172             :     {
     173        1456 :       _disp_z_dot = nullptr;
     174        1456 :       _disp_z_sys_num = libMesh::invalid_uint;
     175        1456 :       _disp_z_num = libMesh::invalid_uint;
     176             :     }
     177             :   }
     178             :   else
     179      422792 :     _disp_x_dot = _disp_y_dot = _disp_z_dot = nullptr;
     180             : 
     181      425644 :   _viscous_form = static_cast<NS::ViscousForm>(
     182      425644 :       int(_object_tracker->get<MooseEnum>("viscous_form", _current_subdomain_id)));
     183             : 
     184      425644 :   if ((_has_coupled_force = _object_tracker->get<bool>("has_coupled_force", _current_subdomain_id)))
     185             :   {
     186       42459 :     _coupled_force_var.clear();
     187       42459 :     _coupled_force_vector_function.clear();
     188       84918 :     if (_object_tracker->isTrackerParamValid("coupled_force_var", _current_subdomain_id))
     189             :     {
     190       43146 :       const auto & var_names = _object_tracker->get<std::vector<VariableName>>(
     191       21573 :           "coupled_force_var", _current_subdomain_id);
     192       43604 :       for (const auto & var_name : var_names)
     193       22031 :         _coupled_force_var.push_back(&_subproblem.getVectorVariable(_tid, var_name).adSln());
     194             :     }
     195             : 
     196       84918 :     if (_object_tracker->isTrackerParamValid("coupled_force_vector_function",
     197       42459 :                                              _current_subdomain_id))
     198             :     {
     199       42688 :       const auto & func_names = _object_tracker->get<std::vector<FunctionName>>(
     200       21344 :           "coupled_force_vector_function", _current_subdomain_id);
     201       43146 :       for (const auto & func_name : func_names)
     202       21802 :         _coupled_force_vector_function.push_back(&_fe_problem.getFunction(func_name, _tid));
     203             :     }
     204             :   }
     205      425644 : }
     206             : 
     207             : void
     208    24590042 : INSADMaterial::computeQpProperties()
     209             : {
     210    24590042 :   _mass_strong_residual[_qp] = -NS::divergence(
     211    49180084 :       _grad_velocity[_qp], _velocity[_qp], _ad_q_point[_qp], _coord_sys, _rz_radial_coord);
     212             : 
     213    49180084 :   _advective_strong_residual[_qp] = _rho[_qp] * _grad_velocity[_qp] * _velocity[_qp];
     214    24590042 :   if (_has_transient)
     215     9857884 :     _td_strong_residual[_qp] = _rho[_qp] * (*_velocity_dot)[_qp];
     216    24590042 :   if (_has_gravity)
     217    24525984 :     _gravity_strong_residual[_qp] = -_rho[_qp] * _gravity_vector;
     218    24590042 :   if (_has_boussinesq)
     219    24439968 :     _boussinesq_strong_residual[_qp] = (*_boussinesq_alpha)[_qp] * _gravity_vector * _rho[_qp] *
     220    24439968 :                                        ((*_temperature)[_qp] - (*_ref_temp)[_qp]);
     221    24590042 :   _relative_velocity[_qp] = _velocity[_qp];
     222             : 
     223    24590042 :   if (_has_advected_mesh)
     224             :   {
     225      463018 :     _mesh_velocity[_qp](0) = (*_disp_x_dot)[_qp];
     226      463018 :     if (_disp_y_dot)
     227      463018 :       _mesh_velocity[_qp](1) = (*_disp_y_dot)[_qp];
     228      463018 :     if (_disp_z_dot)
     229      188648 :       _mesh_velocity[_qp](2) = (*_disp_z_dot)[_qp];
     230             :     _relative_velocity[_qp] -= _mesh_velocity[_qp];
     231     1389054 :     _advected_mesh_strong_residual[_qp] = -_rho[_qp] * _grad_velocity[_qp] * _mesh_velocity[_qp];
     232             :   }
     233             : 
     234    24590042 :   if (_has_coupled_force)
     235             :   {
     236     1210688 :     _coupled_force_strong_residual[_qp] = 0;
     237             :     mooseAssert(!(_coupled_force_var.empty() && _coupled_force_vector_function.empty()),
     238             :                 "Either the coupled force var or the coupled force vector function must be "
     239             :                 "non-empty in 'INSADMaterial'");
     240     1966560 :     for (const auto * var : _coupled_force_var)
     241             :     {
     242             :       mooseAssert(var, "null coupled variable in INSADMaterial");
     243      755872 :       _coupled_force_strong_residual[_qp] -= (*var)[_qp];
     244             :     }
     245     1923552 :     for (const auto * fn : _coupled_force_vector_function)
     246             :     {
     247             :       mooseAssert(fn, "null coupled function in INSADMaterial");
     248     1425728 :       _coupled_force_strong_residual[_qp] -= fn->vectorValue(_t, _q_point[_qp]);
     249             :     }
     250             :   }
     251             : 
     252             :   // // Future Addition
     253             :   // _mms_function_strong_residual[_qp] = -RealVectorValue(_x_vel_fn.value(_t, _q_point[_qp]),
     254             :   //                                                       _y_vel_fn.value(_t, _q_point[_qp]),
     255             :   //                                                       _z_vel_fn.value(_t, _q_point[_qp]));
     256    24590042 : }

Generated by: LCOV version 1.14