LCOV - code coverage report
Current view: top level - src/postprocessors - IntegralDirectedSurfaceForce.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 9fc4b0 Lines: 37 45 82.2 %
Date: 2025-08-14 10:14:56 Functions: 3 4 75.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 "IntegralDirectedSurfaceForce.h"
      11             : #include "MathFVUtils.h"
      12             : #include "NSFVUtils.h"
      13             : #include "NS.h"
      14             : #include "MooseFunctorArguments.h"
      15             : 
      16             : #include <cmath>
      17             : 
      18             : registerMooseObject("NavierStokesApp", IntegralDirectedSurfaceForce);
      19             : 
      20             : InputParameters
      21          90 : IntegralDirectedSurfaceForce::validParams()
      22             : {
      23          90 :   InputParameters params = SideIntegralPostprocessor::validParams();
      24          90 :   params.addClassDescription(
      25             :       "Computes the directed force coming from friction and pressure differences on a surface. One "
      26             :       "can use this object for the computation of the drag and lift coefficient as well.");
      27         180 :   params.addRequiredParam<MooseFunctorName>("vel_x", "The velocity in direction x.");
      28         180 :   params.addParam<MooseFunctorName>("vel_y", "The velocity in direction y.");
      29         180 :   params.addParam<MooseFunctorName>("vel_z", "The velocity in direction z.");
      30          90 :   params.addRequiredParam<MooseFunctorName>(NS::mu, "The dynamic viscosity.");
      31          90 :   params.addRequiredParam<MooseFunctorName>(NS::pressure, "The pressure functor.");
      32         180 :   params.addRequiredParam<RealVectorValue>("principal_direction",
      33             :                                            "The direction in which the force is computed.");
      34          90 :   return params;
      35           0 : }
      36             : 
      37          46 : IntegralDirectedSurfaceForce::IntegralDirectedSurfaceForce(const InputParameters & parameters)
      38             :   : SideIntegralPostprocessor(parameters),
      39          46 :     _mu(getFunctor<Real>(NS::mu)),
      40          46 :     _pressure(getFunctor<Real>(NS::pressure)),
      41         138 :     _direction(getParam<RealVectorValue>("principal_direction"))
      42             : {
      43          92 :   _vel_components.push_back(&getFunctor<Real>("vel_x"));
      44             : 
      45          46 :   if (_mesh.dimension() >= 2)
      46             :   {
      47          92 :     if (!isParamValid("vel_y"))
      48           0 :       paramError("vel_y",
      49             :                  "For 2D meshes the second velocity component should be provided as well!");
      50          92 :     _vel_components.push_back(&getFunctor<Real>("vel_y"));
      51             : 
      52          46 :     if (_mesh.dimension() == 3)
      53             :     {
      54           0 :       if (!isParamValid("vel_z"))
      55           0 :         paramError("vel_z",
      56             :                    "For 3D meshes the third velocity component should be provided as well!");
      57           0 :       _vel_components.push_back(&getFunctor<Real>("vel_z"));
      58             :     }
      59             :   }
      60             : 
      61             :   // This object will only work with finite volume variables
      62          46 :   _qp_integration = false;
      63             : 
      64          92 :   checkFunctorSupportsSideIntegration<Real>("vel_x", _qp_integration);
      65          46 :   if (_vel_components.size() >= 2)
      66          92 :     checkFunctorSupportsSideIntegration<Real>("vel_y", _qp_integration);
      67          46 :   if (_vel_components.size() == 3)
      68           0 :     checkFunctorSupportsSideIntegration<Real>("vel_z", _qp_integration);
      69          46 : }
      70             : 
      71             : Real
      72        1216 : IntegralDirectedSurfaceForce::computeFaceInfoIntegral(const FaceInfo * fi)
      73             : {
      74             :   mooseAssert(fi, "We should have a face info in " + name());
      75             : 
      76        1216 :   const auto state = determineState();
      77        1216 :   const auto face_arg = Moose::FaceArg(
      78        1216 :       {fi, Moose::FV::LimiterType::CentralDifference, true, false, nullptr, nullptr});
      79        1216 :   const auto elem_arg = Moose::ElemArg({fi->elemPtr(), false});
      80             : 
      81             :   RealTensorValue pressure_term;
      82             :   RealVectorValue cell_velocity = 0;
      83             :   RealVectorValue face_velocity = 0;
      84        1216 :   const Real pressure = _pressure(face_arg, state);
      85        1216 :   const Real mu = _mu(face_arg, state);
      86        3648 :   for (const auto i : make_range(_mesh.dimension()))
      87             :   {
      88        2432 :     cell_velocity(i) = (*_vel_components[i])(elem_arg, state);
      89        2432 :     face_velocity(i) = (*_vel_components[i])(face_arg, state);
      90        2432 :     pressure_term(i, i) = -pressure;
      91             :   }
      92             : 
      93             :   const auto shear_force = mu *
      94             :                            (cell_velocity - face_velocity -
      95             :                             (cell_velocity - face_velocity) * fi->normal() * fi->normal()) /
      96             :                            std::abs(fi->dCN() * fi->normal());
      97             : 
      98        1216 :   return (shear_force * _direction - pressure_term * fi->normal() * _direction);
      99             : }
     100             : 
     101             : Real
     102           0 : IntegralDirectedSurfaceForce::computeQpIntegral()
     103             : {
     104           0 :   mooseError(this->type() + " does not have an implementation for quadrature-based evaluation!");
     105             :   return 0.0;
     106             : }

Generated by: LCOV version 1.14