Chi-Tech
angular_product_quadrature.cc
Go to the documentation of this file.
4
5#include <cmath>
6#include <sstream>
7
8#include "chi_runtime.h"
9#include "chi_log.h"
10
11//###################################################################
12/**Initializes the quadrature with custom angles and weights.*/
14 AssembleCosines(const std::vector<double>& azimuthal,
15 const std::vector<double>& polar,
16 const std::vector<double>& in_weights,
17 bool verbose)
18{
19 size_t Na = azimuthal.size();
20 size_t Np = polar.size();
21 size_t Nw = in_weights.size();
22
23 if (Nw != Na*Np)
24 {
26 << "Product Quadrature, InitializeWithCustom: mismatch in the amount "
27 "angles and weights. Number of azimuthal angles times number "
28 "polar angles must equal the amount of weights.";
29 Chi::Exit(EXIT_FAILURE);
30 }
31
32 azimu_ang_ = azimuthal;
33 polar_ang_ = polar;
34
35 if (verbose)
36 {
37 Chi::log.Log() << "Azimuthal angles:";
38 for (const auto& ang : azimu_ang_)
39 Chi::log.Log() << ang;
40
41 Chi::log.Log() << "Polar angles:";
42 for (const auto& ang : polar_ang_)
43 Chi::log.Log() << ang;
44 }
45
46 //================================================== Create angle pairs
47 map_directions_.clear();
48 for (unsigned int j = 0; j < Np; ++j)
49 map_directions_.emplace(j, std::vector<unsigned int>());
50
51 abscissae_.clear();
52 weights_.clear();
53 std::stringstream ostr;
54 double weight_sum = 0.0;
55 for (unsigned int i = 0; i < Na; ++i)
56 {
57 for (unsigned int j = 0; j < Np; ++j)
58 {
59 map_directions_[j].emplace_back(i * Np + j);
60
61 const auto abscissa =
63
64 abscissae_.emplace_back(abscissa);
65
66 const double weight = in_weights[i*Np+j];
67 weights_.emplace_back(weight);
68 weight_sum += weight;
69
70 if (verbose)
71 {
72 char buf[200];
73 snprintf(buf,200,"Varphi=%.2f Theta=%.2f Weight=%.3e\n",
74 abscissa.phi*180.0/M_PI,
75 abscissa.theta*180.0/M_PI,
76 weight);
77 ostr << buf;
78 }
79 }
80 }
81
82 //================================================== Create omega list
83 omegas_.clear();
84 for (const auto& qpoint : abscissae_)
85 {
86 chi_mesh::Vector3 new_omega;
87 new_omega.x = sin(qpoint.theta)*cos(qpoint.phi);
88 new_omega.y = sin(qpoint.theta)*sin(qpoint.phi);
89 new_omega.z = cos(qpoint.theta);
90
91 omegas_.emplace_back(new_omega);
92
93 if (verbose) Chi::log.Log() << "Quadrature angle=" << new_omega.PrintS();
94 }
95
96 if (verbose)
97 {
99 << ostr.str() << "\n"
100 << "Weight sum=" << weight_sum;
101 }
102
103}
104
105//###################################################################
106/**Optimizes the angular quadrature for polar symmetry by removing
107 * all the direction with downward pointing polar angles.
108 *
109 * \param normalization float. (Optional) The default is a negative number
110 * which does not apply any normalization. If a
111 * positive number is provided, the weights will be
112 * normalized to sum to this number.*/
114 OptimizeForPolarSymmetry(const double normalization)
115{
116 std::vector<chi_math::QuadraturePointPhiTheta> new_abscissae;
117 std::vector<double> new_weights;
118 std::vector<chi_mesh::Vector3> new_omegas;
119 std::vector<double> new_polar_ang;
120 std::vector<double> new_azimu_ang;
121
122 const size_t num_pol = polar_ang_.size();
123 const size_t num_azi = azimu_ang_.size();
124
125 std::vector<unsigned int> new_polar_map;
126 for (size_t p=0; p<num_pol; ++p)
127 if (polar_ang_[p] < M_PI_2)
128 {
129 new_polar_ang.push_back(polar_ang_[p]);
130 new_polar_map.push_back(p);
131 }
132 new_azimu_ang = azimu_ang_;
133
134 const size_t new_num_pol = new_polar_ang.size();
135 double weight_sum = 0.0;
136 for (size_t a=0; a<num_azi; ++a)
137 for (size_t p=0; p<new_num_pol; ++p)
138 {
139 const auto pmap = new_polar_map[p];
140 const auto dmap = GetAngleNum(pmap,a);
141 new_weights.push_back(weights_[dmap]);
142 weight_sum += weights_[dmap];
143 }
144
145 if (normalization > 0.0)
146 for (double& w : new_weights)
147 w *= normalization/weight_sum;
148
149
150 AssembleCosines(new_azimu_ang, new_polar_ang,new_weights,false);
151 polar_ang_ = new_polar_ang;
152 azimu_ang_ = new_azimu_ang;
153}
154
155
156//###################################################################
157/**Constructor for Angular Gauss-Legendre.*/
159 AngularQuadratureProdGL(int Nphemi, bool verbose) :
161{
162 chi_math::QuadratureGaussLegendre gl_polar(Nphemi*2);
163
164 //================================================= Create azimuthal angles
165 azimu_ang_.clear();
166 azimu_ang_.emplace_back(0.0);
167
168 //================================================== Create polar angles
169 polar_ang_.clear();
170 for (unsigned int j = 0; j < (Nphemi*2); ++j)
171 polar_ang_.emplace_back(M_PI - acos(gl_polar.qpoints_[j][0]));
172
173 //================================================== Create combined weights
174 auto& weights = gl_polar.weights_;
175
176 //================================================== Initialize
177 AssembleCosines(azimu_ang_, polar_ang_, weights, verbose);
178}
179
180
181//###################################################################
182/**Constructor for Angular Gauss-Legendre-Legendre.*/
184 AngularQuadratureProdGLL(int Na, int Np, bool verbose)
185{
188
189 //================================================= Create azimuthal angles
190 azimu_ang_.clear();
191 for (unsigned int i = 0; i < (Na*4); ++i)
192 azimu_ang_.emplace_back(M_PI * gl_azimu.qpoints_[i][0] + M_PI);
193
194 //================================================== Create polar angles
195 polar_ang_.clear();
196 for (unsigned int j = 0; j < (Np*2); ++j)
197 polar_ang_.emplace_back(M_PI - acos(gl_polar.qpoints_[j][0]));
198
199 //================================================== Create combined weights
200 std::vector<double> weights;
201 for (unsigned int i = 0; i < azimu_ang_.size(); ++i)
202 for (unsigned int j = 0; j < polar_ang_.size(); ++j)
203 weights.emplace_back(M_PI * gl_azimu.weights_[i] * gl_polar.weights_[j]);
204
205 //================================================== Initialize
206 AssembleCosines(azimu_ang_, polar_ang_, weights, verbose);
207}
208
209//###################################################################
210/**Constructor for Angular Gauss-Legendre-Chebyshev.*/
212 AngularQuadratureProdGLC(int Na, int Np, bool verbose)
213{
216
217 //================================================= Create azimuthal angles
218 azimu_ang_.clear();
219 for (unsigned int i = 0; i < (Na*4); ++i)
220 azimu_ang_.emplace_back(M_PI * (2 * (i + 1) - 1) / (Na * 4));
221
222 //================================================== Create polar angles
223 polar_ang_.clear();
224 for (unsigned int j = 0; j < (Np*2); ++j)
225 polar_ang_.emplace_back(M_PI - acos(gl_polar.qpoints_[j][0]));
226
227 //================================================== Create combined weights
228 std::vector<double> weights;
229 for (unsigned int i = 0; i < azimu_ang_.size(); ++i)
230 for (unsigned int j = 0; j < polar_ang_.size(); ++j)
231 weights.emplace_back(2 * gc_azimu.weights_[i] * gl_polar.weights_[j]);
232
233 //================================================== Initialize
234 AssembleCosines(azimu_ang_, polar_ang_, weights, verbose);
235}
236
237//###################################################################
238/**Constructor for Custom Angular Product Quadrature.*/
240 AngularQuadratureProdCustom(const std::vector<double> &azimuthal,
241 const std::vector<double> &polar,
242 const std::vector<double> &in_weights,
243 bool verbose)
244{
245 size_t Na = azimuthal.size();
246 size_t Np = polar.size();
247 size_t Nw = in_weights.size();
248
249 if (Nw != Na*Np)
250 {
252 << "Product Quadrature, InitializeWithCustom: mismatch in the amount "
253 "angles and weights. Number of azimuthal angles times number "
254 "polar angles must equal the amount of weights.";
255 Chi::Exit(EXIT_FAILURE);
256 }
257
258 AssembleCosines(azimuthal, polar, weights_, verbose);
259}
260
static void Exit(int error_code)
Definition: chi_runtime.cc:342
static chi::ChiLog & log
Definition: chi_runtime.h:81
LogStream LogAllError()
Definition: chi_log.h:239
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
std::vector< chi_math::QuadraturePointPhiTheta > abscissae_
std::vector< chi_mesh::Vector3 > omegas_
AngularQuadratureProdCustom(const std::vector< double > &azimuthal, const std::vector< double > &polar, const std::vector< double > &in_weights, bool verbose)
AngularQuadratureProdGLC(int Na, int Np, bool verbose=false)
AngularQuadratureProdGL(int Np, bool verbose=false)
AngularQuadratureProdGLL(int Na, int Np, bool verbose=false)
void AssembleCosines(const std::vector< double > &azimuthal, const std::vector< double > &polar, const std::vector< double > &in_weights, bool verbose)
void OptimizeForPolarSymmetry(double normalization) override
std::map< unsigned int, std::vector< unsigned int > > map_directions_
std::vector< chi_math::QuadraturePointXYZ > qpoints_
Definition: quadrature.h:37
std::vector< double > weights_
Definition: quadrature.h:38
std::string PrintS() const
double x
Element-0.
double y
Element-1.
double z
Element-2.