https://mooseframework.inl.gov
MultiAppProjectionTransfer.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 
11 
12 // MOOSE includes
13 #include "AddVariableAction.h"
14 #include "FEProblem.h"
15 #include "MooseMesh.h"
16 #include "MooseVariableFE.h"
17 #include "SystemBase.h"
18 #include "MooseAppCoordTransform.h"
19 
20 #include "libmesh/dof_map.h"
21 #include "libmesh/linear_implicit_system.h"
22 #include "libmesh/mesh_function.h"
23 #include "libmesh/mesh_tools.h"
24 #include "libmesh/numeric_vector.h"
25 #include "libmesh/parallel_algebra.h"
26 #include "libmesh/quadrature_gauss.h"
27 #include "libmesh/sparse_matrix.h"
28 #include "libmesh/string_to_enum.h"
29 
30 // TIMPI includes
31 #include "timpi/parallel_sync.h"
32 
33 using namespace libMesh;
34 
35 void
36 assemble_l2(EquationSystems & es, const std::string & system_name)
37 {
38  MultiAppProjectionTransfer * transfer =
39  es.parameters.get<MultiAppProjectionTransfer *>("transfer");
40  transfer->assembleL2(es, system_name);
41 }
42 
44 
47 {
49  params.addClassDescription(
50  "Perform a projection between a master and sub-application mesh of a field variable.");
51 
52  MooseEnum proj_type("l2", "l2");
53  params.addParam<MooseEnum>("proj_type", proj_type, "The type of the projection.");
54 
55  params.addParam<bool>("fixed_meshes",
56  false,
57  "Set to true when the meshes are not changing (ie, "
58  "no movement or adaptivity). This will cache some "
59  "information to speed up the transfer.");
60 
61  // Need one layer of ghosting
62  params.addRelationshipManager("ElementSideNeighborLayers",
66  return params;
67 }
68 
70  : MultiAppConservativeTransfer(parameters),
71  _proj_type(getParam<MooseEnum>("proj_type")),
72  _compute_matrix(true),
73  _fixed_meshes(getParam<bool>("fixed_meshes")),
74  _qps_cached(false)
75 {
76  if (_to_var_names.size() != 1)
77  paramError("variable", " Support single to-variable only ");
78 
79  if (_from_var_names.size() != 1)
80  paramError("source_variable", " Support single from-variable only ");
81 }
82 
83 void
85 {
87 
88  _proj_sys.resize(_to_problems.size(), NULL);
89 
90  for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++)
91  {
92  FEProblemBase & to_problem = *_to_problems[i_to];
93  EquationSystems & to_es = to_problem.es();
94 
95  // Add the projection system.
96  FEType fe_type = to_problem
97  .getVariable(0,
101  .feType();
102 
103  LinearImplicitSystem & proj_sys = to_es.add_system<LinearImplicitSystem>("proj-sys-" + name());
104 
105  _proj_var_num = proj_sys.add_variable("var", fe_type);
107  _proj_sys[i_to] = &proj_sys;
108 
109  // Prevent the projection system from being written to checkpoint
110  // files. In the event of a recover or restart, we'll read the checkpoint
111  // before this initialSetup method is called. As a result, we'll find
112  // systems in the checkpoint (the projection systems) that we don't know
113  // what to do with, and there will be a crash. We could fix this by making
114  // the systems in the constructor, except we don't know how many sub apps
115  // there are at the time of construction. So instead, we'll just nuke the
116  // projection system and rebuild it from scratch every recover/restart.
117  proj_sys.hide_output() = true;
118 
119  // Reinitialize EquationSystems since we added a system.
120  to_es.reinit();
121  }
122 }
123 
124 void
125 MultiAppProjectionTransfer::assembleL2(EquationSystems & es, const std::string & system_name)
126 {
127  // Get the system and mesh from the input arguments.
128  LinearImplicitSystem & system = es.get_system<LinearImplicitSystem>(system_name);
129  MeshBase & to_mesh = es.get_mesh();
130 
131  // Get the meshfunction evaluations and the map that was stashed in the es.
132  std::vector<Real> & final_evals = *es.parameters.get<std::vector<Real> *>("final_evals");
133  std::map<dof_id_type, unsigned int> & element_map =
134  *es.parameters.get<std::map<dof_id_type, unsigned int> *>("element_map");
135 
136  // Setup system vectors and matrices.
137  FEType fe_type = system.variable_type(0);
138  std::unique_ptr<FEBase> fe(FEBase::build(to_mesh.mesh_dimension(), fe_type));
139  QGauss qrule(to_mesh.mesh_dimension(), fe_type.default_quadrature_order());
140  fe->attach_quadrature_rule(&qrule);
141  const DofMap & dof_map = system.get_dof_map();
144  std::vector<dof_id_type> dof_indices;
145  const std::vector<Real> & JxW = fe->get_JxW();
146  const std::vector<std::vector<Real>> & phi = fe->get_phi();
147  auto & system_matrix = system.get_system_matrix();
148 
149  for (const auto & elem : to_mesh.active_local_element_ptr_range())
150  {
151  fe->reinit(elem);
152 
153  dof_map.dof_indices(elem, dof_indices);
154  Ke.resize(dof_indices.size(), dof_indices.size());
155  Fe.resize(dof_indices.size());
156 
157  for (unsigned int qp = 0; qp < qrule.n_points(); qp++)
158  {
159  Real meshfun_eval = 0.;
160  if (element_map.find(elem->id()) != element_map.end())
161  {
162  // We have evaluations for this element.
163  meshfun_eval = final_evals[element_map[elem->id()] + qp];
164  }
165 
166  // Now compute the element matrix and RHS contributions.
167  for (unsigned int i = 0; i < phi.size(); i++)
168  {
169  // RHS
170  Fe(i) += JxW[qp] * (meshfun_eval * phi[i][qp]);
171 
172  if (_compute_matrix)
173  for (unsigned int j = 0; j < phi.size(); j++)
174  {
175  // The matrix contribution
176  Ke(i, j) += JxW[qp] * (phi[i][qp] * phi[j][qp]);
177  }
178  }
179  dof_map.constrain_element_matrix_and_vector(Ke, Fe, dof_indices);
180 
181  if (_compute_matrix)
182  system_matrix.add_matrix(Ke, dof_indices);
183  system.rhs->add_vector(Fe, dof_indices);
184  }
185  }
186 }
187 
188 void
190 {
191  TIME_SECTION(
192  "MultiAppProjectionTransfer::execute()", 5, "Transferring variables through projection");
193 
195  // We are going to project the solutions by solving some linear systems. In
196  // order to assemble the systems, we need to evaluate the "from" domain
197  // solutions at quadrature points in the "to" domain. Some parallel
198  // communication is necessary because each processor doesn't necessarily have
199  // all the "from" information it needs to set its "to" values. We don't want
200  // to use a bunch of big all-to-all broadcasts, so we'll use bounding boxes to
201  // figure out which processors have the information we need and only
202  // communicate with those processors.
203  //
204  // Each processor will
205  // 1. Check its local quadrature points in the "to" domains to see which
206  // "from" domains they might be in.
207  // 2. Send quadrature points to the processors with "from" domains that might
208  // contain those points.
209  // 3. Recieve quadrature points from other processors, evaluate its mesh
210  // functions at those points, and send the values back to the proper
211  // processor
212  // 4. Recieve mesh function evaluations from all relevant processors and
213  // decide which one to use at every quadrature point (the lowest global app
214  // index always wins)
215  // 5. And use the mesh function evaluations to assemble and solve an L2
216  // projection system on its local elements.
218 
220  // For every combination of global "from" problem and local "to" problem, find
221  // which "from" bounding boxes overlap with which "to" elements. Keep track
222  // of which processors own bounding boxes that overlap with which elements.
223  // Build vectors of quadrature points to send to other processors for mesh
224  // function evaluations.
226 
227  // Get the bounding boxes for the "from" domains.
228  std::vector<BoundingBox> bboxes = getFromBoundingBoxes();
229 
230  // Figure out how many "from" domains each processor owns.
231  std::vector<unsigned int> froms_per_proc = getFromsPerProc();
232 
233  std::map<processor_id_type, std::vector<Point>> outgoing_qps;
234  std::map<processor_id_type, std::map<std::pair<unsigned int, unsigned int>, unsigned int>>
235  element_index_map;
236  // element_index_map[i_to, element_id] = index
237  // outgoing_qps[index] is the first quadrature point in element
238 
239  if (!_qps_cached)
240  {
241  for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++)
242  {
243  // Indexing into the coordinate transforms vector
244  const auto to_global_num =
246  MeshBase & to_mesh = _to_meshes[i_to]->getMesh();
247 
248  LinearImplicitSystem & system = *_proj_sys[i_to];
249 
250  FEType fe_type = system.variable_type(0);
251  std::unique_ptr<FEBase> fe(FEBase::build(to_mesh.mesh_dimension(), fe_type));
252  QGauss qrule(to_mesh.mesh_dimension(), fe_type.default_quadrature_order());
253  fe->attach_quadrature_rule(&qrule);
254  const std::vector<Point> & xyz = fe->get_xyz();
255 
256  unsigned int from0 = 0;
257  for (processor_id_type i_proc = 0; i_proc < n_processors();
258  from0 += froms_per_proc[i_proc], i_proc++)
259  {
260  for (const auto & elem :
261  as_range(to_mesh.local_elements_begin(), to_mesh.local_elements_end()))
262  {
263  fe->reinit(elem);
264 
265  bool qp_hit = false;
266  for (unsigned int i_from = 0; i_from < froms_per_proc[i_proc] && !qp_hit; i_from++)
267  {
268  for (unsigned int qp = 0; qp < qrule.n_points() && !qp_hit; qp++)
269  {
270  Point qpt = xyz[qp];
271  if (bboxes[from0 + i_from].contains_point((*_to_transforms[to_global_num])(qpt)))
272  qp_hit = true;
273  }
274  }
275 
276  if (qp_hit)
277  {
278  // The selected processor's bounding box contains at least one
279  // quadrature point from this element. Send all qps from this element
280  // and remember where they are in the array using the map.
281  std::pair<unsigned int, unsigned int> key(i_to, elem->id());
282  element_index_map[i_proc][key] = outgoing_qps[i_proc].size();
283  for (unsigned int qp = 0; qp < qrule.n_points(); qp++)
284  {
285  Point qpt = xyz[qp];
286  outgoing_qps[i_proc].push_back((*_to_transforms[to_global_num])(qpt));
287  }
288  }
289  }
290  }
291  }
292 
293  if (_fixed_meshes)
294  _cached_index_map = element_index_map;
295  }
296  else
297  {
298  element_index_map = _cached_index_map;
299  }
300 
302  // Request quadrature point evaluations from other processors and handle
303  // requests sent to this processor.
305 
306  // Get the local bounding boxes.
307  std::vector<BoundingBox> local_bboxes(froms_per_proc[processor_id()]);
308  {
309  // Find the index to the first of this processor's local bounding boxes.
310  unsigned int local_start = 0;
311  for (processor_id_type i_proc = 0; i_proc < n_processors() && i_proc != processor_id();
312  i_proc++)
313  local_start += froms_per_proc[i_proc];
314 
315  // Extract the local bounding boxes.
316  for (unsigned int i_from = 0; i_from < froms_per_proc[processor_id()]; i_from++)
317  local_bboxes[i_from] = bboxes[local_start + i_from];
318  }
319 
320  // Setup the local mesh functions.
321  std::vector<MeshFunction> local_meshfuns;
322  for (unsigned int i_from = 0; i_from < _from_problems.size(); i_from++)
323  {
324  FEProblemBase & from_problem = *_from_problems[i_from];
325  MooseVariableFEBase & from_var = from_problem.getVariable(
327  System & from_sys = from_var.sys().system();
328  unsigned int from_var_num = from_sys.variable_number(from_var.name());
329 
330  local_meshfuns.emplace_back(
331  from_problem.es(), *from_sys.current_local_solution, from_sys.get_dof_map(), from_var_num);
332  local_meshfuns.back().init();
333  local_meshfuns.back().enable_out_of_mesh_mode(OutOfMeshValue);
334  }
335 
336  // Recieve quadrature points from other processors, evaluate mesh frunctions
337  // at those points, and send the values back.
338  std::map<processor_id_type, std::vector<std::pair<Real, unsigned int>>> outgoing_evals_ids;
339 
340  // If there is no cached data, we need to do communication
341  // Quadrature points I will receive from remote processors
342  std::map<processor_id_type, std::vector<Point>> incoming_qps;
343  if (!_qps_cached)
344  {
345  auto qps_action_functor = [&incoming_qps](processor_id_type pid, const std::vector<Point> & qps)
346  {
347  // Quadrature points from processor 'pid'
348  auto & incoming_qps_from_pid = incoming_qps[pid];
349  // Store data for late use
350  incoming_qps_from_pid.reserve(incoming_qps_from_pid.size() + qps.size());
351  std::copy(qps.begin(), qps.end(), std::back_inserter(incoming_qps_from_pid));
352  };
353 
354  Parallel::push_parallel_vector_data(comm(), outgoing_qps, qps_action_functor);
355  }
356 
357  // Cache data
358  if (!_qps_cached)
359  _cached_qps = incoming_qps;
360 
361  for (auto & qps : _cached_qps)
362  {
363  const processor_id_type pid = qps.first;
364 
365  outgoing_evals_ids[pid].resize(qps.second.size(),
366  std::make_pair(OutOfMeshValue, libMesh::invalid_uint));
367 
368  for (unsigned int qp = 0; qp < qps.second.size(); qp++)
369  {
370  Point qpt = qps.second[qp];
371 
372  // Loop until we've found the lowest-ranked app that actually contains
373  // the quadrature point.
374  for (unsigned int i_from = 0; i_from < _from_problems.size(); i_from++)
375  {
376  if (local_bboxes[i_from].contains_point(qpt))
377  {
378  const auto from_global_num =
380  outgoing_evals_ids[pid][qp].first =
381  (local_meshfuns[i_from])(_from_transforms[from_global_num]->mapBack(qpt));
383  outgoing_evals_ids[pid][qp].second = from_global_num;
384  }
385  }
386  }
387  }
388 
390  // Gather all of the qp evaluations and pick out the best ones for each qp.
392 
393  // Values back from remote processors for my local quadrature points
394  std::map<processor_id_type, std::vector<std::pair<Real, unsigned int>>> incoming_evals_ids;
395 
396  auto evals_action_functor =
397  [&incoming_evals_ids](processor_id_type pid,
398  const std::vector<std::pair<Real, unsigned int>> & evals)
399  {
400  // evals for processor 'pid'
401  auto & incoming_evals_ids_for_pid = incoming_evals_ids[pid];
402  // Copy evals for late use
403  incoming_evals_ids_for_pid.reserve(incoming_evals_ids_for_pid.size() + evals.size());
404  std::copy(evals.begin(), evals.end(), std::back_inserter(incoming_evals_ids_for_pid));
405  };
406 
407  Parallel::push_parallel_vector_data(comm(), outgoing_evals_ids, evals_action_functor);
408 
409  std::vector<std::vector<Real>> final_evals(_to_problems.size());
410  std::vector<std::map<dof_id_type, unsigned int>> trimmed_element_maps(_to_problems.size());
411 
412  for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++)
413  {
414  MeshBase & to_mesh = _to_meshes[i_to]->getMesh();
415  LinearImplicitSystem & system = *_proj_sys[i_to];
416 
417  FEType fe_type = system.variable_type(0);
418  std::unique_ptr<FEBase> fe(FEBase::build(to_mesh.mesh_dimension(), fe_type));
419  QGauss qrule(to_mesh.mesh_dimension(), fe_type.default_quadrature_order());
420 
421  for (const auto & elem : to_mesh.active_local_element_ptr_range())
422  {
423  qrule.init(*elem);
424 
425  bool element_is_evaled = false;
426  std::vector<Real> evals(qrule.n_points(), 0.);
427 
428  for (unsigned int qp = 0; qp < qrule.n_points(); qp++)
429  {
430  unsigned int lowest_app_rank = libMesh::invalid_uint;
431  for (auto & values_ids : incoming_evals_ids)
432  {
433  // Current processor id
434  const processor_id_type pid = values_ids.first;
435 
436  // Ignore the selected processor if the element wasn't found in it's
437  // bounding box.
438  std::map<std::pair<unsigned int, unsigned int>, unsigned int> & map =
439  element_index_map[pid];
440  std::pair<unsigned int, unsigned int> key(i_to, elem->id());
441  if (map.find(key) == map.end())
442  continue;
443  unsigned int qp0 = map[key];
444 
445  // Ignore the selected processor if it's app has a higher rank than the
446  // previously found lowest app rank.
448  if (values_ids.second[qp0 + qp].second >= lowest_app_rank)
449  continue;
450 
451  // Ignore the selected processor if the qp was actually outside the
452  // processor's subapp's mesh.
453  if (values_ids.second[qp0 + qp].first == OutOfMeshValue)
454  continue;
455 
456  // This is the best meshfunction evaluation so far, save it.
457  element_is_evaled = true;
458  evals[qp] = values_ids.second[qp0 + qp].first;
459  }
460  }
461 
462  // If we found good evaluations for any of the qps in this element, save
463  // those evaluations for later.
464  if (element_is_evaled)
465  {
466  trimmed_element_maps[i_to][elem->id()] = final_evals[i_to].size();
467  for (unsigned int qp = 0; qp < qrule.n_points(); qp++)
468  final_evals[i_to].push_back(evals[qp]);
469  }
470  }
471  }
472 
474  // We now have just one or zero mesh function values at all of our local
475  // quadrature points. Stash those values (and a map linking them to element
476  // ids) in the equation systems parameters and project the solution.
478 
479  for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++)
480  {
481  _to_es[i_to]->parameters.set<std::vector<Real> *>("final_evals") = &final_evals[i_to];
482  _to_es[i_to]->parameters.set<std::map<dof_id_type, unsigned int> *>("element_map") =
483  &trimmed_element_maps[i_to];
484  projectSolution(i_to);
485  _to_es[i_to]->parameters.set<std::vector<Real> *>("final_evals") = NULL;
486  _to_es[i_to]->parameters.set<std::map<dof_id_type, unsigned int> *>("element_map") = NULL;
487  }
488 
489  if (_fixed_meshes)
490  _qps_cached = true;
491 
492  postExecute();
493 }
494 
495 void
497 {
498  FEProblemBase & to_problem = *_to_problems[i_to];
499  EquationSystems & proj_es = to_problem.es();
500  LinearImplicitSystem & ls = *_proj_sys[i_to];
501  // activate the current transfer
502  proj_es.parameters.set<MultiAppProjectionTransfer *>("transfer") = this;
503 
504  // TODO: specify solver params in an input file
505  // solver tolerance
506  Real tol = proj_es.parameters.get<Real>("linear solver tolerance");
507  proj_es.parameters.set<Real>("linear solver tolerance") = 1e-10; // set our tolerance
508  // solve it
509  ls.solve();
510  proj_es.parameters.set<Real>("linear solver tolerance") = tol; // restore the original tolerance
511 
512  // copy projected solution into target es
513  MeshBase & to_mesh = proj_es.get_mesh();
514 
515  MooseVariableFEBase & to_var = to_problem.getVariable(
517  System & to_sys = to_var.sys().system();
518  NumericVector<Number> * to_solution = to_sys.solution.get();
519 
520  for (const auto & node : to_mesh.local_node_ptr_range())
521  {
522  for (unsigned int comp = 0; comp < node->n_comp(to_sys.number(), to_var.number()); comp++)
523  {
524  const dof_id_type proj_index = node->dof_number(ls.number(), _proj_var_num, comp);
525  const dof_id_type to_index = node->dof_number(to_sys.number(), to_var.number(), comp);
526  to_solution->set(to_index, (*ls.solution)(proj_index));
527  }
528  }
529  for (const auto & elem : to_mesh.active_local_element_ptr_range())
530  for (unsigned int comp = 0; comp < elem->n_comp(to_sys.number(), to_var.number()); comp++)
531  {
532  const dof_id_type proj_index = elem->dof_number(ls.number(), _proj_var_num, comp);
533  const dof_id_type to_index = elem->dof_number(to_sys.number(), to_var.number(), comp);
534  to_solution->set(to_index, (*ls.solution)(proj_index));
535  }
536 
537  to_solution->close();
538  to_sys.update();
539 }
std::vector< std::unique_ptr< MultiAppCoordTransform > > _to_transforms
void assemble_l2(EquationSystems &es, const std::string &system_name)
std::unique_ptr< FEGenericBase< Real > > build(const unsigned int dim, const FEType &fet)
std::vector< libMesh::EquationSystems * > _to_es
const libMesh::FEType & feType() const
Get the type of finite element object.
const unsigned int invalid_uint
MooseEnum _current_direction
Definition: Transfer.h:106
void constrain_element_matrix_and_vector(DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
unsigned int number() const
Get variable number coming from libMesh.
std::map< processor_id_type, std::map< std::pair< unsigned int, unsigned int >, unsigned int > > _cached_index_map
void resize(const unsigned int n)
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
std::vector< libMesh::BoundingBox > getFromBoundingBoxes()
Return the bounding boxes of all the "from" domains, including all the domains not local to this proc...
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
const std::vector< VariableName > _from_var_names
Name of variables transferring from.
std::vector< FEProblemBase * > _to_problems
const std::string & name() const override
Get the variable name.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
NumericVector< Number > * rhs
const Parallel::Communicator & comm() const
Order default_quadrature_order() const
virtual void postExecute()
Add some extra work if necessary after execute().
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...
void addRelationshipManager(const std::string &name, Moose::RelationshipManagerType rm_type, Moose::RelationshipManagerInputParameterCallback input_parameter_callback=nullptr)
Tells MOOSE about a RelationshipManager that this object needs.
virtual void solve() override
const T_sys & get_system(std::string_view name) const
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:57
registerMooseObject("MooseApp", MultiAppProjectionTransfer)
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...
std::vector< unsigned int > _to_local2global_map
Given local app index, returns global app index.
unsigned int variable_number(std::string_view var) const
void assembleL2(libMesh::EquationSystems &es, const std::string &system_name)
virtual void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
uint8_t processor_id_type
processor_id_type n_processors() const
unsigned int number() const
const T & get(std::string_view) const
Project values from one domain to another.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
bool _compute_matrix
True, if we need to recompute the projection matrix.
virtual libMesh::EquationSystems & es() override
const std::vector< AuxVariableName > _to_var_names
Name of variables transferring to.
std::unique_ptr< NumericVector< Number > > solution
std::vector< unsigned int > getFromsPerProc()
Return the number of "from" domains that each processor owns.
Transfers variables on possibly different meshes while conserving a user defined property (Postproces...
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
static InputParameters validParams()
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
virtual void execute() override
Execute the transfer.
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 ...
void attach_assemble_function(void fptr(EquationSystems &es, const std::string &name))
static const libMesh::Number OutOfMeshValue
Definition: Transfer.h:113
std::map< processor_id_type, std::vector< libMesh::Point > > _cached_qps
virtual void close()=0
MultiAppProjectionTransfer(const InputParameters &parameters)
virtual void update()
const FEType & variable_type(const unsigned int i) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
T & set(const std::string &)
const MeshBase & get_mesh() const
void resize(const unsigned int new_m, const unsigned int new_n)
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
unsigned int mesh_dimension() const
virtual void init(const Elem &e, unsigned int p_level=invalid_uint)
std::vector< unsigned int > _from_local2global_map
Given local app index, returns global app index.
std::unique_ptr< NumericVector< Number > > current_local_solution
static void addBBoxFactorParam(InputParameters &params)
Add the bounding box factor parameter to the supplied input parameters.
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...
void projectSolution(unsigned int to_problem)
friend void assemble_l2(libMesh::EquationSystems &es, const std::string &system_name)
virtual void set(const numeric_index_type i, const T value)=0
virtual void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup...
unsigned int _proj_var_num
Having one projection variable number seems weird, but there is always one variable in every system b...
virtual System & add_system(std::string_view system_type, std::string_view name)
processor_id_type processor_id() const
SystemBase & sys()
Get the system this variable is part of.
std::vector< libMesh::LinearImplicitSystem * > _proj_sys
const DofMap & get_dof_map() const
const SparseMatrix< Number > & get_system_matrix() const
std::vector< FEProblemBase * > _from_problems
std::vector< MooseMesh * > _to_meshes
uint8_t dof_id_type
VariableName _from_var_name
This values are used if a derived class only supports one variable.