Chi-Tech
sweep_wgs_context.cc
Go to the documentation of this file.
1#include "sweep_wgs_context.h"
2
3#include <petscksp.h>
4
7
8#include "chi_runtime.h"
9#include "chi_log.h"
10
11#include <iomanip>
12
13#define sc_double static_cast<double>
14#define PCShellPtr PetscErrorCode (*)(PC, Vec, Vec)
15
16namespace lbs
17{
18
19/**General print out of information.*/
20template <>
22{
23 if (log_info_)
24 {
25 std::string method_name;
26 switch (groupset_.iterative_method_)
27 {
29 method_name = "KRYLOV_RICHARDSON";
30 break;
32 method_name = "KRYLOV_GMRES";
33 break;
35 method_name = "KRYLOV_BICGSTAB";
36 break;
37 default:
38 method_name = "KRYLOV_GMRES";
39 }
40 Chi::log.Log() << "\n\n"
41 << "********** Solving groupset " << groupset_.id_
42 << " with " << method_name << ".\n\n"
43 << "Quadrature number of angles: "
44 << groupset_.quadrature_->abscissae_.size() << "\n"
45 << "Groups " << groupset_.groups_.front().id_ << " "
46 << groupset_.groups_.back().id_ << "\n\n";
47 }
48}
49
50/**Sets the preconditioner application function.*/
51template <>
53{
54 auto& ksp = solver;
55
56 PC pc;
57 KSPGetPC(ksp, &pc);
58
59 if (groupset_.apply_wgdsa_ or groupset_.apply_tgdsa_)
60 {
61 PCSetType(pc, PCSHELL);
62 PCShellSetApply(pc, (PCShellPtr)WGDSA_TGDSA_PreConditionerMult);
63 PCShellSetContext(pc, &(*this));
64 }
65
66 KSPSetPCSide(ksp, PC_LEFT);
67 KSPSetUp(ksp);
68}
69
70/**For sweeping we add lagged angular fluxes to the size of the vectors.*/
71template <>
72std::pair<int64_t, int64_t> SweepWGSContext<Mat, Vec, KSP>::SystemSize()
73{
74 const size_t local_node_count = lbs_solver_.LocalNodeCount();
75 const size_t globl_node_count = lbs_solver_.GlobalNodeCount();
76 const size_t num_moments = lbs_solver_.NumMoments();
77
78 const size_t groupset_numgrps = groupset_.groups_.size();
79 const auto num_delayed_psi_info =
80 groupset_.angle_agg_->GetNumDelayedAngularDOFs();
81 const size_t local_size = local_node_count * num_moments * groupset_numgrps +
82 num_delayed_psi_info.first;
83 const size_t globl_size = globl_node_count * num_moments * groupset_numgrps +
84 num_delayed_psi_info.second;
85 const size_t num_angles = groupset_.quadrature_->abscissae_.size();
86 const size_t num_psi_global =
87 globl_node_count * num_angles * groupset_.groups_.size();
88 const size_t num_delayed_psi_globl = num_delayed_psi_info.second;
89
90 if (log_info_)
91 {
92 Chi::log.Log() << "Total number of angular unknowns: " << num_psi_global
93 << "\n"
94 << "Number of lagged angular unknowns: "
95 << num_delayed_psi_globl << "(" << std::setprecision(2)
96 << sc_double(num_delayed_psi_globl) * 100 /
97 sc_double(num_psi_global)
98 << "%)";
99 }
100
101 return {static_cast<int64_t>(local_size), static_cast<int64_t>(globl_size)};
102}
103
104/**With a right-hand side built. This routine applies the inverse
105 * of the transport operator to this right-hand side.*/
106template <>
108{
109 ++counter_applications_of_inv_op_;
110 const bool use_bndry_source_flag =
111 (scope & APPLY_FIXED_SOURCES) and
112 (not lbs_solver_.Options().use_src_moments);
113
114 sweep_scheduler_.SetBoundarySourceActiveFlag(use_bndry_source_flag);
115
116 if (scope & ZERO_INCOMING_DELAYED_PSI)
117 sweep_scheduler_.ZeroIncomingDelayedPsi();
118
119 // Sweep
120 sweep_scheduler_.ZeroOutputFluxDataStructures();
121 sweep_scheduler_.Sweep();
122}
123
124/**This method implements an additional sweep for two reasons:
125 * The first is to compute balance parameters, and the second
126 * is to allow for the calculation of proper angular fluxes. The
127 * latter is needed because some krylov methods do not necessarily
128 * provide the true angular flux at each iteration.*/
129template <>
131{
132 //================================================== Perform final sweep
133 // with converged phi and
134 // delayed psi dofs
135 if (groupset_.iterative_method_ != IterativeMethod::KRYLOV_RICHARDSON)
136 {
137 lbs_ss_solver_.ZeroOutflowBalanceVars(groupset_);
138
139 const int scope = lhs_src_scope_ | rhs_src_scope_;
140
141 set_source_function_(
142 groupset_, lbs_solver_.QMomentsLocal(), lbs_solver_.PhiOldLocal(), scope);
143 sweep_scheduler_.SetDestinationPhi(lbs_solver_.PhiNewLocal());
144
145 ApplyInverseTransportOperator(scope);
146
147 lbs_solver_.GSScopedCopyPrimarySTLvectors(
149 }
150
151 //==================================================== Print solution info
152 {
153 double sweep_time = sweep_scheduler_.GetAverageSweepTime();
154 double chunk_overhead_ratio =
155 1.0 - sweep_scheduler_.GetAngleSetTimings()[2];
156 double source_time =
157 Chi::log.ProcessEvent(lbs_solver_.GetSourceEventTag(),
159 size_t num_angles = groupset_.quadrature_->abscissae_.size();
160 size_t num_unknowns =
161 lbs_solver_.GlobalNodeCount() * num_angles * groupset_.groups_.size();
162
163 if (log_info_)
164 {
165 Chi::log.Log() << "\n\n";
166 Chi::log.Log() << " Set Src Time/sweep (s): "
167 << source_time;
168 Chi::log.Log() << " Average sweep time (s): " << sweep_time;
169 Chi::log.Log() << " Chunk-Overhead-Ratio : "
170 << chunk_overhead_ratio;
171 Chi::log.Log() << " Sweep Time/Unknown (ns): "
172 << sweep_time * 1.0e9 * Chi::mpi.process_count /
173 static_cast<double>(num_unknowns);
174 Chi::log.Log() << " Number of unknowns per sweep: "
175 << num_unknowns;
176 Chi::log.Log() << "\n\n";
177
178 std::string sweep_log_file_name =
179 std::string("GS_") + std::to_string(groupset_.id_) +
180 std::string("_SweepLog_") + std::to_string(Chi::mpi.location_id) +
181 std::string(".log");
182 groupset_.PrintSweepInfoFile(sweep_scheduler_.SweepEventTag(),
183 sweep_log_file_name);
184 }
185 }
186}
187
188} // namespace lbs
static chi::ChiLog & log
Definition: chi_runtime.h:81
static chi::MPI_Info & mpi
Definition: chi_runtime.h:78
double ProcessEvent(size_t ev_tag, EventOperation ev_operation)
Definition: chi_log.cc:275
@ AVERAGE_DURATION
Computes average time between begins and ends.
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
const int & process_count
Total number of processes.
Definition: mpi_info.h:27
int WGDSA_TGDSA_PreConditionerMult(PC pc, Vec phi_input, Vec pc_output)
@ KRYLOV_BICGSTAB
BiCGStab iterative algorithm.
@ KRYLOV_RICHARDSON
Richardson iteration.
@ KRYLOV_GMRES
GMRES iterative algorithm.
@ ZERO_INCOMING_DELAYED_PSI
Definition: lbs_structs.h:96
@ APPLY_FIXED_SOURCES
Definition: lbs_structs.h:90
void ApplyInverseTransportOperator(int scope) override
void SetPreconditioner(SolverType &solver) override
std::pair< int64_t, int64_t > SystemSize() override
void PreSetupCallback() override
void PostSolveCallback() override
#define sc_double
#define PCShellPtr