https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
19using 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
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
56void
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 }
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
145void
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())
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
231void
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}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
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...
virtual MooseMesh & mesh() override
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.
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
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition MooseMesh.C:3549
ParallelType getParallelType() const
Definition MooseMesh.h:1158
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:1726
const std::set< SubdomainID > & meshSubdomains() const
Returns a read-only reference to the set of subdomains currently present in the Mesh.
Definition MooseMesh.C:3272
const libMesh::FEType & feType() const
Get the type of finite element object.
SystemBase & sys()
Get the system this variable is part of.
unsigned int number() const
Get variable number coming from libMesh.
unsigned int count() const
Get the number of components Note: For standard and vector variables, the number is one.
This class provides an interface for common operations on field variables of both FE and FV types wit...
virtual Moose::VarFieldType fieldType() const =0
Field type of this variable.
void transfer(FEProblemBase &to_problem, FEProblemBase &from_problem)
Performs the transfer of a variable between two problems if they have the same mesh.
const bool _has_block_restrictions
Whether block restriction is active.
static InputParameters validParams()
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.
MultiAppDofCopyTransfer(const InputParameters &parameters)
std::set< SubdomainID > _to_blocks
Subdomain IDs of the blocks to transfer to.
std::set< SubdomainID > _from_blocks
Subdomain IDs of the blocks to transfer from.
void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
Intermediary class that allows variable names as inputs.
virtual std::vector< VariableName > getFromVarNames() const =0
Virtual function defining variables to be transferred.
virtual std::vector< AuxVariableName > getToVarNames() const =0
Virtual function defining variables to transfer to.
virtual void initialSetup()
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
static InputParameters validParams()
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 std::shared_ptr< MultiApp > getToMultiApp() const
Get the MultiApp to transfer data to.
const std::shared_ptr< MultiApp > getFromMultiApp() const
Get the MultiApp to transfer data from.
virtual TagID getVectorTagID(const TagName &tag_name) const
Get a TagID from a TagName.
Definition SubProblem.C:204
unsigned int number() const
Gets the number of this system.
virtual NumericVector< Number > & getVector(const std::string &name)
Get a raw NumericVector by name.
Definition SystemBase.C:932
NumericVector< Number > & solution()
Definition SystemBase.h:203
void update()
Update the system (doing libMesh magic)
@ FROM_MULTIAPP
Definition Transfer.h:71
@ TO_MULTIAPP
Definition Transfer.h:70
MooseEnum _current_direction
Definition Transfer.h:106
unsigned int n_comp(const unsigned int s, const unsigned int var) const
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
unsigned int n_dofs(const unsigned int s, const unsigned int var=libMesh::invalid_uint) const
subdomain_id_type subdomain_id() const
virtual ElemType type() const=0
virtual const Node * node_ptr(const dof_id_type i) const=0
virtual dof_id_type n_elem() const=0
virtual dof_id_type n_nodes() const=0
virtual const Elem * elem_ptr(const dof_id_type i) const=0
virtual void set(const numeric_index_type i, const T value)=0
bool hasSubdomainName(const MeshBase &input_mesh, const SubdomainName &name)
Whether a particular subdomain name exists in the mesh.
@ VAR_FIELD_ANY
Definition MooseTypes.h:781
@ VAR_ANY
Definition MooseTypes.h:772
const SubdomainID INVALID_BLOCK_ID
Definition MooseTypes.C:20
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
uint8_t dof_id_type
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::string incompatVarMsg(MooseVariableFieldBase &var1, MooseVariableFieldBase &var2)
Builds and returns a string of the form:
Definition MooseError.C:26