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 464 : NSPressurePin::validParams() 27 : { 28 464 : auto params = GeneralUserObject::validParams(); 29 464 : params += BlockRestrictable::validParams(); 30 : 31 : // Not much flexibility there, applying the pin at the wrong time prevents convergence 32 464 : ExecFlagEnum & exec_enum = params.set<ExecFlagEnum>("execute_on", true); 33 : // all bad choices 34 928 : exec_enum.removeAvailableFlags(EXEC_LINEAR, EXEC_NONE, EXEC_TIMESTEP_BEGIN); 35 1392 : exec_enum = {EXEC_TIMESTEP_END}; 36 : 37 : // Avoid uninitialized residual objects 38 464 : params.suppressParameter<bool>("force_preic"); 39 : 40 928 : params.addParam<NonlinearVariableName>("variable", NS::pressure, "Pressure variable"); 41 928 : params.addParam<PostprocessorName>("phi0", "0", "Pressure pin value"); 42 928 : MooseEnum pin_types("point-value average"); 43 928 : params.addRequiredParam<MooseEnum>("pin_type", pin_types, "How to pin the pressure"); 44 928 : params.addParam<Point>( 45 : "point", 46 : "The XYZ coordinates of a point inside an element where the pinned value shall be enforced."); 47 928 : params.addParam<PostprocessorName>( 48 : "pressure_average", "A postprocessor that computes the average of the pressure variable"); 49 : 50 464 : params.addClassDescription("Pins the pressure after a solve"); 51 464 : params.registerBase("Corrector"); 52 : 53 464 : return params; 54 928 : } 55 : 56 232 : NSPressurePin::NSPressurePin(const InputParameters & params) 57 : : GeneralUserObject(params), 58 : BlockRestrictable(this), 59 : NonADFunctorInterface(this), 60 232 : _mesh(UserObject::_subproblem.mesh().getMesh()), 61 464 : _p(UserObject::_subproblem.getVariable(0, getParam<NonlinearVariableName>("variable"))), 62 232 : _p0(getPostprocessorValue("phi0")), 63 464 : _pressure_pin_type(getParam<MooseEnum>("pin_type")), 64 260 : _pressure_pin_point(_pressure_pin_type == "point-value" ? getParam<Point>("point") 65 : : Point(0, 0, 0)), 66 232 : _current_pressure_average( 67 464 : _pressure_pin_type == "average" ? &getPostprocessorValue("pressure_average") : nullptr) 68 : { 69 232 : } 70 : 71 : void 72 232 : NSPressurePin::initialSetup() 73 : { 74 : mooseAssert(!Threads::in_threads, "paramError is not safe in threaded mode"); 75 : 76 : // Check execute_on of the postprocessor 77 436 : if (_pressure_pin_type == "average" && 78 844 : !_fe_problem.getUserObjectBase(getParam<PostprocessorName>("pressure_average")) 79 204 : .getExecuteOnEnum() 80 204 : .isValueSet(getExecuteOnEnum())) 81 0 : paramError("pressure_average", 82 : "Pressure average postprocessor must include the pin execute_on flags"); 83 232 : } 84 : 85 : void 86 869 : NSPressurePin::execute() 87 : { 88 : // Get the value of the pin 89 : Real pin_value = 0; 90 869 : if (_pressure_pin_type == "point-value") 91 : { 92 465 : Real point_value = _sys.system().point_value(_p.number(), _pressure_pin_point, false); 93 : 94 : /** 95 : * If we get exactly zero, we don't know if the locator couldn't find an element, or 96 : * if the solution is truly zero, more checking is needed. 97 : */ 98 465 : if (MooseUtils::absoluteFuzzyEqual(point_value, 0.0)) 99 : { 100 27 : auto pl = _mesh.sub_point_locator(); 101 27 : pl->enable_out_of_mesh_mode(); 102 : 103 27 : auto * elem = (*pl)(_pressure_pin_point); 104 48 : auto elem_id = elem ? elem->id() : DofObject::invalid_id; 105 : gatherMin(elem_id); 106 : 107 27 : if (elem_id == DofObject::invalid_id) 108 0 : mooseError("No element to gather point pressure from located at ", _pressure_pin_point); 109 : // Default at construction 110 27 : pl->disable_out_of_mesh_mode(); 111 27 : } 112 : 113 465 : pin_value = _p0 - point_value; 114 : } 115 : else 116 404 : pin_value = _p0 - *_current_pressure_average; 117 : 118 : // Offset the entire pressure vector by the value of the pin 119 869 : NumericVector<Number> & sln = _sys.solution(); 120 : std::set<dof_id_type> local_dofs; 121 869 : _sys.system().local_dof_indices(_p.number(), local_dofs); 122 85486 : for (const auto dof : local_dofs) 123 84617 : sln.add(dof, pin_value); 124 869 : sln.close(); 125 869 : _sys.system().update(); 126 869 : }