24 const std::string fname =
"lbs::PowerIterationKEigen";
28 auto context = wgs_solver->GetContext();
30 std::dynamic_pointer_cast<lbs::WGSContext<Mat,Vec,KSP>>(context);
32 if (not wgs_context)
throw std::logic_error(fname +
": Cast failed.");
40 throw std::invalid_argument(fname +
": The \"power1\" method can only "
41 "be used with a single groupset.");
51 auto& front_gs = groupsets.front();
52 auto& front_wgs_solver = lbs_solver.
GetWGSSolvers()[front_gs.id_];
53 auto frons_wgs_context = std::dynamic_pointer_cast<lbs::WGSContext<Mat,Vec,KSP>>(
54 front_wgs_solver->GetContext());
56 front_gs.apply_wgdsa_ =
true;
57 front_gs.wgdsa_tol_ = basic_options(
"PISA_MIP_L_ABS_TOL").FloatValue();
58 front_gs.wgdsa_max_iters_ =
59 static_cast<int>(basic_options(
"PISA_MIP_L_MAX_ITS").IntegerValue());
61 front_gs.apply_wgdsa_ =
false;
63 int pisa_verbose_level =
64 static_cast<int>(basic_options(
"PISA_VERBOSE_LEVEL").IntegerValue());
66 auto& diff_solver = *front_gs.wgdsa_solver_;
68 auto nl_diff_context = std::make_shared<acceleration::NLKEigenDiffContext>(
69 diff_solver, lbs_solver, pisa_verbose_level);
75 tolerances.
nl_abs_tol_ = basic_options(
"PISA_NL_ABS_TOL").FloatValue();
76 tolerances.nl_rel_tol_ = basic_options(
"PISA_NL_REL_TOL").FloatValue();
77 tolerances.nl_sol_tol_ = basic_options(
"PISA_NL_SOL_TOL").FloatValue();
78 tolerances.nl_max_its_ =
79 static_cast<int>(basic_options(
"PISA_NL_MAX_ITS").IntegerValue());
81 tolerances.l_abs_tol_ = basic_options(
"PISA_L_ABS_TOL").FloatValue();
82 tolerances.l_rel_tol_ = basic_options(
"PISA_L_REL_TOL").FloatValue();
83 tolerances.l_max_its_ =
84 static_cast<int>(basic_options(
"PISA_L_MAX_ITS").IntegerValue());
85 tolerances.l_gmres_restart_intvl_ =
86 static_cast<int>(basic_options(
"PISA_L_MAX_ITS").IntegerValue());
90 double k_eff_prev = 1.0;
91 double k_eff_change = 1.0;
94 auto SetLBSFissionSource = [&active_set_source_function,&front_gs]
98 active_set_source_function(front_gs, output,
107 bool converged =
false;
108 while (nit < max_iterations)
110 nl_diff_context->phi_l_ = lbs_solver.
WGSCopyOnlyPhi0(front_gs, phi_old_local);
112 SetLBSFissionSource(phi_old_local, q_moments_local);
115 auto Sffull = q_moments_local;
116 nl_diff_context->Sf_ = lbs_solver.
WGSCopyOnlyPhi0(front_gs, q_moments_local);
120 primary_ags_solver->Setup();
121 primary_ags_solver->Solve();
124 nl_diff_context->phi_lph_i_ = lbs_solver.
WGSCopyOnlyPhi0(front_gs, phi_new_local);
127 q_moments_local = Sffull;
128 active_set_source_function(front_gs, q_moments_local,
133 frons_wgs_context->ApplyInverseTransportOperator(
NO_FLAGS_SET);
137 nl_diff_context->phi_lph_ip1_ = lbs_solver.
WGSCopyOnlyPhi0(front_gs, phi_new_local);
139 nl_diff_context->kresid_func_context_.k_eff = k_eff;
140 nl_diff_context->k_l = k_eff;
144 nl_keigen_diff_solver.
Setup();
145 nl_keigen_diff_solver.
Solve();
146 k_eff = nl_diff_context->kresid_func_context_.k_eff;
151 k_eff = F_new / F_prev * k_eff;
155 double reactivity = (k_eff - 1.0) / k_eff;
158 k_eff_change = fabs(k_eff - k_eff_prev) / k_eff;
162 if (k_eff_change < std::max(tolerance, 1.0e-12))
168 std::stringstream k_iter_info;
171 <<
" Iteration " << std::setw(5) << nit
172 <<
" k_eff " << std::setw(11) << std::setprecision(7) << k_eff
173 <<
" k_eff change " << std::setw(12) << k_eff_change
174 <<
" reactivity " << std::setw(10) << reactivity * 1e5;
175 if (converged) k_iter_info <<
" CONVERGED\n";
180 if (converged)
break;
186 <<
" Final k-eigenvalue : "
187 << std::setprecision(7) << k_eff;
189 <<
" Final change : "
190 << std::setprecision(6) << k_eff_change
191 <<
" (num_TrOps:" << frons_wgs_context->counter_applications_of_inv_op_ <<
")"
static chi::Timer program_timer
LogStream Log(LOG_LVL level=LOG_0)
std::string GetTimeString() const
NonLinearSolverOptions & ToleranceOptions()
BasicOptions & GetBasicOptions()
AGSLinSolverPtr GetPrimaryAGSSolver()
std::vector< double > & PhiNewLocal()
std::vector< double > & QMomentsLocal()
std::vector< LBSGroupset > & Groupsets()
double ComputeFissionProduction(const std::vector< double > &phi)
std::vector< LinSolvePtr > & GetWGSSolvers()
SetSourceFunction GetActiveSetSourceFunction() const
std::vector< double > WGSCopyOnlyPhi0(const LBSGroupset &groupset, const std::vector< double > &phi_in)
void InitWGDSA(LBSGroupset &groupset, bool vaccum_bcs_are_dirichlet=true)
std::vector< double > & PhiOldLocal()
virtual void GSScopedCopyPrimarySTLvectors(LBSGroupset &groupset, const std::vector< double > &x_src, std::vector< double > &y)
void Scale(VecDbl &x, const double &val)
void Set(VecDbl &x, const double &val)
@ APPLY_AGS_FISSION_SOURCES
@ APPLY_WGS_FISSION_SOURCES
@ APPLY_WGS_SCATTER_SOURCES
@ APPLY_AGS_SCATTER_SOURCES
void PowerIterationKEigen2(LBSSolver &lbs_solver, double tolerance, int max_iterations, double &k_eff)
std::vector< double > VecDbl
bool verbose_ags_iterations
bool verbose_outer_iterations