Chi-Tech
lbsDO_sweepdata_00a_assSOs.cc
Go to the documentation of this file.
2
4
7
9
10#define POLAR_ILLEGAL_GEOTYPE (fname + \
11 ": The simulation is using polar angle aggregation for which only " \
12 "certain geometry types are supported, i.e., ORTHOGONAL, DIMENSION_2 " \
13 "or 3D EXTRUDED.")
14
15#define POLAR_ONLY_PRODUCT (fname + \
16 ": The simulation is using polar angle aggregation for which only " \
17 "Product-type quadratures are supported.")
18
19#define PRODUCT_QUAD_CASTING_FAILED (fname + \
20 ": Casting the angular quadrature to the product quadrature base, failed.")
21
22#define AZIMUTHAL_ILLEGAL_GEOTYPE (fname + \
23 ": The simulation is using azimuthal angle aggregation for which only " \
24 "ONED_SPHERICAL or TWOD_CYLINDRICAL derived geometry types are supported.")
25
26#define AZIMUTHAL_ONLY_PRODUCT (fname + \
27 ": The simulation is using azimuthal angle aggregation for which only " \
28 "Product-type quadratures are supported.")
29
30#define LogicCheck(condition, message) \
31if ((condition)) \
32 throw std::logic_error(fname+(message));
33
34namespace lbs
35{
36
37//###################################################################
38/**This routine groups angle-indices to groups sharing the same sweep
39 * ordering. It also takes geometry into account.*/
40std::pair<UniqueSOGroupings, DirIDToSOMap>
43 const chi_math::AngularQuadrature& quadrature,
44 const AngleAggregationType agg_type,
45 const lbs::GeometryType lbs_geo_type)
46{
47 const std::string fname = __FUNCTION__;
48
49 //================================================== Checks
50 LogicCheck(quadrature.omegas_.empty(),
51 ": Quadrature with no omegas cannot be used.")
52 LogicCheck(quadrature.weights_.empty(),
53 ": Quadrature with no weights cannot be used.")
54
55 //================================================== Build groupings
56 UniqueSOGroupings unq_so_grps;
57 switch (agg_type)
58 {
59 //=========================================== Single
60 // The easiest aggregation type. Every direction
61 // either has/is assumed to have a unique sweep
62 // ordering. Hence there is only group holding ALL
63 // the direction indices.
65 {
66 const size_t num_dirs = quadrature.omegas_.size();
67 for (size_t n=0; n<num_dirs; ++n)
68 unq_so_grps.push_back({n});
69 break;
70 }//case agg_type SINGLE
71
72 //=========================================== Polar
73 // The following conditions allow for polar
74 // angle aggregation.
76 {
77 //Check geometry types
78 const auto grid_attribs = grid.Attributes();
79 if (not(grid_attribs & chi_mesh::ORTHOGONAL or
80 grid_attribs & chi_mesh::DIMENSION_2 or
81 grid_attribs & chi_mesh::EXTRUDED))
82 throw std::logic_error(POLAR_ILLEGAL_GEOTYPE);
83
84 //Check quadrature type
85 const auto quad_type = quadrature.type_;
87 throw std::logic_error(POLAR_ONLY_PRODUCT);
88
89 //Process Product Quadrature
90 try
91 {
92 typedef chi_math::ProductQuadrature ProdQuadType;
93 const auto& product_quad = dynamic_cast<const ProdQuadType&>(quadrature);
94
95 const auto num_azi = product_quad.azimu_ang_.size();
96 const auto num_pol = product_quad.polar_ang_.size();
97
98 //Make two separate list of polar angles
99 //One upward-pointing and one downward
100 std::vector<size_t> upward_polar_ids;
101 std::vector<size_t> dnward_polar_ids;
102 for (size_t p=0; p<num_pol; ++p)
103 if (product_quad.polar_ang_[p] > M_PI_2)
104 upward_polar_ids.push_back(p);
105 else
106 dnward_polar_ids.push_back(p);
107
108 //Define lambda working for both upward and dnward polar-ids
109 /**Lambda to convert indices and push it onto unq_so_grps.*/
110 auto MapPolarAndAzimuthalIDs = [&product_quad, &unq_so_grps](
111 const DirIDs& polar_ids,const size_t azimuthal_id)
112 {
113 DirIDs dir_ids;
114 dir_ids.reserve(polar_ids.size());
115 for (const size_t p : polar_ids)
116 dir_ids.push_back(product_quad.GetAngleNum(p, azimuthal_id));
117 unq_so_grps.push_back(std::move(dir_ids));
118 };
119
120 //Stack id's for all azimuthal angles
121 for (size_t a=0; a<num_azi; ++a)
122 {
123 if (not upward_polar_ids.empty())
124 MapPolarAndAzimuthalIDs(upward_polar_ids, a);
125 if (not dnward_polar_ids.empty())
126 MapPolarAndAzimuthalIDs(dnward_polar_ids, a);
127 }//for azi-id a
128
129 }//try product quadrature
130 catch (const std::bad_cast& bc)
131 {
132 throw std::runtime_error(PRODUCT_QUAD_CASTING_FAILED);
133 }
134
135 break;
136 }//case agg_type POLAR
137
138 //====================================== Azimuthal
140 {
141 //Check geometry types
142 if (not (lbs_geo_type == GeometryType::ONED_SPHERICAL or
143 lbs_geo_type == GeometryType::TWOD_CYLINDRICAL))
144 throw std::logic_error(AZIMUTHAL_ILLEGAL_GEOTYPE);
145
146 //Check quadrature type
147 const auto quad_type = quadrature.type_;
149 throw std::logic_error(AZIMUTHAL_ONLY_PRODUCT);
150
151 //Process Product Quadrature
152 try
153 {
154 typedef chi_math::ProductQuadrature ProdQuadType;
155 const auto& product_quad = dynamic_cast<const ProdQuadType&>(quadrature);
156
157 for (const auto& dir_set : product_quad.GetDirectionMap())
158 {
159 std::vector<unsigned int> group1;
160 std::vector<unsigned int> group2;
161 for (const auto& dir_id : dir_set.second)
162 if (quadrature.abscissae_[dir_id].phi > M_PI_2)
163 group1.push_back(dir_id);
164 else
165 group2.push_back(dir_id);
166
167 DirIDs group1_ids(group1.begin(),group1.end());
168 DirIDs group2_ids(group2.begin(),group2.end());
169
170 unq_so_grps.push_back(std::move(group1_ids));
171 unq_so_grps.push_back(std::move(group2_ids));
172 }
173 }//try product quadrature
174 catch (const std::bad_cast& bc)
175 {
176 throw std::runtime_error(PRODUCT_QUAD_CASTING_FAILED);
177 }
178
179 break;
180 }
181 default:
182 throw std::invalid_argument(fname + ": Called with UNDEFINED angle "
183 "aggregation type.");
184 }//switch angle aggregation type
185
186 //================================================== Map directions to sweep
187 // orderings
188 DirIDToSOMap dir_id_to_so_map;
189 {
190 size_t so_grouping_id = 0;
191 for (const auto& so_grouping : unq_so_grps)
192 {
193 for (const size_t dir_id: so_grouping)
194 dir_id_to_so_map[dir_id] = so_grouping_id;
195
196 ++so_grouping_id;
197 }//for so_grouping
198 }//map scope
199
200 return {unq_so_grps, dir_id_to_so_map};
201}
202
203
204}//namespace lbs
205
const chi_math::AngularQuadratureType type_
std::vector< chi_math::QuadraturePointPhiTheta > abscissae_
std::vector< chi_mesh::Vector3 > omegas_
MeshAttributes Attributes() const
static std::pair< UniqueSOGroupings, DirIDToSOMap > AssociateSOsAndDirections(const chi_mesh::MeshContinuum &grid, const chi_math::AngularQuadrature &quadrature, AngleAggregationType agg_type, lbs::GeometryType lbs_geo_type)
#define AZIMUTHAL_ILLEGAL_GEOTYPE
#define LogicCheck(condition, message)
#define POLAR_ILLEGAL_GEOTYPE
#define PRODUCT_QUAD_CASTING_FAILED
#define AZIMUTHAL_ONLY_PRODUCT
#define POLAR_ONLY_PRODUCT
@ EXTRUDED
Definition: chi_mesh.h:76
@ DIMENSION_2
Definition: chi_mesh.h:73
@ ORTHOGONAL
Definition: chi_mesh.h:75
std::vector< size_t > DirIDs
Direction-IDs.
Definition: lbs_structs.h:14
AngleAggregationType
Definition: lbs_structs.h:65
std::map< size_t, size_t > DirIDToSOMap
Definition: lbs_structs.h:16
std::vector< DirIDs > UniqueSOGroupings
Definition: lbs_structs.h:15
GeometryType
Definition: lbs_structs.h:34