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 : }