www.mooseframework.org
SolutionUserObject.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
10 #include "SolutionUserObject.h"
11 
12 // MOOSE includes
13 #include "MooseError.h"
14 #include "MooseMesh.h"
15 #include "MooseUtils.h"
16 #include "MooseVariableFE.h"
17 #include "RotationMatrix.h"
18 
19 // libMesh includes
20 #include "libmesh/equation_systems.h"
21 #include "libmesh/mesh_function.h"
22 #include "libmesh/numeric_vector.h"
23 #include "libmesh/nonlinear_implicit_system.h"
24 #include "libmesh/transient_system.h"
25 #include "libmesh/parallel_mesh.h"
26 #include "libmesh/serial_mesh.h"
27 #include "libmesh/exodusII_io.h"
28 #include "libmesh/enum_xdr_mode.h"
29 
31 
33 
36 {
37  // Get the input parameters from the parent class
39 
40  // Add required parameters
41  params.addRequiredParam<MeshFileName>(
42  "mesh", "The name of the mesh file (must be xda or exodusII file).");
43  params.addParam<std::vector<std::string>>(
44  "system_variables",
45  std::vector<std::string>(),
46  "The name of the nodal and elemental variables from the file you want to use for values");
47 
48  // When using XDA files the following must be defined
49  params.addParam<FileName>(
50  "es",
51  "<not supplied>",
52  "The name of the file holding the equation system info in xda format (xda only).");
53  params.addParam<std::string>(
54  "system", "nl0", "The name of the system to pull values out of (xda only).");
55 
56  // When using ExodusII a specific time is extracted
57  params.addParam<std::string>("timestep",
58  "Index of the single timestep used or \"LATEST\" for "
59  "the last timestep (exodusII only). If not supplied, "
60  "time interpolation will occur.");
61 
62  // Add ability to perform coordinate transformation: scale, factor
63  params.addParam<std::vector<Real>>(
64  "scale", std::vector<Real>(LIBMESH_DIM, 1), "Scale factor for points in the simulation");
65  params.addParam<std::vector<Real>>("scale_multiplier",
66  std::vector<Real>(LIBMESH_DIM, 1),
67  "Scale multiplying factor for points in the simulation");
68  params.addParam<std::vector<Real>>("translation",
69  std::vector<Real>(LIBMESH_DIM, 0),
70  "Translation factors for x,y,z coordinates of the simulation");
71  params.addParam<RealVectorValue>("rotation0_vector",
72  RealVectorValue(0, 0, 1),
73  "Vector about which to rotate points of the simulation.");
74  params.addParam<Real>(
75  "rotation0_angle",
76  0.0,
77  "Anticlockwise rotation angle (in degrees) to use for rotation about rotation0_vector.");
78  params.addParam<RealVectorValue>("rotation1_vector",
79  RealVectorValue(0, 0, 1),
80  "Vector about which to rotate points of the simulation.");
81  params.addParam<Real>(
82  "rotation1_angle",
83  0.0,
84  "Anticlockwise rotation angle (in degrees) to use for rotation about rotation1_vector.");
85 
86  // following lines build the default_transformation_order
87  MultiMooseEnum default_transformation_order(
88  "rotation0 translation scale rotation1 scale_multiplier", "translation scale");
89  params.addParam<MultiMooseEnum>(
90  "transformation_order",
91  default_transformation_order,
92  "The order to perform the operations in. Define R0 to be the rotation matrix encoded by "
93  "rotation0_vector and rotation0_angle. Similarly for R1. Denote the scale by s, the "
94  "scale_multiplier by m, and the translation by t. Then, given a point x in the simulation, "
95  "if transformation_order = 'rotation0 scale_multiplier translation scale rotation1' then "
96  "form p = R1*(R0*x*m - t)/s. Then the values provided by the SolutionUserObject at point x "
97  "in the simulation are the variable values at point p in the mesh.");
98  params.addClassDescription("Reads a variable from a mesh in one simulation to another");
99  // Return the parameters
100  return params;
101 }
102 
103 // Static mutex definition
105 
107  : GeneralUserObject(parameters),
108  _file_type(MooseEnum("xda=0 exodusII=1 xdr=2")),
109  _mesh_file(getParam<MeshFileName>("mesh")),
110  _es_file(getParam<FileName>("es")),
111  _system_name(getParam<std::string>("system")),
112  _system_variables(getParam<std::vector<std::string>>("system_variables")),
113  _exodus_time_index(-1),
114  _interpolate_times(false),
115  _system(nullptr),
116  _system2(nullptr),
117  _interpolation_time(0.0),
118  _interpolation_factor(0.0),
119  _exodus_times(nullptr),
120  _exodus_index1(-1),
121  _exodus_index2(-1),
122  _scale(getParam<std::vector<Real>>("scale")),
123  _scale_multiplier(getParam<std::vector<Real>>("scale_multiplier")),
124  _translation(getParam<std::vector<Real>>("translation")),
125  _rotation0_vector(getParam<RealVectorValue>("rotation0_vector")),
126  _rotation0_angle(getParam<Real>("rotation0_angle")),
127  _r0(RealTensorValue()),
128  _rotation1_vector(getParam<RealVectorValue>("rotation1_vector")),
129  _rotation1_angle(getParam<Real>("rotation1_angle")),
130  _r1(RealTensorValue()),
131  _transformation_order(getParam<MultiMooseEnum>("transformation_order")),
132  _initialized(false)
133 {
134  // form rotation matrices with the specified angles
135  Real halfPi = std::acos(0.0);
136  Real a;
137  Real b;
138 
139  a = std::cos(halfPi * -_rotation0_angle / 90);
140  b = std::sin(halfPi * -_rotation0_angle / 90);
141  // the following is an anticlockwise rotation about z
142  RealTensorValue rot0_z(a, -b, 0, b, a, 0, 0, 0, 1);
143  // form the rotation matrix that will take rotation0_vector to the z axis
145  // _r0 is then: rotate points so vec0 lies along z; then rotate about angle0; then rotate points
146  // back
147  _r0 = vec0_to_z.transpose() * (rot0_z * vec0_to_z);
148 
149  a = std::cos(halfPi * -_rotation1_angle / 90);
150  b = std::sin(halfPi * -_rotation1_angle / 90);
151  // the following is an anticlockwise rotation about z
152  RealTensorValue rot1_z(a, -b, 0, b, a, 0, 0, 0, 1);
153  // form the rotation matrix that will take rotation1_vector to the z axis
155  // _r1 is then: rotate points so vec1 lies along z; then rotate about angle1; then rotate points
156  // back
157  _r1 = vec1_to_z.transpose() * (rot1_z * vec1_to_z);
158 
159  if (isParamValid("timestep") && getParam<std::string>("timestep") == "-1")
160  mooseError("A \"timestep\" of -1 is no longer supported for interpolation. Instead simply "
161  "remove this parameter altogether for interpolation");
162 }
163 
165 
166 void
168 {
169  // Check that the required files exist
172 
173  // Read the libmesh::mesh from the xda file
174  _mesh->read(_mesh_file);
175 
176  // Create the libmesh::EquationSystems
177  _es = libmesh_make_unique<EquationSystems>(*_mesh);
178 
179  // Use new read syntax (binary)
180  if (_file_type == "xdr")
181  _es->read(_es_file,
182  DECODE,
183  EquationSystems::READ_HEADER | EquationSystems::READ_DATA |
184  EquationSystems::READ_ADDITIONAL_DATA);
185 
186  // Use new read syntax
187  else if (_file_type == "xda")
188  _es->read(_es_file,
189  READ,
190  EquationSystems::READ_HEADER | EquationSystems::READ_DATA |
191  EquationSystems::READ_ADDITIONAL_DATA);
192 
193  // This should never occur, just in case produce an error
194  else
195  mooseError("Failed to determine proper read method for XDA/XDR equation system file: ",
196  _es_file);
197 
198  // Update and store the EquationSystems name locally
199  _es->update();
200  _system = &_es->get_system(_system_name);
201 }
202 
203 void
205 {
206  // Define a default system name
207  if (_system_name == "")
208  _system_name = "SolutionUserObjectSystem";
209 
210  // Read the Exodus file
211  _exodusII_io = libmesh_make_unique<ExodusII_IO>(*_mesh);
212  _exodusII_io->read(_mesh_file);
213  _exodus_times = &_exodusII_io->get_time_steps();
214 
215  if (isParamValid("timestep"))
216  {
217  std::string s_timestep = getParam<std::string>("timestep");
218  int n_steps = _exodusII_io->get_num_time_steps();
219  if (s_timestep == "LATEST")
220  _exodus_time_index = n_steps;
221  else
222  {
223  std::istringstream ss(s_timestep);
224  if (!((ss >> _exodus_time_index) && ss.eof()) || _exodus_time_index > n_steps)
225  mooseError("Invalid value passed as \"timestep\". Expected \"LATEST\" or a valid integer "
226  "less than ",
227  n_steps,
228  ", received ",
229  s_timestep);
230  }
231  }
232  else
233  // Interpolate between times rather than using values from a set timestep
234  _interpolate_times = true;
235 
236  // Check that the number of time steps is valid
237  int num_exo_times = _exodus_times->size();
238  if (num_exo_times == 0)
239  mooseError("In SolutionUserObject, exodus file contains no timesteps.");
240 
241  // Account for parallel mesh
242  if (dynamic_cast<DistributedMesh *>(_mesh.get()))
243  {
244  _mesh->allow_renumbering(true);
245  _mesh->prepare_for_use(/*false*/);
246  }
247  else
248  {
249  _mesh->allow_renumbering(false);
250  _mesh->prepare_for_use(/*true*/);
251  }
252 
253  // Create EquationSystems object for solution
254  _es = libmesh_make_unique<EquationSystems>(*_mesh);
255  _es->add_system<ExplicitSystem>(_system_name);
256  _system = &_es->get_system(_system_name);
257 
258  // Get the variable name lists as set; these need to be sets to perform set_intersection
259  const std::vector<std::string> & all_nodal(_exodusII_io->get_nodal_var_names());
260  const std::vector<std::string> & all_elemental(_exodusII_io->get_elem_var_names());
261  const std::vector<std::string> & all_scalar(_exodusII_io->get_global_var_names());
262 
263  // Build nodal/elemental variable lists, limit to variables listed in 'system_variables', if
264  // provided
265  if (!_system_variables.empty())
266  {
267  for (const auto & var_name : _system_variables)
268  {
269  if (std::find(all_nodal.begin(), all_nodal.end(), var_name) != all_nodal.end())
270  _nodal_variables.push_back(var_name);
271  if (std::find(all_elemental.begin(), all_elemental.end(), var_name) != all_elemental.end())
272  _elemental_variables.push_back(var_name);
273  if (std::find(all_scalar.begin(), all_scalar.end(), var_name) != all_scalar.end())
274  _scalar_variables.push_back(var_name);
275  }
276  }
277  else
278  {
279  _nodal_variables = all_nodal;
280  _elemental_variables = all_elemental;
281  _scalar_variables = all_scalar;
282  }
283 
284  // Add the variables to the system
285  for (const auto & var_name : _nodal_variables)
286  _system->add_variable(var_name, FIRST);
287 
288  for (const auto & var_name : _elemental_variables)
289  _system->add_variable(var_name, CONSTANT, MONOMIAL);
290 
291  for (const auto & var_name : _scalar_variables)
292  _system->add_variable(var_name, FIRST, SCALAR);
293 
294  // Initialize the equations systems
295  _es->init();
296 
297  // Interpolate times
298  if (_interpolate_times)
299  {
300  // Create a second equation system
301  _es2 = libmesh_make_unique<EquationSystems>(*_mesh);
302  _es2->add_system<ExplicitSystem>(_system_name);
303  _system2 = &_es2->get_system(_system_name);
304 
305  // Add the variables to the system
306  for (const auto & var_name : _nodal_variables)
307  _system2->add_variable(var_name, FIRST);
308 
309  for (const auto & var_name : _elemental_variables)
310  _system2->add_variable(var_name, CONSTANT, MONOMIAL);
311 
312  for (const auto & var_name : _scalar_variables)
313  _system2->add_variable(var_name, FIRST, SCALAR);
314 
315  // Initialize
316  _es2->init();
317 
318  // Update the times for interpolation (initially start at 0)
320 
321  // Copy the solutions from the first system
322  for (const auto & var_name : _nodal_variables)
323  {
324  _exodusII_io->copy_nodal_solution(*_system, var_name, var_name, _exodus_index1 + 1);
325  _exodusII_io->copy_nodal_solution(*_system2, var_name, var_name, _exodus_index2 + 1);
326  }
327 
328  for (const auto & var_name : _elemental_variables)
329  {
330  _exodusII_io->copy_elemental_solution(*_system, var_name, var_name, _exodus_index1 + 1);
331  _exodusII_io->copy_elemental_solution(*_system2, var_name, var_name, _exodus_index2 + 1);
332  }
333 
334  if (_scalar_variables.size() > 0)
335  {
336  _exodusII_io->copy_scalar_solution(
338  _exodusII_io->copy_scalar_solution(
340  }
341 
342  // Update the systems
343  _system->update();
344  _es->update();
345  _system2->update();
346  _es2->update();
347  }
348 
349  // Non-interpolated times
350  else
351  {
352  if (_exodus_time_index > num_exo_times)
353  mooseError("In SolutionUserObject, timestep = ",
355  ", but there are only ",
356  num_exo_times,
357  " time steps.");
358 
359  // Copy the values from the ExodusII file
360  for (const auto & var_name : _nodal_variables)
361  _exodusII_io->copy_nodal_solution(*_system, var_name, var_name, _exodus_time_index);
362 
363  for (const auto & var_name : _elemental_variables)
364  _exodusII_io->copy_elemental_solution(*_system, var_name, var_name, _exodus_time_index);
365 
366  if (_scalar_variables.size() > 0)
367  _exodusII_io->copy_scalar_solution(
369 
370  // Update the equations systems
371  _system->update();
372  _es->update();
373  }
374 }
375 
376 Real
377 SolutionUserObject::directValue(const Node * node, const std::string & var_name) const
378 {
379  // Get the libmesh variable and system numbers
380  unsigned int var_num = _system->variable_number(var_name);
381  unsigned int sys_num = _system->number();
382 
383  // Get the node id and associated dof
384  dof_id_type node_id = node->id();
385  const Node & sys_node = _system->get_mesh().node_ref(node_id);
386  mooseAssert(sys_node.n_dofs(sys_num, var_num) > 0,
387  "Variable " << var_name << " has no DoFs on node " << sys_node.id());
388  dof_id_type dof_id = sys_node.dof_number(sys_num, var_num, 0);
389 
390  // Return the desired value for the dof
391  return directValue(dof_id);
392 }
393 
394 Real
395 SolutionUserObject::directValue(const Elem * elem, const std::string & var_name) const
396 {
397  // Get the libmesh variable and system numbers
398  unsigned int var_num = _system->variable_number(var_name);
399  unsigned int sys_num = _system->number();
400 
401  // Get the element id and associated dof
402  dof_id_type elem_id = elem->id();
403  const Elem & sys_elem = _system->get_mesh().elem_ref(elem_id);
404  mooseAssert(sys_elem.n_dofs(sys_num, var_num) > 0,
405  "Variable " << var_name << " has no DoFs on element " << sys_elem.id());
406  dof_id_type dof_id = sys_elem.dof_number(sys_num, var_num, 0);
407 
408  // Return the desired value
409  return directValue(dof_id);
410 }
411 
412 void
414 {
415 }
416 
417 void
419 {
420 }
421 
422 void
424 {
425  // Update time interpolation for ExodusII solution
426  if (_file_type == 1 && _interpolate_times)
428 }
429 
430 void
432 {
433 }
434 
435 void
437 {
438 
439  // Make sure this only happens once
440  if (_initialized)
441  return;
442 
443  // Create a libmesh::Mesh object for storing the loaded data.
444  // Several aspects of SolutionUserObject won't work with a DistributedMesh:
445  // .) ExodusII_IO::copy_nodal_solution() doesn't work in parallel.
446  // .) We don't know if directValue will be used, which may request
447  // a value on a Node we don't have.
448  // We force the Mesh used here to be a ReplicatedMesh.
449  _mesh = libmesh_make_unique<ReplicatedMesh>(_communicator);
450 
451  // ExodusII mesh file supplied
452  if (MooseUtils::hasExtension(_mesh_file, "e", /*strip_exodus_ext =*/true))
453  {
454  _file_type = "exodusII";
455  readExodusII();
456  }
457 
458  // XDA mesh file supplied
459  else if (MooseUtils::hasExtension(_mesh_file, "xda"))
460  {
461  _file_type = "xda";
462  readXda();
463  }
464 
465  else if (MooseUtils::hasExtension(_mesh_file, "xdr"))
466  {
467  _file_type = "xdr";
468  readXda();
469  }
470 
471  // Produce an error for an unknown file type
472  else
473  mooseError("In SolutionUserObject, invalid file type (only .xda, .xdr, and .e supported)");
474 
475  // Initialize the serial solution vector
476  _serialized_solution = NumericVector<Number>::build(_communicator);
477  _serialized_solution->init(_system->n_dofs(), false, SERIAL);
478 
479  // Pull down a full copy of this vector on every processor so we can get values in parallel
480  _system->solution->localize(*_serialized_solution);
481 
482  // Vector of variable numbers to apply the MeshFunction to
483  std::vector<unsigned int> var_nums;
484 
485  // If no variables were given, use all of them
486  if (_system_variables.empty())
487  {
488  _system->get_all_variable_numbers(var_nums);
489  for (const auto & var_num : var_nums)
490  _system_variables.push_back(_system->variable_name(var_num));
491  }
492 
493  // Otherwise, gather the numbers for the variables given
494  else
495  {
496  for (const auto & var_name : _system_variables)
497  var_nums.push_back(_system->variable_number(var_name));
498  }
499 
500  // Create the MeshFunction for working with the solution data
501  _mesh_function = libmesh_make_unique<MeshFunction>(
502  *_es, *_serialized_solution, _system->get_dof_map(), var_nums);
503  _mesh_function->init();
504 
505  // Tell the MeshFunctions that we might be querying them outside the
506  // mesh, so we can handle any errors at the MOOSE rather than at the
507  // libMesh level.
508  DenseVector<Number> default_values;
509  _mesh_function->enable_out_of_mesh_mode(default_values);
510 
511  // Build second MeshFunction for interpolation
512  if (_interpolate_times)
513  {
514  // Need to pull down a full copy of this vector on every processor so we can get values in
515  // parallel
516  _serialized_solution2 = NumericVector<Number>::build(_communicator);
517  _serialized_solution2->init(_system2->n_dofs(), false, SERIAL);
518  _system2->solution->localize(*_serialized_solution2);
519 
520  // Create the MeshFunction for the second copy of the data
521  _mesh_function2 = libmesh_make_unique<MeshFunction>(
522  *_es2, *_serialized_solution2, _system2->get_dof_map(), var_nums);
523  _mesh_function2->init();
524  _mesh_function2->enable_out_of_mesh_mode(default_values);
525  }
526 
527  // Populate the MeshFunction variable index
528  for (unsigned int i = 0; i < _system_variables.size(); ++i)
529  {
530  std::string name = _system_variables[i];
532  }
533 
534  // Set initialization flag
535  _initialized = true;
536 }
537 
538 MooseEnum
540 {
541  return _file_type;
542 }
543 
544 void
546 {
547  if (time != _interpolation_time)
548  {
550  {
551 
552  for (const auto & var_name : _nodal_variables)
553  _exodusII_io->copy_nodal_solution(*_system, var_name, var_name, _exodus_index1 + 1);
554  for (const auto & var_name : _elemental_variables)
555  _exodusII_io->copy_elemental_solution(*_system, var_name, var_name, _exodus_index1 + 1);
556  if (_scalar_variables.size() > 0)
557  _exodusII_io->copy_scalar_solution(
559 
560  _system->update();
561  _es->update();
562  _system->solution->localize(*_serialized_solution);
563 
564  for (const auto & var_name : _nodal_variables)
565  _exodusII_io->copy_nodal_solution(*_system2, var_name, var_name, _exodus_index2 + 1);
566  for (const auto & var_name : _elemental_variables)
567  _exodusII_io->copy_elemental_solution(*_system2, var_name, var_name, _exodus_index2 + 1);
568  if (_scalar_variables.size() > 0)
569  _exodusII_io->copy_scalar_solution(
571 
572  _system2->update();
573  _es2->update();
574  _system2->solution->localize(*_serialized_solution2);
575  }
576  _interpolation_time = time;
577  }
578 }
579 
580 bool
582 {
583  if (_file_type != 1)
584  mooseError(
585  "In SolutionUserObject, getTimeInterpolationData only applicable for exodusII file type");
586 
587  int old_index1 = _exodus_index1;
588  int old_index2 = _exodus_index2;
589 
590  int num_exo_times = _exodus_times->size();
591 
592  if (time < (*_exodus_times)[0])
593  {
594  _exodus_index1 = 0;
595  _exodus_index2 = 0;
596  _interpolation_factor = 0.0;
597  }
598  else
599  {
600  for (int i = 0; i < num_exo_times - 1; ++i)
601  {
602  if (time <= (*_exodus_times)[i + 1])
603  {
604  _exodus_index1 = i;
605  _exodus_index2 = i + 1;
607  (time - (*_exodus_times)[i]) / ((*_exodus_times)[i + 1] - (*_exodus_times)[i]);
608  break;
609  }
610  else if (i == num_exo_times - 2)
611  {
612  _exodus_index1 = num_exo_times - 1;
613  _exodus_index2 = num_exo_times - 1;
614  _interpolation_factor = 1.0;
615  break;
616  }
617  }
618  }
619 
620  bool indices_modified(false);
621 
622  if (_exodus_index1 != old_index1 || _exodus_index2 != old_index2)
623  indices_modified = true;
624 
625  return indices_modified;
626 }
627 
628 unsigned int
629 SolutionUserObject::getLocalVarIndex(const std::string & var_name) const
630 {
631  // Extract the variable index for the MeshFunction(s)
632  std::map<std::string, unsigned int>::const_iterator it = _local_variable_index.find(var_name);
633  if (it == _local_variable_index.end())
634  mooseError("Value requested for nonexistent variable '",
635  var_name,
636  "' in the '",
637  name(),
638  "' SolutionUserObject");
639  return it->second;
640 }
641 
642 Real
644  const Point & p,
645  const std::string & var_name,
646  const MooseEnum & weighting_type,
647  const std::set<subdomain_id_type> * subdomain_ids) const
648 {
649  // first check if the FE type is continuous because in that case the value is
650  // unique and we can take a short cut, the default weighting_type found_first also
651  // shortcuts out
652  auto family =
654  .getVariable(
656  .feType()
657  .family;
658 
659  if (weighting_type == 1 ||
660  (family != L2_LAGRANGE && family != MONOMIAL && family != L2_HIERARCHIC))
661  return pointValue(t, p, var_name, subdomain_ids);
662 
663  // the shape function is discontinuous so we need to compute a suitable unique value
664  std::map<const Elem *, Real> values = discontinuousPointValue(t, p, var_name);
665  switch (weighting_type)
666  {
667  case 2:
668  {
669  Real average = 0.0;
670  for (auto & v : values)
671  average += v.second;
672  return average / Real(values.size());
673  }
674  case 4:
675  {
676  Real smallest_elem_id_value = std::numeric_limits<Real>::max();
677  dof_id_type smallest_elem_id = _fe_problem.mesh().maxElemId();
678  for (auto & v : values)
679  if (v.first->id() < smallest_elem_id)
680  {
681  smallest_elem_id = v.first->id();
682  smallest_elem_id_value = v.second;
683  }
684  return smallest_elem_id_value;
685  }
686  case 8:
687  {
688  Real largest_elem_id_value = std::numeric_limits<Real>::lowest();
689  dof_id_type largest_elem_id = 0;
690  for (auto & v : values)
691  if (v.first->id() > largest_elem_id)
692  {
693  largest_elem_id = v.first->id();
694  largest_elem_id_value = v.second;
695  }
696  return largest_elem_id_value;
697  }
698  }
699 
700  mooseError(
701  "SolutionUserObject::pointValueWrapper reaches line that it should not be able to reach.");
702  return 0.0;
703 }
704 
705 Real
707  const Point & p,
708  const std::string & var_name,
709  const std::set<subdomain_id_type> * subdomain_ids) const
710 {
711  const unsigned int local_var_index = getLocalVarIndex(var_name);
712  return pointValue(t, p, local_var_index, subdomain_ids);
713 }
714 
715 Real
716 SolutionUserObject::pointValue(Real libmesh_dbg_var(t),
717  const Point & p,
718  const unsigned int local_var_index,
719  const std::set<subdomain_id_type> * subdomain_ids) const
720 {
721  // Create copy of point
722  Point pt(p);
723 
724  // do the transformations
725  for (unsigned int trans_num = 0; trans_num < _transformation_order.size(); ++trans_num)
726  {
727  if (_transformation_order[trans_num] == "rotation0")
728  pt = _r0 * pt;
729  else if (_transformation_order[trans_num] == "translation")
730  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
731  pt(i) -= _translation[i];
732  else if (_transformation_order[trans_num] == "scale")
733  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
734  pt(i) /= _scale[i];
735  else if (_transformation_order[trans_num] == "scale_multiplier")
736  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
737  pt(i) *= _scale_multiplier[i];
738  else if (_transformation_order[trans_num] == "rotation1")
739  pt = _r1 * pt;
740  }
741 
742  // Extract the value at the current point
743  Real val = evalMeshFunction(pt, local_var_index, 1, subdomain_ids);
744 
745  // Interpolate
746  if (_file_type == 1 && _interpolate_times)
747  {
748  mooseAssert(t == _interpolation_time,
749  "Time passed into value() must match time at last call to timestepSetup()");
750  Real val2 = evalMeshFunction(pt, local_var_index, 2, subdomain_ids);
751  val = val + (val2 - val) * _interpolation_factor;
752  }
753 
754  return val;
755 }
756 
757 std::map<const Elem *, Real>
759  const Point & p,
760  const std::string & var_name,
761  const std::set<subdomain_id_type> * subdomain_ids) const
762 {
763  const unsigned int local_var_index = getLocalVarIndex(var_name);
764  return discontinuousPointValue(t, p, local_var_index, subdomain_ids);
765 }
766 
767 std::map<const Elem *, Real>
768 SolutionUserObject::discontinuousPointValue(Real libmesh_dbg_var(t),
769  Point pt,
770  const unsigned int local_var_index,
771  const std::set<subdomain_id_type> * subdomain_ids) const
772 {
773  // do the transformations
774  for (unsigned int trans_num = 0; trans_num < _transformation_order.size(); ++trans_num)
775  {
776  if (_transformation_order[trans_num] == "rotation0")
777  pt = _r0 * pt;
778  else if (_transformation_order[trans_num] == "translation")
779  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
780  pt(i) -= _translation[i];
781  else if (_transformation_order[trans_num] == "scale")
782  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
783  pt(i) /= _scale[i];
784  else if (_transformation_order[trans_num] == "scale_multiplier")
785  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
786  pt(i) *= _scale_multiplier[i];
787  else if (_transformation_order[trans_num] == "rotation1")
788  pt = _r1 * pt;
789  }
790 
791  // Extract the value at the current point
792  std::map<const Elem *, Real> map =
793  evalMultiValuedMeshFunction(pt, local_var_index, 1, subdomain_ids);
794 
795  // Interpolate
796  if (_file_type == 1 && _interpolate_times)
797  {
798  mooseAssert(t == _interpolation_time,
799  "Time passed into value() must match time at last call to timestepSetup()");
800  std::map<const Elem *, Real> map2 = evalMultiValuedMeshFunction(pt, local_var_index, 2);
801 
802  if (map.size() != map2.size())
803  mooseError("In SolutionUserObject::discontinuousPointValue map and map2 have different size");
804 
805  // construct the interpolated map
806  for (auto & k : map)
807  {
808  if (map2.find(k.first) == map2.end())
809  mooseError(
810  "In SolutionUserObject::discontinuousPointValue map and map2 have differing keys");
811  Real val = k.second;
812  Real val2 = map2[k.first];
813  map[k.first] = val + (val2 - val) * _interpolation_factor;
814  }
815  }
816 
817  return map;
818 }
819 
820 RealGradient
822  Real t,
823  const Point & p,
824  const std::string & var_name,
825  const MooseEnum & weighting_type,
826  const std::set<subdomain_id_type> * subdomain_ids) const
827 {
828  // the default weighting_type found_first shortcuts out
829  if (weighting_type == 1)
830  return pointValueGradient(t, p, var_name, subdomain_ids);
831 
832  // the shape function is discontinuous so we need to compute a suitable unique value
833  std::map<const Elem *, RealGradient> values =
834  discontinuousPointValueGradient(t, p, var_name, subdomain_ids);
835  switch (weighting_type)
836  {
837  case 2:
838  {
839  RealGradient average = RealGradient(0.0, 0.0, 0.0);
840  for (auto & v : values)
841  average += v.second;
842  return average / Real(values.size());
843  }
844  case 4:
845  {
846  RealGradient smallest_elem_id_value;
847  dof_id_type smallest_elem_id = _fe_problem.mesh().maxElemId();
848  for (auto & v : values)
849  if (v.first->id() < smallest_elem_id)
850  {
851  smallest_elem_id = v.first->id();
852  smallest_elem_id_value = v.second;
853  }
854  return smallest_elem_id_value;
855  }
856  case 8:
857  {
858  RealGradient largest_elem_id_value;
859  dof_id_type largest_elem_id = 0;
860  for (auto & v : values)
861  if (v.first->id() > largest_elem_id)
862  {
863  largest_elem_id = v.first->id();
864  largest_elem_id_value = v.second;
865  }
866  return largest_elem_id_value;
867  }
868  }
869 
870  mooseError("SolutionUserObject::pointValueGradientWrapper reaches line that it should not be "
871  "able to reach.");
872  return RealGradient(0.0, 0.0, 0.0);
873 }
874 
875 RealGradient
877  const Point & p,
878  const std::string & var_name,
879  const std::set<subdomain_id_type> * subdomain_ids) const
880 {
881  const unsigned int local_var_index = getLocalVarIndex(var_name);
882  return pointValueGradient(t, p, local_var_index, subdomain_ids);
883 }
884 
885 RealGradient
886 SolutionUserObject::pointValueGradient(Real libmesh_dbg_var(t),
887  Point pt,
888  const unsigned int local_var_index,
889  const std::set<subdomain_id_type> * subdomain_ids) const
890 {
891  // do the transformations
892  for (unsigned int trans_num = 0; trans_num < _transformation_order.size(); ++trans_num)
893  {
894  if (_transformation_order[trans_num] == "rotation0")
895  pt = _r0 * pt;
896  else if (_transformation_order[trans_num] == "translation")
897  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
898  pt(i) -= _translation[i];
899  else if (_transformation_order[trans_num] == "scale")
900  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
901  pt(i) /= _scale[i];
902  else if (_transformation_order[trans_num] == "scale_multiplier")
903  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
904  pt(i) *= _scale_multiplier[i];
905  else if (_transformation_order[trans_num] == "rotation1")
906  pt = _r1 * pt;
907  }
908 
909  // Extract the value at the current point
910  RealGradient val = evalMeshFunctionGradient(pt, local_var_index, 1, subdomain_ids);
911 
912  // Interpolate
913  if (_file_type == 1 && _interpolate_times)
914  {
915  mooseAssert(t == _interpolation_time,
916  "Time passed into value() must match time at last call to timestepSetup()");
917  RealGradient val2 = evalMeshFunctionGradient(pt, local_var_index, 2, subdomain_ids);
918  val = val + (val2 - val) * _interpolation_factor;
919  }
920 
921  return val;
922 }
923 
924 std::map<const Elem *, RealGradient>
926  Real t,
927  const Point & p,
928  const std::string & var_name,
929  const std::set<subdomain_id_type> * subdomain_ids) const
930 {
931  const unsigned int local_var_index = getLocalVarIndex(var_name);
932  return discontinuousPointValueGradient(t, p, local_var_index, subdomain_ids);
933 }
934 
935 std::map<const Elem *, RealGradient>
937  Real libmesh_dbg_var(t),
938  Point pt,
939  const unsigned int local_var_index,
940  const std::set<subdomain_id_type> * subdomain_ids) const
941 {
942  // do the transformations
943  for (unsigned int trans_num = 0; trans_num < _transformation_order.size(); ++trans_num)
944  {
945  if (_transformation_order[trans_num] == "rotation0")
946  pt = _r0 * pt;
947  else if (_transformation_order[trans_num] == "translation")
948  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
949  pt(i) -= _translation[i];
950  else if (_transformation_order[trans_num] == "scale")
951  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
952  pt(i) /= _scale[i];
953  else if (_transformation_order[trans_num] == "scale_multiplier")
954  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
955  pt(i) *= _scale_multiplier[i];
956  else if (_transformation_order[trans_num] == "rotation1")
957  pt = _r1 * pt;
958  }
959 
960  // Extract the value at the current point
961  std::map<const Elem *, RealGradient> map =
962  evalMultiValuedMeshFunctionGradient(pt, local_var_index, 1, subdomain_ids);
963 
964  // Interpolate
965  if (_file_type == 1 && _interpolate_times)
966  {
967  mooseAssert(t == _interpolation_time,
968  "Time passed into value() must match time at last call to timestepSetup()");
969  std::map<const Elem *, RealGradient> map2 =
970  evalMultiValuedMeshFunctionGradient(pt, local_var_index, 1, subdomain_ids);
971 
972  if (map.size() != map2.size())
973  mooseError("In SolutionUserObject::discontinuousPointValue map and map2 have different size");
974 
975  // construct the interpolated map
976  for (auto & k : map)
977  {
978  if (map2.find(k.first) == map2.end())
979  mooseError(
980  "In SolutionUserObject::discontinuousPointValue map and map2 have differing keys");
981  RealGradient val = k.second;
982  RealGradient val2 = map2[k.first];
983  map[k.first] = val + (val2 - val) * _interpolation_factor;
984  }
985  }
986 
987  return map;
988 }
989 
990 Real
991 SolutionUserObject::directValue(dof_id_type dof_index) const
992 {
993  Real val = (*_serialized_solution)(dof_index);
994  if (_file_type == 1 && _interpolate_times)
995  {
996  Real val2 = (*_serialized_solution2)(dof_index);
997  val = val + (val2 - val) * _interpolation_factor;
998  }
999  return val;
1000 }
1001 
1002 Real
1004  const unsigned int local_var_index,
1005  unsigned int func_num,
1006  const std::set<subdomain_id_type> * subdomain_ids) const
1007 {
1008  // Storage for mesh function output
1009  DenseVector<Number> output;
1010 
1011  // Extract a value from the _mesh_function
1012  {
1013  Threads::spin_mutex::scoped_lock lock(_solution_user_object_mutex);
1014  if (func_num == 1)
1015  (*_mesh_function)(p, 0.0, output, subdomain_ids);
1016 
1017  // Extract a value from _mesh_function2
1018  else if (func_num == 2)
1019  (*_mesh_function2)(p, 0.0, output, subdomain_ids);
1020 
1021  else
1022  mooseError("The func_num must be 1 or 2");
1023  }
1024 
1025  // Error if the data is out-of-range, which will be the case if the mesh functions are evaluated
1026  // outside the domain
1027  if (output.size() == 0)
1028  {
1029  std::ostringstream oss;
1030  p.print(oss);
1031  mooseError("Failed to access the data for variable '",
1032  _system_variables[local_var_index],
1033  "' at point ",
1034  oss.str(),
1035  " in the '",
1036  name(),
1037  "' SolutionUserObject");
1038  }
1039  return output(local_var_index);
1040 }
1041 
1042 std::map<const Elem *, Real>
1044  const Point & p,
1045  const unsigned int local_var_index,
1046  unsigned int func_num,
1047  const std::set<subdomain_id_type> * subdomain_ids) const
1048 {
1049  // Storage for mesh function output
1050  std::map<const Elem *, DenseVector<Number>> temporary_output;
1051 
1052  // Extract a value from the _mesh_function
1053  {
1054  Threads::spin_mutex::scoped_lock lock(_solution_user_object_mutex);
1055  if (func_num == 1)
1056  _mesh_function->discontinuous_value(p, 0.0, temporary_output, subdomain_ids);
1057 
1058  // Extract a value from _mesh_function2
1059  else if (func_num == 2)
1060  _mesh_function2->discontinuous_value(p, 0.0, temporary_output, subdomain_ids);
1061 
1062  else
1063  mooseError("The func_num must be 1 or 2");
1064  }
1065 
1066  // Error if the data is out-of-range, which will be the case if the mesh functions are evaluated
1067  // outside the domain
1068  if (temporary_output.size() == 0)
1069  {
1070  std::ostringstream oss;
1071  p.print(oss);
1072  mooseError("Failed to access the data for variable '",
1073  _system_variables[local_var_index],
1074  "' at point ",
1075  oss.str(),
1076  " in the '",
1077  name(),
1078  "' SolutionUserObject");
1079  }
1080 
1081  // Fill the actual map that is returned
1082  std::map<const Elem *, Real> output;
1083  for (auto & k : temporary_output)
1084  {
1085  mooseAssert(k.second.size() > local_var_index,
1086  "In SolutionUserObject::evalMultiValuedMeshFunction variable with local_var_index "
1087  << local_var_index << " does not exist");
1088  output[k.first] = k.second(local_var_index);
1089  }
1090 
1091  return output;
1092 }
1093 
1094 RealGradient
1096  const Point & p,
1097  const unsigned int local_var_index,
1098  unsigned int func_num,
1099  const std::set<subdomain_id_type> * subdomain_ids) const
1100 {
1101  // Storage for mesh function output
1102  std::vector<Gradient> output;
1103 
1104  // Extract a value from the _mesh_function
1105  {
1106  Threads::spin_mutex::scoped_lock lock(_solution_user_object_mutex);
1107  if (func_num == 1)
1108  _mesh_function->gradient(p, 0.0, output, subdomain_ids);
1109 
1110  // Extract a value from _mesh_function2
1111  else if (func_num == 2)
1112  _mesh_function2->gradient(p, 0.0, output, subdomain_ids);
1113 
1114  else
1115  mooseError("The func_num must be 1 or 2");
1116  }
1117 
1118  // Error if the data is out-of-range, which will be the case if the mesh functions are evaluated
1119  // outside the domain
1120  if (output.size() == 0)
1121  {
1122  std::ostringstream oss;
1123  p.print(oss);
1124  mooseError("Failed to access the data for variable '",
1125  _system_variables[local_var_index],
1126  "' at point ",
1127  oss.str(),
1128  " in the '",
1129  name(),
1130  "' SolutionUserObject");
1131  }
1132  return output[local_var_index];
1133 }
1134 
1135 std::map<const Elem *, RealGradient>
1137  const Point & p,
1138  const unsigned int local_var_index,
1139  unsigned int func_num,
1140  const std::set<subdomain_id_type> * subdomain_ids) const
1141 {
1142  // Storage for mesh function output
1143  std::map<const Elem *, std::vector<Gradient>> temporary_output;
1144 
1145  // Extract a value from the _mesh_function
1146  {
1147  Threads::spin_mutex::scoped_lock lock(_solution_user_object_mutex);
1148  if (func_num == 1)
1149  _mesh_function->discontinuous_gradient(p, 0.0, temporary_output, subdomain_ids);
1150 
1151  // Extract a value from _mesh_function2
1152  else if (func_num == 2)
1153  _mesh_function2->discontinuous_gradient(p, 0.0, temporary_output, subdomain_ids);
1154 
1155  else
1156  mooseError("The func_num must be 1 or 2");
1157  }
1158 
1159  // Error if the data is out-of-range, which will be the case if the mesh functions are evaluated
1160  // outside the domain
1161  if (temporary_output.size() == 0)
1162  {
1163  std::ostringstream oss;
1164  p.print(oss);
1165  mooseError("Failed to access the data for variable '",
1166  _system_variables[local_var_index],
1167  "' at point ",
1168  oss.str(),
1169  " in the '",
1170  name(),
1171  "' SolutionUserObject");
1172  }
1173 
1174  // Fill the actual map that is returned
1175  std::map<const Elem *, RealGradient> output;
1176  for (auto & k : temporary_output)
1177  {
1178  mooseAssert(k.second.size() > local_var_index,
1179  "In SolutionUserObject::evalMultiValuedMeshFunction variable with local_var_index "
1180  << local_var_index << " does not exist");
1181  output[k.first] = k.second[local_var_index];
1182  }
1183 
1184  return output;
1185 }
1186 
1187 const std::vector<std::string> &
1189 {
1190  return _system_variables;
1191 }
1192 
1193 bool
1194 SolutionUserObject::isVariableNodal(const std::string & var_name) const
1195 {
1196  return std::find(_nodal_variables.begin(), _nodal_variables.end(), var_name) !=
1197  _nodal_variables.end();
1198 }
1199 
1200 Real
1201 SolutionUserObject::scalarValue(Real /*t*/, const std::string & var_name) const
1202 {
1203  unsigned int var_num = _system->variable_number(var_name);
1204  const DofMap & dof_map = _system->get_dof_map();
1205  std::vector<dof_id_type> dofs;
1206  dof_map.SCALAR_dof_indices(dofs, var_num);
1207  // We can handle only FIRST order scalar variables
1208  return directValue(dofs[0]);
1209 }
registerMooseObject
registerMooseObject("MooseApp", SolutionUserObject)
MooseMesh.h
SolutionUserObject::_rotation1_vector
RealVectorValue _rotation1_vector
vector about which to rotate
Definition: SolutionUserObject.h:466
MooseVariableBase::feType
const FEType & feType() const
Get the type of finite element object.
Definition: MooseVariableBase.h:53
MooseObject::mooseError
void mooseError(Args &&... args) const
Definition: MooseObject.h:141
SolutionUserObject::_file_type
MooseEnum _file_type
File type to read (0 = xda; 1 = ExodusII)
Definition: SolutionUserObject.h:370
SolutionUserObject::discontinuousPointValueGradient
std::map< const Elem *, 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 ...
Definition: SolutionUserObject.C:925
RotationMatrix::rotVecToZ
RealTensorValue rotVecToZ(RealVectorValue vec)
provides a rotation matrix that will rotate the vector vec to the z axis (the "2" direction)
Definition: RotationMatrix.C:13
MooseObject::isParamValid
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseObject.h:100
SolutionUserObject::updateExodusTimeInterpolation
void updateExodusTimeInterpolation(Real time)
Updates the times for interpolating ExodusII data.
Definition: SolutionUserObject.C:545
SolutionUserObject::evalMeshFunctionGradient
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.
Definition: SolutionUserObject.C:1095
SolutionUserObject::evalMeshFunction
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.
Definition: SolutionUserObject.C:1003
SolutionUserObject::_system_name
std::string _system_name
The system name to extract from the XDA file (xda only)
Definition: SolutionUserObject.h:379
SolutionUserObject::getLocalVarIndex
unsigned int getLocalVarIndex(const std::string &var_name) const
Returns the local index for a given variable name.
Definition: SolutionUserObject.C:629
SolutionUserObject::_exodus_index1
int _exodus_index1
Time index 1, used for interpolation.
Definition: SolutionUserObject.h:442
SolutionUserObject::_initialized
bool _initialized
True if initial_setup has executed.
Definition: SolutionUserObject.h:478
SolutionUserObject::_exodus_times
const std::vector< Real > * _exodus_times
The times available in the ExodusII file.
Definition: SolutionUserObject.h:439
SolutionUserObject::_exodusII_io
std::unique_ptr< ExodusII_IO > _exodusII_io
Pointer to the libMesh::ExodusII used to read the files.
Definition: SolutionUserObject.h:415
UserObject::_fe_problem
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
Definition: UserObject.h:145
MooseEnum
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
SolutionUserObject::finalize
virtual void finalize() override
Finalize.
Definition: SolutionUserObject.C:418
SolutionUserObject::pointValueGradient
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)
Definition: SolutionUserObject.C:876
InputParameters::addParam
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object.
Definition: InputParameters.h:1198
SolutionUserObject::_interpolate_times
bool _interpolate_times
Flag for triggering interpolation of ExodusII data.
Definition: SolutionUserObject.h:400
GeneralUserObject::validParams
static InputParameters validParams()
Definition: GeneralUserObject.C:15
SolutionUserObject::_interpolation_factor
Real _interpolation_factor
Interpolation weight factor.
Definition: SolutionUserObject.h:436
SolutionUserObject::_scalar_variables
std::vector< std::string > _scalar_variables
Stores names of scalar variables.
Definition: SolutionUserObject.h:394
libMesh::RealVectorValue
VectorValue< Real > RealVectorValue
Definition: Assembly.h:30
SolutionUserObject::execute
virtual void execute() override
Execute method.
Definition: SolutionUserObject.C:431
SolutionUserObject::readExodusII
void readExodusII()
Method for reading an ExodusII file, which is called when 'file_type = exodusII is set in the input f...
Definition: SolutionUserObject.C:204
SolutionUserObject::initialize
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
Definition: SolutionUserObject.C:413
SolutionUserObject::_nodal_variables
std::vector< std::string > _nodal_variables
Stores names of nodal variables.
Definition: SolutionUserObject.h:388
SolutionUserObject::validParams
static InputParameters validParams()
Definition: SolutionUserObject.C:35
SolutionUserObject::_rotation1_angle
Real _rotation1_angle
angle (in degrees) which to rotate through about vector _rotation1_vector
Definition: SolutionUserObject.h:469
SolutionUserObject::_serialized_solution
std::unique_ptr< NumericVector< Number > > _serialized_solution
Pointer to the serial solution vector.
Definition: SolutionUserObject.h:418
SolutionUserObject::_system_variables
std::vector< std::string > _system_variables
A list of variables to extract from the read system.
Definition: SolutionUserObject.h:382
InputParameters
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
Definition: InputParameters.h:53
SolutionUserObject::_r0
RealTensorValue _r0
Rotation matrix that performs the "_rotation0_angle about rotation0_vector".
Definition: SolutionUserObject.h:463
Moose::VAR_ANY
Definition: MooseTypes.h:610
SolutionUserObject::_system
System * _system
Pointer libMesh::System class storing the read solution.
Definition: SolutionUserObject.h:409
SolutionUserObject::discontinuousPointValue
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...
SolutionUserObject::_es_file
std::string _es_file
The XDA file that contians the EquationSystems data (xda only)
Definition: SolutionUserObject.h:376
SolutionUserObject::_transformation_order
MultiMooseEnum _transformation_order
transformations (rotations, translation, scales) are performed in this order
Definition: SolutionUserObject.h:475
SolutionUserObject::directValue
Real directValue(const Node *node, const std::string &var_name) const
Return a value directly from a Node.
Definition: SolutionUserObject.C:377
SolutionUserObject::timestepSetup
virtual void timestepSetup() override
When reading ExodusII files, this will update the interpolation times.
Definition: SolutionUserObject.C:423
SolutionUserObject::_translation
std::vector< Real > _translation
Translation.
Definition: SolutionUserObject.h:454
SolutionUserObject::_elemental_variables
std::vector< std::string > _elemental_variables
Stores names of elemental variables.
Definition: SolutionUserObject.h:391
SolutionUserObject::~SolutionUserObject
virtual ~SolutionUserObject()
Definition: SolutionUserObject.C:164
MooseUtils::hasExtension
bool hasExtension(const std::string &filename, std::string ext, bool strip_exodus_ext=false)
Function tests if the supplied filename as the desired extension.
Definition: MooseUtils.C:268
SolutionUserObject::_exodus_index2
int _exodus_index2
Time index 2, used for interpolation.
Definition: SolutionUserObject.h:445
TransientInterface::_t
Real & _t
Time.
Definition: TransientInterface.h:58
SolutionUserObject.h
MultiMooseEnum::size
unsigned int size() const
Return the number of active items in the MultiMooseEnum.
Definition: MultiMooseEnum.C:233
RotationMatrix.h
SolutionUserObject::scalarValue
Real scalarValue(Real t, const std::string &var_name) const
Returns a value of a global variable.
Definition: SolutionUserObject.C:1201
SolutionUserObject::_serialized_solution2
std::unique_ptr< NumericVector< Number > > _serialized_solution2
Pointer to second serial solution, used for interpolation.
Definition: SolutionUserObject.h:430
InputParameters::addClassDescription
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.
Definition: InputParameters.C:70
SolutionUserObject::_rotation0_angle
Real _rotation0_angle
angle (in degrees) which to rotate through about vector _rotation0_vector
Definition: SolutionUserObject.h:460
SolutionUserObject
User object that reads an existing solution from an input file and uses it in the current simulation.
Definition: SolutionUserObject.h:36
SolutionUserObject::_mesh_function2
std::unique_ptr< MeshFunction > _mesh_function2
Pointer to second libMesh::MeshFuntion, used for interpolation.
Definition: SolutionUserObject.h:427
SolutionUserObject::updateExodusBracketingTimeIndices
bool updateExodusBracketingTimeIndices(Real time)
Updates the time indices to interpolate between for ExodusII data.
Definition: SolutionUserObject.C:581
SolutionUserObject::SolutionUserObject
SolutionUserObject(const InputParameters &parameters)
Definition: SolutionUserObject.C:106
SolutionUserObject::isVariableNodal
bool isVariableNodal(const std::string &var_name) const
Definition: SolutionUserObject.C:1194
SolutionUserObject::getSolutionFileType
MooseEnum getSolutionFileType()
Get the type of file that was read.
Definition: SolutionUserObject.C:539
SolutionUserObject::_scale_multiplier
std::vector< Real > _scale_multiplier
scale_multiplier parameter
Definition: SolutionUserObject.h:451
MooseVariableFE.h
SolutionUserObject::_mesh_file
std::string _mesh_file
The XDA or ExodusII file that is being read.
Definition: SolutionUserObject.h:373
SolutionUserObject::evalMultiValuedMeshFunction
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...
Definition: SolutionUserObject.C:1043
SolutionUserObject::_interpolation_time
Real _interpolation_time
Interpolation time.
Definition: SolutionUserObject.h:433
std
Definition: TheWarehouse.h:80
SolutionUserObject::pointValue
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)
FEProblemBase::getVariable
virtual MooseVariableFEBase & getVariable(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) override
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
Definition: FEProblemBase.C:4207
SolutionUserObject::pointValueWrapper
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 ...
Definition: SolutionUserObject.C:643
GeneralUserObject
Definition: GeneralUserObject.h:29
MultiMooseEnum
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MultiMooseEnum.h:38
SolutionUserObject::readXda
void readXda()
Method for reading XDA mesh and equation systems file(s) This method is called by the constructor whe...
Definition: SolutionUserObject.C:167
SolutionUserObject::_mesh_function
std::unique_ptr< MeshFunction > _mesh_function
Pointer the libMesh::MeshFunction object that the read data is stored.
Definition: SolutionUserObject.h:412
MooseUtils::checkFileReadable
bool checkFileReadable(const std::string &filename, bool check_line_endings=false, bool throw_on_unreadable=true)
Checks to see if a file is readable (exists and permissions)
Definition: MooseUtils.C:158
MooseError.h
SolutionUserObject::_solution_user_object_mutex
static Threads::spin_mutex _solution_user_object_mutex
Definition: SolutionUserObject.h:481
SolutionUserObject::variableNames
const std::vector< std::string > & variableNames() const
Definition: SolutionUserObject.C:1188
SolutionUserObject::evalMultiValuedMeshFunctionGradient
std::map< const Elem *, 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...
Definition: SolutionUserObject.C:1136
SolutionUserObject::_rotation0_vector
RealVectorValue _rotation0_vector
vector about which to rotate
Definition: SolutionUserObject.h:457
SolutionUserObject::initialSetup
virtual void initialSetup() override
Initialize the System and Mesh objects for the solution being read.
Definition: SolutionUserObject.C:436
SolutionUserObject::_system2
System * _system2
Pointer to a second libMesh::System object, used for interpolation.
Definition: SolutionUserObject.h:424
libMesh::RealTensorValue
TensorValue< Real > RealTensorValue
Definition: MooseTypes.h:140
SolutionUserObject::_es
std::unique_ptr< EquationSystems > _es
Pointer to the libmesh::EquationSystems object.
Definition: SolutionUserObject.h:406
dof_map
DofMap & dof_map
Definition: PetscDMMoose.C:1503
SolutionUserObject::_exodus_time_index
int _exodus_time_index
Current ExodusII time index.
Definition: SolutionUserObject.h:397
SolutionUserObject::_r1
RealTensorValue _r1
Rotation matrix that performs the "_rotation1_angle about rotation1_vector".
Definition: SolutionUserObject.h:472
MooseUtils.h
defineLegacyParams
defineLegacyParams(SolutionUserObject)
InputParameters::addRequiredParam
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...
Definition: InputParameters.h:1176
MooseMesh::maxElemId
virtual dof_id_type maxElemId() const
Definition: MooseMesh.C:2269
SolutionUserObject::_scale
std::vector< Real > _scale
Scale parameter.
Definition: SolutionUserObject.h:448
UserObject::_tid
THREAD_ID _tid
Thread ID of this postprocessor.
Definition: UserObject.h:148
FEProblemBase::mesh
virtual MooseMesh & mesh() override
Definition: FEProblemBase.h:148
SolutionUserObject::pointValueGradientWrapper
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...
Definition: SolutionUserObject.C:821
Moose::VAR_FIELD_STANDARD
Definition: MooseTypes.h:615
MooseObject::name
virtual const std::string & name() const
Get the name of the object.
Definition: MooseObject.h:70
SolutionUserObject::_local_variable_index
std::map< std::string, unsigned int > _local_variable_index
Stores the local index need by MeshFunction.
Definition: SolutionUserObject.h:385
SolutionUserObject::_es2
std::unique_ptr< EquationSystems > _es2
Pointer to second libMesh::EquationSystems object, used for interpolation.
Definition: SolutionUserObject.h:421
SolutionUserObject::_mesh
std::unique_ptr< MeshBase > _mesh
Pointer the libmesh::mesh object.
Definition: SolutionUserObject.h:403