LCOV - code coverage report
Current view: top level - src/correctors - NSPressurePin.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 9fc4b0 Lines: 53 55 96.4 %
Date: 2025-08-14 10:14:56 Functions: 4 4 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 "NSPressurePin.h"
      11             : #include "SubProblem.h"
      12             : #include "SystemBase.h"
      13             : #include "NS.h"
      14             : 
      15             : #include "libmesh/mesh_base.h"
      16             : #include "libmesh/elem_range.h"
      17             : #include "libmesh/numeric_vector.h"
      18             : #include "libmesh/mesh_tools.h"
      19             : 
      20             : using namespace libMesh;
      21             : 
      22             : registerMooseObject("NavierStokesApp", NSPressurePin);
      23             : registerMooseObjectRenamed("NavierStokesApp", NSFVPressurePin, "01/19/2025 00:00", NSPressurePin);
      24             : 
      25             : InputParameters
      26         424 : NSPressurePin::validParams()
      27             : {
      28         424 :   auto params = GeneralUserObject::validParams();
      29         424 :   params += BlockRestrictable::validParams();
      30             : 
      31             :   // Not much flexibility there, applying the pin at the wrong time prevents convergence
      32         424 :   ExecFlagEnum & exec_enum = params.set<ExecFlagEnum>("execute_on", true);
      33             :   // all bad choices
      34         848 :   exec_enum.removeAvailableFlags(EXEC_LINEAR, EXEC_NONE, EXEC_TIMESTEP_BEGIN);
      35        1272 :   exec_enum = {EXEC_TIMESTEP_END};
      36             : 
      37             :   // Avoid uninitialized residual objects
      38         424 :   params.suppressParameter<bool>("force_preic");
      39             : 
      40         848 :   params.addParam<NonlinearVariableName>("variable", NS::pressure, "Pressure variable");
      41         848 :   params.addParam<PostprocessorName>("phi0", "0", "Pressure pin value");
      42         848 :   MooseEnum pin_types("point-value average");
      43         848 :   params.addRequiredParam<MooseEnum>("pin_type", pin_types, "How to pin the pressure");
      44         848 :   params.addParam<Point>(
      45             :       "point",
      46             :       "The XYZ coordinates of a point inside an element where the pinned value shall be enforced.");
      47         848 :   params.addParam<PostprocessorName>(
      48             :       "pressure_average", "A postprocessor that computes the average of the pressure variable");
      49             : 
      50         424 :   params.addClassDescription("Pins the pressure after a solve");
      51         424 :   params.registerBase("Corrector");
      52             : 
      53         424 :   return params;
      54         848 : }
      55             : 
      56         212 : NSPressurePin::NSPressurePin(const InputParameters & params)
      57             :   : GeneralUserObject(params),
      58             :     BlockRestrictable(this),
      59             :     NonADFunctorInterface(this),
      60         212 :     _mesh(UserObject::_subproblem.mesh().getMesh()),
      61         424 :     _p(UserObject::_subproblem.getVariable(0, getParam<NonlinearVariableName>("variable"))),
      62         212 :     _p0(getPostprocessorValue("phi0")),
      63         424 :     _pressure_pin_type(getParam<MooseEnum>("pin_type")),
      64         240 :     _pressure_pin_point(_pressure_pin_type == "point-value" ? getParam<Point>("point")
      65             :                                                             : Point(0, 0, 0)),
      66         212 :     _current_pressure_average(
      67         212 :         _pressure_pin_type == "average" ? &getPostprocessorValue("pressure_average") : nullptr),
      68         636 :     _sys(*getCheckedPointerParam<SystemBase *>("_sys"))
      69             : {
      70         212 : }
      71             : 
      72             : void
      73         212 : NSPressurePin::initialSetup()
      74             : {
      75             :   mooseAssert(!Threads::in_threads, "paramError is not safe in threaded mode");
      76             : 
      77             :   // Check execute_on of the postprocessor
      78         396 :   if (_pressure_pin_type == "average" &&
      79         764 :       !_fe_problem.getUserObjectBase(getParam<PostprocessorName>("pressure_average"))
      80         184 :            .getExecuteOnEnum()
      81         184 :            .isValueSet(getExecuteOnEnum()))
      82           0 :     paramError("pressure_average",
      83             :                "Pressure average postprocessor must include the pin execute_on flags");
      84         212 : }
      85             : 
      86             : void
      87         849 : NSPressurePin::execute()
      88             : {
      89             :   // Get the value of the pin
      90             :   Real pin_value = 0;
      91         849 :   if (_pressure_pin_type == "point-value")
      92             :   {
      93         465 :     Real point_value = _sys.system().point_value(_p.number(), _pressure_pin_point, false);
      94             : 
      95             :     /**
      96             :      * If we get exactly zero, we don't know if the locator couldn't find an element, or
      97             :      * if the solution is truly zero, more checking is needed.
      98             :      */
      99         465 :     if (MooseUtils::absoluteFuzzyEqual(point_value, 0.0))
     100             :     {
     101          27 :       auto pl = _mesh.sub_point_locator();
     102          27 :       pl->enable_out_of_mesh_mode();
     103             : 
     104          27 :       auto * elem = (*pl)(_pressure_pin_point);
     105          48 :       auto elem_id = elem ? elem->id() : DofObject::invalid_id;
     106             :       gatherMin(elem_id);
     107             : 
     108          27 :       if (elem_id == DofObject::invalid_id)
     109           0 :         mooseError("No element to gather point pressure from located at ", _pressure_pin_point);
     110             :       // Default at construction
     111          27 :       pl->disable_out_of_mesh_mode();
     112          27 :     }
     113             : 
     114         465 :     pin_value = _p0 - point_value;
     115             :   }
     116             :   else
     117         384 :     pin_value = _p0 - *_current_pressure_average;
     118             : 
     119             :   // Offset the entire pressure vector by the value of the pin
     120         849 :   NumericVector<Number> & sln = _sys.solution();
     121             :   std::set<dof_id_type> local_dofs;
     122         849 :   _sys.system().local_dof_indices(_p.number(), local_dofs);
     123       65498 :   for (const auto dof : local_dofs)
     124       64649 :     sln.add(dof, pin_value);
     125         849 :   sln.close();
     126         849 :   _sys.system().update();
     127         849 : }

Generated by: LCOV version 1.14