www.mooseframework.org
MultiAppUserObjectTransfer.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 
16 
17 // MOOSE includes
18 #include "DisplacedProblem.h"
19 #include "FEProblem.h"
20 #include "MooseMesh.h"
21 #include "MooseTypes.h"
22 #include "MooseVariable.h"
23 #include "MultiApp.h"
24 #include "UserObject.h"
25 
26 // libMesh
27 #include "libmesh/meshfree_interpolation.h"
28 #include "libmesh/system.h"
29 #include "libmesh/mesh_function.h"
30 #include "libmesh/mesh_tools.h"
31 
32 template <>
35 {
37  params.addRequiredParam<AuxVariableName>(
38  "variable", "The auxiliary variable to store the transferred values in.");
39  params.addRequiredParam<UserObjectName>(
40  "user_object",
41  "The UserObject you want to transfer values from. Note: This might be a "
42  "UserObject from your MultiApp's input file!");
43 
44  params.addParam<bool>("displaced_target_mesh",
45  false,
46  "Whether or not to use the displaced mesh for the target mesh.");
47 
48  return params;
49 }
50 
52  : MultiAppTransfer(parameters),
53  _to_var_name(getParam<AuxVariableName>("variable")),
54  _user_object_name(getParam<UserObjectName>("user_object")),
55  _displaced_target_mesh(getParam<bool>("displaced_target_mesh"))
56 {
57  // This transfer does not work with DistributedMesh
58  _fe_problem.mesh().errorIfDistributedMesh("MultiAppUserObjectTransfer");
59 }
60 
61 void
63 {
64  if (_direction == TO_MULTIAPP)
66 }
67 
68 void
70 {
71  _console << "Beginning MultiAppUserObjectTransfer " << name() << std::endl;
72 
73  switch (_direction)
74  {
75  case TO_MULTIAPP:
76  {
77  for (unsigned int i = 0; i < _multi_app->numGlobalApps(); i++)
78  {
79  if (_multi_app->hasLocalApp(i))
80  {
81  Moose::ScopedCommSwapper swapper(_multi_app->comm());
82 
83  // Loop over the master nodes and set the value of the variable
84  System * to_sys = find_sys(_multi_app->appProblemBase(i).es(), _to_var_name);
85 
86  unsigned int sys_num = to_sys->number();
87  unsigned int var_num = to_sys->variable_number(_to_var_name);
88 
89  NumericVector<Real> & solution = _multi_app->appTransferVector(i, _to_var_name);
90 
91  MeshBase * mesh = NULL;
92 
93  if (_displaced_target_mesh && _multi_app->appProblemBase(i).getDisplacedProblem())
94  {
95  mesh = &_multi_app->appProblemBase(i).getDisplacedProblem()->mesh().getMesh();
96  }
97  else
98  mesh = &_multi_app->appProblemBase(i).mesh().getMesh();
99 
100  bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE;
101 
102  const UserObject & user_object =
103  _multi_app->problemBase().getUserObjectBase(_user_object_name);
104 
105  if (is_nodal)
106  {
107  MeshBase::const_node_iterator node_it = mesh->local_nodes_begin();
108  MeshBase::const_node_iterator node_end = mesh->local_nodes_end();
109 
110  for (; node_it != node_end; ++node_it)
111  {
112  Node * node = *node_it;
113 
114  if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node
115  {
116  // The zero only works for LAGRANGE!
117  dof_id_type dof = node->dof_number(sys_num, var_num, 0);
118 
119  swapper.forceSwap();
120  Real from_value = user_object.spatialValue(*node + _multi_app->position(i));
121  swapper.forceSwap();
122 
123  solution.set(dof, from_value);
124  }
125  }
126  }
127  else // Elemental
128  {
129  MeshBase::const_element_iterator elem_it = mesh->local_elements_begin();
130  MeshBase::const_element_iterator elem_end = mesh->local_elements_end();
131 
132  for (; elem_it != elem_end; ++elem_it)
133  {
134  Elem * elem = *elem_it;
135 
136  Point centroid = elem->centroid();
137 
138  if (elem->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this elem
139  {
140  // The zero only works for LAGRANGE!
141  dof_id_type dof = elem->dof_number(sys_num, var_num, 0);
142 
143  swapper.forceSwap();
144  Real from_value = user_object.spatialValue(centroid + _multi_app->position(i));
145  swapper.forceSwap();
146 
147  solution.set(dof, from_value);
148  }
149  }
150  }
151 
152  solution.close();
153  to_sys->update();
154  }
155  }
156 
157  break;
158  }
159  case FROM_MULTIAPP:
160  {
161  FEProblemBase & to_problem = _multi_app->problemBase();
162  MooseVariable & to_var = to_problem.getVariable(0, _to_var_name);
163  SystemBase & to_system_base = to_var.sys();
164 
165  System & to_sys = to_system_base.system();
166 
167  unsigned int to_sys_num = to_sys.number();
168 
169  // Only works with a serialized mesh to transfer to!
170  mooseAssert(to_sys.get_mesh().is_serial(),
171  "MultiAppUserObjectTransfer only works with ReplicatedMesh!");
172 
173  unsigned int to_var_num = to_sys.variable_number(to_var.name());
174 
175  _console << "Transferring to: " << to_var.name() << std::endl;
176 
177  // EquationSystems & to_es = to_sys.get_equation_systems();
178 
179  // Create a serialized version of the solution vector
180  NumericVector<Number> * to_solution = to_sys.solution.get();
181 
182  MeshBase * to_mesh = NULL;
183 
184  if (_displaced_target_mesh && to_problem.getDisplacedProblem())
185  to_mesh = &to_problem.getDisplacedProblem()->mesh().getMesh();
186  else
187  to_mesh = &to_problem.mesh().getMesh();
188 
189  bool is_nodal = to_sys.variable_type(to_var_num).family == LAGRANGE;
190 
191  for (unsigned int i = 0; i < _multi_app->numGlobalApps(); i++)
192  {
193  if (!_multi_app->hasLocalApp(i))
194  continue;
195 
196  Point app_position = _multi_app->position(i);
197  BoundingBox app_box = _multi_app->getBoundingBox(i);
198  const UserObject & user_object = _multi_app->appUserObjectBase(i, _user_object_name);
199 
200  if (is_nodal)
201  {
202  MeshBase::const_node_iterator node_it = to_mesh->nodes_begin();
203  MeshBase::const_node_iterator node_end = to_mesh->nodes_end();
204 
205  for (; node_it != node_end; ++node_it)
206  {
207  Node * node = *node_it;
208 
209  if (node->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this node
210  {
211  // See if this node falls in this bounding box
212  if (app_box.contains_point(*node))
213  {
214  dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0);
215 
216  Real from_value = 0;
217  {
218  Moose::ScopedCommSwapper swapper(_multi_app->comm());
219  from_value = user_object.spatialValue(*node - app_position);
220  }
221 
222  to_solution->set(dof, from_value);
223  }
224  }
225  }
226  }
227  else // Elemental
228  {
229  MeshBase::const_element_iterator elem_it = to_mesh->elements_begin();
230  MeshBase::const_element_iterator elem_end = to_mesh->elements_end();
231 
232  for (; elem_it != elem_end; ++elem_it)
233  {
234  Elem * elem = *elem_it;
235 
236  if (elem->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this elem
237  {
238  Point centroid = elem->centroid();
239 
240  // See if this elem falls in this bounding box
241  if (app_box.contains_point(centroid))
242  {
243  dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, 0);
244 
245  Real from_value = 0;
246  {
247  Moose::ScopedCommSwapper swapper(_multi_app->comm());
248  from_value = user_object.spatialValue(centroid - app_position);
249  }
250 
251  to_solution->set(dof, from_value);
252  }
253  }
254  }
255  }
256  }
257 
258  to_solution->close();
259  to_sys.update();
260 
261  break;
262  }
263  }
264 
265  _console << "Finished MultiAppUserObjectTransfer " << name() << std::endl;
266 }
const std::string & name() const
Get the name of the object.
Definition: MooseObject.h:47
void variableIntegrityCheck(const AuxVariableName &var_name) const
Utility to verify that the vEariable in the destination system exists.
Class for stuff related to variables.
Definition: MooseVariable.h:43
virtual void execute() override
Execute the transfer.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
FEProblemBase & _fe_problem
Definition: Transfer.h:75
void errorIfDistributedMesh(std::string name) const
Generate a unified error message if the underlying libMesh mesh is a DistributedMesh.
Definition: MooseMesh.C:2473
Base class for a system (of equations)
Definition: SystemBase.h:91
std::shared_ptr< MultiApp > _multi_app
The MultiApp this Transfer is transferring data to or from.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
const std::string & name() const
Get the variable name.
virtual std::shared_ptr< DisplacedProblem > getDisplacedProblem()
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:2355
MooseEnum _direction
Whether we&#39;re transferring to or from the MultiApp.
virtual System & system()=0
Get the reference to the libMesh system.
InputParameters validParams< MultiAppUserObjectTransfer >()
InputParameters validParams< MultiAppTransfer >()
Base class for all MultiAppTransfer objects.
virtual MooseMesh & mesh() override
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...
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
static System * find_sys(EquationSystems &es, const std::string &var_name)
Small helper function for finding the system containing the variable.
Definition: Transfer.C:70
MultiAppUserObjectTransfer(const InputParameters &parameters)
SystemBase & sys()
Get the system this variable is part of.
virtual void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
virtual MooseVariable & getVariable(THREAD_ID tid, const std::string &var_name) override
Returns the variable reference for requested variable which may be in any system. ...
Base class for user-specific data.
Definition: UserObject.h:42
virtual Real spatialValue(const Point &) const
Optional interface function for "evaluating" a UserObject at a spatial position.
Definition: UserObject.h:99