https://mooseframework.inl.gov
Loading...
Searching...
No Matches
EigenExecutionerBase.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 "AuxiliarySystem.h"
14#include "DisplacedProblem.h"
15#include "FEProblem.h"
16#include "MooseApp.h"
17#include "MooseEigenSystem.h"
18#include "UserObject.h"
19
22{
24 params.addClassDescription("Executioner for eigenvalue problems.");
25
27
28 params.addRequiredParam<PostprocessorName>("bx_norm", "To evaluate |Bx| for the eigenvalue");
29 params.addParam<PostprocessorName>("normalization", "To evaluate |x| for normalization");
30 params.addParam<Real>("normal_factor", "Normalize x to make |x| equal to this factor");
31 params.addParam<bool>(
32 "output_before_normalization", true, "True to output a step before normalization");
33 params.addParam<bool>("auto_initialization", true, "True to ask the solver to set initial");
34 params.addParam<Real>("time", 0.0, "System time");
35
36 params.addPrivateParam<bool>("_eigen", true);
37
38 params.addParamNamesToGroup("normalization normal_factor output_before_normalization",
39 "Normalization");
40 params.addParamNamesToGroup("auto_initialization time", "Advanced");
41
42 params.addParam<Real>("k0", 1.0, "Initial guess of the eigenvalue");
43
44 params.addPrivateParam<bool>("_eigen", true);
45
46 return params;
47}
48
49const Real &
54
56 : Executioner(parameters),
57 _problem(_fe_problem),
58 _eigen_sys(static_cast<MooseEigenSystem &>(_problem.getNonlinearSystemBase(/*nl_sys=*/0))),
59 _feproblem_solve(*this),
60 _eigenvalue(addAttributeReporter("eigenvalue", getParam<Real>("k0"))),
61 _source_integral(getPostprocessorValue("bx_norm")),
62 _source_integral_old(1),
63 _normalization(isParamValid("normalization")
64 ? getPostprocessorValue("normalization")
65 : getPostprocessorValue("bx_norm")) // use |Bx| for normalization by default
66{
67 // FIXME: currently we have to use old and older solution vectors for power iteration.
68 // We will need 'step' in the future.
69 _problem.transient(true);
72
73 // we want to tell the App about what our system time is (in case anyone else is interested).
74 Real system_time = getParam<Real>("time");
75 _app.setStartTime(system_time);
76
77 // set the system time
78 _problem.time() = system_time;
79 _problem.timeOld() = system_time;
80
81 // used for controlling screen print-out
82 _problem.timeStep() = 0;
83 _problem.dt() = 1.0;
84}
85
86void
88{
91
92 if (getParam<bool>("auto_initialization"))
93 {
94 // Initialize the solution of the eigen variables
95 // Note: initial conditions will override this if there is any by _problem.initialSetup()
97 }
100
101 // check when the postprocessors are evaluated
102 const ExecFlagEnum & bx_exec =
103 _problem.getUserObject<UserObject>(getParam<PostprocessorName>("bx_norm")).getExecuteOnEnum();
104 if (!bx_exec.isValueSet(EXEC_LINEAR))
105 mooseError("Postprocessor " + getParam<PostprocessorName>("bx_norm") +
106 " requires execute_on = 'linear'");
107
108 if (isParamValid("normalization"))
109 _norm_exec = _problem.getUserObject<UserObject>(getParam<PostprocessorName>("normalization"))
110 .getExecuteOnEnum();
111 else
112 _norm_exec = bx_exec;
113
114 // check if _source_integral has been evaluated during initialSetup()
115 if (!bx_exec.isValueSet(EXEC_INITIAL))
117
118 if (_source_integral == 0.0)
119 mooseError("|Bx| = 0!");
120
121 // normalize solution to make |Bx|=_eigenvalue, _eigenvalue at this point has the initialized
122 // value
124
125 if (_problem.getDisplacedProblem() != NULL)
126 _problem.getDisplacedProblem()->syncSolutions();
127
128 /* a time step check point */
130}
131
132void
134{
135 Real consistency_tolerance = 1e-10;
136
137 // Scale the solution so that the postprocessor is equal to k.
138 // Note: all dependent objects of k must be evaluated on linear!
139 // We have a fix point loop here, in case the postprocessor is a nonlinear function of the scaling
140 // factor.
141 // FIXME: We have assumed this loop always converges.
142 while (std::fabs(k - _source_integral) > consistency_tolerance * std::fabs(k))
143 {
144 // On the first time entering, the _source_integral has been updated properly in
145 // FEProblemBase::initialSetup()
148 std::stringstream ss;
149 ss << std::fixed << std::setprecision(10) << _source_integral;
150 _console << "\n|Bx| = " << ss.str() << std::endl;
151 }
152}
153
154void
156{
157 // check to make sure that we don't have any time kernels in this simulation
159 mooseError("You have specified time kernels in your steady state eigenvalue simulation");
161 mooseError("You have not specified any eigen kernels in your eigenvalue simulation");
162}
163
164bool
166 unsigned int max_iter,
167 Real l_rtol,
168 bool cheb_on,
169 Real tol_eig,
170 bool echo,
171 PostprocessorName xdiff,
172 Real tol_x,
173 Real & k,
174 Real & initial_res)
175{
176 mooseAssert(max_iter >= min_iter,
177 "Maximum number of power iterations must be greater than or equal to its minimum");
178 mooseAssert(l_rtol > 0.0, "Invaid linear convergence tolerance");
179 mooseAssert(tol_eig > 0.0, "Invalid eigenvalue tolerance");
180 mooseAssert(tol_x > 0.0, "Invalid solution norm tolerance");
181
182 // obtain the solution diff
183 const PostprocessorValue * solution_diff = NULL;
184 if (!xdiff.empty())
185 {
186 solution_diff = &_problem.getPostprocessorValueByName(xdiff);
187 const ExecFlagEnum & xdiff_exec = _problem.getUserObject<UserObject>(xdiff).getExecuteOnEnum();
188 if (!xdiff_exec.isValueSet(EXEC_LINEAR))
189 mooseError("Postprocessor " + xdiff + " requires execute_on = 'linear'");
190 }
191
192 // not perform any iteration when max_iter==0
193 if (max_iter == 0)
194 return true;
195
196 // turn off nonlinear flag so that RHS kernels opterate on previous solutions
198
199 // FIXME: currently power iteration use old and older solutions,
200 // so save old and older solutions before they are changed by the power iteration
202 if (_problem.getDisplacedProblem() != NULL)
203 _problem.getDisplacedProblem()->saveOldSolutions();
204
205 // save solver control parameters to be modified by the power iteration
206 Real tol1 = _problem.es().parameters.get<Real>("linear solver tolerance");
207 unsigned int num1 =
208 _problem.es().parameters.get<unsigned int>("nonlinear solver maximum iterations");
209 Real tol2 = _problem.es().parameters.get<Real>("nonlinear solver relative residual tolerance");
210
211 // every power iteration is a linear solve, so set nonlinear iteration number to one
212 _problem.es().parameters.set<Real>("linear solver tolerance") = l_rtol;
213 // disable nonlinear convergence check
214 _problem.es().parameters.set<unsigned int>("nonlinear solver maximum iterations") = 1;
215 _problem.es().parameters.set<Real>("nonlinear solver relative residual tolerance") = 1 - 1e-8;
216
217 if (echo)
218 {
219 _console << '\n';
220 _console << " Power iterations starts\n";
221 _console << " ________________________________________________________________________________ "
222 << std::endl;
223 }
224
225 // some iteration variables
226 Chebyshev_Parameters chebyshev_parameters;
227
228 std::vector<Real> keff_history;
229 std::vector<Real> diff_history;
230
231 bool converged;
232
233 unsigned int iter = 0;
234
235 // power iteration loop...
236 // Note: |Bx|/k will stay constant one!
238 while (true)
239 {
240 if (echo)
241 _console << " Power iteration= " << iter << std::endl;
242
243 // Important: we do not call _problem.advanceState() because we do not
244 // want to overwrite the old postprocessor values and old material
245 // properties in stateful materials.
248 if (_problem.getDisplacedProblem() != NULL)
249 {
250 _problem.getDisplacedProblem()->solverSys(_eigen_sys.number()).copyOldSolutions();
251 _problem.getDisplacedProblem()->auxSys().copyOldSolutions();
252 }
253
254 Real k_old = k;
256
257 preIteration();
259 converged = _problem.converged(_eigen_sys.number());
260 if (!converged)
261 break;
263
264 // save the initial residual
265 if (iter == 0)
266 initial_res = _eigen_sys.referenceResidual();
267
268 // update eigenvalue
270 _eigenvalue = k;
271
272 if (echo)
273 {
274 // output on screen the convergence history only when we want to and MOOSE output system is
275 // not used
276 keff_history.push_back(k);
277 if (solution_diff)
278 diff_history.push_back(*solution_diff);
279
280 std::stringstream ss;
281 if (solution_diff)
282 {
283 ss << '\n';
284 ss << " +================+=====================+=====================+\n";
285 ss << " | iteration | eigenvalue | solution_difference |\n";
286 ss << " +================+=====================+=====================+\n";
287 unsigned int j = 0;
288 if (keff_history.size() > 10)
289 {
290 ss << " : : : :\n";
291 j = keff_history.size() - 10;
292 }
293 for (; j < keff_history.size(); j++)
294 ss << " | " << std::setw(14) << j << " | " << std::setw(19) << std::scientific
295 << std::setprecision(8) << keff_history[j] << " | " << std::setw(19) << std::scientific
296 << std::setprecision(8) << diff_history[j] << " |\n";
297 ss << " +================+=====================+=====================+\n" << std::flush;
298 }
299 else
300 {
301 ss << '\n';
302 ss << " +================+=====================+\n";
303 ss << " | iteration | eigenvalue |\n";
304 ss << " +================+=====================+\n";
305 unsigned int j = 0;
306 if (keff_history.size() > 10)
307 {
308 ss << " : : :\n";
309 j = keff_history.size() - 10;
310 }
311 for (; j < keff_history.size(); j++)
312 ss << " | " << std::setw(14) << j << " | " << std::setw(19) << std::scientific
313 << std::setprecision(8) << keff_history[j] << " |\n";
314 ss << " +================+=====================+\n" << std::flush;
315 ss << std::endl;
316 }
317 _console << ss.str();
318 }
319
320 // increment iteration number here
321 iter++;
322
323 if (cheb_on)
324 {
325 chebyshev(chebyshev_parameters, iter, solution_diff);
326 if (echo)
327 _console << " Chebyshev step: " << chebyshev_parameters.icheb << std::endl;
328 }
329
330 if (echo)
332 << " ________________________________________________________________________________ "
333 << std::endl;
334
335 // not perform any convergence check when number of iterations is less than min_iter
336 if (iter >= min_iter)
337 {
338 // no need to check convergence of the last iteration
339 if (iter != max_iter)
340 {
341 Real keff_error = fabs(k_old - k) / k;
342 if (keff_error > tol_eig)
343 converged = false;
344 if (solution_diff)
345 if (*solution_diff > tol_x)
346 converged = false;
347 if (converged)
348 break;
349 }
350 else
351 {
352 converged = false;
353 break;
354 }
355 }
356 }
357
358 // restore parameters changed by the executioner
359 _problem.es().parameters.set<Real>("linear solver tolerance") = tol1;
360 _problem.es().parameters.set<unsigned int>("nonlinear solver maximum iterations") = num1;
361 _problem.es().parameters.set<Real>("nonlinear solver relative residual tolerance") = tol2;
362
363 // FIXME: currently power iteration use old and older solutions, so restore them
365 if (_problem.getDisplacedProblem() != NULL)
366 _problem.getDisplacedProblem()->restoreOldSolutions();
367
368 return converged;
369}
370
371void
375
376void
380
381void
383{
384 if (getParam<bool>("output_before_normalization"))
385 {
386 _problem.timeStep()++;
387 Real t = _problem.time();
390 _problem.time() = t;
391 }
392
393 Real s = 1.0;
395 {
396 _console << " Cannot let the normalization postprocessor on custom.\n";
397 _console << " Normalization is abandoned!" << std::endl;
398 }
399 else
400 {
402 s = normalizeSolution(force);
403 if (!MooseUtils::absoluteFuzzyEqual(s, 1.0))
404 _console << " Solution is rescaled with factor " << s << " for normalization!" << std::endl;
405 }
406
407 if ((!getParam<bool>("output_before_normalization")) || !MooseUtils::absoluteFuzzyEqual(s, 1.0))
408 {
409 _problem.timeStep()++;
410 Real t = _problem.time();
413 _problem.time() = t;
414 }
415
416 {
417 TIME_SECTION("final", 1, "Executing Final Objects")
421 }
422}
423
424Real
426{
427 if (force)
429
430 Real factor;
431 if (isParamValid("normal_factor"))
432 factor = getParam<Real>("normal_factor");
433 else
434 factor = _eigenvalue;
435 Real scaling = factor / _normalization;
436
437 if (!MooseUtils::absoluteFuzzyEqual(scaling, 1.0))
438 {
439 // FIXME: we assume linear scaling here!
441 // update all aux variables and user objects
442
443 for (const ExecFlagType & flag : _app.getExecuteOnEnum().items())
444 _problem.execute(flag);
445 }
446 return scaling;
447}
448
449void
451{
452 std::ostringstream ss;
453 ss << '\n';
454 ss << "*******************************************************\n";
455 ss << " Eigenvalue = " << std::fixed << std::setprecision(10) << _eigenvalue << '\n';
456 ss << "*******************************************************";
457
458 _console << ss.str() << std::endl;
459}
460
462 : n_iter(50), fsmooth(2), finit(6), lgac(0), icheb(0), flux_error_norm_old(1), icho(0)
463{
464}
465
466void
468{
469 finit = 6;
470 lgac = 0;
471 icheb = 0;
472 flux_error_norm_old = 1;
473 icho = 0;
474}
475
476void
478 unsigned int iter,
479 const PostprocessorValue * solution_diff)
480{
481 if (!solution_diff)
482 mooseError("solution diff is required for Chebyshev acceleration");
483
484 if (chebyshev_parameters.lgac == 0)
485 {
486 if (chebyshev_parameters.icho == 0)
487 chebyshev_parameters.ratio = *solution_diff / chebyshev_parameters.flux_error_norm_old;
488 else
489 {
490 chebyshev_parameters.ratio = chebyshev_parameters.ratio_new;
491 chebyshev_parameters.icho = 0;
492 }
493
494 if (iter > chebyshev_parameters.finit && chebyshev_parameters.ratio >= 0.4 &&
495 chebyshev_parameters.ratio <= 1)
496 {
497 chebyshev_parameters.lgac = 1;
498 chebyshev_parameters.icheb = 1;
499 chebyshev_parameters.error_begin = *solution_diff;
500 chebyshev_parameters.iter_begin = iter;
501 double alp = 2 / (2 - chebyshev_parameters.ratio);
502 std::vector<double> coef(2);
503 coef[0] = alp;
504 coef[1] = 1 - alp;
508 }
509 }
510 else
511 {
512 chebyshev_parameters.icheb++;
513 double gamma = acosh(2 / chebyshev_parameters.ratio - 1);
514 double alp = 4 / chebyshev_parameters.ratio *
515 std::cosh((chebyshev_parameters.icheb - 1) * gamma) /
516 std::cosh(chebyshev_parameters.icheb * gamma);
517 double beta = (1 - chebyshev_parameters.ratio / 2) * alp - 1;
518 /* if (iter<int(chebyshev_parameters.iter_begin+chebyshev_parameters.n_iter))
519 {
520 std::vector<double> coef(3);
521 coef[0] = alp;
522 coef[1] = 1-alp+beta;
523 coef[2] = -beta;
524 _eigen_sys.combineSystemSolution(NonlinearSystem::EIGEN, coef);
525 }
526 else
527 {*/
528 double gamma_new =
529 (*solution_diff / chebyshev_parameters.error_begin) *
530 (std::cosh((chebyshev_parameters.icheb - 1) * acosh(2 / chebyshev_parameters.ratio - 1)));
531 if (gamma_new < 1.0)
532 gamma_new = 1.0;
533
534 chebyshev_parameters.ratio_new =
535 chebyshev_parameters.ratio / 2 *
536 (std::cosh(acosh(gamma_new) / (chebyshev_parameters.icheb - 1)) + 1);
537 if (gamma_new > 1.01)
538 {
539 chebyshev_parameters.lgac = 0;
540 // chebyshev_parameters.icheb = 0;
541 // if (chebyshev_parameters.icheb>30)
542 // {
543 if (chebyshev_parameters.icheb > 0)
544 {
545 chebyshev_parameters.icho = 1;
546 chebyshev_parameters.finit = iter;
547 }
548 else
549 {
550 chebyshev_parameters.icho = 0;
551 chebyshev_parameters.finit = iter + chebyshev_parameters.fsmooth;
552 }
553 }
554 else
555 {
556 std::vector<double> coef(3);
557 coef[0] = alp;
558 coef[1] = 1 - alp + beta;
559 coef[2] = -beta;
563 }
564 // }
565 }
566 chebyshev_parameters.flux_error_norm_old = *solution_diff;
567}
568
569bool
570EigenExecutionerBase::nonlinearSolve(Real nl_rtol, Real nl_atol, Real l_rtol, Real & k)
571{
573
574 // turn on nonlinear flag so that eigen kernels opterate on the current solutions
576
577 // set nonlinear solver controls
578 Real tol1 = _problem.es().parameters.get<Real>("nonlinear solver absolute residual tolerance");
579 Real tol2 = _problem.es().parameters.get<Real>("linear solver tolerance");
580 Real tol3 = _problem.es().parameters.get<Real>("nonlinear solver relative residual tolerance");
581
582 _problem.es().parameters.set<Real>("nonlinear solver absolute residual tolerance") = nl_atol;
583 _problem.es().parameters.set<Real>("nonlinear solver relative residual tolerance") = nl_rtol;
584 _problem.es().parameters.set<Real>("linear solver tolerance") = l_rtol;
585
586 // call nonlinear solve
588
590 _eigenvalue = k;
591
592 _problem.es().parameters.set<Real>("nonlinear solver absolute residual tolerance") = tol1;
593 _problem.es().parameters.set<Real>("linear solver tolerance") = tol2;
594 _problem.es().parameters.set<Real>("nonlinear solver relative residual tolerance") = tol3;
595
597}
Real PostprocessorValue
various MOOSE typedefs
Definition MooseTypes.h:230
const ExecFlagType EXEC_TIMESTEP_END
Definition Moose.C:36
const ExecFlagType EXEC_CUSTOM
Definition Moose.C:51
const ExecFlagType EXEC_INITIAL
Definition Moose.C:30
const ExecFlagType EXEC_LINEAR
Definition Moose.C:31
const ExecFlagType EXEC_FINAL
Definition Moose.C:48
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
virtual void postExecute() override
Override this for actions that should take place after the main solve.
const Real & _normalization
Postprocessor for normalization.
virtual Real normalizeSolution(bool force=true)
Normalize the solution vector based on the postprocessor value for normalization.
virtual void preIteration()
Override this for actions that should take place before linear solve of each inverse power iteration.
virtual void checkIntegrity()
Make sure time kernel is not presented.
MooseEigenSystem & _eigen_sys
static InputParameters validParams()
Constructor.
virtual bool nonlinearSolve(Real rel_tol, Real abs_tol, Real pfactor, Real &k)
Perform nonlinear solve with the initial guess of the solution.
EigenExecutionerBase(const InputParameters &parameters)
const Real & eigenvalueOld()
The old eigenvalue used by inverse power iterations.
PostprocessorValue & _eigenvalue
Storage for the eigenvalue computed by the executioner.
void chebyshev(Chebyshev_Parameters &params, unsigned int iter, const PostprocessorValue *solution_diff)
virtual void printEigenvalue()
Print eigenvalue.
virtual void makeBXConsistent(Real k)
Normalize solution so that |Bx| = k.
virtual void postIteration()
Override this for actions that should take place after linear solve of each inverse power iteration.
virtual bool inversePowerIteration(unsigned int min_iter, unsigned int max_iter, Real pfactor, bool cheb_on, Real tol_eig, bool echo, PostprocessorName xdiff, Real tol_x, Real &k, Real &initial_res)
Perform inverse power iterations with the initial guess of the solution.
virtual void init() override
Initialize the executioner.
A MultiMooseEnum object to hold "execute_on" flags.
const std::set< ExecFlagType > & items() const
Reference the all the available items.
Executioners are objects that do the actual work of solving your problem.
Definition Executioner.h:37
static InputParameters validParams()
Definition Executioner.C:26
FEProblemBase & _fe_problem
virtual void onTimestepEnd() override
T & getUserObject(const std::string &name, unsigned int tid=0) const
Get the user object by its name.
virtual libMesh::EquationSystems & es() override
AuxiliarySystem & getAuxiliarySystem()
const PostprocessorValue & getPostprocessorValueByName(const PostprocessorName &name, std::size_t t_index=0) const
Get a read-only reference to the value associated with a Postprocessor that exists.
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
virtual void restoreOldSolutions()
Restore old solutions from the backup vectors and deallocate them.
virtual Real & dt() const
virtual void transient(bool trans)
virtual void solve(const unsigned int nl_sys_num)
bool execMultiApps(ExecFlagType type, bool auto_advance=true)
Execute the MultiApps associated with the ExecFlagType.
virtual Real & timeOld() const
virtual void saveOldSolutions()
Allocate vectors and save old solutions into them.
virtual void execute(const ExecFlagType &exec_type)
Convenience function for performing execution of MOOSE systems.
virtual Real & time() const
virtual int & timeStep() const
void initialSetup() override
virtual void outputStep(ExecFlagType type)
Output the current step.
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 addPrivateParam(const std::string &name, const T &value)
These method add a parameter to the InputParameters object which can be retrieved like any other para...
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
void setStartTime(Real time)
Set the starting time for the simulation.
Definition MooseApp.C:2396
const ExecFlagEnum & getExecuteOnEnum() const
Return the app level ExecFlagEnum, this contains all the available flags for the app.
Definition MooseApp.h:1040
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition MooseBase.h:271
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
void eigenKernelOnOld()
Ask eigenkernels to operate on old or current solution vectors.
void initSystemSolutionOld(SYSTEMTAG tag, Real v)
void buildSystemDoFIndices(SYSTEMTAG tag=ALL)
Build DoF indices for a system.
void initSystemSolution(SYSTEMTAG tag, Real v)
Initialize the solution vector with a constant value.
bool containsEigenKernel() const
Weather or not the system contains eigen kernels.
void combineSystemSolution(SYSTEMTAG tag, const std::vector< Real > &coefficients)
Linear combination of the solution vectors.
void scaleSystemSolution(SYSTEMTAG tag, Real scaling_factor)
Scale the solution vector.
Class for containing MooseEnum item information.
MooseApp & _app
The MOOSE application this is associated with.
Definition MooseBase.h:375
bool isValueSet(const std::string &value) const
Methods for seeing if a value is set in the MultiMooseEnum.
Real referenceResidual() const
The reference residual used in relative convergence check.
virtual bool containsTimeKernel() override
If the system has a kernel that corresponds to a time derivative.
virtual bool converged(const unsigned int sys_num)
Eventually we want to convert this virtual over to taking a solver system number argument.
Definition SubProblem.h:113
void copyOldSolutions()
Copy the solution back in time (older -> old, etc).
unsigned int number() const
Gets the number of this system.
virtual void needSolutionState(const unsigned int state, Moose::SolutionIterationType iteration_type=Moose::SolutionIterationType::Time, libMesh::ParallelType parallel_type=GHOSTED)
Registers that the solution state state is needed.
Base class for user-specific data.
Definition UserObject.h:20
T & set(const std::string &)
const T & get(std::string_view) const