LCOV - code coverage report
Current view: top level - include/userobjects - RhieChowInterpolatorBase.h (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 9fc4b0 Lines: 25 26 96.2 %
Date: 2025-08-14 10:14:56 Functions: 6 7 85.7 %
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             : #pragma once
      11             : 
      12             : #include "RhieChowFaceFluxProvider.h"
      13             : #include "TaggingInterface.h"
      14             : #include "INSFVPressureVariable.h"
      15             : #include "ADReal.h"
      16             : #include "ADFunctorInterface.h"
      17             : #include "INSFVPressureVariable.h"
      18             : #include "libmesh/vector_value.h"
      19             : #include "libmesh/id_types.h"
      20             : #include "libmesh/stored_range.h"
      21             : 
      22             : class MooseMesh;
      23             : class INSFVVelocityVariable;
      24             : class INSFVPressureVariable;
      25             : namespace libMesh
      26             : {
      27             : class Elem;
      28             : class MeshBase;
      29             : }
      30             : 
      31             : class RhieChowInterpolatorBase : public RhieChowFaceFluxProvider,
      32             :                                  public TaggingInterface,
      33             :                                  public ADFunctorInterface
      34             : {
      35             : public:
      36             :   static InputParameters validParams();
      37             :   RhieChowInterpolatorBase(const InputParameters & params);
      38             : 
      39             :   /**
      40             :    * API for momentum residual objects that have on-diagonals for velocity call.
      41             :    * This is only supposed to be called if we are using an implicit pressure-velocity
      42             :    * coupling in a monolithic solve.
      43             :    * @param The element we are adding 'a' coefficient data for
      44             :    * @param component The velocity component we are adding 'a' coefficient data for
      45             :    * @param value The value of 'a' that we are adding
      46             :    */
      47             :   virtual void addToA(const libMesh::Elem * elem, unsigned int component, const ADReal & value) = 0;
      48             : 
      49             :   /**
      50             :    * Retrieve a face velocity
      51             :    * @param m The velocity interpolation method. This is either Rhie-Chow or Average. Rhie-Chow is
      52             :    * recommended as it avoids checkerboards in the pressure field
      53             :    * @param fi The face that we wish to retrieve the velocity for
      54             :    * @param tid The thread ID
      55             :    * @return The face velocity
      56             :    */
      57             :   virtual VectorValue<ADReal> getVelocity(const Moose::FV::InterpMethod m,
      58             :                                           const FaceInfo & fi,
      59             :                                           const Moose::StateArg & time,
      60             :                                           const THREAD_ID tid,
      61             :                                           bool subtract_mesh_velocity) const = 0;
      62             : 
      63             :   virtual Real getVolumetricFaceFlux(const Moose::FV::InterpMethod m,
      64             :                                      const FaceInfo & fi,
      65             :                                      const Moose::StateArg & time,
      66             :                                      const THREAD_ID tid,
      67             :                                      bool subtract_mesh_velocity) const override;
      68             : 
      69             :   /// Return the interpolation method used for velocity
      70        4097 :   Moose::FV::InterpMethod velocityInterpolationMethod() const { return _velocity_interp_method; }
      71             : 
      72             :   /**
      73             :    * makes sure coefficient data gets communicated on both sides of a given boundary. This
      74             :    * is a virtual function, mostly used for monolithic approaches.
      75             :    */
      76           0 :   virtual void ghostADataOnBoundary(const BoundaryID /*boundary_id*/) {}
      77             : 
      78             :   /**
      79             :    * @return The pressure variable corresponding to the provided thread ID
      80             :    */
      81             :   const INSFVPressureVariable & pressure(THREAD_ID tid) const;
      82             : 
      83             :   const INSFVVelocityVariable * vel() const { return _u; }
      84             : 
      85             :   /// Bool of the Rhie Chow user object is used in monolithic/segregated approaches
      86             :   virtual bool segregated() const = 0;
      87             : 
      88             : protected:
      89             :   /**
      90             :    * A virtual method that allows us to only implement getVelocity once for free and porous flows
      91             :    */
      92             :   virtual const Moose::FunctorBase<ADReal> & epsilon(THREAD_ID tid) const;
      93             : 
      94             :   /**
      95             :    * Fill the passed-in variable container with the thread copies of \p var_name
      96             :    */
      97             :   template <typename Container>
      98             :   void fillContainer(const std::string & var_name, Container & container);
      99             : 
     100             :   /**
     101             :    * Check the block consistency between the passed in \p var and us
     102             :    */
     103             :   template <typename VarType>
     104             :   void checkBlocks(const VarType & var) const;
     105             : 
     106             :   /// The \p MooseMesh that this user object operates on
     107             :   MooseMesh & _moose_mesh;
     108             : 
     109             :   /// The \p libMesh mesh that this object acts on
     110             :   const libMesh::MeshBase & _mesh;
     111             : 
     112             :   /// The dimension of the mesh, e.g. 3 for hexes and tets, 2 for quads and tris
     113             :   const unsigned int _dim;
     114             : 
     115             :   /// The thread 0 copy of the pressure variable
     116             :   INSFVPressureVariable * const _p;
     117             : 
     118             :   /// The thread 0 copy of the x-velocity variable
     119             :   INSFVVelocityVariable * const _u;
     120             : 
     121             :   /// The thread 0 copy of the y-velocity variable (null if the problem is 1D)
     122             :   INSFVVelocityVariable * const _v;
     123             : 
     124             :   /// The thread 0 copy of the z-velocity variable (null if the problem is not 3D)
     125             :   INSFVVelocityVariable * const _w;
     126             : 
     127             :   /// All the thread copies of the pressure variable
     128             :   std::vector<MooseVariableFVReal *> _ps;
     129             : 
     130             :   /// All the thread copies of the x-velocity variable
     131             :   std::vector<MooseVariableFVReal *> _us;
     132             : 
     133             :   /// All the thread copies of the y-velocity variable
     134             :   std::vector<MooseVariableFVReal *> _vs;
     135             : 
     136             :   /// All the thread copies of the z-velocity variable
     137             :   std::vector<MooseVariableFVReal *> _ws;
     138             : 
     139             :   /// The velocity variable numbers
     140             :   std::vector<unsigned int> _var_numbers;
     141             : 
     142             :   /// The nonlinear system
     143             :   SystemBase & _sys;
     144             : 
     145             :   /// The interpolation method to use for the velocity
     146             :   Moose::FV::InterpMethod _velocity_interp_method;
     147             : 
     148             :   /// Whether this object is operating on the displaced mesh
     149             :   const bool _displaced;
     150             : 
     151             : private:
     152             :   /// A unity functor used in the epsilon virtual method
     153             :   const Moose::ConstantFunctor<ADReal> _unity_functor{1};
     154             : };
     155             : 
     156             : inline const Moose::FunctorBase<ADReal> &
     157   183532948 : RhieChowInterpolatorBase::epsilon(THREAD_ID) const
     158             : {
     159   183532948 :   return _unity_functor;
     160             : }
     161             : 
     162             : inline const INSFVPressureVariable &
     163             : RhieChowInterpolatorBase::pressure(const THREAD_ID tid) const
     164             : {
     165             :   mooseAssert(tid < _ps.size(), "Attempt to access out-of-bounds in pressure variable container");
     166             :   return *static_cast<INSFVPressureVariable *>(_ps[tid]);
     167             : }
     168             : 
     169             : template <typename Container>
     170             : void
     171       23521 : RhieChowInterpolatorBase::fillContainer(const std::string & name, Container & container)
     172             : {
     173             :   typedef typename Container::value_type ContainedType;
     174       49617 :   for (const auto tid : make_range(libMesh::n_threads()))
     175             :   {
     176             :     auto * const var = static_cast<ContainedType>(
     177       26096 :         &UserObject::_subproblem.getVariable(tid, getParam<VariableName>(name)));
     178       26096 :     container[tid] = var;
     179             :   }
     180       23521 : }
     181             : 
     182             : template <typename VarType>
     183             : void
     184       23527 : RhieChowInterpolatorBase::checkBlocks(const VarType & var) const
     185             : {
     186       23527 :   const auto & var_blocks = var.blockIDs();
     187       23527 :   const auto & uo_blocks = blockIDs();
     188             : 
     189             :   // Error if this UO has any blocks that the variable does not
     190             :   std::set<SubdomainID> uo_blocks_minus_var_blocks;
     191       23527 :   std::set_difference(uo_blocks.begin(),
     192             :                       uo_blocks.end(),
     193             :                       var_blocks.begin(),
     194             :                       var_blocks.end(),
     195             :                       std::inserter(uo_blocks_minus_var_blocks, uo_blocks_minus_var_blocks.end()));
     196       23527 :   if (uo_blocks_minus_var_blocks.size() > 0)
     197           6 :     mooseError("Block restriction of interpolator user object '",
     198           2 :                this->name(),
     199             :                "' (",
     200             :                Moose::stringify(blocks()),
     201             :                ") includes blocks not in the block restriction of variable '",
     202           2 :                var.name(),
     203             :                "' (",
     204             :                Moose::stringify(var.blocks()),
     205             :                ")");
     206             : 
     207             :   // Get the blocks in the variable but not this UO
     208             :   std::set<SubdomainID> var_blocks_minus_uo_blocks;
     209       23525 :   std::set_difference(var_blocks.begin(),
     210             :                       var_blocks.end(),
     211             :                       uo_blocks.begin(),
     212             :                       uo_blocks.end(),
     213             :                       std::inserter(var_blocks_minus_uo_blocks, var_blocks_minus_uo_blocks.end()));
     214             : 
     215             :   // For each block in the variable but not this UO, error if there is connection
     216             :   // to any blocks on the UO.
     217       23525 :   for (auto & block_id : var_blocks_minus_uo_blocks)
     218             :   {
     219           2 :     const auto connected_blocks = _moose_mesh.getBlockConnectedBlocks(block_id);
     220             :     std::set<SubdomainID> connected_blocks_on_uo;
     221           2 :     std::set_intersection(connected_blocks.begin(),
     222             :                           connected_blocks.end(),
     223             :                           uo_blocks.begin(),
     224             :                           uo_blocks.end(),
     225             :                           std::inserter(connected_blocks_on_uo, connected_blocks_on_uo.end()));
     226           2 :     if (connected_blocks_on_uo.size() > 0)
     227           6 :       mooseError("Block restriction of interpolator user object '",
     228           2 :                  this->name(),
     229             :                  "' (",
     230             :                  Moose::stringify(uo_blocks),
     231             :                  ") doesn't match the block restriction of variable '",
     232           2 :                  var.name(),
     233             :                  "' (",
     234             :                  Moose::stringify(var_blocks),
     235             :                  ")");
     236             :   }
     237       23523 : }

Generated by: LCOV version 1.14