ASCOT5
Loading...
Searching...
No Matches
linint3D.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 "linint.h"
10
30 int n_x, int n_y, int n_z,
31 int bc_x, int bc_y, int bc_z,
32 real x_min, real x_max,
33 real y_min, real y_max,
34 real z_min, real z_max) {
35
36 real x_grid = (x_max - x_min) / ( n_x - 1 * (bc_x == NATURALBC) );
37 real y_grid = (y_max - y_min) / ( n_y - 1 * (bc_y == NATURALBC) );
38 real z_grid = (z_max - z_min) / ( n_z - 1 * (bc_z == NATURALBC) );
39
40 str->n_x = n_x;
41 str->n_y = n_y;
42 str->n_z = n_z;
43 str->bc_x = bc_x;
44 str->bc_y = bc_y;
45 str->bc_z = bc_z;
46 str->x_min = x_min;
47 str->x_max = x_max;
48 str->x_grid = x_grid;
49 str->y_min = y_min;
50 str->y_max = y_max;
51 str->y_grid = y_grid;
52 str->z_min = z_min;
53 str->z_max = z_max;
54 str->z_grid = z_grid;
55 str->c = c;
56}
57
71 real c000, c100, c001, c101, c010, c110, c011, c111;
72 real c00, c01, c10, c11;
73 real c0, c1;
74 /* Make sure periodic coordinates are within [max, min] region. */
75 if(str->bc_x == PERIODICBC) {
76 x = fmod(x - str->x_min, str->x_max - str->x_min) + str->x_min;
77 x = x + (x < str->x_min) * (str->x_max - str->x_min);
78 }
79 if(str->bc_y == PERIODICBC) {
80 y = fmod(y - str->y_min, str->y_max - str->y_min) + str->y_min;
81 y = y + (y < str->y_min) * (str->y_max - str->y_min);
82 }
83 if(str->bc_z == PERIODICBC) {
84 z = fmod(z - str->z_min, str->z_max - str->z_min) + str->z_min;
85 z = z + (z < str->z_min) * (str->z_max - str->z_min);
86 }
87
88 /* index for x variable */
89 int i_x = (x - str->x_min) / str->x_grid;
90 /* Normalized x coordinate in current cell */
91 real dx = (x - (str->x_min + i_x*str->x_grid)) / str->x_grid;
92
93 /* index for y variable */
94 int i_y = (y - str->y_min) / str->y_grid;
95 /* Normalized y coordinate in current cell */
96 real dy = (y - (str->y_min + i_y*str->y_grid)) / str->y_grid;
97
98 /* index for z variable */
99 int i_z = (z - str->z_min) / str->z_grid;
100 /* Normalized z coordinate in current cell */
101 real dz = (z - (str->z_min + i_z*str->z_grid)) / str->z_grid;
102
103 /* Index jump to cell */
104 int n = i_y*str->n_z*str->n_x + i_z*str->n_x + i_x;
105 int x1 = 1; /* Index jump one x forward */
106 int y1 = str->n_z*str->n_x; /* Index jump one y forward */
107 int z1 = str->n_x; /* Index jump one z forward */
108
109 int err = 0;
110
111 /* Enforce periodic BC or check that the coordinate is within the grid. */
112 if( str->bc_x == PERIODICBC && i_x == str->n_x-1 ) {
113 x1 = -(str->n_x-1)*x1;
114 }
115 else if( str->bc_x == NATURALBC && !(x >= str->x_min && x <= str->x_max) ) {
116 err = 1;
117 }
118 if( str->bc_y == PERIODICBC && i_y == str->n_y-1 ) {
119 y1 = -(str->n_y-1)*y1;
120 }
121 else if( str->bc_y == NATURALBC && !(y >= str->y_min && y <= str->y_max) ) {
122 err = 1;
123 }
124 if( str->bc_z == PERIODICBC && i_z == str->n_z-1 ) {
125 z1 = -(str->n_z-1)*z1;
126 }
127 else if( str->bc_z == NATURALBC && !(z >= str->z_min && z <= str->z_max) ) {
128 err = 1;
129 }
130
131 if(!err) {
132 /* Values at grid cell corners */
133 c000 = str->c[n];
134 c100 = str->c[n + x1];
135 c001 = str->c[n + y1];
136 c101 = str->c[n + y1 + x1];
137 c010 = str->c[n + z1];
138 c110 = str->c[n +z1 + x1];
139 c011 = str->c[n + y1 + z1];
140 c111 = str->c[n + y1 + z1 + x1];
141 /* Interpolate along x */
142 c00 = c000*(1 - dx) + c100*dx;
143 c01 = c001*(1 - dx) + c101*dx;
144 c10 = c010*(1 - dx) + c110*dx;
145 c11 = c011*(1 - dx) + c111*dx;
146 /* Interpolate these values along z */
147 c0 = c00*(1 - dz) + c10*dz;
148 c1 = c01*(1 - dz) + c11*dz;
149 /* Finally we interpolate these values along y */
150 *f = c0*(1 - dy) + c1*dy;
151 }
152
153 return err;
154}
Main header file for ASCOT5.
double real
Definition ascot5.h:85
@ NATURALBC
Definition interp.h:37
@ PERIODICBC
Definition interp.h:38
int linint3D_eval_f(real *f, linint3D_data *str, real x, real y, real z)
Evaluate interpolated value of 3D scalar field.
Definition linint3D.c:70
void linint3D_init(linint3D_data *str, real *c, int n_x, int n_y, int n_z, int bc_x, int bc_y, int bc_z, real x_min, real x_max, real y_min, real y_max, real z_min, real z_max)
Initialize linear interpolation struct for scalar 3D data.
Definition linint3D.c:29
Linear interpolation library.
real fmod(real x, real y)
Compute the modulus of two real numbers.
Definition math.c:22
Header file for math.c.
3D interpolation struct.
Definition linint.h:50
real z_max
Definition linint.h:64
real x_max
Definition linint.h:58
real y_grid
Definition linint.h:62
real x_min
Definition linint.h:57
real y_max
Definition linint.h:61
real z_grid
Definition linint.h:65
real * c
Definition linint.h:66
real z_min
Definition linint.h:63
real x_grid
Definition linint.h:59
real y_min
Definition linint.h:60