Chi-Tech
pi_keigen_scdsa_02_exec.cc
Go to the documentation of this file.
1#include "pi_keigen_scdsa.h"
2
3#include "chi_runtime.h"
4#include "chi_log.h"
5#include "utils/chi_timer.h"
6
10
11#include <iomanip>
12
13namespace lbs
14{
15
16// ##################################################################
17/**Executes the scheme.*/
19{
20 auto phi_temp = phi_old_local_;
21
22 /**Lambda for the creation of scattering sources but the
23 * input vector is only the zeroth moment*/
24 auto SetLBSScatterSourcePhi0 =
25 [this, &phi_temp](const VecDbl& input,
26 const bool additive,
27 const bool suppress_wg_scat = false)
28 {
29 ProjectBackPhi0(front_gs_, input, phi_temp);
30 SetLBSScatterSource(/*in*/ phi_temp, additive, suppress_wg_scat);
31 };
32
33 const size_t tag_SCDSA_solve_time =
34 Chi::log.GetRepeatingEventTag("SCDSA_solve_time");
35 const size_t tag_sweep_timing = Chi::log.GetRepeatingEventTag("Sweep Timing");
36
37 using namespace chi_math;
38
39 k_eff_ = 1.0;
40 double k_eff_prev = 1.0;
41 double k_eff_change = 1.0;
42
43 //================================================== Start power iterations
44 int nit = 0;
45 bool converged = false;
46 while (nit < max_iters_)
47 {
48 //================================= Set the fission source
49 SetLBSFissionSource(phi_old_local_, /*additive=*/false);
51
52 auto Sf_ell = q_moments_local_;
54
55 //================================= This solves the inners for transport
56 primary_ags_solver_->Setup();
57 primary_ags_solver_->Solve();
58
59 // lph_i = l + 1/2,i
60 auto phi0_lph_i = CopyOnlyPhi0(front_gs_, phi_new_local_);
61
62 // Now we produce lph_ip1 = l + 1/2, i+1
63 q_moments_local_ = Sf_ell; // Restore 1/k F phi_l
64 SetLBSScatterSource(phi_new_local_, /*additive=*/true);
65
66 front_wgs_context_->ApplyInverseTransportOperator(NO_FLAGS_SET); // Sweep
67
68 auto phi0_lph_ip1 = CopyOnlyPhi0(front_gs_, phi_new_local_);
69
70 //====================================== Power Iteration Acceleration
71 SetLBSScatterSourcePhi0(phi0_lph_ip1 - phi0_lph_i, /*additive=*/false);
73
75
76 VecDbl epsilon_k(phi0_lph_ip1.size(), 0.0);
77 auto epsilon_kp1 = epsilon_k;
78
79 double lambda_k = k_eff_;
80 double lambda_kp1 = lambda_k;
81
82 for (size_t k = 0; k < accel_pi_max_its_; ++k)
83 {
85 /*in*/ epsilon_k + phi0_lph_ip1,
86 /*out*/ phi_temp);
87
88 // double production_k = lbs_solver_.ComputeFissionProduction(phi_temp);
89
90 SetLBSFissionSource(phi_temp, /*additive=*/false);
91 Scale(q_moments_local_, 1.0 / lambda_k);
92
94
95 // Inner iterations seems extremely wasteful therefore I
96 // am leaving this at 1 iteration here for further investigation.
97 for (int i = 0; i < 1; ++i)
98 {
99 SetLBSScatterSourcePhi0(epsilon_k,
100 /*additive=*/false,
101 /*suppress_wg_scat=*/true);
102
104
105 // Solve the diffusion system
106 Chi::log.LogEvent(tag_SCDSA_solve_time,
108 diffusion_solver_->Assemble_b(Ss + Sfaux + Ss_res - Sf0_ell);
109 diffusion_solver_->Solve(epsilon_kp1, /*use_initial_guess=*/true);
110 Chi::log.LogEvent(tag_SCDSA_solve_time,
112
113 epsilon_k = epsilon_kp1;
114 }
115
117 /*in*/ epsilon_kp1 + phi0_lph_ip1,
118 /*out*/ phi_old_local_);
119
120 double production_kp1 =
122
123 lambda_kp1 = production_kp1 / (production_k / lambda_k);
124
125 const double lambda_change = std::fabs(1.0 - lambda_kp1 / lambda_k);
126 if (accel_pi_verbose_ >= 1)
127 Chi::log.Log() << "PISCDSA iteration " << k << " lambda " << lambda_kp1
128 << " lambda change " << lambda_change;
129
130 if (lambda_change < accel_pi_k_tol_) break;
131
132 lambda_k = lambda_kp1;
133 epsilon_k = epsilon_kp1;
134 production_k = production_kp1;
135 } // acceleration
136
138 /*in*/ epsilon_kp1 + phi0_lph_ip1,
139 /*out*/ phi_new_local_);
141 /*in*/ phi_new_local_,
142 /*out*/ phi_old_local_);
143
144 const double production =
146 lbs_solver_.ScalePhiVector(PhiSTLOption::PHI_OLD, lambda_kp1 / production);
147
148 //================================= Recompute k-eigenvalue
149 k_eff_ = lambda_kp1;
150 double reactivity = (k_eff_ - 1.0) / k_eff_;
151
152 //================================= Check convergence, bookkeeping
153 k_eff_change = fabs(k_eff_ - k_eff_prev) / k_eff_;
154 k_eff_prev = k_eff_;
155 nit += 1;
156
157 if (k_eff_change < std::max(k_tolerance_, 1.0e-12)) converged = true;
158
159 //================================= Print iteration summary
161 {
162 std::stringstream k_iter_info;
163 k_iter_info << Chi::program_timer.GetTimeString() << " "
164 << " Iteration " << std::setw(5) << nit << " k_eff "
165 << std::setw(11) << std::setprecision(7) << k_eff_
166 << " k_eff change " << std::setw(12) << k_eff_change
167 << " reactivity " << std::setw(10) << reactivity * 1e5;
168 if (converged) k_iter_info << " CONVERGED\n";
169
170 Chi::log.Log() << k_iter_info.str();
171 }
172
173 if (converged) break;
174 } // for k iterations
175
176 //================================================== Print summary
177 Chi::log.Log() << "\n";
178 Chi::log.Log() << " Final k-eigenvalue : "
179 << std::setprecision(7) << k_eff_;
180 Chi::log.Log()
181 << " Final change : " << std::setprecision(6)
182 << k_eff_change
183 << " (num_TrOps:" << front_wgs_context_->counter_applications_of_inv_op_
184 << ")"
185 << "\n"
186 << " Diffusion solve time : "
187 << Chi::log.ProcessEvent(tag_SCDSA_solve_time,
189 1.0e-6
190 << "s\n"
191 << " Total sweep time : "
192 << Chi::log.ProcessEvent(tag_sweep_timing,
194 Chi::log.Log() << "\n";
195
197 {
200 }
201
203
204 Chi::log.Log()
205 << "LinearBoltzmann::KEigenvalueSolver execution completed\n\n";
206}
207
208} // namespace lbs
static chi::Timer program_timer
Definition: chi_runtime.h:79
static chi::ChiLog & log
Definition: chi_runtime.h:81
double ProcessEvent(size_t ev_tag, EventOperation ev_operation)
Definition: chi_log.cc:275
@ TOTAL_DURATION
Integrates times between begins and ends.
@ EVENT_BEGIN
Signals the begin of an event.
@ EVENT_END
Signals the end of an event.
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
size_t GetRepeatingEventTag(std::string event_name)
Definition: chi_log.cc:176
void LogEvent(size_t ev_tag, EventType ev_type, const std::shared_ptr< EventInfo > &ev_info)
Definition: chi_log.cc:204
std::string GetTimeString() const
Definition: chi_timer.cc:38
std::vector< double > & PrecursorsNewLocal()
double ComputeFissionProduction(const std::vector< double > &phi)
virtual void ScalePhiVector(PhiSTLOption which_phi, double value)
lbs::Options & Options()
virtual void GSScopedCopyPrimarySTLvectors(LBSGroupset &groupset, const std::vector< double > &x_src, std::vector< double > &y)
std::shared_ptr< lbs::WGSContext< Mat, Vec, KSP > > front_wgs_context_
Definition: pi_keigen.h:26
std::shared_ptr< AGSLinearSolver< Mat, Vec, KSP > > primary_ags_solver_
Definition: pi_keigen.h:22
LBSGroupset & front_gs_
Definition: pi_keigen.h:24
void SetLBSScatterSource(const VecDbl &input, bool additive, bool suppress_wg_scat=false)
void SetLBSFissionSource(const VecDbl &input, bool additive)
std::vector< double > CopyOnlyPhi0(const LBSGroupset &groupset, const std::vector< double > &phi_in)
DiffusionSolverPtr diffusion_solver_
void ProjectBackPhi0(const LBSGroupset &groupset, const std::vector< double > &input, std::vector< double > &output)
void Scale(VecDbl &x, const double &val)
@ NO_FLAGS_SET
Definition: lbs_structs.h:89
std::vector< double > VecDbl
Definition: lbs_structs.h:18
bool verbose_outer_iterations
Definition: lbs_structs.h:145
bool use_precursors
Definition: lbs_structs.h:138