https://mooseframework.inl.gov
MultiAppDofCopyTransfer.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 // MOOSE includes
12 #include "FEProblemBase.h"
13 #include "MultiApp.h"
14 #include "SystemBase.h"
15 
16 #include "libmesh/id_types.h"
17 #include "libmesh/string_to_enum.h"
18 
19 using namespace libMesh;
20 
23 {
25 
26  params.addParam<TagName>(
27  "from_solution_tag",
28  "The tag of the solution vector to be transferred (default to the solution)");
29  params.addParam<TagName>(
30  "to_solution_tag",
31  "The tag of the solution vector to be transferred to (default to the solution)");
32 
33  // Block restrictions
34  params.addParam<std::vector<SubdomainName>>(
35  "from_blocks",
36  {},
37  "Subdomain restriction to transfer from (defaults to all the origin app domain)");
38  params.addParam<std::vector<SubdomainName>>(
39  "to_blocks",
40  {},
41  "Subdomain restriction to transfer to, (defaults to all the target app domain)");
42 
43  params.addClassDescription(
44  "Base class for copying degrees-of-freedom values (nonlinear and auxiliary) between apps "
45  "that have identical meshes.");
46  return params;
47 }
48 
50  : MultiAppFieldTransfer(parameters),
51  _has_block_restrictions(!getParam<std::vector<SubdomainName>>("from_blocks").empty() ||
52  !getParam<std::vector<SubdomainName>>("to_blocks").empty())
53 {
54 }
55 
56 void
58 {
60 
61  const FEProblemBase * from_problem;
62  const FEProblemBase * to_problem;
63 
65  {
66  // Subdomain and variable type information is shared on all subapps
67  from_problem = &getFromMultiApp()->appProblemBase(getFromMultiApp()->firstLocalApp());
68  to_problem = &getFromMultiApp()->problemBase();
69  }
70  else if (_current_direction == TO_MULTIAPP)
71  {
72  from_problem = &getToMultiApp()->problemBase();
73  to_problem = &getToMultiApp()->appProblemBase(getToMultiApp()->firstLocalApp());
74  }
75  else
76  {
77  from_problem = &getFromMultiApp()->appProblemBase(getFromMultiApp()->firstLocalApp());
78  to_problem = &getToMultiApp()->appProblemBase(getToMultiApp()->firstLocalApp());
79  }
80 
81  if (from_problem->mesh().getParallelType() != to_problem->mesh().getParallelType())
82  mooseError("The parallel types (distributed or replicated) of the meshes are not the same.");
83 
84  // Convert block names to block IDs, fill with all blocks if unspecified
86  {
87  const auto & from_block_names = getParam<std::vector<SubdomainName>>("from_blocks");
88  for (const auto & b : from_block_names)
89  if (!MooseMeshUtils::hasSubdomainName(const_cast<MeshBase &>(from_problem->mesh().getMesh()),
90  b))
91  paramError("from_blocks", "The block '", b, "' was not found in the mesh");
92 
93  if (from_block_names.size())
94  {
95  if (from_problem)
96  {
97  const auto block_vec = from_problem->mesh().getSubdomainIDs(from_block_names);
98  _from_blocks = std::set<SubdomainID>(block_vec.begin(), block_vec.end());
99  }
100  // We dont even own any of these subapps
101  else
103  }
104  else
105  _from_blocks = from_problem->mesh().meshSubdomains();
106 
107  const auto & to_block_names = getParam<std::vector<SubdomainName>>("to_blocks");
108  for (const auto & b : to_block_names)
109  if (!MooseMeshUtils::hasSubdomainName(const_cast<MeshBase &>(to_problem->mesh().getMesh()),
110  b))
111  paramError("to_blocks", "The block '", b, "' was not found in the mesh");
112 
113  if (to_block_names.size())
114  {
115  if (to_problem)
116  {
117  const auto block_vec = to_problem->mesh().getSubdomainIDs(to_block_names);
118  _to_blocks = std::set<SubdomainID>(block_vec.begin(), block_vec.end());
119  }
120  // We dont even own any of these subapps
121  else
123  }
124  else
125  _to_blocks = to_problem->mesh().meshSubdomains();
126  }
127 
128  // Forbid block restriction on nodal variables as currently not supported
129  if (_from_blocks.size())
130  for (auto & from_var : getFromVarNames())
131  if (from_problem
132  ->getVariable(
134  .hasDoFsOnNodes())
135  paramError("from_blocks", "Block restriction is not implemented for nodal variables");
136  if (_to_blocks.size())
137  for (auto & to_var : getToVarNames())
138  if (to_problem
139  ->getVariable(
141  .hasDoFsOnNodes())
142  paramError("to_blocks", "Block restriction is not implemented for nodal variables");
143 }
144 
145 void
147 {
148  // Perform error checking
149  if (!getToVarNames().size())
150  mooseError("No transferred variables were specified, neither programmatically or through the "
151  "'source_variable' parameter");
152  if (getToVarNames().size() != getFromVarNames().size())
153  mooseError("Number of variables transferred must be same in both systems.");
154  for (auto & to_var : getToVarNames())
155  checkVariable(to_problem, to_var);
156  for (auto & from_var : getFromVarNames())
157  checkVariable(from_problem, from_var);
158 
159  for (unsigned int v = 0; v < getToVarNames().size(); ++v)
160  {
161  // Populate the to/from variables needed to perform the transfer
162  MooseVariableFEBase & to_var = to_problem.getVariable(
164  MeshBase & to_mesh = to_problem.mesh().getMesh();
165 
166  MooseVariableFEBase & from_var = from_problem.getVariable(
168  MeshBase & from_mesh = from_problem.mesh().getMesh();
169 
170  auto & to_solution = isParamValid("to_solution_tag")
171  ? to_var.sys().getVector(
172  to_problem.getVectorTagID(getParam<TagName>("to_solution_tag")))
173  : to_var.sys().solution();
174  auto & from_solution = isParamValid("from_solution_tag")
175  ? from_var.sys().getVector(from_problem.getVectorTagID(
176  getParam<TagName>("from_solution_tag")))
177  : from_var.sys().solution();
178 
179  // Check integrity
180  if (to_var.feType() != from_var.feType())
181  mooseError("MultiAppFieldTransfer '",
182  name(),
183  "'requires that the target variable '",
184  to_var.name(),
185  "' and the source variable'",
186  from_var.name(),
187  "' must be the same type "
188  "(order and family): ",
189  libMesh::Utility::enum_to_string<FEFamily>(to_var.feType().family),
190  moose::internal::incompatVarMsg(to_var, from_var));
191  if (to_var.fieldType() != from_var.fieldType())
192  mooseError(
193  "Corresponding transfer variables must be same field type (STANDARD | VECTOR | ARRAY).");
194  if (to_var.count() != from_var.count())
195  mooseError("Corresponding transfer variables must have same number of components.");
196 
197  if ((to_mesh.n_nodes() != from_mesh.n_nodes()) || (to_mesh.n_elem() != from_mesh.n_elem()))
198  mooseError("The meshes must be identical to utilize MultiAppDofCopyTransfer::transfer.");
199 
200  // Transfer node dofs. Block restriction is not supported, forbidden in initialSetup
201  for (const auto & node : as_range(to_mesh.local_nodes_begin(), to_mesh.local_nodes_end()))
203  node, from_mesh.node_ptr(node->id()), to_var, from_var, to_solution, from_solution);
204 
205  // Transfer elem dofs
206  for (auto & to_elem : as_range(to_mesh.local_elements_begin(), to_mesh.local_elements_end()))
207  {
208  Elem * from_elem = from_mesh.elem_ptr(to_elem->id());
209  mooseAssert(to_elem->type() == from_elem->type(), "The elements must be the same type.");
210 
211  // Examine block restriction
213  {
214  SubdomainID from_block = from_elem->subdomain_id();
215  if (std::find(_from_blocks.begin(), _from_blocks.end(), from_block) == _from_blocks.end())
216  continue;
217 
218  SubdomainID to_block = to_elem->subdomain_id();
219  if (std::find(_to_blocks.begin(), _to_blocks.end(), to_block) == _to_blocks.end())
220  continue;
221  }
222 
223  transferDofObject(to_elem, from_elem, to_var, from_var, to_solution, from_solution);
224  }
225 
226  to_solution.close();
227  to_var.sys().update();
228  }
229 }
230 
231 void
233  libMesh::DofObject * from_object,
234  MooseVariableFEBase & to_var,
235  MooseVariableFEBase & from_var,
236  NumericVector<Number> & to_solution,
237  NumericVector<Number> & from_solution)
238 {
239  for (unsigned int vc = 0; vc < to_var.count(); ++vc)
240  // Transfer from one solution vector to another
241  if (to_object->n_dofs(to_var.sys().number(), to_var.number() + vc) >
242  0) // If this variable has dofs at this node
243  for (unsigned int comp = 0;
244  comp < to_object->n_comp(to_var.sys().number(), to_var.number() + vc);
245  ++comp)
246  {
247  dof_id_type dof = to_object->dof_number(to_var.sys().number(), to_var.number() + vc, comp);
248  dof_id_type from_dof =
249  from_object->dof_number(from_var.sys().number(), from_var.number() + vc, comp);
250  Real from_value = from_solution(from_dof);
251  to_solution.set(dof, from_value);
252  }
253 }
MultiAppDofCopyTransfer(const InputParameters &parameters)
virtual TagID getVectorTagID(const TagName &tag_name) const
Get a TagID from a TagName.
Definition: SubProblem.C:203
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
const libMesh::FEType & feType() const
Get the type of finite element object.
unsigned int n_comp(const unsigned int s, const unsigned int var) const
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
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:435
std::string incompatVarMsg(MooseVariableFieldBase &var1, MooseVariableFieldBase &var2)
Builds and returns a string of the form:
Definition: MooseError.C:26
NumericVector< Number > & solution()
Definition: SystemBase.h:196
MooseEnum _current_direction
Definition: Transfer.h:106
unsigned int number() const
Get variable number coming from libMesh.
void transferDofObject(libMesh::DofObject *to_object, libMesh::DofObject *from_object, MooseVariableFieldBase &to_var, MooseVariableFieldBase &from_var, NumericVector< Number > &to_solution, NumericVector< Number > &from_solution)
Performs the transfer of values between a node or element.
virtual void initialSetup()
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
unsigned int count() const
Get the number of components Note: For standard and vector variables, the number is one...
static InputParameters validParams()
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const std::shared_ptr< MultiApp > getToMultiApp() const
Get the MultiApp to transfer data to.
This class provides an interface for common operations on field variables of both FE and FV types wit...
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_names) const
Get the associated subdomainIDs for the subdomain names that are passed in.
Definition: MooseMesh.C:1737
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
static InputParameters validParams()
void update()
Update the system (doing libMesh magic)
Definition: SystemBase.C:1235
void checkVariable(const FEProblemBase &fe_problem, const VariableName &var_name, const std::string &param_name="") const
Helper for checking a problem for a variable.
const SubdomainID INVALID_BLOCK_ID
Definition: MooseTypes.C:20
unsigned int n_dofs(const unsigned int s, const unsigned int var=libMesh::invalid_uint) const
std::set< SubdomainID > _from_blocks
Subdomain IDs of the blocks to transfer from.
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:99
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:3448
std::set< SubdomainID > _to_blocks
Subdomain IDs of the blocks to transfer to.
Intermediary class that allows variable names as inputs.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
ParallelType getParallelType() const
Definition: MooseMesh.h:1016
unsigned int number() const
Gets the number of this system.
Definition: SystemBase.C:1149
bool hasSubdomainName(const MeshBase &input_mesh, const SubdomainName &name)
Whether a particular subdomain name exists in the mesh.
virtual const Elem * elem_ptr(const dof_id_type i) const=0
const bool _has_block_restrictions
Whether block restriction is active.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
subdomain_id_type subdomain_id() const
virtual MooseMesh & mesh() override
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:267
void transfer(FEProblemBase &to_problem, FEProblemBase &from_problem)
Performs the transfer of a variable between two problems if they have the same mesh.
virtual Moose::VarFieldType fieldType() const =0
Field type of this variable.
virtual std::vector< AuxVariableName > getToVarNames() const =0
Virtual function defining variables to transfer to.
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...
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...
virtual void set(const numeric_index_type i, const T value)=0
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseBase.h:195
virtual dof_id_type n_elem() const=0
virtual const Node * node_ptr(const dof_id_type i) const=0
SystemBase & sys()
Get the system this variable is part of.
virtual NumericVector< Number > & getVector(const std::string &name)
Get a raw NumericVector by name.
Definition: SystemBase.C:925
virtual ElemType type() const=0
virtual std::vector< VariableName > getFromVarNames() const =0
Virtual function defining variables to be transferred.
virtual dof_id_type n_nodes() const=0
uint8_t dof_id_type
const std::set< SubdomainID > & meshSubdomains() const
Returns a read-only reference to the set of subdomains currently present in the Mesh.
Definition: MooseMesh.C:3171