53 nodes.assign(number_of_points, 0.0);
54 weights.assign(number_of_points, 0.0);
55 for (
int index = 0; index < number_of_points; index++) {
58 (
static_cast<Real>(number_of_points) + 0.5));
59 Real derivative = 0.0;
60 for (
int iteration = 0; iteration < 100; iteration++) {
63 for (
int degree = 0; degree < number_of_points; degree++) {
67 ((2.0 * degree + 1.0) * node * current - degree * older) / (degree + 1.0);
69 derivative = number_of_points * (node * previous - current) / (node * node - 1.0);
70 Real step = previous / derivative;
72 if (std::abs(step) < 1e-15)
76 weights[index] = 2.0 / ((1.0 - node * node) * derivative * derivative);
86 int theta_points = 3 * (maximum_angular_momentum + 1);
87 int phi_points = 3 * (maximum_angular_momentum + 1);
93 std::vector<Real> cosines;
94 std::vector<Real> theta_weights;
97 std::vector<AngularPoint> grid;
98 grid.reserve(
static_cast<size_t>(theta_points) * phi_points);
100 for (
int theta_index = 0; theta_index < theta_points; theta_index++) {
101 Real cosine = cosines[theta_index];
102 Real sine = std::sqrt(std::max(
Real(0.0), 1.0 - cosine * cosine));
103 for (
int phi_index = 0; phi_index < phi_points; phi_index++) {
104 Real phi = phi_step *
static_cast<Real>(phi_index);
106 point.
x = sine * std::cos(phi);
107 point.y = sine * std::sin(phi);
109 point.weight = theta_weights[theta_index] * phi_step;
110 grid.push_back(point);