9#define ExceptionReflectedAngleError \
11 fname + "Reflected angle not found for angle " + std::to_string(n) + \
12 " with direction " + quadrature->omegas_[n].PrintStr() + \
13 ". This can happen for two reasons: i) A quadrature is used" \
14 " that is not symmetric about the axis associated with the " \
15 "reflected boundary, or ii) the reflecting boundary is not " \
16 "aligned with any reflecting axis of the quadrature.")
21 const std::map<uint64_t, SweepBndryPtr>& in_sim_boundaries,
22 size_t in_number_of_groups,
23 size_t in_number_of_group_subsets,
24 std::shared_ptr<chi_math::AngularQuadrature>& in_quadrature,
44 for (
auto& angsetgrp : angle_set_groups)
45 for (
auto& angset : angsetgrp.AngleSets())
46 for (
auto& delayed_data : angset->GetFLUDS().DelayedPrelocIOutgoingPsi())
49 for (
auto& angsetgrp : angle_set_groups)
50 for (
auto& angset : angsetgrp.AngleSets())
60 for (
const auto& [bid, bndry] : sim_boundaries)
62 if (bndry->IsReflecting())
66 if (rbndry.IsOpposingReflected())
67 for (
auto& angle : rbndry.GetHeteroBoundaryFluxOld())
68 for (
auto& cellvec : angle)
69 for (
auto& facevec : cellvec)
70 for (
auto& dofvec : facevec)
71 for (
auto& val : dofvec)
78 for (
auto& as_group : angle_set_groups)
79 for (
auto& angle_set : as_group.AngleSets())
80 chi_math::Set(angle_set->GetFLUDS().DelayedLocalPsiOld(), 0.0);
83 for (
auto& as_group : angle_set_groups)
84 for (
auto& angle_set : as_group.AngleSets())
85 for (
auto& loc_vector : angle_set->GetFLUDS().DelayedPrelocIOutgoingPsiOld())
93 const std::string fname =
"chi_mesh::sweep_management::AngleAggregation";
94 const double epsilon = 1.0e-8;
96 bool reflecting_bcs_initialized =
false;
101 for (
auto& [bid, bndry] : sim_boundaries)
103 if (bndry->IsReflecting())
105 size_t tot_num_angles = quadrature->abscissae_.size();
106 size_t num_local_cells = grid->local_cells.size();
109 const auto& normal = rbndry.Normal();
111 rbndry.GetReflectedAngleIndexMap().resize(tot_num_angles, -1);
112 rbndry.GetAngleReadyFlags().resize(
113 tot_num_angles, std::vector<bool>(number_of_group_subsets,
false));
119 for (
int n = 0; n < tot_num_angles; ++n)
121 const Vec3& omega_n = quadrature->omegas_[n];
122 Vec3 omega_reflected;
124 switch (rbndry.CoordType())
127 omega_reflected = -1.0 * omega_n;
132 if (std::fabs(normal.Dot(jhat)) > 0.999999 or
133 normal.Dot(ihat) < -0.999999)
134 omega_reflected = omega_n - 2.0 * normal * omega_n.Dot(normal);
136 else if (normal.Dot(ihat) > 0.999999)
139 if (omega_n.Dot(normal) > 0.0)
140 normal_star = Vec3(omega_n.x, 0.0, omega_n.z).Normalized();
142 normal_star = Vec3(-omega_n.x, 0.0, -omega_n.y).Normalized();
145 omega_n - 2.0 * normal_star * omega_n.Dot(normal_star);
151 omega_reflected = omega_n - 2.0 * normal * omega_n.Dot(normal);
155 auto& index_map = rbndry.GetReflectedAngleIndexMap();
156 for (
int nstar = 0; nstar < tot_num_angles; ++nstar)
157 if (omega_reflected.Dot(quadrature->omegas_[nstar]) > (1.0 - epsilon))
159 index_map[n] = nstar;
168 auto& heteroflux_new = rbndry.GetHeteroBoundaryFluxNew();
169 auto& heteroflux_old = rbndry.GetHeteroBoundaryFluxOld();
170 heteroflux_new.clear();
171 heteroflux_old.clear();
172 heteroflux_new.resize(tot_num_angles);
173 for (
int n = 0; n < tot_num_angles; ++n)
176 if (quadrature->omegas_[n].Dot(rbndry.Normal()) < 0.0)
continue;
179 auto& cell_vec = heteroflux_new[n];
180 cell_vec.resize(num_local_cells);
181 for (
const auto& cell : grid->local_cells)
183 const uint64_t c = cell.local_id_;
186 bool on_ref_bndry =
false;
187 for (
const auto& face : cell.faces_)
189 if ((not face.has_neighbor_) and
190 (face.normal_.Dot(rbndry.Normal()) > 0.999999))
196 if (not on_ref_bndry)
continue;
199 cell_vec[c].resize(cell.faces_.size());
201 for (
const auto& face : cell.faces_)
203 if ((not face.has_neighbor_) and
204 (face.normal_.Dot(rbndry.Normal()) > 0.999999))
206 cell_vec[c][f].clear();
207 cell_vec[c][f].resize(face.vertex_ids_.size(),
208 std::vector<double>(number_of_groups, 0.0));
221 for (
const auto& [otherbid, otherbndry] : sim_boundaries)
223 if (bid == otherbid)
continue;
224 if (not otherbndry->IsReflecting())
continue;
226 const auto& otherRbndry =
229 if (rbndry.Normal().Dot(otherRbndry.Normal()) < (0.0 - epsilon))
233 if (rbndry.IsOpposingReflected())
234 rbndry.GetHeteroBoundaryFluxOld() = rbndry.GetHeteroBoundaryFluxNew();
236 reflecting_bcs_initialized =
true;
240 if (reflecting_bcs_initialized)
247std::pair<size_t, size_t>
251 if (num_ang_unknowns_avail)
return number_angular_unknowns;
254 size_t local_ang_unknowns = 0;
257 for (
auto& [bid, bndry] : sim_boundaries)
259 if (bndry->IsReflecting())
263 if (rbndry.IsOpposingReflected())
264 for (
auto& angle : rbndry.GetHeteroBoundaryFluxNew())
265 for (
auto& cellvec : angle)
266 for (
auto& facevec : cellvec)
267 for (
auto& dofvec : facevec)
268 local_ang_unknowns += dofvec.size();
274 for (
auto& as_group : angle_set_groups)
275 for (
auto& angle_set : as_group.AngleSets())
276 local_ang_unknowns += angle_set->GetFLUDS().DelayedLocalPsi().size();
279 for (
auto& as_group : angle_set_groups)
280 for (
auto& angle_set : as_group.AngleSets())
281 for (
auto& loc_vector : angle_set->GetFLUDS().DelayedPrelocIOutgoingPsi())
282 local_ang_unknowns += loc_vector.size();
284 size_t global_ang_unknowns = 0;
285 MPI_Allreduce(&local_ang_unknowns,
286 &global_ang_unknowns,
288 MPI_UNSIGNED_LONG_LONG,
292 number_angular_unknowns = {local_ang_unknowns, global_ang_unknowns};
294 num_ang_unknowns_avail =
true;
295 return number_angular_unknowns;
304 for (
auto& [bid, bndry] : sim_boundaries)
306 if (bndry->IsReflecting())
310 if (rbndry.IsOpposingReflected())
311 for (
auto& angle : rbndry.GetHeteroBoundaryFluxNew())
312 for (
auto& cellvec : angle)
313 for (
auto& facevec : cellvec)
314 for (
auto& dofvec : facevec)
315 for (
auto val : dofvec)
325 for (
auto& as_group : angle_set_groups)
326 for (
auto& angle_set : as_group.AngleSets())
327 for (
auto val : angle_set->GetFLUDS().DelayedLocalPsi())
334 for (
auto& as_group : angle_set_groups)
335 for (
auto& angle_set : as_group.AngleSets())
336 for (
auto& loc_vector : angle_set->GetFLUDS().DelayedPrelocIOutgoingPsi())
337 for (
auto val : loc_vector)
350 for (
auto& [bid, bndry] : sim_boundaries)
352 if (bndry->IsReflecting())
356 if (rbndry.IsOpposingReflected())
357 for (
auto& angle : rbndry.GetHeteroBoundaryFluxOld())
358 for (
auto& cellvec : angle)
359 for (
auto& facevec : cellvec)
360 for (
auto& dofvec : facevec)
361 for (
auto val : dofvec)
371 for (
auto& as_group : angle_set_groups)
372 for (
auto& angle_set : as_group.AngleSets())
373 for (
auto val : angle_set->GetFLUDS().DelayedLocalPsiOld())
380 for (
auto& as_group : angle_set_groups)
381 for (
auto& angle_set : as_group.AngleSets())
382 for (
auto& loc_vector : angle_set->GetFLUDS().DelayedPrelocIOutgoingPsiOld())
383 for (
auto val : loc_vector)
396 for (
auto& [bid, bndry] : sim_boundaries)
398 if (bndry->IsReflecting())
402 if (rbndry.IsOpposingReflected())
403 for (
auto& angle : rbndry.GetHeteroBoundaryFluxOld())
404 for (
auto& cellvec : angle)
405 for (
auto& facevec : cellvec)
406 for (
auto& dofvec : facevec)
407 for (
auto& val : dofvec)
417 for (
auto& as_group : angle_set_groups)
418 for (
auto& angle_set : as_group.AngleSets())
419 for (
auto& val : angle_set->GetFLUDS().DelayedLocalPsiOld())
426 for (
auto& as_group : angle_set_groups)
427 for (
auto& angle_set : as_group.AngleSets())
428 for (
auto& loc_vector : angle_set->GetFLUDS().DelayedPrelocIOutgoingPsiOld())
429 for (
auto& val : loc_vector)
442 for (
auto& [bid, bndry] : sim_boundaries)
444 if (bndry->IsReflecting())
448 if (rbndry.IsOpposingReflected())
449 for (
auto& angle : rbndry.GetHeteroBoundaryFluxNew())
450 for (
auto& cellvec : angle)
451 for (
auto& facevec : cellvec)
452 for (
auto& dofvec : facevec)
453 for (
auto& val : dofvec)
463 for (
auto& as_group : angle_set_groups)
464 for (
auto& angle_set : as_group.AngleSets())
465 for (
auto& val : angle_set->GetFLUDS().DelayedLocalPsi())
472 for (
auto& as_group : angle_set_groups)
473 for (
auto& angle_set : as_group.AngleSets())
474 for (
auto& loc_vector : angle_set->GetFLUDS().DelayedPrelocIOutgoingPsi())
475 for (
auto& val : loc_vector)
487 std::vector<double> psi_vector;
489 auto psi_size = GetNumDelayedAngularDOFs();
490 psi_vector.reserve(psi_size.first);
493 for (
auto& [bid, bndry] : sim_boundaries)
495 if (bndry->IsReflecting())
499 if (rbndry.IsOpposingReflected())
500 for (
auto& angle : rbndry.GetHeteroBoundaryFluxNew())
501 for (
auto& cellvec : angle)
502 for (
auto& facevec : cellvec)
503 for (
auto& dofvec : facevec)
504 for (
auto val : dofvec)
505 psi_vector.push_back(val);
511 for (
auto& as_group : angle_set_groups)
512 for (
auto& angle_set : as_group.AngleSets())
513 for (
auto val : angle_set->GetFLUDS().DelayedLocalPsi())
514 psi_vector.push_back(val);
517 for (
auto& as_group : angle_set_groups)
518 for (
auto& angle_set : as_group.AngleSets())
519 for (
auto& loc_vector : angle_set->GetFLUDS().DelayedPrelocIOutgoingPsi())
520 for (
auto val : loc_vector)
521 psi_vector.push_back(val);
531 auto psi_size = GetNumDelayedAngularDOFs();
532 size_t stl_size = stl_vector.size();
533 if (stl_size != psi_size.first)
534 throw std::logic_error(
535 std::string(__FUNCTION__) +
537 "is incompatible with number angular unknowns stored "
538 "in the angle-aggregation object.");
542 for (
auto& [bid, bndry] : sim_boundaries)
544 if (bndry->IsReflecting())
548 if (rbndry.IsOpposingReflected())
549 for (
auto& angle : rbndry.GetHeteroBoundaryFluxNew())
550 for (
auto& cellvec : angle)
551 for (
auto& facevec : cellvec)
552 for (
auto& dofvec : facevec)
553 for (
auto& val : dofvec)
554 val = stl_vector[index++];
560 for (
auto& as_group : angle_set_groups)
561 for (
auto& angle_set : as_group.AngleSets())
562 for (
auto& val : angle_set->GetFLUDS().DelayedLocalPsi())
563 val = stl_vector[index++];
566 for (
auto& as_group : angle_set_groups)
567 for (
auto& angle_set : as_group.AngleSets())
568 for (
auto& loc_vector : angle_set->GetFLUDS().DelayedPrelocIOutgoingPsi())
569 for (
auto& val : loc_vector)
570 val = stl_vector[index++];
578 std::vector<double> psi_vector;
580 auto psi_size = GetNumDelayedAngularDOFs();
581 psi_vector.reserve(psi_size.first);
584 for (
auto& [bid, bndry] : sim_boundaries)
586 if (bndry->IsReflecting())
590 if (rbndry.IsOpposingReflected())
591 for (
auto& angle : rbndry.GetHeteroBoundaryFluxOld())
592 for (
auto& cellvec : angle)
593 for (
auto& facevec : cellvec)
594 for (
auto& dofvec : facevec)
595 for (
auto val : dofvec)
596 psi_vector.push_back(val);
602 for (
auto& as_group : angle_set_groups)
603 for (
auto& angle_set : as_group.AngleSets())
604 for (
auto val : angle_set->GetFLUDS().DelayedLocalPsiOld())
605 psi_vector.push_back(val);
608 for (
auto& as_group : angle_set_groups)
609 for (
auto& angle_set : as_group.AngleSets())
610 for (
auto& loc_vector : angle_set->GetFLUDS().DelayedPrelocIOutgoingPsiOld())
611 for (
auto val : loc_vector)
612 psi_vector.push_back(val);
622 auto psi_size = GetNumDelayedAngularDOFs();
623 size_t stl_size = stl_vector.size();
624 if (stl_size != psi_size.first)
625 throw std::logic_error(
626 std::string(__FUNCTION__) +
628 "is incompatible with number angular unknowns stored "
629 "in the angle-aggregation object.");
633 for (
auto& [bid, bndry] : sim_boundaries)
635 if (bndry->IsReflecting())
639 if (rbndry.IsOpposingReflected())
640 for (
auto& angle : rbndry.GetHeteroBoundaryFluxOld())
641 for (
auto& cellvec : angle)
642 for (
auto& facevec : cellvec)
643 for (
auto& dofvec : facevec)
644 for (
auto& val : dofvec)
645 val = stl_vector[index++];
651 for (
auto& as_group : angle_set_groups)
652 for (
auto& angle_set : as_group.AngleSets())
653 for (
auto& val : angle_set->GetFLUDS().DelayedLocalPsiOld())
654 val = stl_vector[index++];
657 for (
auto& as_group : angle_set_groups)
658 for (
auto& angle_set : as_group.AngleSets())
659 for (
auto& loc_vector : angle_set->GetFLUDS().DelayedPrelocIOutgoingPsiOld())
660 for (
auto& val : loc_vector)
661 val = stl_vector[index++];
669 for (
auto& [bid, bndry] : sim_boundaries)
671 if (bndry->IsReflecting())
675 if (rbndry.IsOpposingReflected())
676 rbndry.GetHeteroBoundaryFluxNew() = rbndry.GetHeteroBoundaryFluxOld();
682 for (
auto& as_group : angle_set_groups)
683 for (
auto& angle_set : as_group.AngleSets())
684 angle_set->GetFLUDS().DelayedLocalPsi() =
685 angle_set->GetFLUDS().DelayedLocalPsiOld();
688 for (
auto& as_group : angle_set_groups)
689 for (
auto& angle_set : as_group.AngleSets())
690 angle_set->GetFLUDS().DelayedPrelocIOutgoingPsi() =
691 angle_set->GetFLUDS().DelayedPrelocIOutgoingPsiOld();
699 for (
auto& [bid, bndry] : sim_boundaries)
701 if (bndry->IsReflecting())
705 if (rbndry.IsOpposingReflected())
706 rbndry.GetHeteroBoundaryFluxOld() = rbndry.GetHeteroBoundaryFluxNew();
712 for (
auto& as_group : angle_set_groups)
713 for (
auto& angle_set : as_group.AngleSets())
714 angle_set->GetFLUDS().DelayedLocalPsiOld() =
715 angle_set->GetFLUDS().DelayedLocalPsi();
718 for (
auto& as_group : angle_set_groups)
719 for (
auto& angle_set : as_group.AngleSets())
720 angle_set->GetFLUDS().DelayedPrelocIOutgoingPsiOld() =
721 angle_set->GetFLUDS().DelayedPrelocIOutgoingPsi();
#define ExceptionReflectedAngleError
static chi::MPI_Info & mpi
std::vector< double > GetOldDelayedAngularDOFsAsSTLVector()
void ZeroOutgoingDelayedPsi()
void SetOldDelayedAngularDOFsFromArray(int64_t &index, const double *x_ref)
void SetOldDelayedAngularDOFsFromSTLVector(const std::vector< double > &stl_vector)
void InitializeReflectingBCs()
std::shared_ptr< chi_math::AngularQuadrature > quadrature
void AppendOldDelayedAngularDOFsToArray(int64_t &index, double *x_ref)
std::vector< double > GetNewDelayedAngularDOFsAsSTLVector()
void SetNewDelayedAngularDOFsFromSTLVector(const std::vector< double > &stl_vector)
std::map< uint64_t, SweepBndryPtr > sim_boundaries
void ZeroIncomingDelayedPsi()
chi_mesh::MeshContinuumPtr grid
size_t number_of_group_subsets
void AppendNewDelayedAngularDOFsToArray(int64_t &index, double *x_ref)
void SetNewDelayedAngularDOFsFromArray(int64_t &index, const double *x_ref)
void SetDelayedPsiNew2Old()
AngleAggregation(const std::map< uint64_t, SweepBndryPtr > &in_sim_boundaries, size_t in_number_of_groups, size_t in_number_of_group_subsets, std::shared_ptr< chi_math::AngularQuadrature > &in_quadrature, chi_mesh::MeshContinuumPtr &in_grid)
std::pair< size_t, size_t > GetNumDelayedAngularDOFs()
void SetDelayedPsiOld2New()
void SetOpposingReflected(bool value)
void Set(VecDbl &x, const double &val)
std::shared_ptr< MeshContinuum > MeshContinuumPtr