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  outgoing_evals_ids[pid][qp].first = (local_meshfuns[i_from])(
379  getPointInSourceAppFrame(qpt, i_from, "Projection transfer evaluation"));
381  outgoing_evals_ids[pid][qp].second = getGlobalSourceAppIndex(i_from);
382  }
383  }
384  }
385  }
386 
388  // Gather all of the qp evaluations and pick out the best ones for each qp.
390 
391  // Values back from remote processors for my local quadrature points
392  std::map<processor_id_type, std::vector<std::pair<Real, unsigned int>>> incoming_evals_ids;
393 
394  auto evals_action_functor =
395  [&incoming_evals_ids](processor_id_type pid,
396  const std::vector<std::pair<Real, unsigned int>> & evals)
397  {
398  // evals for processor 'pid'
399  auto & incoming_evals_ids_for_pid = incoming_evals_ids[pid];
400  // Copy evals for late use
401  incoming_evals_ids_for_pid.reserve(incoming_evals_ids_for_pid.size() + evals.size());
402  std::copy(evals.begin(), evals.end(), std::back_inserter(incoming_evals_ids_for_pid));
403  };
404 
405  Parallel::push_parallel_vector_data(comm(), outgoing_evals_ids, evals_action_functor);
406 
407  std::vector<std::vector<Real>> final_evals(_to_problems.size());
408  std::vector<std::map<dof_id_type, unsigned int>> trimmed_element_maps(_to_problems.size());
409 
410  for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++)
411  {
412  MeshBase & to_mesh = _to_meshes[i_to]->getMesh();
413  LinearImplicitSystem & system = *_proj_sys[i_to];
414 
415  FEType fe_type = system.variable_type(0);
416  std::unique_ptr<FEBase> fe(FEBase::build(to_mesh.mesh_dimension(), fe_type));
417  QGauss qrule(to_mesh.mesh_dimension(), fe_type.default_quadrature_order());
418 
419  for (const auto & elem : to_mesh.active_local_element_ptr_range())
420  {
421  qrule.init(*elem);
422 
423  bool element_is_evaled = false;
424  std::vector<Real> evals(qrule.n_points(), 0.);
425 
426  for (unsigned int qp = 0; qp < qrule.n_points(); qp++)
427  {
428  unsigned int lowest_app_rank = libMesh::invalid_uint;
429  for (auto & values_ids : incoming_evals_ids)
430  {
431  // Current processor id
432  const processor_id_type pid = values_ids.first;
433 
434  // Ignore the selected processor if the element wasn't found in it's
435  // bounding box.
436  std::map<std::pair<unsigned int, unsigned int>, unsigned int> & map =
437  element_index_map[pid];
438  std::pair<unsigned int, unsigned int> key(i_to, elem->id());
439  if (map.find(key) == map.end())
440  continue;
441  unsigned int qp0 = map[key];
442 
443  // Ignore the selected processor if it's app has a higher rank than the
444  // previously found lowest app rank.
446  if (values_ids.second[qp0 + qp].second >= lowest_app_rank)
447  continue;
448 
449  // Ignore the selected processor if the qp was actually outside the
450  // processor's subapp's mesh.
451  if (values_ids.second[qp0 + qp].first == OutOfMeshValue)
452  continue;
453 
454  // This is the best meshfunction evaluation so far, save it.
455  element_is_evaled = true;
456  evals[qp] = values_ids.second[qp0 + qp].first;
457  }
458  }
459 
460  // If we found good evaluations for any of the qps in this element, save
461  // those evaluations for later.
462  if (element_is_evaled)
463  {
464  trimmed_element_maps[i_to][elem->id()] = final_evals[i_to].size();
465  for (unsigned int qp = 0; qp < qrule.n_points(); qp++)
466  final_evals[i_to].push_back(evals[qp]);
467  }
468  }
469  }
470 
472  // We now have just one or zero mesh function values at all of our local
473  // quadrature points. Stash those values (and a map linking them to element
474  // ids) in the equation systems parameters and project the solution.
476 
477  for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++)
478  {
479  _to_es[i_to]->parameters.set<std::vector<Real> *>("final_evals") = &final_evals[i_to];
480  _to_es[i_to]->parameters.set<std::map<dof_id_type, unsigned int> *>("element_map") =
481  &trimmed_element_maps[i_to];
482  projectSolution(i_to);
483  _to_es[i_to]->parameters.set<std::vector<Real> *>("final_evals") = NULL;
484  _to_es[i_to]->parameters.set<std::map<dof_id_type, unsigned int> *>("element_map") = NULL;
485  }
486 
487  if (_fixed_meshes)
488  _qps_cached = true;
489 
490  postExecute();
491 }
492 
493 void
495 {
496  FEProblemBase & to_problem = *_to_problems[i_to];
497  EquationSystems & proj_es = to_problem.es();
498  LinearImplicitSystem & ls = *_proj_sys[i_to];
499  // activate the current transfer
500  proj_es.parameters.set<MultiAppProjectionTransfer *>("transfer") = this;
501 
502  // TODO: specify solver params in an input file
503  // solver tolerance
504  Real tol = proj_es.parameters.get<Real>("linear solver tolerance");
505  proj_es.parameters.set<Real>("linear solver tolerance") = 1e-10; // set our tolerance
506  // solve it
507  ls.solve();
508  proj_es.parameters.set<Real>("linear solver tolerance") = tol; // restore the original tolerance
509 
510  // copy projected solution into target es
511  MeshBase & to_mesh = proj_es.get_mesh();
512 
513  MooseVariableFEBase & to_var = to_problem.getVariable(
515  System & to_sys = to_var.sys().system();
516  NumericVector<Number> * to_solution = to_sys.solution.get();
517 
518  for (const auto & node : to_mesh.local_node_ptr_range())
519  {
520  for (unsigned int comp = 0; comp < node->n_comp(to_sys.number(), to_var.number()); comp++)
521  {
522  const dof_id_type proj_index = node->dof_number(ls.number(), _proj_var_num, comp);
523  const dof_id_type to_index = node->dof_number(to_sys.number(), to_var.number(), comp);
524  to_solution->set(to_index, (*ls.solution)(proj_index));
525  }
526  }
527  for (const auto & elem : to_mesh.active_local_element_ptr_range())
528  for (unsigned int comp = 0; comp < elem->n_comp(to_sys.number(), to_var.number()); comp++)
529  {
530  const dof_id_type proj_index = elem->dof_number(ls.number(), _proj_var_num, comp);
531  const dof_id_type to_index = elem->dof_number(to_sys.number(), to_var.number(), comp);
532  to_solution->set(to_index, (*ls.solution)(proj_index));
533  }
534 
535  to_solution->close();
536  to_sys.update();
537 }
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
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:467
MooseEnum _current_direction
Definition: Transfer.h:106
Point getPointInSourceAppFrame(const Point &p, unsigned int local_i_from, const std::string &phase) const
Get the source app point from a point in the reference frame.
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
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.
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 std::string & name() const
Get the name of the class.
Definition: MooseBase.h:103
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:54
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.
unsigned int getGlobalSourceAppIndex(unsigned int i_from) const
Return the global app index from the local index in the "from-multiapp" transfer direction.
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)
unsigned int mesh_dimension() const
virtual void init(const Elem &e, unsigned int p_level=invalid_uint)
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.