2#include "Maths/Grid.hpp"
3#include "Maths/NumCalc_coeficients.hpp"
4#include "qip/Vector.hpp"
15constexpr std::size_t Nquad = 13;
17 Nquad >= 1 && Nquad <= 13 && Nquad % 2 != 0,
18 "\nFAIL10 in NumCalc: Nquad must be in [1,13], and must be odd\n");
21constexpr QintCoefs<Nquad> quintcoef;
22constexpr auto cq = quintcoef.cq;
23constexpr auto dq_inv = quintcoef.dq_inv;
26template <
typename C,
typename... Args>
27inline double integrate(
const double dt, std::size_t beg, std::size_t end,
28 const C &f1,
const Args &...rest)
40 const auto max_grid = f1.size();
43 const auto end_mid = std::min(max_grid - Nquad, end);
44 const auto start_mid = std::max(Nquad, beg);
46 double Rint_ends = qip::inner_product_sub(beg, Nquad, cq, f1, rest...);
48 const double Rint_mid =
49 qip::inner_product_sub(start_mid, end_mid, f1, rest...);
51 for (
auto i = end_mid; i < end; ++i) {
54 return (Rint_mid + dq_inv * Rint_ends) * dt;
59inline std::vector<T> derivative(
const std::vector<T> &f,
60 const std::vector<T> &drdt,
const T dt,
68 std::size_t num_points =
f.size();
69 std::vector<T> df(num_points);
73 df[0] = (
f[1] -
f[0]) / (dt * drdt[0]);
75 (
f[num_points - 1] -
f[num_points - 2]) / (dt * drdt[num_points - 1]);
77 df[1] = (
f[2] -
f[0]) / (2 * dt * drdt[1]);
79 (
f[num_points - 1] -
f[num_points - 3]) / (2 * dt * drdt[num_points - 2]);
81 df[2] = (
f[0] - 8 *
f[1] + 8 *
f[3] -
f[4]) / (12 * dt * drdt[2]);
82 df[num_points - 3] = (
f[num_points - 5] - 8 *
f[num_points - 4] +
83 8 *
f[num_points - 2] -
f[num_points - 1]) /
84 (12 * dt * drdt[num_points - 3]);
86 df[3] = (-1 *
f[0] + 9 *
f[1] - 45 *
f[2] + 45 *
f[4] - 9 *
f[5] + 1 *
f[6]) /
89 (-1 *
f[num_points - 7] + 9 *
f[num_points - 6] - 45 *
f[num_points - 5] +
90 45 *
f[num_points - 3] - 9 *
f[num_points - 2] + 1 *
f[num_points - 1]) /
91 (60 * dt * drdt[num_points - 4]);
93 for (std::size_t i = 4; i < (num_points - 4); i++) {
94 df[i] = ((1.0 / 8) * f[i - 4] - (4.0 / 3) *
f[i - 3] + 7 *
f[i - 2] -
95 28 *
f[i - 1] - (1.0 / 8) * f[i + 4] + (4.0 / 3) *
f[i + 3] -
96 7 *
f[i + 2] + 28 *
f[i + 1]) /
101 df = derivative(df, drdt, dt, order - 1);
107enum Direction { zero_to_r, r_to_inf };
108template <Direction direction,
typename Real>
111 const std::vector<Real> &g,
const std::vector<Real> &h,
112 const Grid &gr, std::size_t pinf = 0)
117 const auto size = g.size();
118 if (pinf == 0 || pinf >= size)
120 const auto max =
static_cast<int>(pinf - 1);
122 constexpr const bool forward = (direction == zero_to_r);
123 constexpr const int inc = forward ? +1 : -1;
124 const auto init = forward ? 0ul : std::size_t(max);
125 const auto fin = forward ? std::size_t(max) : 0ul;
133 Real x = int(init) < max ? 0.5 * g[init] * h[init] * gr.
drdu()[init] : 0.0;
134 answer[init] += f[init] * x * gr.
du();
135 for (
auto i =
int(init) + inc; i != int(fin) + inc; i += inc) {
136 const auto im = std::size_t(i - inc);
137 const auto i2 = std::size_t(i);
138 x += 0.5 * (g[im] * h[im] * gr.
drdu()[im] +
139 g[i2] * h[i2] * gr.
drdu()[i2] );
140 answer[i2] += f[i2] * x * gr.
du();
143 answer[fin] += 0.5 * f[fin] * g[fin] * h[fin] * gr.
drdu()[fin] *
147template <Direction direction,
typename Real>
149 const std::vector<Real> &f,
150 const std::vector<Real> &g,
const Grid &gr,
151 std::size_t pinf = 0)
156 const auto size = g.size();
157 if (pinf == 0 || pinf >= size)
159 const auto max =
static_cast<int>(pinf - 1);
161 constexpr const bool forward = (direction == zero_to_r);
162 constexpr const int inc = forward ? +1 : -1;
163 const auto init = forward ? 0ul : std::size_t(max);
164 const auto fin = forward ? std::size_t(max) : 0ul;
166 Real x = int(init) < max ? 0.5 * g[init] * gr.
drdu()[init] : 0.0;
167 answer[init] += f[init] * x * gr.
du();
168 for (
auto i =
int(init) + inc; i != int(fin) + inc; i += inc) {
169 const auto im = std::size_t(i - inc);
170 const auto i2 = std::size_t(i);
171 x += 0.5 * (g[im] * gr.
drdu()[im] + g[i2] * gr.
drdu()[i2]);
172 answer[i2] += f[i2] * x * gr.
du();
176 0.5 * f[fin] * g[fin] * gr.
drdu()[fin] * gr.
du();
180template <Direction direction,
typename Real>
181std::vector<Real> partialIntegral(
const std::vector<Real> &f,
182 const std::vector<Real> &g,
183 const std::vector<Real> &h,
const Grid &gr,
184 std::size_t pinf = 0) {
185 std::vector<Real> answer(
f.size(), 0.0);
193enum t_grid { linear, logarithmic };
195inline std::function<double(
long unsigned)> linx(
double a,
double dt) {
196 return [=](
long unsigned i) {
return a + double(i) * dt; };
199inline std::function<double(
long unsigned)> one() {
200 return [=](
long unsigned) {
return 1.0; };
203inline std::function<double(
long unsigned)> logx(
double a,
double dt) {
204 return [=](
long unsigned i) {
return a * std::exp(
double(i) * dt); };
208inline double num_integrate(
const std::function<
double(
double)> &f,
double a,
209 double b,
long unsigned n_pts,
210 t_grid type = linear) {
212 if (a >= b || n_pts <= 1)
214 const auto dt = (type == linear) ? (b - a) / double(n_pts - 1) :
215 std::log(b / a) / double(n_pts - 1);
217 std::function<double(
long unsigned)> x =
218 (type == linear) ? linx(a, dt) : logx(a, dt);
219 std::function<double(
long unsigned)> dxdt =
220 (type == linear) ? one() : logx(a, dt);
223 for (
long unsigned i = 0; i < Nquad; i++) {
224 Rint_s += cq[i] *
f(x(i)) * dxdt(i);
228 for (
auto i = Nquad; i < n_pts - Nquad; i++) {
229 Rint_m +=
f(x(i)) * dxdt(i);
233 for (
auto i = n_pts - Nquad; i < n_pts; i++) {
234 Rint_e += cq[n_pts - i - 1] *
f(x(i)) * dxdt(i);
237 return (Rint_m + dq_inv * (Rint_s + Rint_e)) * dt;
Holds grid, including type + Jacobian (dr/du)
Definition Grid.hpp:31
auto du() const
Linear step size dr = (dr/dr)*du.
Definition Grid.hpp:68
const std::vector< double > & drdu() const
Jacobian (dr/du)[i].
Definition Grid.hpp:80
double f(RaB r, PrincipalQN n, DiracQN k, Zeff z, AlphaFS a)
Upper radial component.
Definition DiracHydrogen.cpp:71
Numerical integration and differentiation. Bit of a mess right now..
Definition NumCalc_coeficients.hpp:4
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)
Definition NumCalc_quadIntegrate.hpp:110
T max(T first, Args... rest)
Returns maximum of any number of parameters (variadic function)
Definition Maths.hpp:22
constexpr auto multiply_at(std::size_t i, const T &first, const Args &...rest)
first[i]*...rest[i] – used to allow inner_product
Definition Vector.hpp:331