LCOV - code coverage report
Current view: top level - src/kernels - INSChorinPredictor.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 9fc4b0 Lines: 83 111 74.8 %
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 "INSChorinPredictor.h"
      11             : #include "MooseMesh.h"
      12             : 
      13             : registerMooseObject("NavierStokesApp", INSChorinPredictor);
      14             : 
      15             : InputParameters
      16          82 : INSChorinPredictor::validParams()
      17             : {
      18          82 :   InputParameters params = Kernel::validParams();
      19             : 
      20          82 :   params.addClassDescription("This class computes the 'Chorin' Predictor equation in "
      21             :                              "fully-discrete (both time and space) form.");
      22             :   // Coupled variables
      23         164 :   params.addRequiredCoupledVar("u", "x-velocity");
      24         164 :   params.addCoupledVar("v", "y-velocity"); // only required in 2D and 3D
      25         164 :   params.addCoupledVar("w", "z-velocity"); // only required in 3D
      26             : 
      27             :   // Make star also be required, even though we might not use it?
      28         164 :   params.addRequiredCoupledVar("u_star", "star x-velocity");
      29         164 :   params.addCoupledVar("v_star", "star y-velocity"); // only required in 2D and 3D
      30         164 :   params.addCoupledVar("w_star", "star z-velocity"); // only required in 3D
      31             : 
      32             :   // Required parameters
      33         164 :   params.addRequiredRangeCheckedParam<unsigned>(
      34             :       "component",
      35             :       "component>=0 & component<=2",
      36             :       "0,1,2 depending on if we are solving the x,y,z component of the Predictor equation");
      37         164 :   MooseEnum predictor_type("OLD NEW STAR");
      38         164 :   params.addRequiredParam<MooseEnum>(
      39             :       "predictor_type",
      40             :       predictor_type,
      41             :       "One of: OLD, NEW, STAR.  Indicates which velocity to use in the predictor.");
      42             : 
      43             :   // Optional parameters
      44         164 :   params.addParam<MaterialPropertyName>("mu_name", "mu", "The name of the dynamic viscosity");
      45         164 :   params.addParam<MaterialPropertyName>("rho_name", "rho", "The name of the density");
      46             : 
      47          82 :   return params;
      48          82 : }
      49             : 
      50          44 : INSChorinPredictor::INSChorinPredictor(const InputParameters & parameters)
      51             :   : Kernel(parameters),
      52             : 
      53             :     // Current velocities
      54          44 :     _u_vel(coupledValue("u")),
      55          44 :     _v_vel(_mesh.dimension() >= 2 ? coupledValue("v") : _zero),
      56          44 :     _w_vel(_mesh.dimension() == 3 ? coupledValue("w") : _zero),
      57             : 
      58             :     // Old velocities
      59          44 :     _u_vel_old(coupledValueOld("u")),
      60          44 :     _v_vel_old(_mesh.dimension() >= 2 ? coupledValueOld("v") : _zero),
      61          44 :     _w_vel_old(_mesh.dimension() == 3 ? coupledValueOld("w") : _zero),
      62             : 
      63             :     // Star velocities
      64          44 :     _u_vel_star(coupledValue("u_star")),
      65          44 :     _v_vel_star(_mesh.dimension() >= 2 ? coupledValue("v_star") : _zero),
      66          44 :     _w_vel_star(_mesh.dimension() == 3 ? coupledValue("w_star") : _zero),
      67             : 
      68             :     // Velocity Gradients
      69          44 :     _grad_u_vel(coupledGradient("u")),
      70          44 :     _grad_v_vel(_mesh.dimension() >= 2 ? coupledGradient("v") : _grad_zero),
      71          44 :     _grad_w_vel(_mesh.dimension() == 3 ? coupledGradient("w") : _grad_zero),
      72             : 
      73             :     // Old Velocity Gradients
      74          44 :     _grad_u_vel_old(coupledGradientOld("u")),
      75          44 :     _grad_v_vel_old(_mesh.dimension() >= 2 ? coupledGradientOld("v") : _grad_zero),
      76          44 :     _grad_w_vel_old(_mesh.dimension() == 3 ? coupledGradientOld("w") : _grad_zero),
      77             : 
      78             :     // Star Velocity Gradients
      79          44 :     _grad_u_vel_star(coupledGradient("u_star")),
      80          44 :     _grad_v_vel_star(_mesh.dimension() >= 2 ? coupledGradient("v_star") : _grad_zero),
      81          44 :     _grad_w_vel_star(_mesh.dimension() == 3 ? coupledGradient("w_star") : _grad_zero),
      82             : 
      83             :     // Variable numberings
      84          44 :     _u_vel_var_number(coupled("u")),
      85          44 :     _v_vel_var_number(_mesh.dimension() >= 2 ? coupled("v") : libMesh::invalid_uint),
      86          44 :     _w_vel_var_number(_mesh.dimension() == 3 ? coupled("w") : libMesh::invalid_uint),
      87             : 
      88             :     // Star velocity numberings
      89          44 :     _u_vel_star_var_number(coupled("u_star")),
      90          44 :     _v_vel_star_var_number(_mesh.dimension() >= 2 ? coupled("v_star") : libMesh::invalid_uint),
      91          44 :     _w_vel_star_var_number(_mesh.dimension() == 3 ? coupled("w_star") : libMesh::invalid_uint),
      92             : 
      93             :     // Required parameters
      94          88 :     _component(getParam<unsigned>("component")),
      95          88 :     _predictor_enum(getParam<MooseEnum>("predictor_type")),
      96             : 
      97             :     // Material properties
      98          88 :     _mu(getMaterialProperty<Real>("mu_name")),
      99         132 :     _rho(getMaterialProperty<Real>("rho_name"))
     100             : {
     101          44 : }
     102             : 
     103             : Real
     104    11776000 : INSChorinPredictor::computeQpResidual()
     105             : {
     106             :   // Vector object for test function
     107             :   RealVectorValue test;
     108    11776000 :   test(_component) = _test[_i][_qp];
     109             : 
     110             :   // Tensor object for test function gradient
     111             :   RealTensorValue grad_test;
     112    47104000 :   for (unsigned k = 0; k < 3; ++k)
     113    35328000 :     grad_test(_component, k) = _grad_test[_i][_qp](k);
     114             : 
     115             :   // Decide what velocity vector, gradient to use:
     116             :   RealVectorValue U;
     117             :   RealTensorValue grad_U;
     118             : 
     119    11776000 :   switch (_predictor_enum)
     120             :   {
     121           0 :     case OLD:
     122             :     {
     123           0 :       U = RealVectorValue(_u_vel_old[_qp], _v_vel_old[_qp], _w_vel_old[_qp]);
     124           0 :       grad_U = RealTensorValue(_grad_u_vel_old[_qp], _grad_v_vel_old[_qp], _grad_w_vel_old[_qp]);
     125           0 :       break;
     126             :     }
     127    11776000 :     case NEW:
     128             :     {
     129    11776000 :       U = RealVectorValue(_u_vel[_qp], _v_vel[_qp], _w_vel[_qp]);
     130    11776000 :       grad_U = RealTensorValue(_grad_u_vel[_qp], _grad_v_vel[_qp], _grad_w_vel[_qp]);
     131    11776000 :       break;
     132             :     }
     133           0 :     case STAR:
     134             :     {
     135             :       // Note: Donea and Huerta's book says you are supposed to use "star" velocity to make Chorin
     136             :       // implicit, not U^{n+1}.
     137           0 :       U = RealVectorValue(_u_vel_star[_qp], _v_vel_star[_qp], _w_vel_star[_qp]);
     138           0 :       grad_U = RealTensorValue(_grad_u_vel_star[_qp], _grad_v_vel_star[_qp], _grad_w_vel_star[_qp]);
     139           0 :       break;
     140             :     }
     141           0 :     default:
     142           0 :       mooseError("Unrecognized Chorin predictor type requested.");
     143             :   }
     144             : 
     145             :   //
     146             :   // Compute the different parts
     147             :   //
     148             : 
     149             :   // Note: _u is the component'th entry of "u_star" in Chorin's method.
     150    11776000 :   RealVectorValue U_old(_u_vel_old[_qp], _v_vel_old[_qp], _w_vel_old[_qp]);
     151    11776000 :   Real symmetric_part = (_u[_qp] - U_old(_component)) * _test[_i][_qp];
     152             : 
     153             :   // Convective part.  Remember to multiply by _dt!
     154    11776000 :   Real convective_part = _dt * (grad_U * U) * test;
     155             : 
     156             :   // Viscous part - we are using the Laplacian form here for simplicity.
     157             :   // Remember to multiply by _dt!
     158    11776000 :   Real viscous_part = _dt * (_mu[_qp] / _rho[_qp]) * grad_U.contract(grad_test);
     159             : 
     160    11776000 :   return symmetric_part + convective_part + viscous_part;
     161             : }
     162             : 
     163             : Real
     164    47104000 : INSChorinPredictor::computeQpJacobian()
     165             : {
     166             :   // The mass matrix part is always there.
     167    47104000 :   Real mass_part = _phi[_j][_qp] * _test[_i][_qp];
     168             : 
     169             :   // The on-diagonal Jacobian contribution depends on whether the predictor uses the
     170             :   // 'new' or 'star' velocity.
     171             :   Real other_part = 0.;
     172    47104000 :   switch (_predictor_enum)
     173             :   {
     174             :     case OLD:
     175             :     case NEW:
     176             :       break;
     177           0 :     case STAR:
     178             :     {
     179           0 :       RealVectorValue U_star(_u_vel_star[_qp], _v_vel_star[_qp], _w_vel_star[_qp]);
     180             :       Real convective_part =
     181           0 :           _dt * ((U_star * _grad_phi[_j][_qp]) + _phi[_j][_qp] * _grad_u[_qp](_component)) *
     182           0 :           _test[_i][_qp];
     183             :       Real viscous_part =
     184           0 :           _dt * ((_mu[_qp] / _rho[_qp]) * (_grad_phi[_j][_qp] * _grad_test[_i][_qp]));
     185           0 :       other_part = convective_part + viscous_part;
     186             :       break;
     187             :     }
     188           0 :     default:
     189           0 :       mooseError("Unrecognized Chorin predictor type requested.");
     190             :   }
     191             : 
     192    47104000 :   return mass_part + other_part;
     193             : }
     194             : 
     195             : Real
     196   150732800 : INSChorinPredictor::computeQpOffDiagJacobian(unsigned jvar)
     197             : {
     198   150732800 :   switch (_predictor_enum)
     199             :   {
     200             :     case OLD:
     201             :     {
     202             :       return 0.;
     203             :     }
     204             : 
     205   150732800 :     case NEW:
     206             :     {
     207   150732800 :       if ((jvar == _u_vel_var_number) || (jvar == _v_vel_var_number) || (jvar == _w_vel_var_number))
     208             :       {
     209             :         // Derivative of grad_U wrt the velocity component
     210             :         RealTensorValue dgrad_U;
     211             : 
     212             :         // Initialize to invalid value, then determine correct value.
     213             :         unsigned vel_index = 99;
     214             : 
     215             :         // Map jvar into the indices (0,1,2)
     216    75366400 :         if (jvar == _u_vel_var_number)
     217             :           vel_index = 0;
     218             : 
     219    37683200 :         else if (jvar == _v_vel_var_number)
     220             :           vel_index = 1;
     221             : 
     222           0 :         else if (jvar == _w_vel_var_number)
     223             :           vel_index = 2;
     224             : 
     225             :         // Fill in the vel_index'th row of dgrad_U with _grad_phi[_j][_qp]
     226   301465600 :         for (unsigned k = 0; k < 3; ++k)
     227   226099200 :           dgrad_U(vel_index, k) = _grad_phi[_j][_qp](k);
     228             : 
     229             :         // Vector object for test function
     230             :         RealVectorValue test;
     231    75366400 :         test(_component) = _test[_i][_qp];
     232             : 
     233             :         // Vector object for U
     234    75366400 :         RealVectorValue U(_u_vel[_qp], _v_vel[_qp], _w_vel[_qp]);
     235             : 
     236             :         // Tensor object for test function gradient
     237             :         RealTensorValue grad_test;
     238   301465600 :         for (unsigned k = 0; k < 3; ++k)
     239   226099200 :           grad_test(_component, k) = _grad_test[_i][_qp](k);
     240             : 
     241             :         // Compute the convective part
     242             :         RealVectorValue convective_jac =
     243    75366400 :             _phi[_j][_qp] * RealVectorValue(_grad_u_vel[_qp](vel_index),
     244    75366400 :                                             _grad_v_vel[_qp](vel_index),
     245    75366400 :                                             _grad_w_vel[_qp](vel_index));
     246             : 
     247             :         // Extra contribution in vel_index component
     248    75366400 :         convective_jac(vel_index) += U * _grad_phi[_j][_qp];
     249             : 
     250             :         // Be sure to scale by _dt!
     251    75366400 :         Real convective_part = _dt * (convective_jac * test);
     252             : 
     253             :         // Compute the viscous part, be sure to scale by _dt.  Note: the contracted
     254             :         // value should be zero unless vel_index and _component match.
     255    75366400 :         Real viscous_part = _dt * (_mu[_qp] / _rho[_qp]) * dgrad_U.contract(grad_test);
     256             : 
     257             :         // Return the result
     258    75366400 :         return convective_part + viscous_part;
     259             :       }
     260             :       else
     261             :         return 0;
     262             :     }
     263             : 
     264           0 :     case STAR:
     265             :     {
     266           0 :       if (jvar == _u_vel_star_var_number)
     267             :       {
     268           0 :         return _dt * _phi[_j][_qp] * _grad_u[_qp](0) * _test[_i][_qp];
     269             :       }
     270             : 
     271           0 :       else if (jvar == _v_vel_star_var_number)
     272             :       {
     273           0 :         return _dt * _phi[_j][_qp] * _grad_u[_qp](1) * _test[_i][_qp];
     274             :       }
     275             : 
     276           0 :       else if (jvar == _w_vel_star_var_number)
     277             :       {
     278           0 :         return _dt * _phi[_j][_qp] * _grad_u[_qp](2) * _test[_i][_qp];
     279             :       }
     280             : 
     281             :       else
     282             :         return 0;
     283             :     }
     284             : 
     285           0 :     default:
     286           0 :       mooseError("Unrecognized Chorin predictor type requested.");
     287             :   }
     288             : }

Generated by: LCOV version 1.14