ASCOT5
Loading...
Searching...
No Matches
interp1Dcomp.c
Go to the documentation of this file.
1
5#include <stdlib.h>
6#include <math.h>
7#include "../ascot5.h"
8#include "../math.h"
9#include "interp.h"
10#include "spline.h"
11
25int interp1Dcomp_init_coeff(real* c, real* f, int n_x, int bc_x,
26 real x_min, real x_max) {
27
28 /* Check boundary condition and calculate grid interval. Grid interval
29 needed because we use normalized grid intervals. For periodic boundary
30 condition, grid maximum value and the last data point are not the same.
31 Take this into account in grid interval. */
32 real x_grid;
33 if(bc_x == PERIODICBC || bc_x == NATURALBC) {
34 x_grid = (x_max - x_min) / ( n_x - 1 * (bc_x == NATURALBC) );
35 }
36 else {
37 return 1;
38 }
39
40 if(c == NULL) {
41 return 1;
42 }
43
44 /* Calculate cubic spline coefficients, i.e. second derivative. For each
45 grid cell i_x, there are two coefficients: [f, fxx]. Note how we account
46 for normalized grid. */
47
48 /* Cubic spline along x, using f values to get fxx */
49 splinecomp(f, n_x, bc_x, c);
50 for(int i_x=0; i_x<n_x; i_x++) {
51 /* Accounting for normalized grid. Affects fxx, but not f. */
52 c[i_x*2 + 1] = c[i_x*2+1] / (x_grid*x_grid);
53 }
54
55 return 0;
56}
57
69 int n_x, int bc_x, real x_min, real x_max) {
70
71 /* Calculate grid interval. For periodic boundary condition, grid maximum
72 value and the last data point are not the same. Take this into account
73 in grid interval. */
74 real x_grid = (x_max - x_min) / ( n_x - 1 * (bc_x == NATURALBC) );
75
76 /* Initialize the interp1D_data struct */
77 str->n_x = n_x;
78 str->bc_x = bc_x;
79 str->x_min = x_min;
80 str->x_max = x_max;
81 str->x_grid = x_grid;
82 str->c = c;
83}
84
98
99 /* Make sure periodic coordinates are within [min, max] region. */
100 if(str->bc_x == PERIODICBC) {
101 x = fmod(x - str->x_min, str->x_max - str->x_min) + str->x_min;
102 x = x + (x < str->x_min) * (str->x_max - str->x_min);
103 }
104
105 /* Index for x variable. The -1 needed at exactly grid end. */
106 int i_x = (x-str->x_min) / str->x_grid - 1*(x==str->x_max);
107 /* Normalized x coordinate in current cell */
108 real dx = ( x - (str->x_min + i_x*str->x_grid) ) / str->x_grid;
109 /* Helper varibles */
110 real dx3 = dx * (dx*dx - 1.0);
111 real dxi = 1.0 - dx;
112 real dxi3 = dxi * (dxi*dxi - 1.0);
113 real xg2 = str->x_grid*str->x_grid;
114
115 int n = i_x*2; /* Index jump to cell */
116 int x1 = 2; /* Index jump one x forward */
117
118 int err = 0;
119
120 /* Enforce periodic BC or check that the coordinate is within the grid. */
121 if( str->bc_x == PERIODICBC && i_x == str->n_x-1 ) {
122 x1 = -(str->n_x-1)*x1;
123 }
124 else if( str->bc_x == NATURALBC && !(x >= str->x_min && x <= str->x_max) ) {
125 err = 1;
126 }
127
128 if(!err) {
129 *f =
130 dxi *str->c[n+0]+dx *str->c[n+x1+0]
131 +(xg2/6)*(dxi3*str->c[n+1]+dx3*str->c[n+x1+1]);
132 }
133
134 return err;
135}
136
156
157 /* Make sure periodic coordinates are within [min, max] region. */
158 if(str->bc_x == PERIODICBC) {
159 x = fmod(x - str->x_min, str->x_max - str->x_min) + str->x_min;
160 x = x + (x < str->x_min) * (str->x_max - str->x_min);
161 }
162
164 int i_x = (x - str->x_min) / str->x_grid - 1*(x==str->x_max);
166 real dx = ( x - (str->x_min + i_x*str->x_grid) ) / str->x_grid;
167 /* Helper varibles */
168 real dx3 = dx * (dx*dx - 1.0);
169 real dx3dx = 3*dx*dx - 1;
170 real dxi = 1.0 - dx;
171 real dxi3 = dxi * (dxi*dxi - 1);
172 real dxi3dx = -3*dxi*dxi + 1;
173 real xg = str->x_grid;
174 real xg2 = xg*xg;
175 real xgi = 1.0 / xg;
176
177 int n = i_x*2; /* Index jump to cell */
178 int x1 = 2; /* Index jump one x forward */
179
180 int err = 0;
181
182 /* Enforce periodic BC or check that the coordinate is within the grid. */
183 if( str->bc_x == PERIODICBC && i_x == str->n_x-1 ) {
184 x1 = -(str->n_x-1)*x1;
185 }
186 else if( str->bc_x == NATURALBC && !(x >= str->x_min && x <= str->x_max) ) {
187 err = 1;
188 }
189
190 if(!err) {
191 /* f */
192 f_df[0] =
193 dxi *str->c[n+0]+dx *str->c[n+x1+0]
194 +(xg2/6)*(dxi3*str->c[n+1]+dx3*str->c[n+x1+1]);
195
196 /* df/dx */
197 f_df[1] =
198 xgi*(str->c[n+x1+0]- str->c[n+0])
199 +(xg/6)*(dx3dx*str->c[n+x1+1]+dxi3dx*str->c[n+1]);
200
201 /* d2f/dx2 */
202 f_df[2] = dxi*str->c[n+1]+dx*str->c[n+x1+1];
203 }
204
205 return err;
206}
Main header file for ASCOT5.
double real
Definition ascot5.h:85
unsigned long int a5err
Simulation error flag.
Definition error.h:17
int interp1Dcomp_init_coeff(real *c, real *f, int n_x, int bc_x, real x_min, real x_max)
Calculate cubic spline interpolation coefficients for scalar 1D data.
a5err interp1Dcomp_eval_f(real *f, interp1D_data *str, real x)
Evaluate interpolated value of 1D scalar field.
a5err interp1Dcomp_eval_df(real *f_df, interp1D_data *str, real x)
Evaluate interpolated value of 1D and its 1st and 2nd derivatives.
void interp1Dcomp_init_spline(interp1D_data *str, real *c, int n_x, int bc_x, real x_min, real x_max)
Initialize a cubic spline.
Spline interpolation library.
@ NATURALBC
Definition interp.h:37
@ PERIODICBC
Definition interp.h:38
real fmod(real x, real y)
Compute the modulus of two real numbers.
Definition math.c:22
Header file for math.c.
Header file for splineexpl.c and splinecomp.c.
void splinecomp(real *f, int n, int bc, real *c)
Calculate compact cubic spline interpolation coefficients in 1D.
Definition splinecomp.c:22
Cubic interpolation struct.
Definition interp.h:56
real x_min
Definition interp.h:59
real x_max
Definition interp.h:60
real x_grid
Definition interp.h:61
real * c
Definition interp.h:62