Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
map_test_3d_openmp.cpp
Go to the documentation of this file.
1#include <stdio.h>
2#include "common.h"
4
5#define index(i,j,k) ( k + WID + j * (blocks_per_dim_z + 2) * WID + i * (blocks_per_dim_z + 2) * blocks_per_dim_y * WID2 )
6#define colindex(i,j) ( j * (blocks_per_dim_z + 2) * WID + i * (blocks_per_dim_z + 2) * blocks_per_dim_y * WID2 )
7
8/*print all values in the vector valued values array. In this array
9 there are blocks_per_dim blocks with a width of WID*/
10void print_values(int step, Real *values, uint blocks_per_dim, Real v_min, Real dv){
11 char name[256];
12 sprintf(name,"dist_%03d.dat",step);
13
14 FILE* fp=fopen(name,"w");
15 for(int i=0; i < blocks_per_dim * WID; i++){
16 Real v = v_min + i*dv;
17 fprintf(fp,"%20.12g %20.12g\n", v, values[i + WID]);
18 }
19 fclose(fp);
20}
21
22
23void propagate(const Real * const values_in, Real *values_out,
24 uint blocks_per_dim_x, uint blocks_per_dim_y, uint blocks_per_dim_z,
27 #pragma omp parallel for
28 for (uint k=0; k< (blocks_per_dim_z+2) * blocks_per_dim_x * blocks_per_dim_z * WID3; ++k){
29 values_out[k] = 0.0;
30 }
31
32 #pragma omp parallel for collapse(2)
33 for(int i = 0; i < blocks_per_dim_x * WID; i++){
34 for(int j = 0; j < blocks_per_dim_y * WID; j++){
35 for (uint k = 0; k < blocks_per_dim_z * WID; k++){
36 const int i_block = i / WID;
37 const int i_cell = i % WID;
38 const int j_block = j / WID;
39 const int j_cell = j % WID;
40 const Real * const values = values_in + colindex(i,j);
41
42 Real a[RECONSTRUCTION_ORDER + 1];
43#ifdef ACC_SEMILAG_PLM
44 const Real d_cv=slope_limiter(values[k - 1 + WID], values[k + WID], values[k + 1 + WID]);
45 a[0] = values[k + WID] - d_cv * 0.5;
46 a[1] = d_cv * 0.5;
47#endif
48#ifdef ACC_SEMILAG_PPM
49 // TODO!
50 cerr << "PPM not done yet"<<endl;
51 exit(1);
52#endif
53 /* intersection_min is the intersection z coordinate (z after
54 swaps that is) of the lowest possible z plane for each i,j
55 index
56 */
57 const Real intersection_min = intersection +
58 (i_block * WID + i_cell) * intersection_di +
59 (j_block * WID + j_cell) * intersection_dj;
60
61 /*compute some initial values, that are used to set up the
62 * shifting of values as we go through all blocks in
63 * order. See comments where they are shifted for
64 * explanations of their meening*/
65
66 /*loop through all blocks in column and compute the mapping as integrals*/
67 /*v_l, v_r are the left and right velocity coordinates of source cell*/
68 const Real v_l = v_min + k * dv;
69 const Real v_r = v_l + dv;
70 /*left(l) and right(r) k values (global index) in the target
71 lagrangian grid, the intersecting cells. Again old right is new left*/
72 const int target_gk_l = (int)((v_l - intersection_min)/intersection_dk);
73 const int target_gk_r = (int)((v_r - intersection_min)/intersection_dk);
74
75 for(int gk = target_gk_l; gk <= target_gk_r; gk++){
76 //the velocity limits for the integration to put mass
77 //in the targe cell. If both v_r and v_l are in same target cell
78 //then v_int_l,v_int_r should be between v_l and v_r.
79 //v_int_norm_l and v_int_norm_r normalized to be between 0 and 1 in the cell.
80 const Real v_int_l = min( max((Real)(gk) * intersection_dk + intersection_min, v_l), v_r);
81 const Real v_int_norm_l = (v_int_l - v_l)/dv;
82 const Real v_int_r = min((Real)(gk + 1) * intersection_dk + intersection_min, v_r);
83 const Real v_int_norm_r = (v_int_r - v_l)/dv;
84
85 /*compute left and right integrand*/
86#ifdef ACC_SEMILAG_PLM
87 Real target_density_l =
88 v_int_norm_l * a[0] +
89 v_int_norm_l * v_int_norm_l * a[1];
90 Real target_density_r =
91 v_int_norm_r * a[0] +
92 v_int_norm_r * v_int_norm_r * a[1];
93#endif
94#ifdef ACC_SEMILAG_PPM
95 Real target_density_l =
96 v_int_norm_l * a[0] +
97 v_int_norm_l * v_int_norm_l * a[1] +
98 v_int_norm_l * v_int_norm_l * v_int_norm_l * a[2];
99 Real target_density_r =
100 v_int_norm_r * a[0] +
101 v_int_norm_r * v_int_norm_r * a[1] +
102 v_int_norm_r * v_int_norm_r * v_int_norm_r * a[2];
103#endif
104 /*total value of integrand, if it is wihtin bounds*/
105 if ( gk >= 0 && gk <= blocks_per_dim_z * WID )
106 //atomic not needed if k index is not threaded
107 //#pragma omp atomic update
108 values_out[colindex(i,j) + gk + WID] += target_density_r - target_density_l;
109 }
110 }
111 }
112 }
113}
114
115
116int main(void) {
117 /*define grid size*/
118 const int dv = 20000;
119 const Real v_min = -2e6;
120 const int blocks_per_dim_x = 10;
121 const int blocks_per_dim_y = 10;
122 const int blocks_per_dim_z = 50;
123
124
125 Real *values_a = new Real[(blocks_per_dim_z+2) * blocks_per_dim_x * blocks_per_dim_z * WID3];
126 Real *values_b = new Real[(blocks_per_dim_z+2) * blocks_per_dim_x * blocks_per_dim_z * WID3];
127
128 /*intersection values define the acceleration transformation. These would be obtained from other routines, but are here fixed*/
129 Real intersection = v_min + 0.6*dv;
130 Real intersection_di = dv/4.0;
132 Real intersection_dj = dv; //does not matter here, fixed j.
133
134 const int iterations=1000;
135
136 /*clear target & values array*/
137 for (uint k=0; k< (blocks_per_dim_z+2) * blocks_per_dim_x * blocks_per_dim_z * WID3; ++k){
138 values_a[k] = 0.0;
139 }
140
141 /*Add square wave*/
142 for(int i=0; i < blocks_per_dim_x * WID; i++){
143 for(int j=0; j < blocks_per_dim_y * WID; j++){
144 for(int k=0; k < blocks_per_dim_z * WID; k++){
145 Real v = v_min + k * dv;
146 if (v > v_min + 0.8 * (blocks_per_dim_z * WID * dv) &&
147 v < v_min + 0.9 * (blocks_per_dim_z * WID * dv))
148 values_a[index(i,j,k)] = 1.0;
149 }
150 }
151 }
152
153 /*loop over propagations*/
154 for(int step = 0; step < iterations; step+=2){
155 if(step % 10 ==0)
156 print_values(step, values_a + colindex(0,0), blocks_per_dim_z, v_min, dv);
157 propagate(values_a, values_b,
158 blocks_per_dim_x, blocks_per_dim_y, blocks_per_dim_z,
159 v_min, dv,
161 propagate(values_b, values_a,
162 blocks_per_dim_x, blocks_per_dim_y, blocks_per_dim_z,
163 v_min, dv,
165
166 }
167}
168
fclose(file)
for i
Definition Dispersion.m:24
#define WID
Definition common.h:514
const int WID3
Definition common.h:517
float Real
Definition definitions.h:41
const Realf intersection
const Realf intersection_dk
__global__ void vmesh::VelocityMesh **__restrict__ ColumnOffsets split::SplitVector< vmesh::GlobalID > Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > const uint *__restrict__ const Realf const int const int const Realf v_min
const Realf intersection_di
__global__ void vmesh::VelocityMesh **__restrict__ ColumnOffsets split::SplitVector< vmesh::GlobalID > Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > const uint *__restrict__ const Realf const int const int const Realf const Realf dv
const Realf intersection_dj
const int j
const int k
void print_values(int step, Real *values, uint blocks_per_dim, Real v_min, Real dv)
void propagate(const Real *const values_in, Real *values_out, uint blocks_per_dim_x, uint blocks_per_dim_y, uint blocks_per_dim_z, Real v_min, Real dv, Real intersection, Real intersection_di, Real intersection_dj, Real intersection_dk)
int main(void)
#define index(i, j, k)
#define colindex(i, j)
Real slope_limiter(const Real &l, const Real &m, const Real &r)
static ARCH_HOSTDEV VecSimple< T > min(VecSimple< T > const &l, VecSimple< T > const &r)
static ARCH_HOSTDEV VecSimple< T > max(VecSimple< T > const &l, VecSimple< T > const &r)