https://mooseframework.inl.gov
Loading...
Searching...
No Matches
AddPeriodicBCAction.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 "AddPeriodicBCAction.h"
11
12#include "DisplacedProblem.h"
13#include "FEProblem.h"
14#include "MooseMesh.h"
15#include "MooseVariableFE.h"
16#include "NonlinearSystemBase.h"
17#include "RelationshipManager.h"
18
19#include "libmesh/periodic_boundary.h"
20
21#include <optional>
22
23registerMooseAction("MooseApp", AddPeriodicBCAction, "add_periodic_bc");
24registerMooseAction("MooseApp", AddPeriodicBCAction, "add_geometric_rm");
25registerMooseAction("MooseApp", AddPeriodicBCAction, "add_algebraic_rm");
26
29{
32
33 params.addParam<std::vector<VariableName>>("variable",
34 "Variable(s) to apply periodic boundary conditions "
35 "to; if unset, apply to all field variables.");
36
37 params.addClassDescription("Action that adds periodic boundary conditions");
38
39 return params;
40}
41
43 : Action(params), Moose::PeriodicBCHelper(static_cast<const Action &>(*this))
44{
46}
47
48void
50{
51 if (_current_task == "add_geometric_rm")
52 // Tell the mesh to hold off on deleting remote elements because we need to wait for our
53 // periodic boundaries to be added
54 Action::_mesh->allowRemoteElementRemoval(false);
55
56 if (_current_task == "add_algebraic_rm" && getPeriodicBoundaries().size())
57 {
58 auto rm_params = _factory.getValidParams("ElementSideNeighborLayers");
59
60 rm_params.set<std::string>("for_whom") = "PeriodicBCs";
61 if (!_mesh)
62 mooseError("We should have added periodic boundaries and consequently we should have set the "
63 "_mesh by now");
64
65 rm_params.set<MooseMesh *>("mesh") = _mesh;
66 // The default GhostPointNeighbors ghosting functor in libMesh handles the geometric ghosting
67 // of periodic boundaries for us, so we only need to handle the algebraic ghosting here
68 rm_params.set<Moose::RelationshipManagerType>("rm_type") =
70
71 if (rm_params.areAllRequiredParamsValid())
72 {
73 auto rm_obj = _factory.create<RelationshipManager>(
74 "ElementSideNeighborLayers", "periodic_bc_ghosting_" + name(), rm_params);
75
76 if (!_app.addRelationshipManager(rm_obj))
78 }
79 else
80 mooseError("Invalid initialization of ElementSideNeighborLayers");
81 }
82
83 if (_current_task == "add_periodic_bc")
84 {
85 _mesh = &_problem->mesh();
86
87 // Set _vars so that variables can be used in onSetupPeriodicBoundary
89 mooseAssert(_vars.size(), "Shouldn't run without variables");
90
91 // Query the helper to determine the periodic boundaries, which will
92 // call onSetupPeriodicBoundary() for every periodic boundary
94
96 {
97 std::ostringstream out;
98 out << "Periodicity information for the variables\n";
99 for (const auto & var_ptr : _vars)
100 out << " - " << var_ptr->name() << "\n";
101 out << "will only be stored in the system's DoF map, not on the MooseMesh";
102 mooseInfoRepeated(out.str());
103 }
104 }
105}
106
107void
109{
110 const auto is_regular_orthogonal = _mesh->isRegularOrthogonal();
111 for (const auto & var_ptr : _vars)
112 {
113 const auto sys_num = var_ptr->sys().number();
114 for (const auto component : make_range(var_ptr->count()))
115 {
116 const auto var_num = var_ptr->number() + component;
117
118 // Set variable number in PeriodicBoundaryBase object
119 p.set_variable(var_num);
120
121 // Add to MooseMesh to querying variable periodicity
122 if (is_regular_orthogonal)
123 _mesh->addPeriodicVariable(sys_num, var_num, p.myboundary, p.pairedboundary);
124
125 // Add to dof maps for algebraic ghosting
126 const auto add_to_dof_map = [&p, &sys_num](auto & problem)
127 { problem.es().get_system(sys_num).get_dof_map().add_periodic_boundary(p); };
128 add_to_dof_map(*_problem);
129 if (auto displaced_problem = _problem->getDisplacedProblem())
130 add_to_dof_map(*displaced_problem);
131 }
132 }
133}
134
135std::vector<const MooseVariableFieldBase *>
137{
138 std::vector<VariableName> var_names;
139 // Variable is set, use it
140 if (isParamValid("variable"))
141 {
142 var_names = getParam<std::vector<VariableName>>("variable");
143 if (var_names.empty())
144 paramError("variable", "No variables are set to apply periodic boundaries to");
145 for (const auto & var_name : var_names)
146 {
147 if (_problem->hasScalarVariable(var_name))
148 paramError("variable",
149 "Variable '" + var_name +
150 "' is a scalar variable and does not support a periodic boundary condition");
151 if (!_problem->hasVariable(var_name))
152 paramError("variable", "Variable '" + var_name + "' not found");
153 if (_problem->getVariable(0, var_name).isFV())
154 paramError("variable",
155 "Variable '" + var_name +
156 "' is a finite volume variable and does not support a periodic boundary "
157 "condition.");
158 }
159 }
160 // Variable is not set, use all nonlinear variables that are non-scalar and non-FV
161 else
162 {
163 // We can't currently distinguish PeriodicBoundaries objects across
164 // multiple systems so we can't use vars across all systems
165 if (_problem->numSolverSystems() > 1)
166 mooseError("Parameter 'variable' must be specified when multiple solver systems exist");
167 const auto & nl = _problem->getNonlinearSystemBase(0);
168 var_names = nl.getVariableNames();
169 var_names.erase(std::remove_if(var_names.begin(),
170 var_names.end(),
171 [&nl](const auto & var_name)
172 {
173 return nl.hasScalarVariable(var_name) ||
174 nl.getVariable(0, var_name).isFV();
175 }),
176 var_names.end());
177 if (var_names.empty())
178 mooseError("There are no variables to apply periodic boundaries to");
179 }
180
181 // Verify and collect variables
182 std::vector<const MooseVariableFieldBase *> vars;
183 vars.reserve(var_names.size());
184 std::optional<unsigned int> used_sys_num;
185 for (const auto & var_name : var_names)
186 {
187 const auto & var = _problem->getVariable(0, var_name);
188 const auto sys_num = var.sys().number();
189
190 // Until we have a way to have separate PeriodicBoundaries objects for each systems,
191 // we can't do these in the same block
192 if (used_sys_num && *used_sys_num != sys_num)
193 paramError("variable",
194 "Variables were specified across multiple systems; this is not supported. Use a "
195 "separate [Periodic/BCs] block for each system.");
196 used_sys_num = sys_num;
197
198 vars.push_back(&var);
199 }
200
201 return vars;
202}
registerMooseAction("MooseApp", AddPeriodicBCAction, "add_periodic_bc")
void mooseInfoRepeated(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
Definition MooseError.h:409
std::shared_ptr< DisplacedProblem > displaced_problem
char ** vars
Base class for actions.
Definition Action.h:38
std::shared_ptr< MooseMesh > & _mesh
Definition Action.h:174
static InputParameters validParams()
Definition Action.C:26
MooseApp & _app
The MOOSE application this is associated with.
Definition MooseBase.h:375
std::shared_ptr< FEProblemBase > & _problem
Convenience reference to a problem this action works on.
Definition Action.h:178
const std::string & _current_task
The current action (even though we have separate instances for each action)
Definition Action.h:172
This Action adds a periodic boundary to the problem.
static InputParameters validParams()
AddPeriodicBCAction(const InputParameters &params)
virtual void act() override
Method to add objects to the simulation or perform other setup tasks.
virtual void onSetupPeriodicBoundary(libMesh::PeriodicBoundaryBase &p) override
Overriden method from PeriodicBCHelper that is called on every periodic boundary, in which we will se...
std::vector< const MooseVariableFieldBase * > _vars
The variables to apply periodic boundary conditions to.
std::vector< const MooseVariableFieldBase * > getVariables() const
Helper for getting the variables to which periodic boundary conditions will be applied.
std::shared_ptr< MooseObject > create(const std::string &obj_name, const std::string &name, const InputParameters &parameters, THREAD_ID tid=0, bool print_deprecated=true)
Definition Factory.C:142
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
Definition Factory.C:68
void releaseSharedObjects(const MooseObject &moose_object, THREAD_ID tid=0)
Releases any shared resources created as a side effect of creating an object through the Factory::cre...
Definition Factory.C:156
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
bool addRelationshipManager(std::shared_ptr< RelationshipManager > relationship_manager)
Transfers ownership of a RelationshipManager to the application for lifetime management.
Definition MooseApp.C:2991
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
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
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition MooseMesh.h:95
bool isRegularOrthogonal()
Getter to query if the mesh was detected to be regular and orthogonal.
Definition MooseMesh.h:1198
void addPeriodicVariable(const unsigned int sys_num, const unsigned int var_num, const BoundaryID primary, const BoundaryID secondary)
For "regular orthogonal" meshes, determine if variable var_num is periodic with respect to the primar...
Definition MooseMesh.C:2195
static InputParameters validParams()
void checkPeriodicParams() const
Checks the validity of the periodic boundary condition parameters.
void setupPeriodicBoundaries(FEProblemBase &problem)
Sets up the periodic boundaries.
const libMesh::PeriodicBoundaries & getPeriodicBoundaries() const
Get the PeriodicBoundaries map produced in setupPeriodicBoundaries().
Factory & _factory
The Factory associated with the MooseApp.
RelationshipManagers are used for describing what kinds of non-local resources are needed for an obje...
void set_variable(unsigned int var)
boundary_id_type pairedboundary
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
RelationshipManagerType
Main types of Relationship Managers.