www.mooseframework.org
AddPeriodicBCAction.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* DO NOT MODIFY THIS HEADER */
3 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
4 /* */
5 /* (c) 2010 Battelle Energy Alliance, LLC */
6 /* ALL RIGHTS RESERVED */
7 /* */
8 /* Prepared by Battelle Energy Alliance, LLC */
9 /* Under Contract No. DE-AC07-05ID14517 */
10 /* With the U. S. Department of Energy */
11 /* */
12 /* See COPYRIGHT for full restrictions */
13 /****************************************************************/
14 
15 #include "AddPeriodicBCAction.h"
16 
17 // MOOSE includes
18 #include "DisplacedProblem.h"
19 #include "FEProblem.h"
21 #include "GeneratedMesh.h"
22 #include "InputParameters.h"
23 #include "MooseMesh.h"
24 #include "MooseVariable.h"
25 #include "NonlinearSystem.h"
26 
27 #include "libmesh/periodic_boundary.h" // translation PBCs provided by libmesh
28 
29 template <>
32 {
34  params.addParam<std::vector<std::string>>("auto_direction",
35  "If using a generated mesh, you can "
36  "specifiy just the dimension(s) you "
37  "want to mark as periodic");
38 
39  params.addParam<BoundaryName>("primary", "Boundary ID associated with the primary boundary.");
40  params.addParam<BoundaryName>("secondary", "Boundary ID associated with the secondary boundary.");
41  params.addParam<RealVectorValue>("translation",
42  "Vector that translates coordinates on the "
43  "primary boundary to coordinates on the "
44  "secondary boundary.");
45  params.addParam<std::vector<std::string>>("transform_func",
46  "Functions that specify the transformation");
47  params.addParam<std::vector<std::string>>("inv_transform_func",
48  "Functions that specify the inverse transformation");
49 
50  params.addParam<std::vector<VariableName>>("variable", "Variable for the periodic boundary");
51  return params;
52 }
53 
55 
56 void
57 AddPeriodicBCAction::setPeriodicVars(PeriodicBoundaryBase & p,
58  const std::vector<VariableName> & var_names)
59 {
60  NonlinearSystemBase & nl = _problem->getNonlinearSystemBase();
61  const std::vector<VariableName> * var_names_ptr;
62 
63  // If var_names is empty - then apply this periodic condition to all variables in the system
64  if (var_names.empty())
65  var_names_ptr = &nl.getVariableNames();
66  else
67  var_names_ptr = &var_names;
68 
69  for (const auto & var_name : *var_names_ptr)
70  {
71  unsigned int var_num = nl.getVariable(0, var_name).number();
72 
73  p.set_variable(var_num);
74  _mesh->addPeriodicVariable(var_num, p.myboundary, p.pairedboundary);
75  }
76 }
77 
78 bool
80 {
81  auto displaced_problem = _problem->getDisplacedProblem();
82 
83  if (isParamValid("auto_direction"))
84  {
85  // If we are working with a parallel mesh then we're going to ghost all the boundaries
86  // everywhere because we don't know what we need...
87  if (_mesh->isDistributedMesh())
88  {
89  const std::set<BoundaryID> & ids = _mesh->meshBoundaryIds();
90  for (const auto & bid : ids)
91  _problem->addGhostedBoundary(bid);
92 
93  _problem->ghostGhostedBoundaries();
94 
95  bool is_orthogonal_mesh = _mesh->detectOrthogonalDimRanges();
96 
97  // If we can't detect the orthogonal dimension ranges for this
98  // Mesh, then auto_direction periodicity isn't going to work.
99  if (!is_orthogonal_mesh)
100  mooseError("Could not detect orthogonal dimension ranges for DistributedMesh.");
101  }
102 
103  NonlinearSystemBase & nl = _problem->getNonlinearSystemBase();
104  std::vector<std::string> auto_dirs = getParam<std::vector<std::string>>("auto_direction");
105 
106  int dim_offset = _mesh->dimension() - 2;
107  for (const auto & dir : auto_dirs)
108  {
109  int component = -1;
110  if (dir == "X" || dir == "x")
111  component = 0;
112  else if (dir == "Y" || dir == "y")
113  {
114  if (dim_offset < 0)
115  mooseError("Cannot wrap 'Y' direction when using a 1D mesh");
116  component = 1;
117  }
118  else if (dir == "Z" || dir == "z")
119  {
120  if (dim_offset <= 0)
121  mooseError("Cannot wrap 'Z' direction when using a 1D or 2D mesh");
122  component = 2;
123  }
124 
125  if (component >= 0)
126  {
127  const std::pair<BoundaryID, BoundaryID> * boundary_ids =
128  _mesh->getPairedBoundaryMapping(component);
129  RealVectorValue v;
130  v(component) = _mesh->dimensionWidth(component);
131  PeriodicBoundary p(v);
132 
133  if (boundary_ids == NULL)
134  mooseError(
135  "Couldn't auto-detect a paired boundary for use with periodic boundary conditions");
136 
137  p.myboundary = boundary_ids->first;
138  p.pairedboundary = boundary_ids->second;
139  setPeriodicVars(p, getParam<std::vector<VariableName>>("variable"));
140  nl.dofMap().add_periodic_boundary(p);
141  if (displaced_problem)
142  displaced_problem->nlSys().dofMap().add_periodic_boundary(p);
143  }
144  }
145  return true;
146  }
147  return false;
148 }
149 
150 void
152 {
153  NonlinearSystemBase & nl = _problem->getNonlinearSystemBase();
154  _mesh = &_problem->mesh();
155  auto displaced_problem = _problem->getDisplacedProblem();
156 
158  return;
159 
160  if (_pars.isParamValid("translation"))
161  {
162  RealVectorValue translation = getParam<RealVectorValue>("translation");
163 
164  PeriodicBoundary p(translation);
165  p.myboundary = _mesh->getBoundaryID(getParam<BoundaryName>("primary"));
166  p.pairedboundary = _mesh->getBoundaryID(getParam<BoundaryName>("secondary"));
167  setPeriodicVars(p, getParam<std::vector<VariableName>>("variable"));
168 
169  _problem->addGhostedBoundary(p.myboundary);
170  _problem->addGhostedBoundary(p.pairedboundary);
171 
172  nl.dofMap().add_periodic_boundary(p);
173  if (displaced_problem)
174  displaced_problem->nlSys().dofMap().add_periodic_boundary(p);
175  }
176  else if (getParam<std::vector<std::string>>("transform_func") != std::vector<std::string>())
177  {
178  std::vector<std::string> inv_fn_names =
179  getParam<std::vector<std::string>>("inv_transform_func");
180  std::vector<std::string> fn_names = getParam<std::vector<std::string>>("transform_func");
181 
182  // If the user provided a forward transformation, he must also provide an inverse -- we can't
183  // form the inverse of an arbitrary function automatically...
184  if (inv_fn_names == std::vector<std::string>())
185  mooseError("You must provide an inv_transform_func for FunctionPeriodicBoundary!");
186 
187  FunctionPeriodicBoundary pb(*_problem, fn_names);
188  pb.myboundary = _mesh->getBoundaryID(getParam<BoundaryName>("primary"));
189  pb.pairedboundary = _mesh->getBoundaryID(getParam<BoundaryName>("secondary"));
190  setPeriodicVars(pb, getParam<std::vector<VariableName>>("variable"));
191 
192  FunctionPeriodicBoundary ipb(*_problem, inv_fn_names);
193  ipb.myboundary = _mesh->getBoundaryID(getParam<BoundaryName>("secondary")); // these are swapped
194  ipb.pairedboundary =
195  _mesh->getBoundaryID(getParam<BoundaryName>("primary")); // these are swapped
196  setPeriodicVars(ipb, getParam<std::vector<VariableName>>("variable"));
197 
198  _problem->addGhostedBoundary(ipb.myboundary);
199  _problem->addGhostedBoundary(ipb.pairedboundary);
200 
201  // Add the pair of periodic boundaries to the dof map
202  nl.dofMap().add_periodic_boundary(pb, ipb);
203  if (displaced_problem)
204  displaced_problem->nlSys().dofMap().add_periodic_boundary(pb, ipb);
205  }
206  else
207  {
208  mooseError("You have to specify either 'auto_direction', 'translation' or 'trans_func' in your "
209  "period boundary section '" +
210  _name + "'");
211  }
212 }
void setPeriodicVars(PeriodicBoundaryBase &p, const std::vector< VariableName > &var_names)
VectorValue< Real > RealVectorValue
Definition: Assembly.h:40
virtual unsigned int dimension() const
Returns MeshBase::mesh_dimsension(), (not MeshBase::spatial_dimension()!) of the underlying libMesh m...
Definition: MooseMesh.C:1945
Periodic boundary for calculation periodic BC on domains where the translation is given by functions...
void mooseError(Args &&...args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:182
const std::set< BoundaryID > & meshBoundaryIds() const
Returns a read-only reference to the set of boundary IDs currently present in the Mesh...
Definition: MooseMesh.C:2110
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
Real dimensionWidth(unsigned int component) const
Returns the width of the requested dimension.
Definition: MooseMesh.C:1364
Base class for actions.
Definition: Action.h:39
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
Get the associated BoundaryID for the boundary name.
Definition: MooseMesh.C:929
bool autoTranslationBoundaries()
This function will automatically add the correct translation vectors for each requested dimension whe...
std::string _name
The name of the action.
Definition: Action.h:92
NonlinearSystemBase * nl
virtual void act() override
Nonlinear system to be solved.
virtual DofMap & dofMap()
Gets the dof map.
Definition: SystemBase.C:610
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.
virtual MooseVariable & getVariable(THREAD_ID tid, const std::string &var_name)
Gets a reference to a variable of with specified name.
Definition: SystemBase.C:103
InputParameters _pars
Input parameters for the action.
Definition: Action.h:86
const std::pair< BoundaryID, BoundaryID > * getPairedBoundaryMapping(unsigned int component)
This function attempts to return the paired boundary ids for the given component. ...
Definition: MooseMesh.C:1452
bool isParamValid(const std::string &name) const
Definition: Action.h:80
AddPeriodicBCAction(InputParameters params)
unsigned int number() const
Get variable number coming from libMesh.
void addPeriodicVariable(unsigned int var_num, BoundaryID primary, BoundaryID secondary)
For "regular orthogonal" meshes, determine if variable var_num is periodic with respect to the primar...
Definition: MooseMesh.C:1388
bool detectOrthogonalDimRanges(Real tol=1e-6)
This routine determines whether the Mesh is a regular orthogonal mesh (i.e.
Definition: MooseMesh.C:1182
std::shared_ptr< FEProblemBase > & _problem
Convenience reference to a problem this action works on.
Definition: Action.h:131
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
InputParameters validParams< AddPeriodicBCAction >()
const std::vector< VariableName > & getVariableNames() const
Definition: SystemBase.h:466
InputParameters validParams< Action >()
Definition: Action.C:23
bool isDistributedMesh() const
Returns the final Mesh distribution type.
Definition: MooseMesh.h:737
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: Action.h:139