ASCOT5
Loading...
Searching...
No Matches
splineexpl.c
Go to the documentation of this file.
1
5#include <stdlib.h>
6#include "../ascot5.h"
7#include "spline.h"
8#include "interp.h"
9
22void splineexpl(real* f, int n, int bc, real* c) {
23
24 /* Allocate needed variables */
25
26 /* Array for RHS of matrix equation */
27 real* Y = malloc(n*sizeof(real));
28 /* Array superdiagonal values */
29 real* p = malloc((n-1)*sizeof(real));
30 /* Array for derivative vector to solve */
31 real* D = malloc(n*sizeof(real));
32
33 if(bc == NATURALBC) {
36 /* Initialize RHS of equation */
37 Y[0] = 3 * (f[1] - f[0]);
38 for(int i=1; i<n-1; i++) {
39 Y[i] = 3 * (f[i+1] - f[i-1]);
40 }
41 Y[n-1] = 3 * (f[n-1] - f[n-2]);
42
43 /* Thomas algorithm is used*/
44
45 /* Forward sweep */
46 p[0] = 1.0 / 2;
47 Y[0] = Y[0] / 2;
48 for(int i=1; i<n-1; i++) {
49 p[i] = 1 / (4 - p[i-1]);
50 Y[i] = (Y[i] - Y[i-1]) / (4 - p[i-1]);
51 }
52 Y[n-1] = (Y[n-1] - Y[n-2]) / (2 - p[n-2]);
53
54 /* Back substitution */
55 D[n-1] = Y[n-1];
56 for(int i=n-2; i>-1; i--) {
57 D[i] = Y[i] - p[i] * D[i+1];
58 }
59 }
60 else if(bc== PERIODICBC) {
63 /* Initialize some additional helper variables */
64 real l = 1.0; /*Value that starts from lwr left corner and moves right*/
65 real dlast = 4.0; /* Last diagonal value */
66 real* r = malloc((n-2)*sizeof(real)); /* Matrix right column values */
67 real blast; /* Last subdiagonal value */
68
69 /* Initialize RHS of equation */
70 Y[0] = 3 * (f[1] - f[n-1]);
71 for(int i=1; i<n-1; i++) {
72 Y[i] = 3 * (f[i+1] - f[i-1]);
73 }
74 Y[n-1] = 3 * (f[0] - f[n-2]);
75
76 /* Simplified Gauss elimination is used (own algorithm) */
77
78 /* Forward sweep */
79 p[0] = 1.0 / 4;
80 r[0] = 1.0 / 4;
81 Y[0] = Y[0] / 4;
82 for(int i=1; i<n-2; i++) {
83 dlast = dlast - l * r[i-1];
84 Y[n-1] = Y[n-1] - l * Y[i-1];
85 l = -l * p[i-1];
86 p[i] = 1 / (4 - p[i-1]);
87 r[i] = -r[i-1] / (4 - p[i-1]);
88 Y[i] = (Y[i] - Y[i-1]) / (4 - p[i-1]);
89 }
90 blast = 1.0 - l * p[n-3];
91 dlast = dlast - l * r[n-3];
92 Y[n-1] = Y[n-1] - l * Y[n-3];
93
94 p[n-2] = (1 - r[n-3]) / (4 - p[n-3]);
95 Y[n-2] = (Y[n-2] - Y[n-3]) / (4 - p[n-3]);
96 Y[n-1] = (Y[n-1] - blast * Y[n-2]) / (dlast - blast * p[n-2]);
97
98 /* Back substitution */
99 D[n-1] = Y[n-1];
100 D[n-2] = Y[n-2] - p[n-2] * D[n-1];
101 for(int i=n-3; i>-1; i--) {
102 D[i] = Y[i] - p[i] * D[i+1] - r[i] * D[n-1];
103 }
104
105 /* Free allocated memory */
106 free(r);
107
108 /*Period-closing spline coefficients. This has to be done separately
109 here in the explicit form algorithm, because explicit coefficients
110 are usually stored only to n-1, because that is enough for evaluation.
111 The periodic boundary condition is an exeption to this, since it gives
112 rise to the extra, loop closing cell.*/
113 c[(n-1)*4] = f[n-1];
114 c[(n-1)*4+1] = D[n-1];
115 c[(n-1)*4+2] = 3 * (f[0] - f[n-1]) - 2 * D[n-1] - D[0];
116 c[(n-1)*4+3] = 2 * (f[n-1] - f[0]) + D[n-1] + D[0];
117 }
118
119 /*Derive spline coefficients from solved first derivatives and store them*/
120 for(int i=0; i<n-1; i++) {
121 c[i*4] = f[i];
122 c[i*4+1] = D[i];
123 c[i*4+2] = 3 * (f[i+1] - f[i]) - 2*D[i] - D[i+1];
124 c[i*4+3] = 2 * (f[i] - f[i+1]) + D[i] + D[i+1];
125 }
126
127 /* Free allocated memory */
128 free(Y);
129 free(p);
130 free(D);
131}
Main header file for ASCOT5.
double real
Definition ascot5.h:85
Spline interpolation library.
@ NATURALBC
Definition interp.h:37
@ PERIODICBC
Definition interp.h:38
Header file for splineexpl.c and splinecomp.c.
void splineexpl(real *f, int n, int bc, real *c)
Calculate explicit cubic spline interpolation coefficients in 1D.
Definition splineexpl.c:22