https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MultiAppGeometricInterpolationTransfer.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 "DisplacedProblem.h"
14#include "FEProblem.h"
15#include "MooseMesh.h"
16#include "MooseTypes.h"
17#include "MooseVariableFE.h"
18#include "MultiApp.h"
20
21#include "libmesh/parallel_algebra.h"
22#include "libmesh/meshfree_interpolation.h"
23#include "libmesh/system.h"
24#include "libmesh/radial_basis_interpolation.h"
25
26using namespace libMesh;
27
30 MultiAppInterpolationTransfer,
31 "12/31/2023 24:00",
33
36{
39 "Transfers the value to the target domain from a combination/interpolation of the values on "
40 "the nearest nodes in the source domain, using coefficients based on the distance to each "
41 "node.");
42 params.addParam<unsigned int>(
43 "num_points", 3, "The number of nearest points to use for interpolation.");
44 params.addParam<Real>(
45 "power", 2, "The polynomial power to use for calculation of the decay in the interpolation.");
46
47 MooseEnum interp_type("inverse_distance radial_basis", "inverse_distance");
48 params.addParam<MooseEnum>("interp_type", interp_type, "The algorithm to use for interpolation.");
49
50 params.addParam<Real>("radius",
51 -1,
52 "Radius to use for radial_basis interpolation. If negative "
53 "then the radius is taken as the max distance between "
54 "points.");
55 params.addParam<Real>(
56 "shrink_gap_width",
57 0,
58 "gap width with which we want to temporarily shrink mesh in transfering solution");
59
60 MooseEnum shrink_type("SOURCE TARGET", "SOURCE");
61 params.addParam<MooseEnum>("shrink_mesh", shrink_type, "Which mesh we want to shrink");
62
63 params.addParam<std::vector<SubdomainName>>(
64 "exclude_gap_blocks",
65 {},
66 "Gap subdomains we want to exclude when constructing/using virtually translated points");
67
68 params.addParam<Real>("distance_tol",
69 1e-10,
70 "If the distance between two points is smaller than distance_tol, two "
71 "points will be considered as identical");
72
73 return params;
74}
75
77 const InputParameters & parameters)
78 : MultiAppConservativeTransfer(parameters),
79 _num_points(getParam<unsigned int>("num_points")),
80 _power(getParam<Real>("power")),
81 _interp_type(getParam<MooseEnum>("interp_type")),
82 _radius(getParam<Real>("radius")),
83 _shrink_gap_width(getParam<Real>("shrink_gap_width")),
84 _shrink_mesh(getParam<MooseEnum>("shrink_mesh")),
85 _exclude_gap_blocks(getParam<std::vector<SubdomainName>>("exclude_gap_blocks")),
86 _distance_tol(getParam<Real>("distance_tol"))
87{
88 // This transfer does not work with DistributedMesh
89 _fe_problem.mesh().errorIfDistributedMesh("MultiAppGeometricInterpolationTransfer");
90
91 if (_to_var_names.size() != 1)
92 paramError("variable", " Support single to-variable only ");
93
94 if (_from_var_names.size() != 1)
95 paramError("source_variable", " Support single from-variable only ");
96}
97
98void
100 const Node & node,
101 std::set<subdomain_id_type> & subdomainids)
102{
103 // We need this map to figure out to which subdomains a given mesh point is attached
104 // We can not make mesh const here because we may need to create a node-to-elems map
105 // if it does not exists
106 auto & node_to_elem = mesh.nodeToElemMap();
107 auto node_to_elem_pair = node_to_elem.find(node.id());
108
109 if (node_to_elem_pair == node_to_elem.end())
110 mooseError("Can not find elements for node ", node.id());
111
112 subdomainids.clear();
113 // Add all subdomain IDs that are attached to node
114 for (auto element : node_to_elem_pair->second)
115 {
116 auto & elem = mesh.getMesh().elem_ref(element);
117 auto subdomain = elem.subdomain_id();
118
119 subdomainids.insert(subdomain);
120 }
121}
122
123void
125 FEProblemBase & from_problem,
126 const MooseVariableFieldBase & from_var,
127 const MultiAppCoordTransform & from_app_transform,
128 std::unique_ptr<InverseDistanceInterpolation<LIBMESH_DIM>> & idi)
129{
130 auto & from_moose_mesh = from_problem.mesh(_displaced_source_mesh);
131 const auto & from_mesh = from_moose_mesh.getMesh();
132
133 // Moose system
134 const SystemBase & from_system_base = from_var.sys();
135 // libmesh system
136 const System & from_sys = from_system_base.system();
137
138 // System number and var number
139 auto from_sys_num = from_sys.number();
140 auto from_var_num = from_sys.variable_number(from_var.name());
141
142 // Check FE type so we can figure out how to sample points
143 const auto & fe_type = from_sys.variable_type(from_var_num);
144 bool from_is_constant = fe_type.order == CONSTANT;
145 bool from_is_nodal = fe_type.family == LAGRANGE;
146
147 // Currently, for an elemental variable, we support the constant and first order
148 if (fe_type.order > FIRST && !from_is_nodal)
149 mooseError("We don't currently support second order or higher elemental variable ");
150
151 // Containers for points and values
152 // We later will push data into these containers
153 std::vector<Point> & src_pts(idi->get_source_points());
154 std::vector<Number> & src_vals(idi->get_source_vals());
155
156 // How much we want to translate mesh if users ask
157 std::unordered_map<dof_id_type, Point> from_tranforms;
158 std::set<subdomain_id_type> exclude_block_ids;
159 if (_shrink_gap_width > 0 && _shrink_mesh == "source")
160 {
161 computeTransformation(from_moose_mesh, from_tranforms);
162 auto exclude_subdomainids = from_moose_mesh.getSubdomainIDs(_exclude_gap_blocks);
163 exclude_block_ids.insert(exclude_subdomainids.begin(), exclude_subdomainids.end());
164 }
165
166 // The solution from the system with which the from_var is associated
167 const NumericVector<Number> & from_solution = *from_sys.solution;
168
169 std::set<subdomain_id_type> subdomainids;
170 std::vector<subdomain_id_type> include_block_ids;
171 if (from_is_nodal)
172 {
173 for (const auto * const from_node : from_mesh.local_node_ptr_range())
174 {
175 // Assuming LAGRANGE!
176 if (from_node->n_comp(from_sys_num, from_var_num) == 0)
177 continue;
178
179 Point translate(0);
180
181 if (from_tranforms.size() > 0)
182 {
183 subdomainIDsNode(const_cast<MooseMesh &>(from_moose_mesh), *from_node, subdomainids);
184 // Check if node is excluded
185 // Node will be excluded if it is in the interior of excluded subdomains
186 include_block_ids.clear();
187 include_block_ids.resize(std::max(subdomainids.size(), exclude_block_ids.size()));
188 auto it = std::set_difference(subdomainids.begin(),
189 subdomainids.end(),
190 exclude_block_ids.begin(),
191 exclude_block_ids.end(),
192 include_block_ids.begin());
193
194 include_block_ids.resize(it - include_block_ids.begin());
195 // Node is not excluded
196 if (include_block_ids.size())
197 translate = from_tranforms[*include_block_ids.begin()];
198 else
199 continue;
200 }
201
202 // Push value and point to KDTree
203 dof_id_type from_dof = from_node->dof_number(from_sys_num, from_var_num, 0);
204 src_vals.push_back(from_solution(from_dof));
205 src_pts.push_back(from_app_transform(*from_node) + translate);
206 }
207 }
208 else
209 {
210 std::vector<Point> points;
211 for (const auto * const from_elem :
212 as_range(from_mesh.local_elements_begin(), from_mesh.local_elements_end()))
213 {
214 // Skip this element if the variable has no dofs at it.
215 if (from_elem->n_dofs(from_sys_num, from_var_num) < 1)
216 continue;
217
218 points.clear();
219 if (from_is_constant)
220 points.push_back(from_elem->vertex_average());
221 else
222 for (const auto & node : from_elem->node_ref_range())
223 points.push_back(node);
224
225 unsigned int n_comp = from_elem->n_comp(from_sys_num, from_var_num);
226 auto n_points = points.size();
227 // We assume each point corresponds to one component of elemental variable
228 if (n_points != n_comp)
229 mooseError(" Number of points ",
230 n_points,
231 " does not equal to number of variable components ",
232 n_comp);
233
234 unsigned int offset = 0;
235
236 Point translate(0);
237
238 if (from_tranforms.size() > 0)
239 {
240 auto subdomain = from_elem->subdomain_id();
241
242 if (subdomain == Moose::INVALID_BLOCK_ID)
243 mooseError("subdomain id does not make sense", subdomain);
244
245 // subdomain is not excluded
246 if (exclude_block_ids.find(subdomain) == exclude_block_ids.end())
247 translate = from_tranforms[subdomain];
248 else
249 continue;
250 }
251
252 for (const auto & point : points)
253 {
254 dof_id_type from_dof = from_elem->dof_number(from_sys_num, from_var_num, offset++);
255 src_vals.push_back(from_solution(from_dof));
256 src_pts.push_back(from_app_transform(point) + translate);
257 }
258 }
259 }
260}
261
262void
264 FEProblemBase & to_problem,
265 MooseVariableFieldBase & to_var,
266 NumericVector<Real> & to_solution,
267 const MultiAppCoordTransform & to_app_transform,
268 const std::unique_ptr<InverseDistanceInterpolation<LIBMESH_DIM>> & idi)
269{
270 // Moose system
271 SystemBase & to_system_base = to_var.sys();
272 // libmesh system
273 System & to_sys = to_system_base.system();
274
275 // System number and var number
276 auto to_sys_num = to_sys.number();
277 auto to_var_num = to_sys.variable_number(to_var.name());
278
279 const MooseMesh & to_moose_mesh = to_problem.mesh(_displaced_target_mesh);
280 const MeshBase & to_mesh = to_moose_mesh.getMesh();
281
282 // Compute transform info
283 std::unordered_map<dof_id_type, Point> to_tranforms;
284 std::set<subdomain_id_type> exclude_block_ids;
285 if (_shrink_gap_width > 0 && _shrink_mesh == "target")
286 {
287 computeTransformation(to_moose_mesh, to_tranforms);
288 auto exclude_subdomainids = to_moose_mesh.getSubdomainIDs(_exclude_gap_blocks);
289 exclude_block_ids.insert(exclude_subdomainids.begin(), exclude_subdomainids.end());
290 }
291
292 const auto & to_fe_type = to_sys.variable_type(to_var_num);
293 bool to_is_constant = to_fe_type.order == CONSTANT;
294 bool to_is_nodal = to_fe_type.family == LAGRANGE;
295
296 if (to_fe_type.order > FIRST && !to_is_nodal)
297 mooseError("We don't currently support second order or higher elemental variable ");
298
299 std::set<subdomain_id_type> subdomainids;
300 std::vector<subdomain_id_type> include_block_ids;
301 std::vector<Point> pts;
302 std::vector<Number> vals;
303 if (to_is_nodal)
304 {
305 for (const auto * const node : to_mesh.local_node_ptr_range())
306 {
307 if (node->n_dofs(to_sys_num, to_var_num) <= 0) // If this variable has dofs at this node
308 continue;
309
310 Point translate(0);
311 if (to_tranforms.size() > 0)
312 {
313 subdomainIDsNode(const_cast<MooseMesh &>(to_moose_mesh), *node, subdomainids);
314 // Check if node is excluded
315 // Node will be excluded if it is in the interior of excluded subdomains
316 include_block_ids.clear();
317 include_block_ids.resize(std::max(subdomainids.size(), exclude_block_ids.size()));
318 auto it = std::set_difference(subdomainids.begin(),
319 subdomainids.end(),
320 exclude_block_ids.begin(),
321 exclude_block_ids.end(),
322 include_block_ids.begin());
323 include_block_ids.resize(it - include_block_ids.begin());
324 if (include_block_ids.size())
325 translate = to_tranforms[*include_block_ids.begin()];
326 else
327 continue;
328 }
329
330 pts.clear();
331 pts.push_back(to_app_transform(*node) + translate);
332 vals.resize(1);
333
334 idi->interpolate_field_data({_to_var_name}, pts, vals);
335 dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0);
336 to_solution.set(dof, vals.front());
337 }
338 }
339 else // Elemental
340 {
341 std::vector<Point> points;
342 for (const auto * const elem :
343 as_range(to_mesh.local_elements_begin(), to_mesh.local_elements_end()))
344 {
345 // Skip this element if the variable has no dofs at it.
346 if (elem->n_dofs(to_sys_num, to_var_num) < 1)
347 continue;
348
349 points.clear();
350 if (to_is_constant)
351 points.push_back(elem->vertex_average());
352 else
353 for (const auto & node : elem->node_ref_range())
354 points.push_back(node);
355
356 auto n_points = points.size();
357 unsigned int n_comp = elem->n_comp(to_sys_num, to_var_num);
358 // We assume each point corresponds to one component of elemental variable
359 if (n_points != n_comp)
360 mooseError(" Number of points ",
361 n_points,
362 " does not equal to number of variable components ",
363 n_comp);
364
365 Point translate(0);
366
367 if (to_tranforms.size() > 0)
368 {
369 auto subdomain = elem->subdomain_id();
370
371 if (subdomain == Moose::INVALID_BLOCK_ID)
372 mooseError("subdomain id does not make sense", subdomain);
373
374 if (exclude_block_ids.find(subdomain) == exclude_block_ids.end())
375 translate = to_tranforms[subdomain];
376 else
377 continue;
378 }
379
380 unsigned int offset = 0;
381 for (const auto & point : points)
382 {
383 pts.clear();
384 pts.push_back(to_app_transform(point) + translate);
385 vals.resize(1);
386
387 idi->interpolate_field_data({_to_var_name}, pts, vals);
388 dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, offset++);
389 to_solution.set(dof, vals.front());
390 } // point
391 } // auto elem
392 } // else
393
394 to_solution.close();
395 to_sys.update();
396}
397
398void
400{
401 TIME_SECTION("MultiAppGeometricInterpolationTransfer::execute()",
402 5,
403 "Transferring variables based on node interpolation");
404
405 const FEProblemBase & fe_problem =
406 hasFromMultiApp() ? getFromMultiApp()->problemBase() : getToMultiApp()->problemBase();
407 std::unique_ptr<InverseDistanceInterpolation<LIBMESH_DIM>> idi;
408 switch (_interp_type)
409 {
410 case 0:
411 idi = std::make_unique<InverseDistanceInterpolation<LIBMESH_DIM>>(
412 fe_problem.comm(), _num_points, _power);
413 break;
414 case 1:
415 idi = std::make_unique<RadialBasisInterpolation<LIBMESH_DIM>>(fe_problem.comm(), _radius);
416 break;
417 default:
418 mooseError("Unknown interpolation type!");
419 }
420
421 idi->set_field_variables({_to_var_name});
422
423 switch (_current_direction)
424 {
425 case TO_MULTIAPP:
426 {
427 FEProblemBase & from_problem = getToMultiApp()->problemBase();
428 const auto & from_var = from_problem.getVariable(
430
431 mooseAssert(_from_transforms.size() == 1, "This should be size 1");
432 fillSourceInterpolationPoints(from_problem, from_var, *_from_transforms[0], idi);
433
434 // We have only set local values - prepare for use by gathering remote gata
435 idi->prepare_for_use();
436
437 for (unsigned int i = 0; i < getToMultiApp()->numGlobalApps(); i++)
438 {
439 if (getToMultiApp()->hasLocalApp(i))
440 {
441 auto & to_problem = getToMultiApp()->appProblemBase(i);
442 Moose::ScopedCommSwapper swapper(to_problem.comm().get());
443 auto & to_var = to_problem.getVariable(0,
447
448 auto & to_solution = getToMultiApp()->appTransferVector(i, _to_var_name);
449
450 interpolateTargetPoints(to_problem, to_var, to_solution, *_to_transforms[i], idi);
451 }
452 }
453
454 break;
455 }
456
457 case FROM_MULTIAPP:
458 {
459 for (unsigned int i = 0; i < getFromMultiApp()->numGlobalApps(); i++)
460 {
461 if (getFromMultiApp()->hasLocalApp(i))
462 {
463 auto & from_problem = getFromMultiApp()->appProblemBase(i);
464 Moose::ScopedCommSwapper swapper(from_problem.comm().get());
465 const auto & from_var = from_problem.getVariable(0,
469
470 fillSourceInterpolationPoints(from_problem, from_var, *_from_transforms[i], idi);
471 }
472 }
473
474 idi->prepare_for_use();
475
476 FEProblemBase & to_problem = getFromMultiApp()->problemBase();
477 MooseVariableFieldBase & to_var = to_problem.getVariable(
479
480 auto & to_solution = *to_var.sys().system().solution;
481
482 mooseAssert(_to_transforms.size() == 1, "This should be size 1");
483 interpolateTargetPoints(to_problem, to_var, to_solution, *_to_transforms[0], idi);
484
485 break;
486 }
487 default:
488 {
489 mooseError("Unsupported transfer direction ", _current_direction);
490 break;
491 }
492 }
493}
494
495void
497 const MooseMesh & mesh, std::unordered_map<dof_id_type, Point> & transformation)
498{
499 auto & libmesh_mesh = mesh.getMesh();
500
501 auto & subdomainids = mesh.meshSubdomains();
502
503 subdomain_id_type max_subdomain_id = 0;
504
505 // max_subdomain_id will be used to represent the center of the entire domain
506 for (auto subdomain_id : subdomainids)
507 {
508 max_subdomain_id = max_subdomain_id > subdomain_id ? max_subdomain_id : subdomain_id;
509 }
510
511 max_subdomain_id += 1;
512
513 std::unordered_map<dof_id_type, Point> subdomain_centers;
514 std::unordered_map<dof_id_type, dof_id_type> nelems;
515
516 for (auto & elem :
517 as_range(libmesh_mesh.local_elements_begin(), libmesh_mesh.local_elements_end()))
518 {
519 // Compute center of the entire domain
520 subdomain_centers[max_subdomain_id] += elem->vertex_average();
521 nelems[max_subdomain_id] += 1;
522
523 auto subdomain = elem->subdomain_id();
524
525 if (subdomain == Moose::INVALID_BLOCK_ID)
526 mooseError("block is invalid");
527
528 // Centers for subdomains
529 subdomain_centers[subdomain] += elem->vertex_average();
530
531 nelems[subdomain] += 1;
532 }
533
534 comm().sum(subdomain_centers);
535
536 comm().sum(nelems);
537
538 subdomain_centers[max_subdomain_id] /= nelems[max_subdomain_id];
539
540 for (auto subdomain_id : subdomainids)
541 {
542 subdomain_centers[subdomain_id] /= nelems[subdomain_id];
543 }
544
545 // Compute unit vectors representing directions in which we want to shrink mesh
546 // The unit vectors is scaled by 'shrink_gap_width'
547 transformation.clear();
548 for (auto subdomain_id : subdomainids)
549 {
550 transformation[subdomain_id] =
551 subdomain_centers[max_subdomain_id] - subdomain_centers[subdomain_id];
552
553 auto norm = transformation[subdomain_id].norm();
554
555 // The current subdomain is the center of the entire domain,
556 // then we do not move this subdomain
557 if (norm > _distance_tol)
558 transformation[subdomain_id] /= norm;
559
560 transformation[subdomain_id] *= _shrink_gap_width;
561 }
562}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
registerMooseObjectRenamed("MooseApp", MultiAppInterpolationTransfer, "12/31/2023 24:00", MultiAppGeometricInterpolationTransfer)
registerMooseObject("MooseApp", MultiAppGeometricInterpolationTransfer)
void ErrorVector unsigned int
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
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition MooseMesh.h:95
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition MooseMesh.C:3549
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
void errorIfDistributedMesh(std::string name) const
Generate a unified error message if the underlying libMesh mesh is a DistributedMesh.
Definition MooseMesh.C:3718
SystemBase & sys()
Get the system this variable is part of.
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.
This class contains transformation information that only exists in a context in which there are multi...
Interpolate variable values using geometry/mesh-based coefficients.
void interpolateTargetPoints(FEProblemBase &to_problem, MooseVariableFieldBase &to_var, NumericVector< Real > &to_solution, const MultiAppCoordTransform &to_app_transform, const std::unique_ptr< libMesh::InverseDistanceInterpolation< Moose::dim > > &idi)
void computeTransformation(const MooseMesh &mesh, std::unordered_map< dof_id_type, Point > &transformation)
void fillSourceInterpolationPoints(FEProblemBase &from_problem, const MooseVariableFieldBase &from_var, const MultiAppCoordTransform &from_app_transform, std::unique_ptr< libMesh::InverseDistanceInterpolation< Moose::dim > > &idi)
void subdomainIDsNode(MooseMesh &mesh, const Node &node, std::set< subdomain_id_type > &subdomainids)
virtual void execute() override
Execute the transfer.
MultiAppGeometricInterpolationTransfer(const InputParameters &parameters)
bool _displaced_source_mesh
True if displaced mesh is used for the source mesh, otherwise false.
std::vector< std::unique_ptr< MultiAppCoordTransform > > _from_transforms
bool _displaced_target_mesh
True if displaced mesh is used for the target mesh, otherwise false.
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.
std::vector< std::unique_ptr< MultiAppCoordTransform > > _to_transforms
bool hasFromMultiApp() const
Whether the transfer owns a non-null from_multi_app.
Base class for a system (of equations)
Definition SystemBase.h:87
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
@ FROM_MULTIAPP
Definition Transfer.h:71
@ TO_MULTIAPP
Definition Transfer.h:70
FEProblemBase & _fe_problem
Definition Transfer.h:97
MooseEnum _current_direction
Definition Transfer.h:106
dof_id_type id() const
subdomain_id_type subdomain_id() const
OrderWrapper order
virtual const Elem & elem_ref(const dof_id_type i) const
virtual void set(const numeric_index_type i, const T value)=0
virtual void close()=0
const Parallel::Communicator & comm() const
const FEType & variable_type(const unsigned int i) const
std::unique_ptr< NumericVector< Number > > solution
virtual void update()
unsigned int variable_number(std::string_view var) const
unsigned int number() const
MeshBase & mesh
@ VAR_FIELD_STANDARD
Definition MooseTypes.h:777
@ 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