2#include "Maths/Grid.hpp"
3#include "Maths/NumCalc_coeficients.hpp"
4#include "qip/Vector.hpp"
15constexpr std::size_t
Nquad = 13;
18 "\nFAIL10 in NumCalc: Nquad must be in [1,13], and must be odd\n");
22constexpr auto cq = quintcoef.cq;
23constexpr auto dq_inv = quintcoef.dq_inv;
52template <
typename C,
typename... Args>
53inline double integrate(
const double dt, std::size_t beg, std::size_t end,
54 const C &f1,
const Args &...rest) {
56 const auto max_grid = f1.size();
59 const auto end_mid = std::min(max_grid -
Nquad, end);
60 const auto start_mid = std::max(
Nquad, beg);
64 const double Rint_mid =
67 for (
auto i = end_mid; i < end; ++i) {
70 return (Rint_mid + dq_inv * Rint_ends) * dt;
98 const std::vector<T> &drdt,
const T dt,
99 const int order = 1) {
104 std::size_t num_points = f.size();
105 std::vector<T> df(num_points);
109 df[0] = (f[1] - f[0]) / (dt * drdt[0]);
111 (f[num_points - 1] - f[num_points - 2]) / (dt * drdt[num_points - 1]);
113 df[1] = (f[2] - f[0]) / (2 * dt * drdt[1]);
115 (f[num_points - 1] - f[num_points - 3]) / (2 * dt * drdt[num_points - 2]);
117 df[2] = (f[0] - 8 * f[1] + 8 * f[3] - f[4]) / (12 * dt * drdt[2]);
118 df[num_points - 3] = (f[num_points - 5] - 8 * f[num_points - 4] +
119 8 * f[num_points - 2] - f[num_points - 1]) /
120 (12 * dt * drdt[num_points - 3]);
122 df[3] = (-1 * f[0] + 9 * f[1] - 45 * f[2] + 45 * f[4] - 9 * f[5] + 1 * f[6]) /
125 (-1 * f[num_points - 7] + 9 * f[num_points - 6] - 45 * f[num_points - 5] +
126 45 * f[num_points - 3] - 9 * f[num_points - 2] + 1 * f[num_points - 1]) /
127 (60 * dt * drdt[num_points - 4]);
129 for (std::size_t i = 4; i < (num_points - 4); i++) {
130 df[i] = ((1.0 / 8) * f[i - 4] - (4.0 / 3) * f[i - 3] + 7 * f[i - 2] -
131 28 * f[i - 1] - (1.0 / 8) * f[i + 4] + (4.0 / 3) * f[i + 3] -
132 7 * f[i + 2] + 28 * f[i + 1]) /
171template <Direction direction,
typename Real>
174 const std::vector<Real> &g,
const std::vector<Real> &h,
175 const Grid &gr, std::size_t pinf = 0) {
176 const auto size = g.size();
177 if (pinf == 0 || pinf >= size)
179 const auto max =
static_cast<int>(pinf - 1);
181 constexpr const bool forward = (direction ==
zero_to_r);
182 constexpr const int inc = forward ? +1 : -1;
183 const auto init = forward ? 0ul : std::size_t(max);
184 const auto fin = forward ? std::size_t(max) : 0ul;
186 Real x = int(init) < max ? 0.5 * g[init] * h[init] * gr.
drdu()[init] : 0.0;
187 answer[init] += f[init] * x * gr.
du();
188 for (
auto i =
int(init) + inc; i != int(fin) + inc; i += inc) {
189 const auto im = std::size_t(i - inc);
190 const auto i2 = std::size_t(i);
191 x += 0.5 * (g[im] * h[im] * gr.
drdu()[im] + g[i2] * h[i2] * gr.
drdu()[i2]);
192 answer[i2] += f[i2] * x * gr.
du();
195 answer[fin] += 0.5 * f[fin] * g[fin] * h[fin] * gr.
drdu()[fin] * gr.
du();
208template <Direction direction,
typename Real>
210 const std::vector<Real> &f,
211 const std::vector<Real> &g,
const Grid &gr,
212 std::size_t pinf = 0) {
213 const auto size = g.size();
214 if (pinf == 0 || pinf >= size)
216 const auto max =
static_cast<int>(pinf - 1);
218 constexpr const bool forward = (direction ==
zero_to_r);
219 constexpr const int inc = forward ? +1 : -1;
220 const auto init = forward ? 0ul : std::size_t(max);
221 const auto fin = forward ? std::size_t(max) : 0ul;
223 Real x = int(init) < max ? 0.5 * g[init] * gr.
drdu()[init] : 0.0;
224 answer[init] += f[init] * x * gr.
du();
225 for (
auto i =
int(init) + inc; i != int(fin) + inc; i += inc) {
226 const auto im = std::size_t(i - inc);
227 const auto i2 = std::size_t(i);
228 x += 0.5 * (g[im] * gr.
drdu()[im] + g[i2] * gr.
drdu()[i2]);
229 answer[i2] += f[i2] * x * gr.
du();
232 answer[fin] += 0.5 * f[fin] * g[fin] * gr.
drdu()[fin] * gr.
du();
241template <Direction direction,
typename Real>
243 const std::vector<Real> &g,
244 const std::vector<Real> &h,
const Grid &gr,
245 std::size_t pinf = 0) {
246 std::vector<Real> answer(f.size(), 0.0);
247 additivePIntegral<direction>(answer, f, g, h, gr, pinf);
258inline std::function<double(
long unsigned)>
linx(
double a,
double dt) {
259 return [=](
long unsigned i) {
return a + double(i) * dt; };
263inline std::function<double(
long unsigned)>
one() {
264 return [=](
long unsigned) {
return 1.0; };
268inline std::function<double(
long unsigned)>
logx(
double a,
double dt) {
269 return [=](
long unsigned i) {
return a * std::exp(
double(i) * dt); };
288inline double num_integrate(
const std::function<
double(
double)> &f,
double a,
289 double b,
long unsigned n_pts,
291 if (a >= b || n_pts <= 1)
293 const auto dt = (type == linear) ? (b - a) / double(n_pts - 1) :
294 std::log(b / a) / double(n_pts - 1);
296 std::function<double(
long unsigned)> x =
297 (type == linear) ?
linx(a, dt) :
logx(a, dt);
298 std::function<double(
long unsigned)> dxdt =
299 (type == linear) ?
one() :
logx(a, dt);
302 for (
long unsigned i = 0; i <
Nquad; i++) {
303 Rint_s += cq[i] * f(x(i)) * dxdt(i);
307 for (
auto i =
Nquad; i < n_pts -
Nquad; i++) {
308 Rint_m += f(x(i)) * dxdt(i);
312 for (
auto i = n_pts -
Nquad; i < n_pts; i++) {
313 Rint_e += cq[n_pts - i - 1] * f(x(i)) * dxdt(i);
316 return (Rint_m + dq_inv * (Rint_s + Rint_e)) * dt;
Non-uniform radial grid with Jacobian, suitable for atomic structure calculations.
Definition Grid.hpp:85
auto du() const
Uniform step size du.
Definition Grid.hpp:124
const std::vector< double > & drdu() const
Full Jacobian vector dr/du.
Definition Grid.hpp:140
Numerical integration and differentiation routines.
Definition NumCalc_coeficients.hpp:4
std::vector< Real > partialIntegral(const std::vector< Real > &f, const std::vector< Real > &g, const std::vector< Real > &h, const Grid &gr, std::size_t pinf=0)
Returns the partial integral ‘f(r) * Int[g(r’)*h(r'), {r', 0, r}]`.
Definition NumCalc_quadIntegrate.hpp:242
t_grid
Grid type for num_integrate.
Definition NumCalc_quadIntegrate.hpp:255
double integrate(const double dt, std::size_t beg, std::size_t end, const C &f1, const Args &...rest)
Quadrature integration of one or more vectors over a regular grid in t.
Definition NumCalc_quadIntegrate.hpp:53
double num_integrate(const std::function< double(double)> &f, double a, double b, long unsigned n_pts, t_grid type=linear)
Numerically integrates a function f(x) over [a, b].
Definition NumCalc_quadIntegrate.hpp:288
Direction
Integration direction for additivePIntegral.
Definition NumCalc_quadIntegrate.hpp:145
@ r_to_inf
Integrate from infinity inward to r.
Definition NumCalc_quadIntegrate.hpp:149
@ zero_to_r
Integrate from 0 outward to r.
Definition NumCalc_quadIntegrate.hpp:147
std::function< double(long unsigned)> one()
Returns a function that always returns 1.0 (uniform Jacobian)
Definition NumCalc_quadIntegrate.hpp:263
void additivePIntegral(std::vector< Real > &answer, const std::vector< Real > &f, const std::vector< Real > &g, const std::vector< Real > &h, const Grid &gr, std::size_t pinf=0)
Additively accumulates a partial integral into answer.
Definition NumCalc_quadIntegrate.hpp:173
std::function< double(long unsigned)> linx(double a, double dt)
Returns a function giving linearly-spaced x values: x(i) = a + i*dt.
Definition NumCalc_quadIntegrate.hpp:258
constexpr std::size_t Nquad
Quadrature integration order; must be odd and in [1, 13].
Definition NumCalc_quadIntegrate.hpp:15
std::vector< T > derivative(const std::vector< T > &f, const std::vector< T > &drdt, const T dt, const int order=1)
Computes the derivative df/dr on a non-uniform grid.
Definition NumCalc_quadIntegrate.hpp:97
std::function< double(long unsigned)> logx(double a, double dt)
Returns a function giving logarithmically-spaced x values: x(i) = a*exp(i*dt)
Definition NumCalc_quadIntegrate.hpp:268
Quadrature integration coefficients for a given number of points N. cq holds the weights; the step co...
Definition NumCalc_coeficients.hpp:10
auto inner_product_sub(std::size_t p0, std::size_t pinf, const T &first, const Args &...rest)
Inner product over the subrange [p0, pinf).
Definition Vector.hpp:378
constexpr auto multiply_at(std::size_t i, const T &first, const Args &...rest)
Helper: returns first[i] * rest[i] * ... at index i.
Definition Vector.hpp:357