EigenExecutionerBase::EigenExecutionerBase(const std::string & name, InputParameters parameters) :Executioner(name, parameters), _problem(*parameters.getCheckedPointerParam<FEProblem *>("_fe_problem", "This might happen if you don't have a mesh")), _eigen_sys(static_cast<EigenSystem &>(_problem.getNonlinearSystem())), _eigenvalue(_problem.parameters().set<Real>("eigenvalue")), // used for storing the eigenvalue _source_integral(getPostprocessorValue("bx_norm")), _source_integral_old(getPostprocessorValueOld("bx_norm")), _solution_diff(isParamValid("xdiff") ? &getPostprocessorValue("xdiff") : NULL), _normalization(isParamValid("normalization") ? getPostprocessorValue("normalization") : getPostprocessorValue("bx_norm")) // use |Bx| for normalization by default { _eigenvalue = 1.0; // EigenKernel needs this postprocessor _problem.parameters().set<PostprocessorName>("eigen_postprocessor") = getParam<PostprocessorName>("bx_norm"); //FIXME: currently we have to use old and older solution vectors for power iteration. // We will need 'step' in the future. _problem.transient(true); { // No time integrator for eigenvalue problem std::string ti_str = "SteadyState"; InputParameters params = _app.getFactory().getValidParams(ti_str); _problem.addTimeIntegrator(ti_str, "ti", params); } // set the system time _problem.time() = getParam<Real>("time"); // used for controlling screen print-out _problem.timeStep() = 0; _problem.dt() = 1.0; }
Real TestPostprocessor::getValue() { if (_test_type == "grow") { if (_t_step == 0) return 1; return _old_val + 1; } else if (_test_type == "use_older_value") { if (_t_step == 0) return 1; return _old_val + _older_val; } else if (_test_type == "report_old") return getPostprocessorValueOld("report_name"); // This should not be attainable else { mooseError("Invalid test type."); return 0.0; } }
// DEPRECATED CONSTRUCTOR TotalVariableValue::TotalVariableValue(const std::string & deprecated_name, InputParameters parameters) : GeneralPostprocessor(deprecated_name, parameters), _value(0), _value_old(getPostprocessorValueOldByName(name())), _pps_value(getPostprocessorValue("value")), _pps_value_old(getPostprocessorValueOld("value")) { }
TotalVariableValue::TotalVariableValue(const InputParameters & parameters) : GeneralPostprocessor(parameters), _value(0), _value_old(getPostprocessorValueOldByName(name())), _pps_value(getPostprocessorValue("value")), _pps_value_old(getPostprocessorValueOld("value")) { }
void EigenExecutionerBase::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) { mooseAssert(max_iter>=min_iter, "Maximum number of power iterations must be greater than or equal to its minimum"); mooseAssert(pfactor>0.0, "Invaid linear convergence tolerance"); mooseAssert(tol_eig>0.0, "Invalid eigenvalue tolerance"); mooseAssert(tol_x>0.0, "Invalid solution norm tolerance"); // obtain the solution diff const PostprocessorValue * solution_diff = NULL; if (xdiff != "") { solution_diff = &getPostprocessorValueByName(xdiff); ExecFlagType xdiff_execflag = _problem.getUserObject<UserObject>(xdiff).execBitFlags(); if ((xdiff_execflag & EXEC_LINEAR) == EXEC_NONE) mooseError("Postprocessor "+xdiff+" requires execute_on = 'linear'"); } // not perform any iteration when max_iter==0 if (max_iter==0) return; // turn off nonlinear flag so that RHS kernels opterate on previous solutions _eigen_sys.eigenKernelOnOld(); // FIXME: currently power iteration use old and older solutions, // so save old and older solutions before they are changed by the power iteration _eigen_sys.saveOldSolutions(); // save solver control parameters to be modified by the power iteration Real tol1 = _problem.es().parameters.get<Real> ("linear solver tolerance"); unsigned int num1 = _problem.es().parameters.get<unsigned int>("nonlinear solver maximum iterations"); // every power iteration is a linear solve, so set nonlinear iteration number to one _problem.es().parameters.set<Real> ("linear solver tolerance") = pfactor; _problem.es().parameters.set<unsigned int>("nonlinear solver maximum iterations") = 1; if (echo) { _console << std::endl; _console << " Power iterations starts" << std::endl; _console << " ________________________________________________________________________________ " << std::endl; } // some iteration variables Real k_old = 0.0; Real & source_integral_old = getPostprocessorValueOld("bx_norm"); Real saved_source_integral_old = source_integral_old; Chebyshev_Parameters chebyshev_parameters; std::vector<Real> keff_history; std::vector<Real> diff_history; unsigned int iter = 0; // power iteration loop... // Note: |Bx|/k will stay constant one! makeBXConsistent(k); while (true) { if (echo) _console << " Power iteration= "<< iter << std::endl; // important: solutions of aux system is also copied _problem.advanceState(); k_old = k; source_integral_old = _source_integral; preIteration(); _problem.solve(); postIteration(); // save the initial residual if (iter==0) initial_res = _eigen_sys._initial_residual_before_preset_bcs; // update eigenvalue k = k_old * _source_integral / source_integral_old; _eigenvalue = k; if (echo) { // output on screen the convergence history only when we want to and MOOSE output system is not used keff_history.push_back(k); if (solution_diff) diff_history.push_back(*solution_diff); std::stringstream ss; if (solution_diff) { ss << std::endl; ss << " +================+=====================+=====================+\n"; ss << " | iteration | eigenvalue | solution_difference |\n"; ss << " +================+=====================+=====================+\n"; unsigned int j = 0; if (keff_history.size()>10) { ss << " : : : :\n"; j = keff_history.size()-10; } for (; j<keff_history.size(); j++) ss << " | " << std::setw(14) << j << " | " << std::setw(19) << std::scientific << std::setprecision(8) << keff_history[j] << " | " << std::setw(19) << std::scientific << std::setprecision(8) << diff_history[j] << " |\n"; ss << " +================+=====================+=====================+\n" << std::flush; } else { ss << std::endl; ss << " +================+=====================+\n"; ss << " | iteration | eigenvalue |\n"; ss << " +================+=====================+\n"; unsigned int j = 0; if (keff_history.size()>10) { ss << " : : :\n"; j = keff_history.size()-10; } for (; j<keff_history.size(); j++) ss << " | " << std::setw(14) << j << " | " << std::setw(19) << std::scientific << std::setprecision(8) << keff_history[j] << " |\n"; ss << " +================+=====================+\n" << std::flush; ss << std::endl; } _console << ss.str() << std::endl; } // increment iteration number here iter++; if (cheb_on) { chebyshev(chebyshev_parameters, iter, solution_diff); if (echo) _console << " Chebyshev step: " << chebyshev_parameters.icheb << std::endl; } if (echo) _console << " ________________________________________________________________________________ " << std::endl; // not perform any convergence check when number of iterations is less than min_iter if (iter>=min_iter) { // no need to check convergence of the last iteration if (iter!=max_iter) { bool converged = true; Real keff_error = fabs(k_old-k)/k; if (keff_error>tol_eig) converged = false; if (solution_diff) if (*solution_diff > tol_x) converged = false; if (converged) break; } else break; } } source_integral_old = saved_source_integral_old; // restore parameters changed by the executioner _problem.es().parameters.set<Real> ("linear solver tolerance") = tol1; _problem.es().parameters.set<unsigned int>("nonlinear solver maximum iterations") = num1; //FIXME: currently power iteration use old and older solutions, so restore them _eigen_sys.restoreOldSolutions(); }