Line data Source code
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 :
10 : #include "EigenExecutionerBase.h"
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 :
20 : InputParameters
21 28762 : EigenExecutionerBase::validParams()
22 : {
23 28762 : InputParameters params = Executioner::validParams();
24 28762 : params.addClassDescription("Executioner for eigenvalue problems.");
25 :
26 28762 : params += FEProblemSolve::validParams();
27 :
28 28762 : params.addRequiredParam<PostprocessorName>("bx_norm", "To evaluate |Bx| for the eigenvalue");
29 28762 : params.addParam<PostprocessorName>("normalization", "To evaluate |x| for normalization");
30 28762 : params.addParam<Real>("normal_factor", "Normalize x to make |x| equal to this factor");
31 86286 : params.addParam<bool>(
32 57524 : "output_before_normalization", true, "True to output a step before normalization");
33 28762 : params.addParam<bool>("auto_initialization", true, "True to ask the solver to set initial");
34 28762 : params.addParam<Real>("time", 0.0, "System time");
35 :
36 28762 : params.addPrivateParam<bool>("_eigen", true);
37 :
38 28762 : params.addParamNamesToGroup("normalization normal_factor output_before_normalization",
39 : "Normalization");
40 28762 : params.addParamNamesToGroup("auto_initialization time", "Advanced");
41 :
42 28762 : params.addParam<Real>("k0", 1.0, "Initial guess of the eigenvalue");
43 :
44 28762 : params.addPrivateParam<bool>("_eigen", true);
45 :
46 28762 : return params;
47 0 : }
48 :
49 : const Real &
50 169 : EigenExecutionerBase::eigenvalueOld()
51 : {
52 169 : return _source_integral_old;
53 : }
54 :
55 116 : EigenExecutionerBase::EigenExecutionerBase(const InputParameters & parameters)
56 : : Executioner(parameters),
57 116 : _problem(_fe_problem),
58 232 : _eigen_sys(static_cast<MooseEigenSystem &>(_problem.getNonlinearSystemBase(/*nl_sys=*/0))),
59 116 : _feproblem_solve(*this),
60 116 : _eigenvalue(addAttributeReporter("eigenvalue", getParam<Real>("k0"))),
61 116 : _source_integral(getPostprocessorValue("bx_norm")),
62 116 : _source_integral_old(1),
63 232 : _normalization(isParamValid("normalization")
64 154 : ? getPostprocessorValue("normalization")
65 348 : : 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 116 : _problem.transient(true);
70 116 : _eigen_sys.needSolutionState(2);
71 116 : _fe_problem.getAuxiliarySystem().needSolutionState(2);
72 :
73 : // we want to tell the App about what our system time is (in case anyone else is interested).
74 116 : Real system_time = getParam<Real>("time");
75 116 : _app.setStartTime(system_time);
76 :
77 : // set the system time
78 116 : _problem.time() = system_time;
79 116 : _problem.timeOld() = system_time;
80 :
81 : // used for controlling screen print-out
82 116 : _problem.timeStep() = 0;
83 116 : _problem.dt() = 1.0;
84 116 : }
85 :
86 : void
87 115 : EigenExecutionerBase::init()
88 : {
89 115 : checkIntegrity();
90 115 : _eigen_sys.buildSystemDoFIndices(MooseEigenSystem::EIGEN);
91 :
92 115 : 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()
96 104 : _eigen_sys.initSystemSolution(MooseEigenSystem::EIGEN, 1.0);
97 : }
98 115 : _problem.initialSetup();
99 115 : _eigen_sys.initSystemSolutionOld(MooseEigenSystem::EIGEN, 0.0);
100 :
101 : // check when the postprocessors are evaluated
102 : const ExecFlagEnum & bx_exec =
103 115 : _problem.getUserObject<UserObject>(getParam<PostprocessorName>("bx_norm")).getExecuteOnEnum();
104 115 : if (!bx_exec.isValueSet(EXEC_LINEAR))
105 0 : mooseError("Postprocessor " + getParam<PostprocessorName>("bx_norm") +
106 : " requires execute_on = 'linear'");
107 :
108 115 : if (isParamValid("normalization"))
109 76 : _norm_exec = _problem.getUserObject<UserObject>(getParam<PostprocessorName>("normalization"))
110 38 : .getExecuteOnEnum();
111 : else
112 77 : _norm_exec = bx_exec;
113 :
114 : // check if _source_integral has been evaluated during initialSetup()
115 115 : if (!bx_exec.isValueSet(EXEC_INITIAL))
116 115 : _problem.execute(EXEC_LINEAR);
117 :
118 115 : if (_source_integral == 0.0)
119 0 : mooseError("|Bx| = 0!");
120 :
121 : // normalize solution to make |Bx|=_eigenvalue, _eigenvalue at this point has the initialized
122 : // value
123 115 : makeBXConsistent(_eigenvalue);
124 :
125 115 : if (_problem.getDisplacedProblem() != NULL)
126 11 : _problem.getDisplacedProblem()->syncSolutions();
127 :
128 : /* a time step check point */
129 115 : _problem.onTimestepEnd();
130 115 : }
131 :
132 : void
133 334 : EigenExecutionerBase::makeBXConsistent(Real k)
134 : {
135 334 : 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 427 : 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()
146 93 : _eigen_sys.scaleSystemSolution(MooseEigenSystem::EIGEN, k / _source_integral);
147 93 : _problem.execute(EXEC_LINEAR);
148 93 : std::stringstream ss;
149 93 : ss << std::fixed << std::setprecision(10) << _source_integral;
150 93 : _console << "\n|Bx| = " << ss.str() << std::endl;
151 93 : }
152 334 : }
153 :
154 : void
155 115 : EigenExecutionerBase::checkIntegrity()
156 : {
157 : // check to make sure that we don't have any time kernels in this simulation
158 115 : if (_eigen_sys.containsTimeKernel())
159 0 : mooseError("You have specified time kernels in your steady state eigenvalue simulation");
160 115 : if (!_eigen_sys.containsEigenKernel())
161 0 : mooseError("You have not specified any eigen kernels in your eigenvalue simulation");
162 115 : }
163 :
164 : bool
165 115 : EigenExecutionerBase::inversePowerIteration(unsigned int min_iter,
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 115 : const PostprocessorValue * solution_diff = NULL;
184 115 : if (!xdiff.empty())
185 : {
186 11 : solution_diff = &_problem.getPostprocessorValueByName(xdiff);
187 11 : const ExecFlagEnum & xdiff_exec = _problem.getUserObject<UserObject>(xdiff).getExecuteOnEnum();
188 11 : if (!xdiff_exec.isValueSet(EXEC_LINEAR))
189 0 : mooseError("Postprocessor " + xdiff + " requires execute_on = 'linear'");
190 : }
191 :
192 : // not perform any iteration when max_iter==0
193 115 : if (max_iter == 0)
194 0 : return true;
195 :
196 : // turn off nonlinear flag so that RHS kernels opterate on previous solutions
197 115 : _eigen_sys.eigenKernelOnOld();
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
201 115 : _problem.saveOldSolutions();
202 115 : if (_problem.getDisplacedProblem() != NULL)
203 11 : _problem.getDisplacedProblem()->saveOldSolutions();
204 :
205 : // save solver control parameters to be modified by the power iteration
206 115 : Real tol1 = _problem.es().parameters.get<Real>("linear solver tolerance");
207 : unsigned int num1 =
208 115 : _problem.es().parameters.get<unsigned int>("nonlinear solver maximum iterations");
209 115 : 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 115 : _problem.es().parameters.set<Real>("linear solver tolerance") = l_rtol;
213 : // disable nonlinear convergence check
214 115 : _problem.es().parameters.set<unsigned int>("nonlinear solver maximum iterations") = 1;
215 115 : _problem.es().parameters.set<Real>("nonlinear solver relative residual tolerance") = 1 - 1e-8;
216 :
217 115 : if (echo)
218 : {
219 115 : _console << '\n';
220 115 : _console << " Power iterations starts\n";
221 115 : _console << " ________________________________________________________________________________ "
222 115 : << std::endl;
223 : }
224 :
225 : // some iteration variables
226 115 : Chebyshev_Parameters chebyshev_parameters;
227 :
228 115 : std::vector<Real> keff_history;
229 115 : std::vector<Real> diff_history;
230 :
231 : bool converged;
232 :
233 115 : unsigned int iter = 0;
234 :
235 : // power iteration loop...
236 : // Note: |Bx|/k will stay constant one!
237 115 : makeBXConsistent(k);
238 : while (true)
239 : {
240 2737 : if (echo)
241 2737 : _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.
246 2737 : _eigen_sys.copyOldSolutions();
247 2737 : _problem.getAuxiliarySystem().copyOldSolutions();
248 2737 : if (_problem.getDisplacedProblem() != NULL)
249 : {
250 2353 : _problem.getDisplacedProblem()->solverSys(_eigen_sys.number()).copyOldSolutions();
251 2353 : _problem.getDisplacedProblem()->auxSys().copyOldSolutions();
252 : }
253 :
254 2737 : Real k_old = k;
255 2737 : _source_integral_old = _source_integral;
256 :
257 2737 : preIteration();
258 2737 : _problem.solve(_eigen_sys.number());
259 2737 : converged = _problem.converged(_eigen_sys.number());
260 2737 : if (!converged)
261 0 : break;
262 2737 : postIteration();
263 :
264 : // save the initial residual
265 2737 : if (iter == 0)
266 115 : initial_res = _eigen_sys.referenceResidual();
267 :
268 : // update eigenvalue
269 2737 : k = k_old * _source_integral / _source_integral_old;
270 2737 : _eigenvalue = k;
271 :
272 2737 : if (echo)
273 : {
274 : // output on screen the convergence history only when we want to and MOOSE output system is
275 : // not used
276 2737 : keff_history.push_back(k);
277 2737 : if (solution_diff)
278 2353 : diff_history.push_back(*solution_diff);
279 :
280 2737 : std::stringstream ss;
281 2737 : if (solution_diff)
282 : {
283 2353 : ss << '\n';
284 2353 : ss << " +================+=====================+=====================+\n";
285 2353 : ss << " | iteration | eigenvalue | solution_difference |\n";
286 2353 : ss << " +================+=====================+=====================+\n";
287 2353 : unsigned int j = 0;
288 2353 : if (keff_history.size() > 10)
289 : {
290 2243 : ss << " : : : :\n";
291 2243 : j = keff_history.size() - 10;
292 : }
293 25388 : for (; j < keff_history.size(); j++)
294 23035 : ss << " | " << std::setw(14) << j << " | " << std::setw(19) << std::scientific
295 23035 : << std::setprecision(8) << keff_history[j] << " | " << std::setw(19) << std::scientific
296 23035 : << std::setprecision(8) << diff_history[j] << " |\n";
297 2353 : ss << " +================+=====================+=====================+\n" << std::flush;
298 : }
299 : else
300 : {
301 384 : ss << '\n';
302 384 : ss << " +================+=====================+\n";
303 384 : ss << " | iteration | eigenvalue |\n";
304 384 : ss << " +================+=====================+\n";
305 384 : unsigned int j = 0;
306 384 : if (keff_history.size() > 10)
307 : {
308 0 : ss << " : : :\n";
309 0 : j = keff_history.size() - 10;
310 : }
311 1576 : for (; j < keff_history.size(); j++)
312 1192 : ss << " | " << std::setw(14) << j << " | " << std::setw(19) << std::scientific
313 1192 : << std::setprecision(8) << keff_history[j] << " |\n";
314 384 : ss << " +================+=====================+\n" << std::flush;
315 384 : ss << std::endl;
316 : }
317 2737 : _console << ss.str();
318 2737 : }
319 :
320 : // increment iteration number here
321 2737 : iter++;
322 :
323 2737 : if (cheb_on)
324 : {
325 2353 : chebyshev(chebyshev_parameters, iter, solution_diff);
326 2353 : if (echo)
327 2353 : _console << " Chebyshev step: " << chebyshev_parameters.icheb << std::endl;
328 : }
329 :
330 2737 : if (echo)
331 : _console
332 2737 : << " ________________________________________________________________________________ "
333 2737 : << std::endl;
334 :
335 : // not perform any convergence check when number of iterations is less than min_iter
336 2737 : if (iter >= min_iter)
337 : {
338 : // no need to check convergence of the last iteration
339 2347 : if (iter != max_iter)
340 : {
341 2243 : Real keff_error = fabs(k_old - k) / k;
342 2243 : if (keff_error > tol_eig)
343 2232 : converged = false;
344 2243 : if (solution_diff)
345 2243 : if (*solution_diff > tol_x)
346 0 : converged = false;
347 2243 : if (converged)
348 11 : break;
349 : }
350 : else
351 : {
352 104 : converged = false;
353 104 : break;
354 : }
355 : }
356 2622 : }
357 :
358 : // restore parameters changed by the executioner
359 115 : _problem.es().parameters.set<Real>("linear solver tolerance") = tol1;
360 115 : _problem.es().parameters.set<unsigned int>("nonlinear solver maximum iterations") = num1;
361 115 : _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
364 115 : _problem.restoreOldSolutions();
365 115 : if (_problem.getDisplacedProblem() != NULL)
366 11 : _problem.getDisplacedProblem()->restoreOldSolutions();
367 :
368 115 : return converged;
369 115 : }
370 :
371 : void
372 2737 : EigenExecutionerBase::preIteration()
373 : {
374 2737 : }
375 :
376 : void
377 2737 : EigenExecutionerBase::postIteration()
378 : {
379 2737 : }
380 :
381 : void
382 115 : EigenExecutionerBase::postExecute()
383 : {
384 115 : if (getParam<bool>("output_before_normalization"))
385 : {
386 104 : _problem.timeStep()++;
387 104 : Real t = _problem.time();
388 104 : _problem.time() = _problem.timeStep();
389 104 : _problem.outputStep(EXEC_TIMESTEP_END);
390 104 : _problem.time() = t;
391 : }
392 :
393 115 : Real s = 1.0;
394 115 : if (_norm_exec.isValueSet(EXEC_CUSTOM))
395 : {
396 0 : _console << " Cannot let the normalization postprocessor on custom.\n";
397 0 : _console << " Normalization is abandoned!" << std::endl;
398 : }
399 : else
400 : {
401 115 : bool force = _norm_exec.isValueSet(EXEC_TIMESTEP_END) || _norm_exec.isValueSet(EXEC_LINEAR);
402 115 : s = normalizeSolution(force);
403 115 : if (!MooseUtils::absoluteFuzzyEqual(s, 1.0))
404 27 : _console << " Solution is rescaled with factor " << s << " for normalization!" << std::endl;
405 : }
406 :
407 115 : if ((!getParam<bool>("output_before_normalization")) || !MooseUtils::absoluteFuzzyEqual(s, 1.0))
408 : {
409 27 : _problem.timeStep()++;
410 27 : Real t = _problem.time();
411 27 : _problem.time() = _problem.timeStep();
412 27 : _problem.outputStep(EXEC_TIMESTEP_END);
413 27 : _problem.time() = t;
414 : }
415 :
416 : {
417 115 : TIME_SECTION("final", 1, "Executing Final Objects")
418 115 : _problem.execMultiApps(EXEC_FINAL);
419 115 : _problem.execute(EXEC_FINAL);
420 115 : _problem.outputStep(EXEC_FINAL);
421 115 : }
422 115 : }
423 :
424 : Real
425 115 : EigenExecutionerBase::normalizeSolution(bool force)
426 : {
427 115 : if (force)
428 115 : _problem.execute(EXEC_INITIAL);
429 :
430 : Real factor;
431 115 : if (isParamValid("normal_factor"))
432 27 : factor = getParam<Real>("normal_factor");
433 : else
434 88 : factor = _eigenvalue;
435 115 : Real scaling = factor / _normalization;
436 :
437 115 : if (!MooseUtils::absoluteFuzzyEqual(scaling, 1.0))
438 : {
439 : // FIXME: we assume linear scaling here!
440 27 : _eigen_sys.scaleSystemSolution(MooseEigenSystem::EIGEN, scaling);
441 : // update all aux variables and user objects
442 :
443 756 : for (const ExecFlagType & flag : _app.getExecuteOnEnum().items())
444 729 : _problem.execute(flag);
445 : }
446 115 : return scaling;
447 : }
448 :
449 : void
450 115 : EigenExecutionerBase::printEigenvalue()
451 : {
452 115 : std::ostringstream ss;
453 115 : ss << '\n';
454 115 : ss << "*******************************************************\n";
455 115 : ss << " Eigenvalue = " << std::fixed << std::setprecision(10) << _eigenvalue << '\n';
456 115 : ss << "*******************************************************";
457 :
458 115 : _console << ss.str() << std::endl;
459 115 : }
460 :
461 115 : EigenExecutionerBase::Chebyshev_Parameters::Chebyshev_Parameters()
462 115 : : n_iter(50), fsmooth(2), finit(6), lgac(0), icheb(0), flux_error_norm_old(1), icho(0)
463 : {
464 115 : }
465 :
466 : void
467 0 : EigenExecutionerBase::Chebyshev_Parameters::reinit()
468 : {
469 0 : finit = 6;
470 0 : lgac = 0;
471 0 : icheb = 0;
472 0 : flux_error_norm_old = 1;
473 0 : icho = 0;
474 0 : }
475 :
476 : void
477 2353 : EigenExecutionerBase::chebyshev(Chebyshev_Parameters & chebyshev_parameters,
478 : unsigned int iter,
479 : const PostprocessorValue * solution_diff)
480 : {
481 2353 : if (!solution_diff)
482 0 : mooseError("solution diff is required for Chebyshev acceleration");
483 :
484 2353 : if (chebyshev_parameters.lgac == 0)
485 : {
486 293 : if (chebyshev_parameters.icho == 0)
487 77 : chebyshev_parameters.ratio = *solution_diff / chebyshev_parameters.flux_error_norm_old;
488 : else
489 : {
490 216 : chebyshev_parameters.ratio = chebyshev_parameters.ratio_new;
491 216 : chebyshev_parameters.icho = 0;
492 : }
493 :
494 293 : if (iter > chebyshev_parameters.finit && chebyshev_parameters.ratio >= 0.4 &&
495 227 : chebyshev_parameters.ratio <= 1)
496 : {
497 227 : chebyshev_parameters.lgac = 1;
498 227 : chebyshev_parameters.icheb = 1;
499 227 : chebyshev_parameters.error_begin = *solution_diff;
500 227 : chebyshev_parameters.iter_begin = iter;
501 227 : double alp = 2 / (2 - chebyshev_parameters.ratio);
502 227 : std::vector<double> coef(2);
503 227 : coef[0] = alp;
504 227 : coef[1] = 1 - alp;
505 227 : _eigen_sys.combineSystemSolution(MooseEigenSystem::EIGEN, coef);
506 227 : _problem.execute(EXEC_LINEAR);
507 227 : _eigenvalue = _source_integral;
508 227 : }
509 : }
510 : else
511 : {
512 2060 : chebyshev_parameters.icheb++;
513 2060 : double gamma = acosh(2 / chebyshev_parameters.ratio - 1);
514 2060 : double alp = 4 / chebyshev_parameters.ratio *
515 2060 : std::cosh((chebyshev_parameters.icheb - 1) * gamma) /
516 2060 : std::cosh(chebyshev_parameters.icheb * gamma);
517 2060 : 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 2060 : (*solution_diff / chebyshev_parameters.error_begin) *
530 2060 : (std::cosh((chebyshev_parameters.icheb - 1) * acosh(2 / chebyshev_parameters.ratio - 1)));
531 2060 : if (gamma_new < 1.0)
532 968 : gamma_new = 1.0;
533 :
534 2060 : chebyshev_parameters.ratio_new =
535 2060 : chebyshev_parameters.ratio / 2 *
536 2060 : (std::cosh(acosh(gamma_new) / (chebyshev_parameters.icheb - 1)) + 1);
537 2060 : if (gamma_new > 1.01)
538 : {
539 222 : chebyshev_parameters.lgac = 0;
540 : // chebyshev_parameters.icheb = 0;
541 : // if (chebyshev_parameters.icheb>30)
542 : // {
543 222 : if (chebyshev_parameters.icheb > 0)
544 : {
545 222 : chebyshev_parameters.icho = 1;
546 222 : chebyshev_parameters.finit = iter;
547 : }
548 : else
549 : {
550 0 : chebyshev_parameters.icho = 0;
551 0 : chebyshev_parameters.finit = iter + chebyshev_parameters.fsmooth;
552 : }
553 : }
554 : else
555 : {
556 1838 : std::vector<double> coef(3);
557 1838 : coef[0] = alp;
558 1838 : coef[1] = 1 - alp + beta;
559 1838 : coef[2] = -beta;
560 1838 : _eigen_sys.combineSystemSolution(MooseEigenSystem::EIGEN, coef);
561 1838 : _problem.execute(EXEC_LINEAR);
562 1838 : _eigenvalue = _source_integral;
563 1838 : }
564 : // }
565 : }
566 2353 : chebyshev_parameters.flux_error_norm_old = *solution_diff;
567 2353 : }
568 :
569 : bool
570 104 : EigenExecutionerBase::nonlinearSolve(Real nl_rtol, Real nl_atol, Real l_rtol, Real & k)
571 : {
572 104 : makeBXConsistent(k);
573 :
574 : // turn on nonlinear flag so that eigen kernels opterate on the current solutions
575 104 : _eigen_sys.eigenKernelOnCurrent();
576 :
577 : // set nonlinear solver controls
578 104 : Real tol1 = _problem.es().parameters.get<Real>("nonlinear solver absolute residual tolerance");
579 104 : Real tol2 = _problem.es().parameters.get<Real>("linear solver tolerance");
580 104 : Real tol3 = _problem.es().parameters.get<Real>("nonlinear solver relative residual tolerance");
581 :
582 104 : _problem.es().parameters.set<Real>("nonlinear solver absolute residual tolerance") = nl_atol;
583 104 : _problem.es().parameters.set<Real>("nonlinear solver relative residual tolerance") = nl_rtol;
584 104 : _problem.es().parameters.set<Real>("linear solver tolerance") = l_rtol;
585 :
586 : // call nonlinear solve
587 104 : _problem.solve(_eigen_sys.number());
588 :
589 104 : k = _source_integral;
590 104 : _eigenvalue = k;
591 :
592 104 : _problem.es().parameters.set<Real>("nonlinear solver absolute residual tolerance") = tol1;
593 104 : _problem.es().parameters.set<Real>("linear solver tolerance") = tol2;
594 104 : _problem.es().parameters.set<Real>("nonlinear solver relative residual tolerance") = tol3;
595 :
596 104 : return _problem.converged(_eigen_sys.number());
597 : }
|