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