Chi-Tech
SweepChunk.cc
Go to the documentation of this file.
1#include "SweepChunk.h"
2
5
6#include "chi_runtime.h"
7#include "chi_log.h"
9
10#define scint static_cast<int>
11
12namespace lbs
13{
14
16 std::vector<double>& destination_phi,
17 std::vector<double>& destination_psi,
18 const chi_mesh::MeshContinuum& grid,
19 const chi_math::SpatialDiscretization& discretization,
20 const std::vector<UnitCellMatrices>& unit_cell_matrices,
21 std::vector<lbs::CellLBSView>& cell_transport_views,
22 const std::vector<double>& source_moments,
23 const LBSGroupset& groupset,
24 const std::map<int, XSPtr>& xs,
25 int num_moments,
26 int max_num_cell_dofs,
27 std::unique_ptr<SweepDependencyInterface> sweep_dependency_interface_ptr)
28 : chi_mesh::sweep_management::SweepChunk(destination_phi, destination_psi),
29 grid_(grid),
30 grid_fe_view_(discretization),
31 unit_cell_matrices_(unit_cell_matrices),
32 grid_transport_view_(cell_transport_views),
33 q_moments_(source_moments),
34 groupset_(groupset),
35 xs_(xs),
36 num_moments_(num_moments),
37 save_angular_flux_(!destination_psi.empty()),
38 sweep_dependency_interface_ptr_(std::move(sweep_dependency_interface_ptr)),
39 sweep_dependency_interface_(*sweep_dependency_interface_ptr_),
40 groupset_angle_group_stride_(groupset_.psi_uk_man_.NumberOfUnknowns() *
41 groupset_.groups_.size()),
42 groupset_group_stride_(groupset_.groups_.size())
43{
44 Amat_.resize(max_num_cell_dofs, std::vector<double>(max_num_cell_dofs));
45 Atemp_.resize(max_num_cell_dofs, std::vector<double>(max_num_cell_dofs));
46 b_.resize(groupset.groups_.size(),
47 std::vector<double>(max_num_cell_dofs, 0.0));
48 source_.resize(max_num_cell_dofs, 0.0);
49
53}
54
55// ##################################################################
56/**Registers a kernel as a named callback function*/
57void SweepChunk::RegisterKernel(const std::string& name,
58 CallbackFunction function)
59{
60 ChiInvalidArgumentIf(kernels_.count(name) > 0,
61 "Attempting to register kernel with name \"" + name +
62 "\" but the kernel already exists.");
63
64 kernels_[name] = std::move(function);
65}
66
67// ##################################################################
68/**Returns a kernel if the given name exists.*/
70{
71 ChiInvalidArgumentIf(kernels_.count(name) == 0,
72 "No register kernel with name \"" + name + "\" found");
73 return kernels_.at(name);
74}
75
76// ##################################################################
77/**Executes the supplied kernels list.*/
78void SweepChunk::ExecuteKernels(const std::vector<CallbackFunction>& kernels)
79{
80 for (auto& kernel : kernels)
81 kernel();
82}
83
84// ##################################################################
85/**Operations when outgoing fluxes are handled including passing
86 * face angular fluxes downstream and computing
87 * balance parameters (i.e. outflow)
88 * */
90{
92 const auto& IntF_shapeI = (*IntS_shapeI_)[f];
93 const double mu = face_mu_values_[f];
94 const double wt = direction_qweight_;
95
96 const bool on_boundary = sweep_dependency_interface_.on_boundary_;
97 const bool is_reflecting_boundary =
99
100 const size_t num_face_nodes = cell_mapping_->NumFaceNodes(f);
101 for (int fi = 0; fi < num_face_nodes; ++fi)
102 {
103 const int i = cell_mapping_->MapFaceNode(f, fi);
104
106
107 if (psi != nullptr)
108 if (not on_boundary or is_reflecting_boundary)
109 for (int gsg = 0; gsg < gs_ss_size_; ++gsg)
110 psi[gsg] = b_[gsg][i];
111 if (on_boundary and not is_reflecting_boundary)
112 for (int gsg = 0; gsg < gs_ss_size_; ++gsg)
114 wt * mu * b_[gsg][i] * IntF_shapeI[i]);
115
116 } // for fi
117}
118
119// ##################################################################
120/**Assembles the volumetric gradient term.*/
122{
123 const auto& G = *G_;
124
125 for (int i = 0; i < cell_num_nodes_; ++i)
126 for (int j = 0; j < cell_num_nodes_; ++j)
127 Amat_[i][j] = omega_.Dot(G[i][j]);
128}
129
130// ##################################################################
131/**Performs the integral over the surface of a face.*/
133{
135 const auto& M_surf_f = (*M_surf_)[f];
136 const double mu = face_mu_values_[f];
137 const size_t num_face_nodes = sweep_dependency_interface_.num_face_nodes_;
138 for (int fi = 0; fi < num_face_nodes; ++fi)
139 {
140 const int i = cell_mapping_->MapFaceNode(f, fi);
141 for (int fj = 0; fj < num_face_nodes; ++fj)
142 {
143 const int j = cell_mapping_->MapFaceNode(f, fj);
144
145 const double* psi = sweep_dependency_interface_.GetUpwindPsi(fj);
146
147 const double mu_Nij = -mu * M_surf_f[i][j];
148 Amat_[i][j] += mu_Nij;
149
150 if (psi == nullptr) continue;
151
152 for (int gsg = 0; gsg < gs_ss_size_; ++gsg)
153 b_[gsg][i] += psi[gsg] * mu_Nij;
154 } // for face node j
155 } // for face node i
156}
157
158// ##################################################################
159/**Assembles angular sources and applies the mass matrix terms.*/
161{
162 const auto& M = *M_;
163 const auto& m2d_op = groupset_.quadrature_->GetMomentToDiscreteOperator();
164
165 // ============================= Contribute source moments
166 // q = M_n^T * q_moms
167 for (int i = 0; i < cell_num_nodes_; ++i)
168 {
169 double temp_src = 0.0;
170 for (int m = 0; m < num_moments_; ++m)
171 {
172 const size_t ir = cell_transport_view_->MapDOF(i, m, scint(g_));
173 temp_src += m2d_op[m][direction_num_] * q_moments_[ir];
174 } // for m
175 source_[i] = temp_src;
176 } // for i
177
178 // ============================= Mass Matrix and Source
179 // Atemp = Amat + sigma_tgr * M
180 // b += M * q
181 for (int i = 0; i < cell_num_nodes_; ++i)
182 {
183 double temp = 0.0;
184 for (int j = 0; j < cell_num_nodes_; ++j)
185 {
186 const double Mij = M[i][j];
187 Atemp_[i][j] = Amat_[i][j] + Mij * sigma_tg_;
188 temp += Mij * source_[j];
189 } // for j
190 b_[gsg_][i] += temp;
191 } // for i
192}
193
194// ##################################################################
195/**Adds a single direction's contribution to the moment integrals.*/
197{
198 const auto& d2m_op = groupset_.quadrature_->GetDiscreteToMomentOperator();
199
200 auto& output_phi = GetDestinationPhi();
201
202 for (int m = 0; m < num_moments_; ++m)
203 {
204 const double wn_d2m = d2m_op[m][direction_num_];
205 for (int i = 0; i < cell_num_nodes_; ++i)
206 {
207 const size_t ir = cell_transport_view_->MapDOF(i, m, gs_gi_);
208 for (int gsg = 0; gsg < gs_ss_size_; ++gsg)
209 output_phi[ir + gsg] += wn_d2m * b_[gsg][i];
210 }
211 }
212}
213
214// ##################################################################
215/**Updates angular fluxes.*/
217{
218 if (not save_angular_flux_) return;
219
220 auto& output_psi = GetDestinationPsi();
221 double* cell_psi_data = &output_psi[grid_fe_view_.MapDOFLocal(
222 *cell_, 0, groupset_.psi_uk_man_, 0, 0)];
223
224
225 for (size_t i = 0; i < cell_num_nodes_; ++i)
226 {
227 const size_t imap = i * groupset_angle_group_stride_ +
229 for (int gsg = 0; gsg < gs_ss_size_; ++gsg)
230 cell_psi_data[imap + gsg] = b_[gsg][i];
231 } // for i
232}
233
234// ##################################################################
235/**Sets data for the current incoming face.*/
237 size_t num_face_nodes,
238 uint64_t neighbor_id,
239 bool on_local_face,
240 bool on_boundary)
241{
242 current_face_idx_ = face_id;
243 num_face_nodes_ = num_face_nodes;
244 neighbor_id_ = neighbor_id;
245 on_local_face_ = on_local_face;
246 on_boundary_ = on_boundary;
247}
248
249// ##################################################################
250/**Sets data for the current outgoing face.*/
252 size_t num_face_nodes,
253 uint64_t neighbor_id,
254 bool on_local_face,
255 bool on_boundary,
256 int locality)
257{
258 current_face_idx_ = face_id;
259 num_face_nodes_ = num_face_nodes;
260 neighbor_id_ = neighbor_id;
261 face_locality_ = locality;
262 on_local_face_ = on_local_face;
263 on_boundary_ = on_boundary;
264
266 (on_boundary_ and
267 angle_set_->GetBoundaries()[neighbor_id_]->IsReflecting());
268}
269
270} // namespace lbs
#define scint
Definition: SweepChunk.cc:10
#define ChiInvalidArgumentIf(condition, message)
int MapFaceNode(size_t face_index, size_t face_node_index) const
Definition: CellMapping.cc:53
size_t NumFaceNodes(size_t face_index) const
Definition: CellMapping.cc:36
virtual int64_t MapDOFLocal(const chi_mesh::Cell &cell, unsigned int node, const UnknownManager &unknown_manager, unsigned int unknown_id, unsigned int component) const =0
std::map< uint64_t, SweepBndryPtr > & GetBoundaries()
Definition: AngleSet.cc:50
std::vector< double > & GetDestinationPsi()
std::vector< double > & GetDestinationPhi()
size_t MapDOF(int node, int moment, int grp) const
Definition: lbs_structs.h:198
void AddOutflow(int g, double intS_mu_psi)
Definition: lbs_structs.h:221
std::shared_ptr< chi_math::AngularQuadrature > quadrature_
Definition: lbs_groupset.h:42
chi_math::UnknownManager psi_uk_man_
Definition: lbs_groupset.h:83
std::vector< LBSGroup > groups_
Definition: lbs_groupset.h:41
std::vector< std::vector< double > > Atemp_
Definition: SweepChunk.h:108
std::vector< double > source_
Definition: SweepChunk.h:109
void KernelPhiUpdate()
Definition: SweepChunk.cc:196
const int num_moments_
Definition: SweepChunk.h:93
void KernelFEMSTDMassTerms()
Definition: SweepChunk.cc:160
chi_mesh::Vector3 omega_
Definition: SweepChunk.h:129
size_t direction_num_
Definition: SweepChunk.h:128
void RegisterKernel(const std::string &name, CallbackFunction function)
Definition: SweepChunk.cc:57
double direction_qweight_
Definition: SweepChunk.h:130
size_t gs_ss_begin_
Definition: SweepChunk.h:104
std::function< void()> CallbackFunction
Definition: SweepChunk.h:84
std::vector< double > face_mu_values_
Definition: SweepChunk.h:127
const MatDbl * M_
Definition: SweepChunk.h:120
const size_t groupset_angle_group_stride_
Definition: SweepChunk.h:99
CellLBSView * cell_transport_view_
Definition: SweepChunk.h:116
const LBSGroupset & groupset_
Definition: SweepChunk.h:91
const chi_math::SpatialDiscretization & grid_fe_view_
Definition: SweepChunk.h:87
void KernelPsiUpdate()
Definition: SweepChunk.cc:216
CallbackFunction Kernel(const std::string &name) const
Definition: SweepChunk.cc:69
const std::vector< double > & q_moments_
Definition: SweepChunk.h:90
SweepDependencyInterface & sweep_dependency_interface_
Definition: SweepChunk.h:97
void KernelFEMVolumetricGradientTerm()
Definition: SweepChunk.cc:121
std::map< std::string, CallbackFunction > kernels_
Definition: SweepChunk.h:169
size_t cell_num_nodes_
Definition: SweepChunk.h:118
virtual void OutgoingSurfaceOperations()
Definition: SweepChunk.cc:89
size_t gs_ss_size_
Definition: SweepChunk.h:103
double sigma_tg_
Definition: SweepChunk.h:140
static void ExecuteKernels(const std::vector< CallbackFunction > &kernels)
Definition: SweepChunk.cc:78
const chi_mesh::Cell * cell_
Definition: SweepChunk.h:114
std::vector< std::vector< double > > b_
Definition: SweepChunk.h:110
std::vector< std::vector< double > > Amat_
Definition: SweepChunk.h:107
const MatVec3 * G_
Definition: SweepChunk.h:119
const size_t groupset_group_stride_
Definition: SweepChunk.h:100
void KernelFEMUpwindSurfaceIntegrals()
Definition: SweepChunk.cc:132
const chi_math::CellMapping * cell_mapping_
Definition: SweepChunk.h:115
SweepChunk(std::vector< double > &destination_phi, std::vector< double > &destination_psi, const chi_mesh::MeshContinuum &grid, const chi_math::SpatialDiscretization &discretization, const std::vector< UnitCellMatrices > &unit_cell_matrices, std::vector< lbs::CellLBSView > &cell_transport_views, const std::vector< double > &source_moments, const LBSGroupset &groupset, const std::map< int, XSPtr > &xs, int num_moments, int max_num_cell_dofs, std::unique_ptr< SweepDependencyInterface > sweep_dependency_interface_ptr)
Definition: SweepChunk.cc:15
const bool save_angular_flux_
Definition: SweepChunk.h:94
Vector3 Dot(const chi_mesh::TensorRank2Dim3 &that) const
virtual void SetupOutgoingFace(int face_id, size_t num_face_nodes, uint64_t neighbor_id, bool on_local_face, bool on_boundary, int locality)
Definition: SweepChunk.cc:251
virtual const double * GetUpwindPsi(int face_node_local_idx) const =0
virtual void SetupIncomingFace(int face_id, size_t num_face_nodes, uint64_t neighbor_id, bool on_local_face, bool on_boundary)
Definition: SweepChunk.cc:236
chi_mesh::sweep_management::AngleSet * angle_set_
Definition: SweepChunk.h:20
virtual double * GetDownwindPsi(int face_node_local_idx) const =0