https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PeriodicBCHelper.C
Go to the documentation of this file.
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 "PeriodicBCHelper.h"
11
12#include "DisplacedProblem.h"
13#include "FEProblemBase.h"
15#include "MooseObjectAction.h"
16#include "MooseMesh.h"
17
18#include "libmesh/periodic_boundary.h"
19#include "libmesh/ghost_point_neighbors.h"
20
21namespace Moose
22{
25{
26 auto params = emptyInputParameters();
27
28 const MultiMooseEnum auto_direction("x=0 y=1 z=2");
29 params.addParam<MultiMooseEnum>(
30 "auto_direction",
31 auto_direction,
32 "If using a generated mesh, the dimension(s) you want to mark as periodic.");
33
34 params.addParam<BoundaryName>("primary", "Boundary associated with the primary boundary.");
35 params.addParam<BoundaryName>("secondary", "Boundary associated with the secondary boundary.");
36 params.addParam<RealVectorValue>("translation",
37 "Vector that translates coordinates on the primary boundary to "
38 "coordinates on the secondary boundary.");
39 params.addParam<std::vector<std::string>>("transform_func",
40 "Functions that specify the transformation");
41 params.addParam<std::vector<std::string>>("inv_transform_func",
42 "Functions that specify the inverse transformation");
43 return params;
44}
45
46PeriodicBCHelper::PeriodicBCHelper(const Action & action) : _action(action), _params(getParams()) {}
47
48void
50{
51 if (_params.isParamValid("auto_direction"))
52 {
53 for (const auto & param :
54 {"primary", "secondary", "translation", "transform_func", "inv_transform_func"})
55 if (_params.isParamValid(param))
56 _params.paramError(param, "Should not be specified along with 'auto_direction'");
57 }
58 else if (!_params.isParamValid("primary") || !_params.isParamValid("secondary"))
60 "Either 'auto_direction' or both 'primary' and 'secondary' must be specified");
61}
62
63void
65{
66 mooseAssert(_periodic_boundaries.empty(), "Already set");
67
68 // Setup paired sidesets to be able to call MooseMesh::getPairedBoundaryMapping()
69 if (!problem.mesh().hasDetectedPairedSidesets())
70 problem.mesh().detectPairedSidesets();
71
72 if (_params.isParamValid("auto_direction"))
74 else
76
77 mooseAssert(getPeriodicBoundaries().size(), "Shouldn't run without boundaries");
78
79 const auto add_ghosting = [this](auto & problem)
80 {
81 auto & mesh = problem.mesh().getMesh();
82 auto functor = std::make_shared<libMesh::GhostPointNeighbors>(mesh);
83 functor->set_periodic_boundaries(&getPeriodicBoundaries());
84 mesh.add_ghosting_functor(functor);
85 };
86
87 add_ghosting(problem);
88 if (const auto displaced_problem = problem.getDisplacedProblem())
89 add_ghosting(*displaced_problem);
90}
91
92void
93PeriodicBCHelper::addPeriodicBoundary(std::unique_ptr<libMesh::PeriodicBoundaryBase> p)
94{
96
97 _periodic_boundaries.emplace(p->myboundary, p->clone());
98 _periodic_boundaries.emplace(p->pairedboundary, p->clone(libMesh::PeriodicBoundaryBase::INVERSE));
99}
100
101void
103{
104 // If we are working with a parallel mesh then we're going to ghost all the boundaries
105 // everywhere because we don't know what we need...
106 if (mesh.isDistributedMesh() && !mesh.detectOrthogonalDimRanges())
107 _action.mooseError("Could not detect orthogonal dimension ranges for DistributedMesh.");
108
109 for (const auto & dir : _params.get<MultiMooseEnum>("auto_direction"))
110 {
111 const int component = dir.id();
112 if (component > (cast_int<int>(mesh.dimension()) - 1))
113 _params.paramError("auto_direction",
114 MooseUtils::toLower(dir.name()),
115 "-dimension component not valid for ",
116 mesh.dimension(),
117 "D mesh");
118
119 const auto boundary_ids = mesh.getPairedBoundaryMapping(component);
120 if (!boundary_ids)
121 _params.paramError("auto_direction",
122 "Couldn't auto-detect a paired boundary in the ",
123 MooseUtils::toLower(dir.name()),
124 "-direction");
125
126 RealVectorValue v;
127 v(component) = mesh.dimensionWidth(component);
128
129 auto p = std::make_unique<libMesh::PeriodicBoundary>(v);
130 p->myboundary = boundary_ids->first;
131 p->pairedboundary = boundary_ids->second;
132
133 addPeriodicBoundary(std::move(p));
134 }
135}
136
137void
139{
140 auto & mesh = problem.mesh();
141 std::unique_ptr<libMesh::PeriodicBoundaryBase> p;
142
143 if (const auto translation_ptr = _params.queryParam<RealVectorValue>("translation"))
144 p = std::make_unique<libMesh::PeriodicBoundary>(*translation_ptr);
145 else if (const auto fn_names_ptr = _params.queryParam<std::vector<std::string>>("transform_func"))
146 {
147 const auto inv_fn_names_ptr =
148 _params.queryParam<std::vector<std::string>>("inv_transform_func");
149 if (!inv_fn_names_ptr)
150 _params.paramError("transform_func", "Must also specify 'inv_transform_func'");
151 if (fn_names_ptr->size() != mesh.dimension())
153 "transform_func", "Must be the size of the mesh dimension ", mesh.dimension());
154 if (inv_fn_names_ptr->size() != mesh.dimension())
156 "inv_transform_func", "Must be the size of the mesh dimension ", mesh.dimension());
157
158 p = std::make_unique<FunctionPeriodicBoundary>(problem, *fn_names_ptr, *inv_fn_names_ptr);
159 }
160 else
162 "You need to specify either 'auto_direction', 'translation', or 'transform_func'");
163
164 const auto get_boundary = [this, &mesh](const auto & param) -> BoundaryID
165 {
166 if (const auto name_ptr = _params.queryParam<BoundaryName>(param))
167 {
168 if (const auto id = MooseMeshUtils::getBoundaryID(*name_ptr, mesh);
170 return id;
171 _params.paramError(param, "Boundary '", *name_ptr, "' does not exist in the mesh");
172 }
173 _action.mooseError("Parameter '", param, "' is required when 'auto_direction' is not set");
174 };
175 p->myboundary = get_boundary("primary");
176 p->pairedboundary = get_boundary("secondary");
177
178 addPeriodicBoundary(std::move(p));
179}
180
181const InputParameters &
183{
184 if (const auto moa = dynamic_cast<const MooseObjectAction *>(&_action))
185 return moa->getObjectParams();
186 return _action.parameters();
187}
188}
boundary_id_type BoundaryID
InputParameters emptyInputParameters()
std::shared_ptr< DisplacedProblem > displaced_problem
Base class for actions.
Definition Action.h:38
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
virtual MooseMesh & mesh() override
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
void paramError(const std::string &param, Args... args) const
Emits a parameter error prefixed with the parameter location and object information if available.
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another,...
const T * queryParam(const std::string &name) const
Query a parameter.
const InputParameters & parameters() const
Get the parameters of the object.
Definition MooseBase.h:131
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition MooseBase.h:271
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition MooseMesh.h:95
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition MooseMesh.C:3549
void detectPairedSidesets()
This routine detects paired sidesets of a regular orthogonal mesh (.i.e.
Definition MooseMesh.C:1994
bool hasDetectedPairedSidesets() const
Whether or not detectedPairedSidesets() has been called.
Definition MooseMesh.h:1002
static InputParameters validParams()
void setupAutoPeriodicBoundaries(MooseMesh &mesh)
Internal method for setting up periodic boundaries via the "auto_direction" param.
void setupManualPeriodicBoundaries(FEProblemBase &problem)
Internal method for setting up manual periodic boundaries via the "translation" and "transform_func" ...
const InputParameters & _params
The parameters used to create the periodic boundary.
void checkPeriodicParams() const
Checks the validity of the periodic boundary condition parameters.
void setupPeriodicBoundaries(FEProblemBase &problem)
Sets up the periodic boundaries.
libMesh::PeriodicBoundaries _periodic_boundaries
The PeriodicBoundaries map, filled in setupPeriodicBoundaries()
const Action & _action
The owning Action.
const libMesh::PeriodicBoundaries & getPeriodicBoundaries() const
Get the PeriodicBoundaries map produced in setupPeriodicBoundaries().
void addPeriodicBoundary(std::unique_ptr< libMesh::PeriodicBoundaryBase >)
Internal helper for adding a periodic boundary.
virtual void onSetupPeriodicBoundary(libMesh::PeriodicBoundaryBase &)
Entry-point for derived actions to extend the addition of a periodic boundary.
const InputParameters & getParams() const
Internal method for getting the parameters by the owned action.
PeriodicBCHelper(const Action &action)
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type.
MeshBase & mesh
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
Gets the boundary ID associated with the given BoundaryName.
std::string toLower(std::string name)
Convert supplied string to lower case.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
const BoundaryID INVALID_BOUNDARY_ID
Definition MooseTypes.C:22