Quantum 3xplorer (Q3)
An AI-native quantum simulation engine
Loading...
Searching...
No Matches
gradient.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * Numerical gradient on a non-uniform grid.
5 *
6 * At each interior node the derivative is that of the unique quadratic
7 * through the node and its two neighbours, which on a non-uniform grid is
8 * second-order accurate where a plain centered difference is only first.
9 *
10 * Endpoints are conventions, not consequences of that formula, and the caller
11 * has to accept both. The last node's derivative is set to zero: this is
12 * written for functions that have already decayed by the outer mesh point --
13 * a pseudo-core charge is the case in hand -- where a one-sided stencil on
14 * the sparsest part of a logarithmic grid would differentiate noise. The
15 * first node's derivative is extrapolated from the next two rather than
16 * computed, because the 3-point stencil has no centre there; a one-sided
17 * formula on the first three nodes is the standard alternative and is the
18 * re-derivation to prefer if this is ever revisited.
19 */
20
22
23namespace q3 {
24
25/**
26 * Compute gradient on a non-uniform grid using a 3-point asymmetric formula.
27 *
28 * @param function_values Function values at grid points
29 * @param gradient Output gradient array
30 * @param grid Grid point positions
31 * @param mesh_size Number of grid points
32 */
33inline void
34gradient_nonuniform(const Real* function_values, Real* gradient, const Real* grid, int mesh_size) {
35 for (int grid_index = 1; grid_index < mesh_size - 1; grid_index++) {
36 Real delta_r_forward = grid[grid_index + 1] - grid[grid_index];
37 Real delta_r_backward = grid[grid_index - 1] - grid[grid_index];
38 Real delta_f_forward = function_values[grid_index + 1] - function_values[grid_index];
39 Real delta_f_backward = function_values[grid_index - 1] - function_values[grid_index];
40 gradient[grid_index] =
41 (delta_r_forward * delta_r_forward * delta_f_backward -
42 delta_r_backward * delta_r_backward * delta_f_forward) /
43 (delta_r_forward * delta_r_backward * (grid[grid_index + 1] - grid[grid_index - 1]));
44 }
45 gradient[mesh_size - 1] = 0.0;
46 // Extrapolate gradient[0] from gradient[1] and gradient[2]
47 if (mesh_size >= 3) {
48 gradient[0] =
49 gradient[1] + (gradient[2] - gradient[1]) * (grid[0] - grid[1]) / (grid[2] - grid[1]);
50 } else {
51 gradient[0] = gradient[1];
52 }
53}
54
55} // namespace q3
void gradient_nonuniform(const Real *function_values, Real *gradient, const Real *grid, int mesh_size)
Definition gradient.hpp:34
double Real