https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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"
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
33using namespace libMesh;
34
35void
36assemble_l2(EquationSystems & es, const std::string & system_name)
37{
40 transfer->assembleL2(es, system_name);
41}
42
44
47{
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
83void
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
124void
125MultiAppProjectionTransfer::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
188void
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
493void
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}
registerMooseObject("MooseApp", MultiAppProjectionTransfer)
void assemble_l2(EquationSystems &es, const std::string &system_name)
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual libMesh::EquationSystems & es() override
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...
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 addRelationshipManager(const std::string &name, Moose::RelationshipManagerType rm_type, Moose::RelationshipManagerInputParameterCallback input_parameter_callback=nullptr)
Tells MOOSE about a RelationshipManager that this object needs.
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
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
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.
This class provides an interface for common operations on field variables of both FE and FV types wit...
Transfers variables on possibly different meshes while conserving a user defined property (Postproces...
VariableName _from_var_name
This values are used if a derived class only supports one variable.
const std::vector< VariableName > _from_var_names
Name of variables transferring from.
const std::vector< AuxVariableName > _to_var_names
Name of variables transferring to.
virtual void postExecute()
Add some extra work if necessary after execute().
virtual void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
Project values from one domain to another.
bool _compute_matrix
True, if we need to recompute the projection matrix.
std::map< processor_id_type, std::map< std::pair< unsigned int, unsigned int >, unsigned int > > _cached_index_map
void assembleL2(libMesh::EquationSystems &es, const std::string &system_name)
void projectSolution(unsigned int to_problem)
std::vector< libMesh::LinearImplicitSystem * > _proj_sys
unsigned int _proj_var_num
Having one projection variable number seems weird, but there is always one variable in every system b...
std::map< processor_id_type, std::vector< libMesh::Point > > _cached_qps
virtual void initialSetup() override
Method called at the beginning of the simulation for checking integrity or doing one-time setup.
MultiAppProjectionTransfer(const InputParameters &parameters)
friend void assemble_l2(libMesh::EquationSystems &es, const std::string &system_name)
virtual void execute() override
Execute the transfer.
static InputParameters validParams()
std::vector< unsigned int > _to_local2global_map
Given local app index, returns global app index.
unsigned int getGlobalSourceAppIndex(unsigned int i_from) const
Return the global app index from the local index in the "from-multiapp" transfer direction.
static void addBBoxFactorParam(InputParameters &params)
Add the bounding box factor parameter to the supplied input parameters.
std::vector< FEProblemBase * > _from_problems
std::vector< unsigned int > getFromsPerProc()
Return the number of "from" domains that each processor owns.
std::vector< libMesh::BoundingBox > getFromBoundingBoxes()
Return the bounding boxes of all the "from" domains, including all the domains not local to this proc...
std::vector< FEProblemBase * > _to_problems
std::vector< MooseMesh * > _to_meshes
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.
std::vector< libMesh::EquationSystems * > _to_es
std::vector< std::unique_ptr< MultiAppCoordTransform > > _to_transforms
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
@ FROM_MULTIAPP
Definition Transfer.h:71
static const libMesh::Number OutOfMeshValue
Definition Transfer.h:113
MooseEnum _current_direction
Definition Transfer.h:106
void resize(const unsigned int new_m, const unsigned int new_n)
void resize(const unsigned int n)
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
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
const MeshBase & get_mesh() const
virtual System & add_system(std::string_view system_type, std::string_view name)
const T_sys & get_system(std::string_view name) const
NumericVector< Number > * rhs
std::unique_ptr< FEGenericBase< Real > > build(const unsigned int dim, const FEType &fet)
Order default_quadrature_order() const
const SparseMatrix< Number > & get_system_matrix() const
virtual void solve() override
unsigned int mesh_dimension() const
virtual void set(const numeric_index_type i, const T value)=0
virtual void close()=0
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
processor_id_type n_processors() const
T & set(const std::string &)
const T & get(std::string_view) const
unsigned int n_points() const
virtual void init(const Elem &e, unsigned int p_level=invalid_uint)
std::unique_ptr< NumericVector< Number > > current_local_solution
const FEType & variable_type(const unsigned int i) const
void attach_assemble_function(void fptr(EquationSystems &es, const std::string &name))
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
std::unique_ptr< NumericVector< Number > > solution
virtual void update()
unsigned int variable_number(std::string_view var) const
const DofMap & get_dof_map() const
unsigned int number() const
@ VAR_FIELD_STANDARD
Definition MooseTypes.h:777
@ VAR_ANY
Definition MooseTypes.h:772
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
const unsigned int invalid_uint
uint8_t dof_id_type
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
uint8_t processor_id_type