-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #25445 from GiudGiud/PR_pressure_pin
Use a postprocessing step to apply the pressure constraint in loops
- Loading branch information
Showing
5 changed files
with
276 additions
and
16 deletions.
There are no files selected for viewing
22 changes: 22 additions & 0 deletions
22
modules/navier_stokes/doc/content/source/userobjects/NSFVPressurePin.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# NSFVPressurePin | ||
|
||
!syntax description /UserObjects/NSFVPressurePin | ||
|
||
## Overview | ||
|
||
The `NSFVPressurePin` can pin the pressure in two modes: | ||
|
||
- by offsetting the pressure variable to make it have an average equal to the [!param](/UserObjects/NSFVPressurePin/phi0) parameter value | ||
- by offsetting the pressure variable to make its value equal to the [!param](/UserObjects/NSFVPressurePin/phi0) parameter value in the element | ||
containing the point specified by the [!param](/UserObjects/NSFVPressurePin/point) parameter. | ||
|
||
|
||
!alert note | ||
In the [NSFVAction.md], a `NSFVPressurePin` can be used by setting the [!param](/Modules/NavierStokesFV/pinned_pressure_type) parameter | ||
to `average-uo` or `point-value-uo` respectively. | ||
|
||
!syntax parameters /UserObjects/NSFVPressurePin | ||
|
||
!syntax inputs /UserObjects/NSFVPressurePin | ||
|
||
!syntax children /UserObjects/NSFVPressurePin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
modules/navier_stokes/include/userobjects/NSFVPressurePin.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* All rights reserved, see COPYRIGHT for full restrictions | ||
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
//* | ||
//* Licensed under LGPL 2.1, please see LICENSE for details | ||
//* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
||
#pragma once | ||
|
||
#include "GeneralUserObject.h" | ||
#include "BlockRestrictable.h" | ||
#include "INSFVPressureVariable.h" | ||
#include "NonADFunctorInterface.h" | ||
|
||
class MooseMesh; | ||
class INSFVPressureVariable; | ||
|
||
/** | ||
* This user-object corrects the pressure | ||
*/ | ||
class NSFVPressurePin : public GeneralUserObject, | ||
public BlockRestrictable, | ||
public NonADFunctorInterface | ||
{ | ||
public: | ||
static InputParameters validParams(); | ||
NSFVPressurePin(const InputParameters & params); | ||
|
||
void initialSetup() override{}; | ||
void initialize() override{}; | ||
void execute() override; | ||
void finalize() override{}; | ||
|
||
protected: | ||
/// LibMesh mesh class for the current simulation mesh | ||
MeshBase & _mesh; | ||
|
||
/// The thread 0 copy of the pressure variable | ||
INSFVPressureVariable * const _p; | ||
|
||
/// Value of the pressure pin | ||
const PostprocessorValue & _p0; | ||
|
||
/// Pressure pin type | ||
const MooseEnum _pressure_pin_type; | ||
|
||
/// If using point-value pressure pin, the point at which to apply the pin | ||
const Point _pressure_pin_point; | ||
|
||
/// If using average pressure pin, provides the average pressure value | ||
const PostprocessorValue * const _current_pressure_average; | ||
|
||
private: | ||
/// The nonlinear system | ||
SystemBase & _sys; | ||
}; |
121 changes: 121 additions & 0 deletions
121
modules/navier_stokes/src/userobjects/NSFVPressurePin.C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* All rights reserved, see COPYRIGHT for full restrictions | ||
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
//* | ||
//* Licensed under LGPL 2.1, please see LICENSE for details | ||
//* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
||
#include "NSFVPressurePin.h" | ||
#include "SubProblem.h" | ||
#include "SystemBase.h" | ||
#include "NS.h" | ||
|
||
#include "libmesh/mesh_base.h" | ||
#include "libmesh/elem_range.h" | ||
#include "libmesh/numeric_vector.h" | ||
#include "libmesh/mesh_tools.h" | ||
|
||
using namespace libMesh; | ||
|
||
registerMooseObject("NavierStokesApp", NSFVPressurePin); | ||
|
||
InputParameters | ||
NSFVPressurePin::validParams() | ||
{ | ||
auto params = GeneralUserObject::validParams(); | ||
params += BlockRestrictable::validParams(); | ||
|
||
// Not much flexibility there, applying the pin at the wrong time prevents convergence | ||
ExecFlagEnum & exec_enum = params.set<ExecFlagEnum>("execute_on", true); | ||
// all bad choices | ||
exec_enum.removeAvailableFlags(EXEC_LINEAR, EXEC_NONE, EXEC_TIMESTEP_BEGIN, EXEC_ALWAYS); | ||
exec_enum = {EXEC_TIMESTEP_END}; | ||
|
||
// Avoid uninitialized residual objects | ||
params.suppressParameter<bool>("force_preic"); | ||
|
||
params.addParam<NonlinearVariableName>("variable", NS::pressure, "Pressure variable"); | ||
params.addParam<PostprocessorName>("phi0", "Pressure pin value"); | ||
MooseEnum pin_types("point-value average"); | ||
params.addRequiredParam<MooseEnum>("pin_type", pin_types, "How to pin the pressure"); | ||
params.addParam<Point>( | ||
"point", | ||
"The XYZ coordinates of a point inside an element where the pinned value shall be enforced."); | ||
params.addParam<PostprocessorName>( | ||
"pressure_average", "A postprocessor that computes the average of the pressure variable"); | ||
|
||
params.addClassDescription("Pins the pressure after a solve"); | ||
|
||
return params; | ||
} | ||
|
||
NSFVPressurePin::NSFVPressurePin(const InputParameters & params) | ||
: GeneralUserObject(params), | ||
BlockRestrictable(this), | ||
NonADFunctorInterface(this), | ||
_mesh(UserObject::_subproblem.mesh().getMesh()), | ||
_p(dynamic_cast<INSFVPressureVariable *>( | ||
&UserObject::_subproblem.getVariable(0, getParam<NonlinearVariableName>("variable")))), | ||
_p0(getPostprocessorValue("phi0")), | ||
_pressure_pin_type(getParam<MooseEnum>("pin_type")), | ||
_pressure_pin_point(_pressure_pin_type == "point-value" ? getParam<Point>("point") | ||
: Point(0, 0, 0)), | ||
_current_pressure_average( | ||
_pressure_pin_type == "average" ? &getPostprocessorValue("pressure_average") : nullptr), | ||
_sys(*getCheckedPointerParam<SystemBase *>("_sys")) | ||
{ | ||
if (!_p) | ||
paramError(NS::pressure, "the pressure must be a INSFVPressureVariable."); | ||
// Check execute_on of the postprocessor | ||
if (_pressure_pin_type == "average" && | ||
!_fe_problem.getUserObjectBase(getParam<PostprocessorName>("pressure_average")) | ||
.getExecuteOnEnum() | ||
.contains(getExecuteOnEnum())) | ||
paramError("pressure_average", | ||
"Pressure average postprocessor must include the pin execute_on flags"); | ||
} | ||
|
||
void | ||
NSFVPressurePin::execute() | ||
{ | ||
// Get the value of the pin | ||
Real pin_value = 0; | ||
if (_pressure_pin_type == "point-value") | ||
{ | ||
Real point_value = _sys.system().point_value(_p->number(), _pressure_pin_point, false); | ||
|
||
/** | ||
* If we get exactly zero, we don't know if the locator couldn't find an element, or | ||
* if the solution is truly zero, more checking is needed. | ||
*/ | ||
if (MooseUtils::absoluteFuzzyEqual(point_value, 0.0)) | ||
{ | ||
auto pl = _mesh.sub_point_locator(); | ||
pl->enable_out_of_mesh_mode(); | ||
|
||
auto * elem = (*pl)(_pressure_pin_point); | ||
auto elem_id = elem ? elem->id() : DofObject::invalid_id; | ||
gatherMin(elem_id); | ||
|
||
if (elem_id == DofObject::invalid_id) | ||
mooseError("No element to gather point pressure from located at ", _pressure_pin_point); | ||
// Default at construction | ||
pl->disable_out_of_mesh_mode(); | ||
} | ||
|
||
pin_value = _p0 - point_value; | ||
} | ||
else | ||
pin_value = _p0 - *_current_pressure_average; | ||
|
||
// Offset the entire pressure vector by the value of the pin | ||
NumericVector<Number> & sln = _sys.solution(); | ||
std::set<dof_id_type> local_dofs; | ||
_sys.system().local_dof_indices(_p->number(), local_dofs); | ||
for (const auto dof : local_dofs) | ||
sln.add(dof, pin_value); | ||
sln.close(); | ||
_sys.system().update(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters