ASCOT5
Loading...
Searching...
No Matches
math.c
Go to the documentation of this file.
1
5#include <math.h>
6#include <stdlib.h>
7#include "ascot5.h"
8#include "math.h"
9
10int rcomp(const void* a, const void* b);
11double math_simpson_helper(double (*f)(double), double a, double b, double eps,
12 double S, double fa, double fb, double fc,
13 int bottom);
14
23 return x - y * floor( x / y );
24}
25
44void math_jac_rpz2xyz(real* rpz, real* xyz, real r, real phi) {
45 // Temporary variables
46 real c = cos(phi);
47 real s = sin(phi);
48 real temp[3];
49
50 xyz[0] = rpz[0] * c - rpz[4] * s;
51 xyz[4] = rpz[0] * s + rpz[4] * c;
52 xyz[8] = rpz[8];
53
54 // Step 1: Vector [dBr/dx dBr/dy dBr/dz]
55 temp[0] = rpz[1] * c - rpz[5] * s;
56 temp[1] = rpz[2] * c - rpz[6] * s;
57 temp[2] = rpz[3] * c - rpz[7] * s;
58
59 // Step 2: Gradient
60 xyz[1] = temp[0] * c - temp[1] * s / r + (rpz[0]*s + rpz[4]*c) * s / r;
61 xyz[2] = temp[0] * s + temp[1] * c / r - (rpz[0]*s + rpz[4]*c) * c / r;
62 xyz[3] = temp[2];
63
64 // Step 1: Vector [dBphi/dx dBphi/dy dBphi/dz]
65 temp[0] = rpz[1] * s + rpz[5] * c;
66 temp[1] = rpz[2] * s + rpz[6] * c;
67 temp[2] = rpz[3] * s + rpz[7] * c;
68
69 // Step 2: Gradient
70 xyz[5] = temp[0] * c - temp[1] * s / r + (rpz[0]*c - rpz[4]*s) * s / r;
71 xyz[6] = temp[0] * s + temp[1] * c / r - (rpz[0]*c - rpz[4]*s) * c / r;
72 xyz[7] = temp[2];
73
74 // Step 1: Vector [dBz/dx dBz/dy dBz/dz]
75 temp[0] = rpz[9];
76 temp[1] = rpz[10];
77 temp[2] = rpz[11];
78
79 // Step 2: Gradient
80 xyz[9] = temp[0] * c - temp[1] * s / r;
81 xyz[10] = temp[0] * s + temp[1] * c / r;
82 xyz[11] = temp[2];
83}
84
103void math_jac_xyz2rpz(real* xyz, real* rpz, real r, real phi) {
104 // Temporary variables
105 real c = cos(phi);
106 real s = sin(phi);
107 real temp[3];
108
109 rpz[0] = xyz[0] * c + xyz[4] * s;
110 rpz[4] = -xyz[0] * s + xyz[4] * c;
111 rpz[8] = xyz[8];
112
113 // Step 1: Vector [dBx/dr dBx/dphi dBx/dz]
114 temp[0] = xyz[1] * c + xyz[5] * s;
115 temp[1] = xyz[2] * c + xyz[6] * s;
116 temp[2] = xyz[3] * c + xyz[7] * s;
117
118 // Step 2: Gradient
119 rpz[1] = temp[0] * c + temp[1] * s;
120 rpz[2] = -temp[0] * s * r + temp[1] * c * r
121 - xyz[0] * s + xyz[4] * c;
122 rpz[3] = temp[2];
123
124 // Step 1: Vector [dBy/dr dBy/dphi dBy/dz]
125 temp[0] = -xyz[1] * s + xyz[5] * c;
126 temp[1] = -xyz[2] * s + xyz[6] * c;
127 temp[2] = -xyz[3] * s + xyz[7] * c;
128
129 // Step 2: Gradient
130 rpz[5] = temp[0] * c + temp[1] * s;
131 rpz[6] = -temp[0] * s * r + temp[1] * c * r
132 - xyz[0] * c - xyz[4] * s;
133 rpz[7] = temp[2];
134
135 // Step 1: Vector [dBz/dr dBz/dphi dBz/dz]
136 temp[0] = xyz[9];
137 temp[1] = xyz[10];
138 temp[2] = xyz[11];
139
140 // Step 2: Gradient
141 rpz[9] = temp[0] * c + temp[1] * s;
142 rpz[10] = -temp[0] * s * r + temp[1] * c * r;
143 rpz[11] = temp[2];
144}
145
159void math_matmul(real* matA, real* matB, int d1, int d2, int d3, real* matC) {
160 real sum;
161 for (int i = 0; i < d1; i=i+1) {
162 for (int j = 0; j < d3; j=j+1) {
163 sum = 0.0;
164 for (int k = 0; k < d2; k=k+1){
165 sum = sum + matA[k * d1 + i]*matB[j * d2 + k];
166 }
167 matC[i * d3 + j] = sum;
168 }
169 }
170}
171
189 real X;
190 real v1, v2, s;
191 do {
192 v1 = drand48() * 2 - 1;
193 v2 = drand48() * 2 - 1;
194 s = v1*v1 + v2*v2;
195 } while(s >= 1);
196
197 X = v1 * sqrt(-2*log(s) / s);
198
199 return X;
200}
201
210int math_ipow(int a, int p) {
211 int pow = 1;
212 for(int i = 0; i < p; i++) {
213 pow *= a;
214 }
215 return pow;
216}
217
232double math_simpson(double (*f)(double), double a, double b, double eps) {
233 double c = (a + b)/2, h = b - a;
234 double fa = f(a), fb = f(b), fc = f(c);
235 double S = (h/6)*(fa + 4*fc + fb);
236 return math_simpson_helper(f, a, b, eps, S, fa, fb, fc,
238}
239
251void math_linspace(real* vec, real a, real b, int n) {
252 if(n == 1) {
253 vec[0] = b;
254 } else {
255 real d = (b-a)/(n-1);
256 int i;
257 for(i = 0; i < n; i++) {
258 vec[i] = a+i*d;
259 }
260 }
261}
262
276void math_uniquecount(int* in, int* unique, int* count, int n) {
277
278 for(int i=0; i<n; i++) {
279 unique[i] = 0;
280 count[i] = 0;
281 }
282
283 int n_unique = 0;
284 for(int i=0; i<n; i++) {
285
286 int test = in[i];
287 int isunique = 1;
288 for(int j=0; j<n_unique; j++) {
289 if(test == unique[j]) {
290 isunique = 0;
291 count[j] += 1;
292 }
293 }
294
295 if(isunique) {
296 unique[n_unique] = test;
297 count[n_unique] = 1;
298 n_unique++;
299 }
300 }
301}
302
303
324 int math_point_on_plane(real q[3], real t1[3], real t2[3], real t3[3]){
325 real x = q[0], y = q[1], z = q[2];
326 real x1 = t1[0], y1 = t1[1], z1 = t1[2];
327 real x2 = t2[0], y2 = t2[1], z2 = t2[2];
328 real x3 = t3[0], y3 = t3[1], z3 = t3[2];
329
330 int val = 0;
332 x -x1, y -y1, z -z1,
333 x2-x1, y2-y1, z2-z1,
334 x3-x1, y3-y1, z3-z1) != 0.0){
335 return val;
336 }
338 x -x1, y -y1, z -z1,
339 x -x2, y -y2, z -z2,
340 x -x3, y -y3, z -z3) != 0.0){
341 return val;
342 }
343 return val;
344 }
345
361 real n[3], real *s, real *t){
362 real n0[3],area;
363 math_unit(n,n0);
364 area = math_scalar_triple_product(AB,AC,n0);
365 *s = math_scalar_triple_product(AP,AC,n0) / area;
366 *t = math_scalar_triple_product(AB,AP,n0) / area;
367}
368
381int rcomp(const void* a, const void* b) {
382 real a_val = *((real*) a);
383 real b_val = *((real*) b);
384 real c_val = *((real*) b + 1);
385
386 if (a_val >= b_val && a_val < c_val) {
387 return 0;
388 }
389 return a_val > b_val ? 1 : -1;
390}
391
405real* math_rsearch(const real key, const real* base, int num) {
406 return (real*) bsearch(&key, base, num-1, sizeof(real), rcomp);
407}
408
427int math_point_in_polygon(real r, real z, real* rv, real* zv, int n) {
428 int hits = 0;
429
430 int i;
431 for(i = 0; i < n - 1; i++) {
432 real z1 = zv[i] - z;
433 real z2 = zv[i+1] - z;
434 real r1 = rv[i] - r;
435 real r2 = rv[i+1] - r;
436 if(z1 * z2 < 0) {
437 real ri = r1 + (z1*(r2-r1)) / (z1-z2);
438 if(ri > 0) {
439 hits++;
440 }
441 }
442 }
443 return hits % 2;
444}
445
449double math_simpson_helper(double (*f)(double), double a, double b, double eps,
450 double S, double fa, double fb, double fc,
451 int bottom) {
452 double c = (a + b)/2, h = b - a;
453 double d = (a + c)/2, e = (c + b)/2;
454 double fd = f(d), fe = f(e);
455 double Sleft = (h/12)*(fa + 4*fd + fc);
456 double Sright = (h/12)*(fc + 4*fe + fb);
457 double S2 = Sleft + Sright;
458 if (bottom <= 0 || fabs(S2 - S) <= eps*fabs(S)) {
459 return S2 + (S2 - S)/15;
460 }
461 return math_simpson_helper(f, a, c, eps, Sleft, fa, fc, fd, bottom-1)
462 +math_simpson_helper(f, c, b, eps, Sright, fc, fb, fe, bottom-1);
463}
Main header file for ASCOT5.
double real
Definition ascot5.h:85
void math_uniquecount(int *in, int *unique, int *count, int n)
Find unique numbers and their frequency in given array.
Definition math.c:276
double math_simpson(double(*f)(double), double a, double b, double eps)
Adaptive Simpsons rule for integral.
Definition math.c:232
int math_ipow(int a, int p)
Calculate a^p where both a and p are integers (p >= 0)
Definition math.c:210
int math_point_in_polygon(real r, real z, real *rv, real *zv, int n)
Check if coordinates are within polygon.
Definition math.c:427
void math_matmul(real *matA, real *matB, int d1, int d2, int d3, real *matC)
Matrix multiplication.
Definition math.c:159
real fmod(real x, real y)
Compute the modulus of two real numbers.
Definition math.c:22
int rcomp(const void *a, const void *b)
Helper comparison routine for "math_rsearch".
Definition math.c:381
void math_barycentric_coords_triangle(real AP[3], real AB[3], real AC[3], real n[3], real *s, real *t)
Find barycentric coordinates for a given point.
Definition math.c:360
real * math_rsearch(const real key, const real *base, int num)
Search for array element preceding a key value.
Definition math.c:405
double math_simpson_helper(double(*f)(double), double a, double b, double eps, double S, double fa, double fb, double fc, int bottom)
Helper routine for "math_simpson".
Definition math.c:449
void math_linspace(real *vec, real a, real b, int n)
Generate linearly spaced vector.
Definition math.c:251
int math_point_on_plane(real q[3], real t1[3], real t2[3], real t3[3])
Find if a point is on a given plane.
Definition math.c:324
void math_jac_xyz2rpz(real *xyz, real *rpz, real r, real phi)
Convert a Jacobian from cartesian to cylindrical coordinates.
Definition math.c:103
real math_normal_rand(void)
Generate normally distributed random numbers.
Definition math.c:188
void math_jac_rpz2xyz(real *rpz, real *xyz, real r, real phi)
Convert a Jacobian from cylindrical to cartesian coordinates.
Definition math.c:44
Header file for math.c.
#define math_determinant3x3(x1, x2, x3, y1, y2, y3, z1, z2, z3)
Direct expansion of 3x3 matrix determinant.
Definition math.h:97
#define math_unit(a, b)
Calculate unit vector b from a 3D vector a.
Definition math.h:70
#define math_maxSimpsonDepth
Maximum recursion depth for the simpson integral rule.
Definition math.h:18
#define math_scalar_triple_product(a, b, c)
the mixed or triple product of three vectors (a cross b) dot c mathematica: a={a0,...
Definition math.h:39