LCOV - code coverage report
Current view: top level - src/materials - INSADMaterial.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 9fc4b0 Lines: 139 143 97.2 %
Date: 2025-08-14 10:14:56 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        6050 : INSADMaterial::validParams()
      23             : {
      24        6050 :   InputParameters params = Material::validParams();
      25        6050 :   params.addClassDescription("This is the material class used to compute some of the strong "
      26             :                              "residuals for the INS equations.");
      27       12100 :   params.addRequiredCoupledVar("velocity", "The velocity");
      28        6050 :   params.addRequiredCoupledVar(NS::pressure, "The pressure");
      29       12100 :   params.addParam<MaterialPropertyName>("mu_name", "mu", "The name of the dynamic viscosity");
      30       12100 :   params.addParam<MaterialPropertyName>("rho_name", "rho", "The name of the density");
      31        6050 :   return params;
      32           0 : }
      33             : 
      34        4731 : INSADMaterial::INSADMaterial(const InputParameters & parameters)
      35             :   : Material(parameters),
      36        4731 :     _velocity(adCoupledVectorValue("velocity")),
      37        4731 :     _grad_velocity(adCoupledVectorGradient("velocity")),
      38        4731 :     _grad_p(adCoupledGradient(NS::pressure)),
      39        9462 :     _mu(getADMaterialProperty<Real>("mu_name")),
      40        9462 :     _rho(getADMaterialProperty<Real>("rho_name")),
      41        4731 :     _velocity_dot(nullptr),
      42        4731 :     _mass_strong_residual(declareADProperty<Real>("mass_strong_residual")),
      43        4731 :     _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        4731 :     _td_strong_residual(declareADProperty<RealVectorValue>("td_strong_residual")),
      49        4731 :     _gravity_strong_residual(declareADProperty<RealVectorValue>("gravity_strong_residual")),
      50        4731 :     _boussinesq_strong_residual(declareADProperty<RealVectorValue>("boussinesq_strong_residual")),
      51        4731 :     _coupled_force_strong_residual(
      52        4731 :         declareADProperty<RealVectorValue>("coupled_force_strong_residual")),
      53        4731 :     _mesh_velocity(declareADProperty<RealVectorValue>("mesh_velocity")),
      54        4731 :     _relative_velocity(declareADProperty<RealVectorValue>("relative_velocity")),
      55        4731 :     _advected_mesh_strong_residual(
      56        4731 :         declareADProperty<RealVectorValue>("advected_mesh_strong_residual")),
      57             :     // _mms_function_strong_residual(declareProperty<RealVectorValue>("mms_function_strong_residual")),
      58        9462 :     _use_displaced_mesh(getParam<bool>("use_displaced_mesh")),
      59        4731 :     _ad_q_point(_bnd ? _assembly.adQPointsFace() : _assembly.adQPoints()),
      60        4731 :     _rz_radial_coord(_mesh.getAxisymmetricRadialCoord()),
      61        9858 :     _rz_axial_coord(_rz_radial_coord == 0 ? 1 : 0)
      62             : {
      63        9462 :   if (!_fe_problem.hasUserObject("ins_ad_object_tracker"))
      64             :   {
      65        1281 :     InputParameters tracker_params = INSADObjectTracker::validParams();
      66        1281 :     tracker_params.addPrivateParam("_moose_app", &_app);
      67             : 
      68        2562 :     _fe_problem.addUserObject("INSADObjectTracker", "ins_ad_object_tracker", tracker_params);
      69        1281 :   }
      70             : 
      71             :   // Bypass the UserObjectInterface method because it requires a UserObjectName param which we
      72             :   // don't need
      73        4731 :   _object_tracker = &_fe_problem.getUserObject<INSADObjectTracker>("ins_ad_object_tracker");
      74        4731 :   const_cast<INSADObjectTracker *>(_object_tracker)->addBlockIDs(this->blockIDs());
      75        4731 : }
      76             : 
      77             : void
      78        4731 : INSADMaterial::resolveOptionalProperties()
      79             : {
      80        4731 :   Material::resolveOptionalProperties();
      81             : 
      82        9528 :   for (const auto sub_id : this->blockIDs())
      83        4797 :     if ((_object_tracker->get<bool>("has_boussinesq", sub_id)))
      84             :     {
      85         924 :       _boussinesq_alphas[sub_id] = &getPossiblyConstantGenericMaterialPropertyByName<Real, true>(
      86         462 :           _object_tracker->get<MaterialPropertyName>("alpha", sub_id), _material_data, 0);
      87         924 :       _ref_temps[sub_id] = &getPossiblyConstantGenericMaterialPropertyByName<Real, false>(
      88         462 :           _object_tracker->get<MaterialPropertyName>("ref_temp", sub_id), _material_data, 0);
      89             :     }
      90        4731 : }
      91             : 
      92             : void
      93      662442 : INSADMaterial::subdomainSetup()
      94             : {
      95      662442 :   if ((_has_transient = _object_tracker->get<bool>("has_transient", _current_subdomain_id)))
      96      169187 :     _velocity_dot = &adCoupledVectorDot("velocity");
      97             :   else
      98      493255 :     _velocity_dot = nullptr;
      99             : 
     100      662442 :   if (auto alpha_it = _boussinesq_alphas.find(_current_subdomain_id);
     101             :       alpha_it != _boussinesq_alphas.end())
     102             :   {
     103      350113 :     _has_boussinesq = true;
     104      350113 :     _boussinesq_alpha = alpha_it->second;
     105      350113 :     auto & temp_var = _subproblem.getStandardVariable(
     106      350113 :         _tid, _object_tracker->get<std::string>("temperature", _current_subdomain_id));
     107      350113 :     addMooseVariableDependency(&temp_var);
     108      350113 :     _temperature = &temp_var.adSln();
     109      350113 :     _ref_temp = libmesh_map_find(_ref_temps, _current_subdomain_id);
     110             :   }
     111             :   else
     112             :   {
     113      312329 :     _has_boussinesq = false;
     114      312329 :     _boussinesq_alpha = nullptr;
     115      312329 :     _temperature = nullptr;
     116      312329 :     _ref_temp = nullptr;
     117             :   }
     118             : 
     119      662442 :   _has_gravity = _object_tracker->get<bool>("has_gravity", _current_subdomain_id);
     120      662442 :   if (_has_gravity || _has_boussinesq)
     121      350558 :     _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      662442 :   if ((_has_advected_mesh = _object_tracker->get<bool>("has_advected_mesh", _current_subdomain_id)))
     129             :   {
     130        5364 :     auto & disp_x = _subproblem.getStandardVariable(
     131        5364 :         _tid, _object_tracker->get<VariableName>("disp_x", _current_subdomain_id));
     132        5364 :     addMooseVariableDependency(&disp_x);
     133        5364 :     _disp_x_dot = &disp_x.adUDot();
     134        5364 :     _disp_x_sys_num = disp_x.sys().number();
     135        5364 :     _disp_x_num = (disp_x.kind() == Moose::VarKindType::VAR_SOLVER) &&
     136        5364 :                           (_disp_x_sys_num == _fe_problem.currentNonlinearSystem().number())
     137        5364 :                       ? disp_x.number()
     138             :                       : libMesh::invalid_uint;
     139       10728 :     if (_object_tracker->isTrackerParamValid("disp_y", _current_subdomain_id))
     140             :     {
     141        5364 :       auto & disp_y = _subproblem.getStandardVariable(
     142        5364 :           _tid, _object_tracker->get<VariableName>("disp_y", _current_subdomain_id));
     143        5364 :       addMooseVariableDependency(&disp_y);
     144        5364 :       _disp_y_dot = &disp_y.adUDot();
     145        5364 :       _disp_y_sys_num = disp_y.sys().number();
     146        5364 :       _disp_y_num =
     147             :           disp_y.kind() == (Moose::VarKindType::VAR_SOLVER &&
     148             :                             (_disp_y_sys_num == _fe_problem.currentNonlinearSystem().number()))
     149        5364 :               ? 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       10728 :     if (_object_tracker->isTrackerParamValid("disp_z", _current_subdomain_id))
     159             :     {
     160        2628 :       auto & disp_z = _subproblem.getStandardVariable(
     161        2628 :           _tid, _object_tracker->get<VariableName>("disp_z", _current_subdomain_id));
     162        2628 :       addMooseVariableDependency(&disp_z);
     163        2628 :       _disp_z_dot = &disp_z.adUDot();
     164        2628 :       _disp_z_sys_num = disp_z.sys().number();
     165        2628 :       _disp_z_num =
     166             :           disp_z.kind() == (Moose::VarKindType::VAR_SOLVER &&
     167             :                             (_disp_z_sys_num == _fe_problem.currentNonlinearSystem().number()))
     168        2628 :               ? disp_z.number()
     169             :               : libMesh::invalid_uint;
     170             :     }
     171             :     else
     172             :     {
     173        2736 :       _disp_z_dot = nullptr;
     174        2736 :       _disp_z_sys_num = libMesh::invalid_uint;
     175        2736 :       _disp_z_num = libMesh::invalid_uint;
     176             :     }
     177             :   }
     178             :   else
     179      657078 :     _disp_x_dot = _disp_y_dot = _disp_z_dot = nullptr;
     180             : 
     181      662442 :   _viscous_form = static_cast<NS::ViscousForm>(
     182      662442 :       int(_object_tracker->get<MooseEnum>("viscous_form", _current_subdomain_id)));
     183             : 
     184      662442 :   if ((_has_coupled_force = _object_tracker->get<bool>("has_coupled_force", _current_subdomain_id)))
     185             :   {
     186       71443 :     _coupled_force_var.clear();
     187       71443 :     _coupled_force_vector_function.clear();
     188      142886 :     if (_object_tracker->isTrackerParamValid("coupled_force_var", _current_subdomain_id))
     189             :     {
     190       72778 :       const auto & var_names = _object_tracker->get<std::vector<VariableName>>(
     191       36389 :           "coupled_force_var", _current_subdomain_id);
     192       73668 :       for (const auto & var_name : var_names)
     193       37279 :         _coupled_force_var.push_back(&_subproblem.getVectorVariable(_tid, var_name).adSln());
     194             :     }
     195             : 
     196      142886 :     if (_object_tracker->isTrackerParamValid("coupled_force_vector_function",
     197       71443 :                                              _current_subdomain_id))
     198             :     {
     199       71888 :       const auto & func_names = _object_tracker->get<std::vector<FunctionName>>(
     200       35944 :           "coupled_force_vector_function", _current_subdomain_id);
     201       72778 :       for (const auto & func_name : func_names)
     202       36834 :         _coupled_force_vector_function.push_back(&_fe_problem.getFunction(func_name, _tid));
     203             :     }
     204             :   }
     205      662442 : }
     206             : 
     207             : void
     208    32242651 : INSADMaterial::computeQpProperties()
     209             : {
     210    32242651 :   _mass_strong_residual[_qp] = -NS::divergence(
     211    64485302 :       _grad_velocity[_qp], _velocity[_qp], _ad_q_point[_qp], _coord_sys, _rz_radial_coord);
     212             : 
     213    64485302 :   _advective_strong_residual[_qp] = _rho[_qp] * _grad_velocity[_qp] * _velocity[_qp];
     214    32242651 :   if (_has_transient)
     215    13909142 :     _td_strong_residual[_qp] = _rho[_qp] * (*_velocity_dot)[_qp];
     216    32242651 :   if (_has_gravity)
     217    31054272 :     _gravity_strong_residual[_qp] = -_rho[_qp] * _gravity_vector;
     218    32242651 :   if (_has_boussinesq)
     219    30925248 :     _boussinesq_strong_residual[_qp] = (*_boussinesq_alpha)[_qp] * _gravity_vector * _rho[_qp] *
     220    30925248 :                                        ((*_temperature)[_qp] - (*_ref_temp)[_qp]);
     221    32242651 :   _relative_velocity[_qp] = _velocity[_qp];
     222             : 
     223    32242651 :   if (_has_advected_mesh)
     224             :   {
     225      690184 :     _mesh_velocity[_qp](0) = (*_disp_x_dot)[_qp];
     226      690184 :     if (_disp_y_dot)
     227      690184 :       _mesh_velocity[_qp](1) = (*_disp_y_dot)[_qp];
     228      690184 :     if (_disp_z_dot)
     229      282128 :       _mesh_velocity[_qp](2) = (*_disp_z_dot)[_qp];
     230      690184 :     _relative_velocity[_qp] -= _mesh_velocity[_qp];
     231     2070552 :     _advected_mesh_strong_residual[_qp] = -_rho[_qp] * _grad_velocity[_qp] * _mesh_velocity[_qp];
     232             :   }
     233             : 
     234    32242651 :   if (_has_coupled_force)
     235             :   {
     236     1668432 :     _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     2728440 :     for (const auto * var : _coupled_force_var)
     241             :     {
     242             :       mooseAssert(var, "null coupled variable in INSADMaterial");
     243     1060008 :       _coupled_force_strong_residual[_qp] -= (*var)[_qp];
     244             :     }
     245     2663928 :     for (const auto * fn : _coupled_force_vector_function)
     246             :     {
     247             :       mooseAssert(fn, "null coupled function in INSADMaterial");
     248     1990992 :       _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    32242651 : }

Generated by: LCOV version 1.14