https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SolutionUserObjectBase.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 "ConsoleUtils.h"
14#include "MooseError.h"
15#include "MooseMesh.h"
16#include "MooseUtils.h"
17#include "MooseVariableFE.h"
18#include "RotationMatrix.h"
19#include "Function.h"
20
21// libMesh includes
22#include "libmesh/equation_systems.h"
23#include "libmesh/mesh_function.h"
24#include "libmesh/numeric_vector.h"
25#include "libmesh/nonlinear_implicit_system.h"
26#include "libmesh/transient_system.h"
27#include "libmesh/parallel_mesh.h"
28#include "libmesh/serial_mesh.h"
29#include "libmesh/exodusII_io.h"
30#include "libmesh/exodusII_io_helper.h"
31#include "libmesh/nemesis_io.h"
32#include "libmesh/nemesis_io_helper.h"
33#include "libmesh/enum_xdr_mode.h"
34#include "libmesh/string_to_enum.h"
35
38{
39 // Get the input parameters from the parent class
41
42 // Add required parameters
43 params.addRequiredParam<MeshFileName>(
44 "mesh", "The name of the mesh file (must be xda/xdr, exodusII or nemesis file).");
45 params.addParam<std::vector<std::string>>(
46 "system_variables",
47 std::vector<std::string>(),
48 "The name of the nodal and elemental variables from the file you want to use for values");
49 params.addParam<bool>(
50 "force_replicated_source_mesh",
51 false,
52 "Whether to force the serialization of the source mesh. This can be useful for discontinuous "
53 "variables or if the partitioning of the source mesh and the current mesh are different");
54
55 // When using XDA/XDR files the following must be defined
56 params.addParam<FileName>(
57 "es",
58 "<not supplied>",
59 "The name of the file holding the equation system info in xda/xdr format (xda/xdr only).");
60 params.addParam<std::string>(
61 "system",
62 "nl0",
63 "The name of the system to pull values out of (xda/xdr only). The default name for the "
64 "nonlinear system is 'nl0', auxiliary system is 'aux0'");
65
66 // When using ExodusII a specific time is extracted
67 params.addParam<std::string>("timestep",
68 "Index of the single timestep used or \"LATEST\" for "
69 "the last timestep (exodusII only). If not supplied, "
70 "time interpolation will occur.");
71
72 // Choose the interpolation order for incoming nodal variables
73 params.addParam<MooseEnum>("nodal_variable_order",
74 MooseEnum("FIRST SECOND", "FIRST"),
75 "Specifies the order of the nodal solution data.");
76
77 // Add ability to perform coordinate transformation: scale, factor
78 params.addParam<std::vector<Real>>(
79 "scale", std::vector<Real>(LIBMESH_DIM, 1), "Scale factor for points in the simulation");
80 params.addParam<std::vector<Real>>("scale_multiplier",
81 std::vector<Real>(LIBMESH_DIM, 1),
82 "Scale multiplying factor for points in the simulation");
83 params.addParam<std::vector<Real>>("translation",
84 std::vector<Real>(LIBMESH_DIM, 0),
85 "Translation factors for x,y,z coordinates of the simulation");
86 params.addParam<RealVectorValue>("rotation0_vector",
87 RealVectorValue(0, 0, 1),
88 "Vector about which to rotate points of the simulation.");
89 params.addParam<Real>(
90 "rotation0_angle",
91 0.0,
92 "Anticlockwise rotation angle (in degrees) to use for rotation about rotation0_vector.");
93 params.addParam<RealVectorValue>("rotation1_vector",
94 RealVectorValue(0, 0, 1),
95 "Vector about which to rotate points of the simulation.");
96 params.addParam<Real>(
97 "rotation1_angle",
98 0.0,
99 "Anticlockwise rotation angle (in degrees) to use for rotation about rotation1_vector.");
100
101 // following lines build the default_transformation_order
102 MultiMooseEnum default_transformation_order(
103 "rotation0 translation scale rotation1 scale_multiplier", "translation scale");
104 params.addParam<MultiMooseEnum>(
105 "transformation_order",
106 default_transformation_order,
107 "The order to perform the operations in. Define R0 to be the rotation matrix encoded by "
108 "rotation0_vector and rotation0_angle. Similarly for R1. Denote the scale by s, the "
109 "scale_multiplier by m, and the translation by t. Then, given a point x in the simulation, "
110 "if transformation_order = 'rotation0 scale_multiplier translation scale rotation1' then "
111 "form p = R1*(R0*x*m - t)/s. Then the values provided by the SolutionUserObjectBase at "
112 "point x "
113 "in the simulation are the variable values at point p in the mesh.");
114 params.addParamNamesToGroup("scale scale_multiplier translation rotation0_vector rotation0_angle "
115 "rotation1_angle transformation_order",
116 "Coordinate system transformation");
117 params.addClassDescription("Reads a variable from a mesh in one simulation to another");
118 return params;
119}
120
121// Static mutex definition
123
125 : GeneralUserObject(parameters),
126 _file_type(MooseEnum("xda=0 exodusII=1 xdr=2 nemesis=3")),
127 _mesh_file(getParam<MeshFileName>("mesh")),
128 _es_file(getParam<FileName>("es")),
129 _system_name(getParam<std::string>("system")),
130 _system_variables(getParam<std::vector<std::string>>("system_variables")),
131 _exodus_time_index(-1),
132 _interpolate_times(false),
133 _system(nullptr),
134 _system2(nullptr),
135 _interpolation_time(0.0),
136 _interpolation_factor(0.0),
137 _exodus_times(nullptr),
138 _exodus_index1(0),
139 _exodus_index2(0),
140 _nodal_variable_order(getParam<MooseEnum>("nodal_variable_order")),
141 _scale(getParam<std::vector<Real>>("scale")),
142 _scale_multiplier(getParam<std::vector<Real>>("scale_multiplier")),
143 _translation(getParam<std::vector<Real>>("translation")),
144 _rotation0_vector(getParam<RealVectorValue>("rotation0_vector")),
145 _rotation0_angle(getParam<Real>("rotation0_angle")),
146 _r0(RealTensorValue()),
147 _rotation1_vector(getParam<RealVectorValue>("rotation1_vector")),
148 _rotation1_angle(getParam<Real>("rotation1_angle")),
149 _r1(RealTensorValue()),
150 _transformation_order(getParam<MultiMooseEnum>("transformation_order")),
151 _force_replicated_source(getParam<bool>("force_replicated_source_mesh")),
152 _initialized(false)
153{
154 // form rotation matrices with the specified angles
155 Real halfPi = libMesh::pi / 2.0;
156 Real a;
157 Real b;
158
159 a = std::cos(halfPi * -_rotation0_angle / 90.0);
160 b = std::sin(halfPi * -_rotation0_angle / 90.0);
161 // the following is an anticlockwise rotation about z
162 RealTensorValue rot0_z(a, -b, 0, b, a, 0, 0, 0, 1);
163 // form the rotation matrix that will take rotation0_vector to the z axis
164 RealTensorValue vec0_to_z = RotationMatrix::rotVecToZ(_rotation0_vector);
165 // _r0 is then: rotate points so vec0 lies along z; then rotate about angle0; then rotate points
166 // back
167 _r0 = vec0_to_z.transpose() * (rot0_z * vec0_to_z);
168
169 a = std::cos(halfPi * -_rotation1_angle / 90.0);
170 b = std::sin(halfPi * -_rotation1_angle / 90.0);
171 // the following is an anticlockwise rotation about z
172 RealTensorValue rot1_z(a, -b, 0, b, a, 0, 0, 0, 1);
173 // form the rotation matrix that will take rotation1_vector to the z axis
174 RealTensorValue vec1_to_z = RotationMatrix::rotVecToZ(_rotation1_vector);
175 // _r1 is then: rotate points so vec1 lies along z; then rotate about angle1; then rotate points
176 // back
177 _r1 = vec1_to_z.transpose() * (rot1_z * vec1_to_z);
178
179 if (isParamValid("timestep") && getParam<std::string>("timestep") == "-1")
180 mooseError("A \"timestep\" of -1 is no longer supported for interpolation. Instead simply "
181 "remove this parameter altogether for interpolation");
182
183 // check for possible inconsistencies between mesh and input data
185 mooseInfo(
186 "The mesh has second-order elements, be sure to set 'nodal_variable_order' if needed.");
187}
188
189void
191{
192 if (!isParamSetByUser("es"))
193 paramError("es", "Equation system file (.xda or .xdr) should have been specified");
194
195 // Check that the required files exist
198
199 // Read the libmesh::mesh from the xda file
200 _mesh->read(_mesh_file);
201
202 // Create the libmesh::EquationSystems
203 _es = std::make_unique<EquationSystems>(*_mesh);
204
205 // Use new read syntax (binary)
206 if (_file_type == "xdr")
207 _es->read(_es_file,
209 EquationSystems::READ_HEADER | EquationSystems::READ_DATA |
210 EquationSystems::READ_ADDITIONAL_DATA);
211
212 // Use new read syntax
213 else if (_file_type == "xda")
214 _es->read(_es_file,
216 EquationSystems::READ_HEADER | EquationSystems::READ_DATA |
217 EquationSystems::READ_ADDITIONAL_DATA);
218
219 // This should never occur, just in case produce an error
220 else
221 mooseError("Failed to determine proper read method for XDA/XDR equation system file: ",
222 _es_file);
223
224 // Update and store the EquationSystems name locally
225 _es->update();
226 _system = &_es->get_system(_system_name);
227}
228
229void
231{
232 // Define a default system name
233 if (_system_name == "")
234 _system_name = "SolutionUserObjectSystem";
235
236 // Read the Exodus or Nemesis file
237 if (_file_type == "exodusII")
238 {
239 _exodusII_io = std::make_unique<libMesh::ExodusII_IO>(*_mesh);
241 _exodus_times = &_exodusII_io->get_time_steps();
242 }
243 else
244 {
245 _nemesis_io = std::make_unique<libMesh::Nemesis_IO>(*_mesh);
246 _nemesis_io->read(_mesh_file);
247 _exodus_times = &_nemesis_io->get_time_steps();
248 }
249 // Same routine for Nemesis
251
252 if (isParamValid("timestep"))
253 {
254 std::string s_timestep = getParam<std::string>("timestep");
255 int n_steps = (_file_type == "exodusII") ? _exodusII_io->get_num_time_steps()
256 : _nemesis_io->get_num_time_steps();
257 if (s_timestep == "LATEST")
258 _exodus_time_index = n_steps;
259 else
260 {
261 std::istringstream ss(s_timestep);
262 if (!((ss >> _exodus_time_index) && ss.eof()) || _exodus_time_index > n_steps)
263 mooseError("Invalid value passed as \"timestep\". Expected \"LATEST\" or a valid integer "
264 "less than ",
265 n_steps,
266 ", received ",
267 s_timestep);
268 }
269 }
270 else
271 // Interpolate between times rather than using values from a set timestep
272 _interpolate_times = true;
273
274 // Check that the number of time steps is valid
275 int num_exo_times = _exodus_times->size();
276 if (num_exo_times == 0)
277 mooseError("In SolutionUserObjectBase, exodus file contains no timesteps.");
278
279 // Account for parallel mesh
280 if (_fe_problem.mesh().isDistributedMesh() && (_file_type != "exodusII") &&
282 {
283 _mesh->allow_renumbering(true);
284 _mesh->prepare_for_use();
285 }
286 else
287 {
288 _mesh->allow_renumbering(false);
289 _mesh->prepare_for_use();
290 }
291
292 // Create EquationSystems object for solution
293 _es = std::make_unique<EquationSystems>(*_mesh);
295 _system = &_es->get_system(_system_name);
296
297 // Get the variable name lists as set; these need to be sets to perform set_intersection
298 const std::vector<std::string> & all_nodal((_file_type == "exodusII")
299 ? _exodusII_io->get_nodal_var_names()
300 : _nemesis_io->get_nodal_var_names());
301 const std::vector<std::string> & all_elemental((_file_type == "exodusII")
302 ? _exodusII_io->get_elem_var_names()
303 : _nemesis_io->get_elem_var_names());
304 const std::vector<std::string> & all_scalar((_file_type == "exodusII")
305 ? _exodusII_io->get_global_var_names()
306 : _nemesis_io->get_global_var_names());
307
308 // Build nodal/elemental variable lists, limit to variables listed in 'system_variables', if
309 // provided
310 // This function could be called more than once, so clear the member variables so we don't keep
311 // adding to the vectors
313 _elemental_variables.clear();
314 _scalar_variables.clear();
315 if (!_system_variables.empty())
316 {
317 for (const auto & var_name : _system_variables)
318 {
319 if (std::find(all_nodal.begin(), all_nodal.end(), var_name) != all_nodal.end())
320 _nodal_variables.push_back(var_name);
321 else if (std::find(all_elemental.begin(), all_elemental.end(), var_name) !=
322 all_elemental.end())
323 _elemental_variables.push_back(var_name);
324 else if (std::find(all_scalar.begin(), all_scalar.end(), var_name) != all_scalar.end())
325 // We checked other variables types first, so if a postprocessor has the same name as a
326 // field variable, it won't get loaded as a scalar variable
327 _scalar_variables.push_back(var_name);
328 else
329 paramError("system_variables", "Variable '" + var_name + "' was not found in Exodus file");
330 }
331 }
332 else
333 {
334 _nodal_variables = all_nodal;
335 _elemental_variables = all_elemental;
336
337 for (auto var_name : all_scalar)
338 // Check if the scalar matches any field variables, and ignore the var if it does. This means
339 // its a Postprocessor.
340 if (std::find(begin(_nodal_variables), end(_nodal_variables), var_name) ==
341 _nodal_variables.end() &&
342 std::find(begin(_elemental_variables), end(_elemental_variables), var_name) ==
344 _scalar_variables.push_back(var_name);
345 }
346
347 // Add the variables to the system
348 for (const auto & var_name : _nodal_variables)
349 _system->add_variable(var_name, Utility::string_to_enum<Order>(_nodal_variable_order));
350
351 for (const auto & var_name : _elemental_variables)
352 _system->add_variable(var_name, CONSTANT, MONOMIAL);
353
354 for (const auto & var_name : _scalar_variables)
355 _system->add_variable(var_name, FIRST, SCALAR);
356
357 // Helper for copying from the ExodusII/Nemesis file
358 const auto copy_solutions = [this](auto & io, libMesh::System & system, unsigned int index)
359 {
360 for (const auto & var_name : _nodal_variables)
361 io.copy_nodal_solution(system, var_name, var_name, index);
362
363 for (const auto & var_name : _elemental_variables)
364 io.copy_elemental_solution(system, var_name, var_name, index);
365
366 if (_scalar_variables.size() > 0)
367 io.copy_scalar_solution(system, _scalar_variables, _scalar_variables, index);
368 };
369
370 // Initialize the equations systems
371 _es->init();
372
373 // Interpolate times
375 {
376 // Create a second equation system
377 _es2 = std::make_unique<EquationSystems>(*_mesh);
379 _system2 = &_es2->get_system(_system_name);
380
381 // Add the variables to the system
382 for (const auto & var_name : _nodal_variables)
383 _system2->add_variable(var_name, Utility::string_to_enum<Order>(_nodal_variable_order));
384
385 for (const auto & var_name : _elemental_variables)
386 _system2->add_variable(var_name, CONSTANT, MONOMIAL);
387
388 for (const auto & var_name : _scalar_variables)
389 _system2->add_variable(var_name, FIRST, SCALAR);
390
391 // Initialize
392 _es2->init();
393
394 // Update the times for interpolation (initially start at 0)
396
397 // Copy the solutions from the first system
398 if (_file_type == "exodusII")
399 {
400 copy_solutions(*_exodusII_io, *_system, _exodus_index1 + 1);
401 copy_solutions(*_exodusII_io, *_system2, _exodus_index2 + 1);
402 }
403 else
404 {
405 copy_solutions(*_nemesis_io, *_system, _exodus_index1 + 1);
406 copy_solutions(*_nemesis_io, *_system2, _exodus_index2 + 1);
407 }
408
409 // Update the systems
410 _system->update();
411 _es->update();
412 _system2->update();
413 _es2->update();
414 }
415
416 // Non-interpolated times
417 else
418 {
419 if (_exodus_time_index > num_exo_times)
420 mooseError("In SolutionUserObjectBase, timestep = ",
422 ", but there are only ",
423 num_exo_times,
424 " time steps.");
425
426 // Copy the values from the ExodusII/Nemsis file
427 if (_file_type == "exodusII")
428 copy_solutions(*_exodusII_io, *_system, _exodus_time_index);
429 else
430 copy_solutions(*_nemesis_io, *_system, _exodus_time_index);
431
432 // Update the equations systems
433 _system->update();
434 _es->update();
435 }
436}
437
438Real
439SolutionUserObjectBase::directValue(const Node * node, const std::string & var_name) const
440{
441 // Get the libmesh variable and system numbers
442 unsigned int var_num = _system->variable_number(var_name);
443 unsigned int sys_num = _system->number();
444
445 // Get the node id and associated dof
446 dof_id_type node_id = node->id();
447 const Node & sys_node = _system->get_mesh().node_ref(node_id);
448 mooseAssert(sys_node.n_dofs(sys_num, var_num) > 0,
449 "Variable " << var_name << " has no DoFs on node " << sys_node.id());
450 dof_id_type dof_id = sys_node.dof_number(sys_num, var_num, 0);
451
452 // Return the desired value for the dof
453 return directValue(dof_id);
454}
455
456Real
457SolutionUserObjectBase::directValue(const Elem * elem, const std::string & var_name) const
458{
459 // Get the libmesh variable and system numbers
460 unsigned int var_num = _system->variable_number(var_name);
461 unsigned int sys_num = _system->number();
462
463 // Get the element id and associated dof
464 dof_id_type elem_id = elem->id();
465 const Elem & sys_elem = _system->get_mesh().elem_ref(elem_id);
466 mooseAssert(sys_elem.n_dofs(sys_num, var_num) > 0,
467 "Variable " << var_name << " has no DoFs on element " << sys_elem.id());
468 dof_id_type dof_id = sys_elem.dof_number(sys_num, var_num, 0);
469
470 // Return the desired value
471 return directValue(dof_id);
472}
473
474void
478
479void
483
484void
486{
487 // Update time interpolation for ExodusII or Nemesis solution
490
491 // Clear the caches
492 _cached_p(0) = std::numeric_limits<Real>::max();
493 _cached_p2(0) = std::numeric_limits<Real>::max();
494}
495
496void
500
501void
503{
504
505 // Make sure this only happens once
506 if (_initialized)
507 return;
508
509 // We need to detect exodus files early
510 const bool has_exodus_extension =
511 MooseUtils::hasExtension(_mesh_file, "e", /*strip_exodus_ext =*/true) ||
513 const bool has_nemesis_extension =
514 MooseUtils::hasExtension(_mesh_file, "n", /*strip_exodus_ext =*/true) ||
516 if (has_exodus_extension)
517 _file_type = "exodusII";
518 else if (has_nemesis_extension)
519 _file_type = "nemesis";
520
521 // Create a libmesh::Mesh object for storing the loaded data.
522 if (!_fe_problem.mesh().isDistributedMesh() || (_file_type == "exodusII") ||
524 _mesh = std::make_unique<ReplicatedMesh>(_communicator);
525 else
526 _mesh = std::make_unique<DistributedMesh>(_communicator);
527
528 // ExodusII or Nemesis mesh file supplied
529 if (has_exodus_extension || has_nemesis_extension)
531
532 // XDA mesh file supplied
533 else if (MooseUtils::hasExtension(_mesh_file, "xda"))
534 {
535 _file_type = "xda";
536 readXda();
537 }
538
539 // XDR mesh file supplied
540 else if (MooseUtils::hasExtension(_mesh_file, "xdr"))
541 {
542 _file_type = "xdr";
543 readXda();
544 }
545
546 // Produce an error for an unknown file type
547 else
549 "In SolutionUserObjectBase, invalid file type: only .xda, .xdr, .exo and .e supported");
550
551 // Initialize the serial solution vector
552 _serialized_solution = NumericVector<Number>::build(_communicator);
554
555 // Pull down a full copy of this vector on every processor so we can get values in parallel
557
558 // Vector of variable numbers to apply the MeshFunction to
559 std::vector<unsigned int> var_nums;
560
561 // If no variables were given, use all of them
562 if (_system_variables.empty())
563 {
565 for (const auto & var_num : var_nums)
566 _system_variables.push_back(_system->variable_name(var_num));
567 }
568
569 // Otherwise, gather the numbers for the variables given
570 else
571 {
572 for (const auto & var_name : _system_variables)
573 var_nums.push_back(_system->variable_number(var_name));
574 }
575
576 // Create the MeshFunction for working with the solution data
577 _mesh_function = std::make_unique<libMesh::MeshFunction>(
579 _mesh_function->init();
580
581 // Tell the MeshFunctions that we might be querying them outside the
582 // mesh, so we can handle any errors at the MOOSE rather than at the
583 // libMesh level.
584 DenseVector<Number> default_values;
585 _mesh_function->enable_out_of_mesh_mode(default_values);
586
587 // Build second MeshFunction for interpolation
589 {
590 // Need to pull down a full copy of this vector on every processor so we can get values in
591 // parallel
592 _serialized_solution2 = NumericVector<Number>::build(_communicator);
595
596 // Create the MeshFunction for the second copy of the data
597 _mesh_function2 = std::make_unique<libMesh::MeshFunction>(
599 _mesh_function2->init();
600 _mesh_function2->enable_out_of_mesh_mode(default_values);
601 }
602
603 // Populate the MeshFunction variable index
604 for (unsigned int i = 0; i < _system_variables.size(); ++i)
605 {
606 std::string name = _system_variables[i];
608 }
609
610 // If the start time is not the same as in the exodus file, we may need this on INITIAL
613
614 // Set initialization flag
615 _initialized = true;
616}
617
623
624void
626{
627 if (_t != _interpolation_time)
628 {
630 {
631 // Helper to copy/update solutions from a file IO to a system
632 const auto update_solutions = [this](auto & io, libMesh::System & system, unsigned int index)
633 {
634 for (const auto & var_name : _nodal_variables)
635 io.copy_nodal_solution(system, var_name, var_name, index);
636 for (const auto & var_name : _elemental_variables)
637 io.copy_elemental_solution(system, var_name, var_name, index);
638 if (_scalar_variables.size() > 0)
639 io.copy_scalar_solution(system, _scalar_variables, _scalar_variables, index);
640 };
641
642 if (_file_type == "exodusII")
643 update_solutions(*_exodusII_io, *_system, _exodus_index1 + 1);
644 else
645 update_solutions(*_nemesis_io, *_system, _exodus_index1 + 1);
646
647 _system->update();
648 _es->update();
650
651 if (_file_type == "exodusII")
652 update_solutions(*_exodusII_io, *_system2, _exodus_index2 + 1);
653 else
654 update_solutions(*_nemesis_io, *_system2, _exodus_index2 + 1);
655
656 _system2->update();
657 _es2->update();
659 }
661 }
662}
663
664bool
666{
667 if (_file_type != "exodusII" && _file_type != "nemesis")
668 mooseError("getTimeInterpolationData only applicable for exodusII or Nemesis file type");
669
670 int old_index1 = _exodus_index1;
671 int old_index2 = _exodus_index2;
672
673 int num_exo_times = _exodus_times->size();
674
675 const auto solution_time = solutionSampleTime();
676
677 if (solution_time < (*_exodus_times)[0])
678 {
679 _exodus_index1 = 0;
680 _exodus_index2 = 0;
682 }
683 else
684 {
685 for (int i = 0; i < num_exo_times - 1; ++i)
686 {
687 if (solution_time <= (*_exodus_times)[i + 1])
688 {
689 _exodus_index1 = i;
690 _exodus_index2 = i + 1;
692 (solution_time - (*_exodus_times)[i]) / ((*_exodus_times)[i + 1] - (*_exodus_times)[i]);
693 break;
694 }
695 else if (i == num_exo_times - 2)
696 {
697 _exodus_index1 = num_exo_times - 1;
698 _exodus_index2 = num_exo_times - 1;
700 break;
701 }
702 }
703 }
704
705 bool indices_modified(false);
706
707 if (_exodus_index1 != old_index1 || _exodus_index2 != old_index2)
708 indices_modified = true;
709
710 return indices_modified;
711}
712
713unsigned int
714SolutionUserObjectBase::getLocalVarIndex(const std::string & var_name) const
715{
716 // Extract the variable index for the MeshFunction(s)
717 std::map<std::string, unsigned int>::const_iterator it = _local_variable_index.find(var_name);
718 if (it == _local_variable_index.end())
719 mooseError("Value requested for nonexistent variable '",
720 var_name,
721 "' in the '",
722 name(),
723 "' SolutionUserObjectBase.\nSystem selected: ",
725 "\nAvailable variables:\n",
727 return it->second;
728}
729
730Real
732 const Point & p,
733 const std::string & var_name,
734 const MooseEnum & weighting_type,
735 const std::set<subdomain_id_type> * subdomain_ids) const
736{
737 // first check if the FE type is continuous because in that case the value is
738 // unique and we can take a short cut, the default weighting_type found_first also
739 // shortcuts out
740 auto family =
744 .feType()
745 .family;
746
747 if (weighting_type == 1 ||
748 (family != L2_LAGRANGE && family != MONOMIAL && family != L2_HIERARCHIC))
749 return pointValue(t, p, var_name, subdomain_ids);
750
751 // the shape function is discontinuous so we need to compute a suitable unique value
752 std::map<const Elem *, Real> values = discontinuousPointValue(t, p, var_name);
753 switch (weighting_type)
754 {
755 case 2:
756 {
757 Real average = 0.0;
758 for (auto & v : values)
759 average += v.second;
760 return average / Real(values.size());
761 }
762 case 4:
763 {
764 Real smallest_elem_id_value = std::numeric_limits<Real>::max();
765 dof_id_type smallest_elem_id = _fe_problem.mesh().maxElemId();
766 for (auto & v : values)
767 if (v.first->id() < smallest_elem_id)
768 {
769 smallest_elem_id = v.first->id();
770 smallest_elem_id_value = v.second;
771 }
772 return smallest_elem_id_value;
773 }
774 case 8:
775 {
776 Real largest_elem_id_value = std::numeric_limits<Real>::lowest();
777 dof_id_type largest_elem_id = 0;
778 for (auto & v : values)
779 if (v.first->id() > largest_elem_id)
780 {
781 largest_elem_id = v.first->id();
782 largest_elem_id_value = v.second;
783 }
784 return largest_elem_id_value;
785 }
786 }
787
788 mooseError("SolutionUserObjectBase::pointValueWrapper reaches line that it should not be able to "
789 "reach.");
790 return 0.0;
791}
792
793Real
795 const Point & p,
796 const std::string & var_name,
797 const std::set<subdomain_id_type> * subdomain_ids) const
798{
799 const unsigned int local_var_index = getLocalVarIndex(var_name);
800 return pointValue(t, p, local_var_index, subdomain_ids);
801}
802
803Real
804SolutionUserObjectBase::pointValue(Real libmesh_dbg_var(t),
805 const Point & p,
806 const unsigned int local_var_index,
807 const std::set<subdomain_id_type> * subdomain_ids) const
808{
809 // Create copy of point
810 Point pt(p);
811
812 // do the transformations
813 for (unsigned int trans_num = 0; trans_num < _transformation_order.size(); ++trans_num)
814 {
815 if (_transformation_order[trans_num] == "rotation0")
816 pt = _r0 * pt;
817 else if (_transformation_order[trans_num] == "translation")
818 for (const auto i : make_range(Moose::dim))
819 pt(i) -= _translation[i];
820 else if (_transformation_order[trans_num] == "scale")
821 for (const auto i : make_range(Moose::dim))
822 pt(i) /= _scale[i];
823 else if (_transformation_order[trans_num] == "scale_multiplier")
824 for (const auto i : make_range(Moose::dim))
825 pt(i) *= _scale_multiplier[i];
826 else if (_transformation_order[trans_num] == "rotation1")
827 pt = _r1 * pt;
828 }
829
830 // Extract the value at the current point
831 Real val = evalMeshFunction(pt, local_var_index, 1, subdomain_ids);
832
833 // Interpolate
834 if (_interpolate_times && (_file_type == "exodusII" || _file_type == "nemesis"))
835 {
836 mooseAssert(t == _interpolation_time,
837 "Time passed into value() must match time at last call to timestepSetup()");
838 Real val2 = evalMeshFunction(pt, local_var_index, 2, subdomain_ids);
839 val = val + (val2 - val) * _interpolation_factor;
840 }
841
842 return val;
843}
844
845std::map<const Elem *, Real>
847 Real t,
848 const Point & p,
849 const std::string & var_name,
850 const std::set<subdomain_id_type> * subdomain_ids) const
851{
852 const unsigned int local_var_index = getLocalVarIndex(var_name);
853 return discontinuousPointValue(t, p, local_var_index, subdomain_ids);
854}
855
856std::map<const Elem *, Real>
858 Real libmesh_dbg_var(t),
859 Point pt,
860 const unsigned int local_var_index,
861 const std::set<subdomain_id_type> * subdomain_ids) const
862{
863 // do the transformations
864 for (unsigned int trans_num = 0; trans_num < _transformation_order.size(); ++trans_num)
865 {
866 if (_transformation_order[trans_num] == "rotation0")
867 pt = _r0 * pt;
868 else if (_transformation_order[trans_num] == "translation")
869 for (const auto i : make_range(Moose::dim))
870 pt(i) -= _translation[i];
871 else if (_transformation_order[trans_num] == "scale")
872 for (const auto i : make_range(Moose::dim))
873 pt(i) /= _scale[i];
874 else if (_transformation_order[trans_num] == "scale_multiplier")
875 for (const auto i : make_range(Moose::dim))
876 pt(i) *= _scale_multiplier[i];
877 else if (_transformation_order[trans_num] == "rotation1")
878 pt = _r1 * pt;
879 }
880
881 // Extract the value at the current point
882 std::map<const Elem *, Real> map =
883 evalMultiValuedMeshFunction(pt, local_var_index, 1, subdomain_ids);
884
885 // Interpolate
886 if (_interpolate_times && (_file_type == "exodusII" || _file_type == "nemesis"))
887 {
888 mooseAssert(t == _interpolation_time,
889 "Time passed into value() must match time at last call to timestepSetup()");
890 std::map<const Elem *, Real> map2 = evalMultiValuedMeshFunction(pt, local_var_index, 2);
891
892 if (map.size() != map2.size())
894 "In SolutionUserObjectBase::discontinuousPointValue map and map2 have different size");
895
896 // construct the interpolated map
897 for (auto & k : map)
898 {
899 if (map2.find(k.first) == map2.end())
901 "In SolutionUserObjectBase::discontinuousPointValue map and map2 have differing keys");
902 Real val = k.second;
903 Real val2 = map2[k.first];
904 map[k.first] = val + (val2 - val) * _interpolation_factor;
905 }
906 }
907
908 return map;
909}
910
913 Real t,
914 const Point & p,
915 const std::string & var_name,
916 const MooseEnum & weighting_type,
917 const std::set<subdomain_id_type> * subdomain_ids) const
918{
919 // the default weighting_type found_first shortcuts out
920 if (weighting_type == 1)
921 return pointValueGradient(t, p, var_name, subdomain_ids);
922
923 // the shape function is discontinuous so we need to compute a suitable unique value
924 std::map<const Elem *, RealGradient> values =
925 discontinuousPointValueGradient(t, p, var_name, subdomain_ids);
926 switch (weighting_type)
927 {
928 case 2:
929 {
930 RealGradient average = RealGradient(0.0, 0.0, 0.0);
931 for (auto & v : values)
932 average += v.second;
933 return average / Real(values.size());
934 }
935 case 4:
936 {
937 RealGradient smallest_elem_id_value;
938 dof_id_type smallest_elem_id = _fe_problem.mesh().maxElemId();
939 for (auto & v : values)
940 if (v.first->id() < smallest_elem_id)
941 {
942 smallest_elem_id = v.first->id();
943 smallest_elem_id_value = v.second;
944 }
945 return smallest_elem_id_value;
946 }
947 case 8:
948 {
949 RealGradient largest_elem_id_value;
950 dof_id_type largest_elem_id = 0;
951 for (auto & v : values)
952 if (v.first->id() > largest_elem_id)
953 {
954 largest_elem_id = v.first->id();
955 largest_elem_id_value = v.second;
956 }
957 return largest_elem_id_value;
958 }
959 }
960
961 mooseError("SolutionUserObjectBase::pointValueGradientWrapper reaches line that it should not be "
962 "able to reach.");
963 return RealGradient(0.0, 0.0, 0.0);
964}
965
966RealGradient
968 const Point & p,
969 const std::string & var_name,
970 const std::set<subdomain_id_type> * subdomain_ids) const
971{
972 const unsigned int local_var_index = getLocalVarIndex(var_name);
973 return pointValueGradient(t, p, local_var_index, subdomain_ids);
974}
975
976RealGradient
977SolutionUserObjectBase::pointValueGradient(Real libmesh_dbg_var(t),
978 Point pt,
979 const unsigned int local_var_index,
980 const std::set<subdomain_id_type> * subdomain_ids) const
981{
982 // do the transformations
983 for (unsigned int trans_num = 0; trans_num < _transformation_order.size(); ++trans_num)
984 {
985 if (_transformation_order[trans_num] == "rotation0")
986 pt = _r0 * pt;
987 else if (_transformation_order[trans_num] == "translation")
988 for (const auto i : make_range(Moose::dim))
989 pt(i) -= _translation[i];
990 else if (_transformation_order[trans_num] == "scale")
991 for (const auto i : make_range(Moose::dim))
992 pt(i) /= _scale[i];
993 else if (_transformation_order[trans_num] == "scale_multiplier")
994 for (const auto i : make_range(Moose::dim))
995 pt(i) *= _scale_multiplier[i];
996 else if (_transformation_order[trans_num] == "rotation1")
997 pt = _r1 * pt;
998 }
999
1000 // Extract the value at the current point
1001 RealGradient val = evalMeshFunctionGradient(pt, local_var_index, 1, subdomain_ids);
1002
1003 // Interpolate
1004 if (_interpolate_times && (_file_type == "exodusII" || _file_type == "nemesis"))
1005 {
1006 mooseAssert(t == _interpolation_time,
1007 "Time passed into value() must match time at last call to timestepSetup()");
1008 RealGradient val2 = evalMeshFunctionGradient(pt, local_var_index, 2, subdomain_ids);
1009 val = val + (val2 - val) * _interpolation_factor;
1010 }
1011
1012 return val;
1013}
1014
1015std::map<const Elem *, RealGradient>
1017 Real t,
1018 const Point & p,
1019 const std::string & var_name,
1020 const std::set<subdomain_id_type> * subdomain_ids) const
1021{
1022 const unsigned int local_var_index = getLocalVarIndex(var_name);
1023 return discontinuousPointValueGradient(t, p, local_var_index, subdomain_ids);
1024}
1025
1026std::map<const Elem *, RealGradient>
1028 Real libmesh_dbg_var(t),
1029 Point pt,
1030 const unsigned int local_var_index,
1031 const std::set<subdomain_id_type> * subdomain_ids) const
1032{
1033 // do the transformations
1034 for (unsigned int trans_num = 0; trans_num < _transformation_order.size(); ++trans_num)
1035 {
1036 if (_transformation_order[trans_num] == "rotation0")
1037 pt = _r0 * pt;
1038 else if (_transformation_order[trans_num] == "translation")
1039 for (const auto i : make_range(Moose::dim))
1040 pt(i) -= _translation[i];
1041 else if (_transformation_order[trans_num] == "scale")
1042 for (const auto i : make_range(Moose::dim))
1043 pt(i) /= _scale[i];
1044 else if (_transformation_order[trans_num] == "scale_multiplier")
1045 for (const auto i : make_range(Moose::dim))
1046 pt(i) *= _scale_multiplier[i];
1047 else if (_transformation_order[trans_num] == "rotation1")
1048 pt = _r1 * pt;
1049 }
1050
1051 // Extract the value at the current point
1052 std::map<const Elem *, RealGradient> map =
1053 evalMultiValuedMeshFunctionGradient(pt, local_var_index, 1, subdomain_ids);
1054
1055 // Interpolate
1056 if (_interpolate_times && (_file_type == "exodusII" || _file_type == "nemesis"))
1057 {
1058 mooseAssert(t == _interpolation_time,
1059 "Time passed into value() must match time at last call to timestepSetup()");
1060 std::map<const Elem *, RealGradient> map2 =
1061 evalMultiValuedMeshFunctionGradient(pt, local_var_index, 1, subdomain_ids);
1062
1063 if (map.size() != map2.size())
1064 mooseError(
1065 "In SolutionUserObjectBase::discontinuousPointValue map and map2 have different size");
1066
1067 // construct the interpolated map
1068 for (auto & k : map)
1069 {
1070 if (map2.find(k.first) == map2.end())
1071 mooseError(
1072 "In SolutionUserObjectBase::discontinuousPointValue map and map2 have differing keys");
1073 RealGradient val = k.second;
1074 RealGradient val2 = map2[k.first];
1075 map[k.first] = val + (val2 - val) * _interpolation_factor;
1076 }
1077 }
1078
1079 return map;
1080}
1081
1082Real
1083SolutionUserObjectBase::directValue(dof_id_type dof_index) const
1084{
1085 Real val = (*_serialized_solution)(dof_index);
1086 if (_interpolate_times && (_file_type == "exodusII" || _file_type == "nemesis"))
1087 {
1088 Real val2 = (*_serialized_solution2)(dof_index);
1089 val = val + (val2 - val) * _interpolation_factor;
1090 }
1091 return val;
1092}
1093
1094Real
1096 const unsigned int local_var_index,
1097 unsigned int func_num,
1098 const std::set<subdomain_id_type> * subdomain_ids) const
1099{
1100 // Storage for mesh function output
1101 DenseVector<Number> output;
1102
1103 // Extract a value from the _mesh_function
1104 {
1105 Threads::spin_mutex::scoped_lock lock(_solution_user_object_mutex);
1106
1107 if (func_num == 1)
1108 {
1109 // Check the cache
1110 if (p == _cached_p && (!subdomain_ids || (*subdomain_ids == _cached_subdomain_ids)))
1111 return _cached_values(local_var_index);
1112
1113 // else get a new value
1114 (*_mesh_function)(p, 0.0, output, subdomain_ids);
1115 // and cache it
1116 _cached_p = p;
1117 if (subdomain_ids)
1118 _cached_subdomain_ids = *subdomain_ids;
1119 _cached_values = output;
1120 }
1121
1122 // Extract a value from _mesh_function2
1123 else if (func_num == 2)
1124 {
1125 // Check the cache
1126 if (p == _cached_p2 && (!subdomain_ids || (*subdomain_ids == _cached_subdomain_ids2)))
1127 return _cached_values2(local_var_index);
1128
1129 // else get a new value
1130 (*_mesh_function2)(p, 0.0, output, subdomain_ids);
1131 // and cache it
1132 _cached_p2 = p;
1133 if (subdomain_ids)
1134 _cached_subdomain_ids2 = *subdomain_ids;
1135 _cached_values2 = output;
1136 }
1137 else
1138 mooseError("The func_num must be 1 or 2");
1139 }
1140
1141 // Error if the data is out-of-range, which will be the case if the mesh functions are evaluated
1142 // outside the domain
1143 if (output.size() == 0)
1144 {
1145 std::ostringstream oss;
1146 p.print(oss);
1147 mooseError("Failed to access the data for variable '",
1148 _system_variables[local_var_index],
1149 "' at point ",
1150 oss.str(),
1151 " in the '",
1152 name(),
1153 "' SolutionUserObjectBase");
1154 }
1155 return output(local_var_index);
1156}
1157
1158std::map<const Elem *, Real>
1160 const Point & p,
1161 const unsigned int local_var_index,
1162 unsigned int func_num,
1163 const std::set<subdomain_id_type> * subdomain_ids) const
1164{
1165 // Storage for mesh function output
1166 std::map<const Elem *, DenseVector<Number>> temporary_output;
1167
1168 // Extract a value from the _mesh_function
1169 {
1170 Threads::spin_mutex::scoped_lock lock(_solution_user_object_mutex);
1171 if (func_num == 1)
1172 _mesh_function->discontinuous_value(p, 0.0, temporary_output, subdomain_ids);
1173
1174 // Extract a value from _mesh_function2
1175 else if (func_num == 2)
1176 _mesh_function2->discontinuous_value(p, 0.0, temporary_output, subdomain_ids);
1177
1178 else
1179 mooseError("The func_num must be 1 or 2");
1180 }
1181
1182 // Error if the data is out-of-range, which will be the case if the mesh functions are evaluated
1183 // outside the domain
1184 if (temporary_output.size() == 0)
1185 {
1186 std::ostringstream oss;
1187 p.print(oss);
1188 mooseError("Failed to access the data for variable '",
1189 _system_variables[local_var_index],
1190 "' at point ",
1191 oss.str(),
1192 " in the '",
1193 name(),
1194 "' SolutionUserObjectBase");
1195 }
1196
1197 // Fill the actual map that is returned
1198 std::map<const Elem *, Real> output;
1199 for (auto & k : temporary_output)
1200 {
1201 mooseAssert(
1202 k.second.size() > local_var_index,
1203 "In SolutionUserObjectBase::evalMultiValuedMeshFunction variable with local_var_index "
1204 << local_var_index << " does not exist");
1205 output[k.first] = k.second(local_var_index);
1206 }
1207
1208 return output;
1209}
1210
1211RealGradient
1213 const Point & p,
1214 const unsigned int local_var_index,
1215 unsigned int func_num,
1216 const std::set<subdomain_id_type> * subdomain_ids) const
1217{
1218 // Storage for mesh function output
1219 std::vector<Gradient> output;
1220
1221 // Extract a value from the _mesh_function
1222 {
1223 Threads::spin_mutex::scoped_lock lock(_solution_user_object_mutex);
1224 if (func_num == 1)
1225 _mesh_function->gradient(p, 0.0, output, subdomain_ids);
1226
1227 // Extract a value from _mesh_function2
1228 else if (func_num == 2)
1229 _mesh_function2->gradient(p, 0.0, output, subdomain_ids);
1230
1231 else
1232 mooseError("The func_num must be 1 or 2");
1233 }
1234
1235 // Error if the data is out-of-range, which will be the case if the mesh functions are evaluated
1236 // outside the domain
1237 if (output.size() == 0)
1238 {
1239 std::ostringstream oss;
1240 p.print(oss);
1241 mooseError("Failed to access the data for variable '",
1242 _system_variables[local_var_index],
1243 "' at point ",
1244 oss.str(),
1245 " in the '",
1246 name(),
1247 "' SolutionUserObjectBase");
1248 }
1249 return output[local_var_index];
1250}
1251
1252std::map<const Elem *, RealGradient>
1254 const Point & p,
1255 const unsigned int local_var_index,
1256 unsigned int func_num,
1257 const std::set<subdomain_id_type> * subdomain_ids) const
1258{
1259 // Storage for mesh function output
1260 std::map<const Elem *, std::vector<Gradient>> temporary_output;
1261
1262 // Extract a value from the _mesh_function
1263 {
1264 Threads::spin_mutex::scoped_lock lock(_solution_user_object_mutex);
1265 if (func_num == 1)
1266 _mesh_function->discontinuous_gradient(p, 0.0, temporary_output, subdomain_ids);
1267
1268 // Extract a value from _mesh_function2
1269 else if (func_num == 2)
1270 _mesh_function2->discontinuous_gradient(p, 0.0, temporary_output, subdomain_ids);
1271
1272 else
1273 mooseError("The func_num must be 1 or 2");
1274 }
1275
1276 // Error if the data is out-of-range, which will be the case if the mesh functions are evaluated
1277 // outside the domain
1278 if (temporary_output.size() == 0)
1279 {
1280 std::ostringstream oss;
1281 p.print(oss);
1282 mooseError("Failed to access the data for variable '",
1283 _system_variables[local_var_index],
1284 "' at point ",
1285 oss.str(),
1286 " in the '",
1287 name(),
1288 "' SolutionUserObjectBase");
1289 }
1290
1291 // Fill the actual map that is returned
1292 std::map<const Elem *, RealGradient> output;
1293 for (auto & k : temporary_output)
1294 {
1295 mooseAssert(
1296 k.second.size() > local_var_index,
1297 "In SolutionUserObjectBase::evalMultiValuedMeshFunction variable with local_var_index "
1298 << local_var_index << " does not exist");
1299 output[k.first] = k.second[local_var_index];
1300 }
1301
1302 return output;
1303}
1304
1305const std::vector<std::string> &
1310
1311bool
1312SolutionUserObjectBase::isVariableNodal(const std::string & var_name) const
1313{
1314 return std::find(_nodal_variables.begin(), _nodal_variables.end(), var_name) !=
1315 _nodal_variables.end();
1316}
1317
1318Real
1319SolutionUserObjectBase::scalarValue(Real /*t*/, const std::string & var_name) const
1320{
1321 unsigned int var_num = _system->variable_number(var_name);
1322 const DofMap & dof_map = _system->get_dof_map();
1323 std::vector<dof_id_type> dofs;
1324 dof_map.SCALAR_dof_indices(dofs, var_num);
1325 // We can handle only FIRST order scalar variables
1326 return directValue(dofs[0]);
1327}
1328
1329void
1331{
1332#ifdef LIBMESH_HAVE_EXODUS_API
1333 const auto * exio_helper = (_file_type == "exodusII") ? &_exodusII_io->get_exio_helper()
1334 : &_nemesis_io->get_nemio_helper();
1335 const auto & id_to_block = exio_helper->id_to_block_names;
1336 _block_name_to_id.clear();
1337 _block_id_to_name.clear();
1338 for (const auto & it : id_to_block)
1339 {
1340 _block_name_to_id[it.second] = it.first;
1341 _block_id_to_name[it.first] = it.second;
1342 }
1343#endif
1344}
void mooseInfo(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
Definition MooseError.h:401
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
std::array< Real, 2 > values
Definition MortarUtils.C:52
unsigned int dim
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
static InputParameters validParams()
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...
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 addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
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
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
Definition MooseBase.h:205
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
virtual dof_id_type maxElemId() const
Definition MooseMesh.C:3194
virtual bool isDistributedMesh() const
Returns the final Mesh distribution type.
Definition MooseMesh.h:1143
bool hasSecondOrderElements()
check if the mesh has SECOND order elements
Definition MooseMesh.C:3816
const libMesh::FEType & feType() const
Get the type of finite element object.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type.
unsigned int size() const
Return the number of active items in the MultiMooseEnum.
MooseEnum _file_type
File type to read (0 = xda; 1 = ExodusII, 2 = xdr, 3 = Nemesis)
virtual Real solutionSampleTime()=0
Get the time at which to sample the solution.
std::set< subdomain_id_type > _cached_subdomain_ids2
const bool _force_replicated_source
Whether to force the source mesh to be replicated.
MooseEnum getSolutionFileType() const
Get the type of file that was read.
Real pointValue(Real t, const Point &p, const unsigned int local_var_index, const std::set< subdomain_id_type > *subdomain_ids=nullptr) const
Returns a value at a specific location and variable (see SolutionFunction)
const MooseEnum _nodal_variable_order
Nodal variable order, used when reading in solution data.
std::string _system_name
The system name to extract from the XDA/XDR file (xda/xdr only)
RealTensorValue _r0
Rotation matrix that performs the "_rotation0_angle about rotation0_vector".
libMesh::RealGradient evalMeshFunctionGradient(const Point &p, const unsigned int local_var_index, unsigned int func_num, const std::set< subdomain_id_type > *subdomain_ids=nullptr) const
A wrapper method interfacing with the libMesh mesh function for evaluating the gradient.
std::unique_ptr< libMesh::MeshFunction > _mesh_function2
Pointer to second libMesh::MeshFuntion, used for interpolation.
std::map< SubdomainID, SubdomainName > _block_id_to_name
Map from block names to block IDs. Read from the ExodusII file.
std::vector< std::string > _system_variables
A list of variables to extract from the read system.
std::unique_ptr< libMesh::MeshBase > _mesh
Pointer the libMesh::mesh object.
std::vector< std::string > _nodal_variables
Stores names of nodal variables.
DenseVector< Number > _cached_values2
bool _interpolate_times
Flag for triggering interpolation of ExodusII data.
int _exodus_index2
Time index 2, used for interpolation.
unsigned int getLocalVarIndex(const std::string &var_name) const
Returns the local index for a given variable name.
std::vector< Real > _scale
Scale parameter.
std::unique_ptr< libMesh::EquationSystems > _es2
Pointer to second libMesh::EquationSystems object, used for interpolation.
Real _interpolation_factor
Interpolation weight factor.
std::unique_ptr< libMesh::EquationSystems > _es
Pointer to the libMesh::EquationSystems object.
virtual void timestepSetup() override
When reading ExodusII files, this will update the interpolation times.
std::vector< Real > _scale_multiplier
scale_multiplier parameter
void readBlockIdMapFromExodusII()
Read block ID map from the ExodusII file.
std::unique_ptr< NumericVector< Number > > _serialized_solution
Pointer to the serial solution vector.
std::unique_ptr< libMesh::MeshFunction > _mesh_function
Pointer the libMesh::MeshFunction object that the read data is stored.
void readXda()
Method for reading XDA mesh and equation systems file(s) This method is called by the constructor whe...
static Threads::spin_mutex _solution_user_object_mutex
Real pointValueWrapper(Real t, const Point &p, const std::string &var_name, const MooseEnum &weighting_type=weightingType(), const std::set< subdomain_id_type > *subdomain_ids=nullptr) const
Returns a value at a specific location and variable checking for multiple values and weighting these ...
std::map< const Elem *, libMesh::RealGradient > evalMultiValuedMeshFunctionGradient(const Point &p, const unsigned int local_var_index, unsigned int func_num, const std::set< subdomain_id_type > *subdomain_ids=nullptr) const
A wrapper method interfacing with the libMesh mesh function that calls the gradient functionality for...
Real _interpolation_time
Time in the current simulation at which the solution interpolation was last updated.
Real scalarValue(Real t, const std::string &var_name) const
Returns a value of a global variable.
static InputParameters validParams()
bool _initialized
True if initial_setup has executed.
std::vector< std::string > _scalar_variables
Stores names of scalar variables.
std::string _es_file
The XDA/XDR file that contians the EquationSystems data (xda/xdr only)
int _exodus_time_index
Current ExodusII time index.
RealVectorValue _rotation0_vector
vector about which to rotate
std::string _mesh_file
The XDA/ExodusII/XDR/Nemesis file that is being read.
void readExodusIIOrNemesis()
Method for reading an ExodusII or Nemesis file, which is called when a mesh file with a ....
MultiMooseEnum _transformation_order
transformations (rotations, translation, scales) are performed in this order
std::unique_ptr< libMesh::Nemesis_IO > _nemesis_io
Pointer to the libMesh::Nemesis_IO used to read the files.
const std::vector< std::string > & variableNames() const
RealTensorValue _r1
Rotation matrix that performs the "_rotation1_angle about rotation1_vector".
libMesh::System * _system2
Pointer to a second libMesh::System object, used for interpolation.
std::unique_ptr< libMesh::ExodusII_IO > _exodusII_io
Pointer to the libMesh::ExodusII used to read the files.
virtual void execute() override
Execute method.
libMesh::RealGradient pointValueGradient(Real t, const Point &p, const std::string &var_name, const std::set< subdomain_id_type > *subdomain_ids=nullptr) const
Returns the gradient at a specific location and variable (see SolutionFunction)
SolutionUserObjectBase(const InputParameters &parameters)
DenseVector< Number > _cached_values
Cached values.
Real directValue(const Node *node, const std::string &var_name) const
Return a value directly from a Node.
virtual void initialSetup() override
Initialize the System and Mesh objects for the solution being read.
std::map< std::string, unsigned int > _local_variable_index
Stores the local index need by MeshFunction.
std::map< const Elem *, libMesh::RealGradient > discontinuousPointValueGradient(Real t, const Point &p, const std::string &var_name, const std::set< subdomain_id_type > *subdomain_ids=nullptr) const
Returns the gradient at a specific location and variable for cases where the gradient is multivalued ...
libMesh::System * _system
Pointer libMesh::System class storing the read solution.
std::unique_ptr< NumericVector< Number > > _serialized_solution2
Pointer to second serial solution, used for interpolation.
std::vector< std::string > _elemental_variables
Stores names of elemental variables.
virtual void finalize() override
Finalize.
void updateTimeInterpolationFromFile()
Updates the times for interpolating ExodusII or Nemesis data.
Real evalMeshFunction(const Point &p, const unsigned int local_var_index, unsigned int func_num, const std::set< subdomain_id_type > *subdomain_ids=nullptr) const
A wrapper method for calling the various MeshFunctions used for reading the data.
bool isVariableNodal(const std::string &var_name) const
libMesh::RealGradient pointValueGradientWrapper(Real t, const Point &p, const std::string &var_name, const MooseEnum &weighting_type=weightingType(), const std::set< subdomain_id_type > *subdomain_ids=nullptr) const
Returns the gradient at a specific location and variable checking for multiple values and weighting t...
const std::vector< Real > * _exodus_times
The times available in the ExodusII file.
bool updateInterpolationBracketingTimeIndices()
Updates the time indices to interpolate between for ExodusII or Nemesis data.
std::set< subdomain_id_type > _cached_subdomain_ids
Cached subdomain ids.
Real _rotation1_angle
angle (in degrees) which to rotate through about vector _rotation1_vector
std::map< SubdomainName, SubdomainID > _block_name_to_id
Map from block ID to block names. Read from the ExodusII file.
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
int _exodus_index1
Time index 1, used for interpolation.
RealVectorValue _rotation1_vector
vector about which to rotate
std::vector< Real > _translation
Translation.
Real _rotation0_angle
angle (in degrees) which to rotate through about vector _rotation0_vector
std::map< const Elem *, Real > discontinuousPointValue(Real t, Point pt, const unsigned int local_var_index, const std::set< subdomain_id_type > *subdomain_ids=nullptr) const
Returns a value at a specific location and variable for cases where the solution is multivalued at el...
std::map< const Elem *, Real > evalMultiValuedMeshFunction(const Point &p, const unsigned int local_var_index, unsigned int func_num, const std::set< subdomain_id_type > *subdomain_ids=nullptr) const
A wrapper method for calling the various MeshFunctions that calls the mesh function functionality for...
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
const THREAD_ID _tid
Thread ID of this postprocessor.
void SCALAR_dof_indices(std::vector< dof_id_type > &di, const unsigned int vn, const bool old_dofs=false) const
virtual const Node & node_ref(const dof_id_type i) const
virtual const Elem & elem_ref(const dof_id_type i) const
const Parallel::Communicator & _communicator
void get_all_variable_numbers(std::vector< unsigned int > &all_variable_numbers) const
dof_id_type n_dofs() const
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
virtual void clear()
std::unique_ptr< NumericVector< Number > > solution
const std::string & variable_name(const unsigned int i) const
virtual void update()
unsigned int variable_number(std::string_view var) const
const DofMap & get_dof_map() const
unsigned int number() const
const MeshBase & get_mesh() const
std::string formatString(std::string message, const std::string &prefix)
Add new lines and prefixes to a string for pretty display in output NOTE: This makes a copy of the st...
bool hasExtension(const std::string &filename, std::string ext, bool strip_exodus_ext)
Definition MooseUtils.C:398
bool checkFileReadable(const std::string &filename, bool check_line_endings, bool throw_on_unreadable, bool check_for_git_lfs_pointer)
Definition MooseUtils.C:265
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
@ VAR_FIELD_STANDARD
Definition MooseTypes.h:777
std::string stringify(const T &t)
conversion to string
Definition Conversion.h:64
@ VAR_ANY
Definition MooseTypes.h:772
GenericRealTensorValue< is_ad > rotVecToZ(GenericRealVectorValue< is_ad > vec)
provides a rotation matrix that will rotate the vector vec to the z axis (the "2" direction)
const Real pi
RealVectorValue RealGradient
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real