Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
map_test.cpp
Go to the documentation of this file.
1#include <stdio.h>
2#include "common.h"
3#include "vlasovsolver/vec.h"
7
8const int fluxlimiterscalingfactor=1.e-15;
9// Used for better calculation of flux limiters at extreme values.
10// In vlasiator, the value of spatial_cell->getVelocityBlockMinValue(popID)
11// is used here.
12
13/*print all values in the vector valued values array. In this array
14 there are blocks_per_dim blocks with a width of WID*/
15void print_values(int step, Vec *values, uint blocks_per_dim, Real v_min, Real dv){
16 char name[256];
17 sprintf(name,"dist_%03d.dat",step);
18
19 FILE* fp=fopen(name,"w");
20 for(int i=0; i < blocks_per_dim * WID; i++){
21 Real v=v_min + (i + 0.5)*dv;
22 fprintf(fp,"%20.12g %20.12g %20.12g %20.12g %20.12g\n", v, values[i + WID][0], values[i + WID][1], values[i + WID][2], values[i + WID][3]);
23 }
24 fclose(fp);
25}
26
27
28void propagate(Vec values[], uint blocks_per_dim, Real v_min, Real dv,
29 uint i_block, uint j_block, uint j_cell,
31 Vec target[(MAX_BLOCKS_PER_DIM+2)*WID];
32
33
34 /*clear temporary taret*/
35 for (uint k=0; k<WID* (blocks_per_dim + 2); ++k){
36 target[k] = 0.0;
37 }
38
39 /* intersection_min is the intersection z coordinate (z after
40 swaps that is) of the lowest possible z plane for each i,j
41 index (i in vector)
42 */
43 const Real intersection_min_base =
45 (i_block * WID) * intersection_di +
46 (j_block * WID + j_cell) * intersection_dj;
47
48 //const Vec intersection_min(intersection_min_base);
49 const Vec intersection_min(intersection_min_base + 0 * intersection_di,
50 intersection_min_base + 1 * intersection_di,
51 intersection_min_base + 2 * intersection_di,
52 intersection_min_base + 3 * intersection_di);
53 /*compute some initial values, that are used to set up the
54 * shifting of values as we go through all blocks in
55 * order. See comments where they are shifted for
56 * explanations of their meening*/
57
58 /*loop through all blocks in column and compute the mapping as integrals*/
59 for (unsigned int k_block = 0; k_block<blocks_per_dim;k_block++){
60 for (uint k_cell=0; k_cell<WID; ++k_cell){
61
62#ifdef ACC_SEMILAG_PLM
63 Vec a[2];
64 compute_plm_coeff(values, (k_block + 1) * WID + k_cell , a, fluxlimiterscalingfactor);
65#endif
66#ifdef ACC_SEMILAG_PPM
67 Vec a[3];
68 compute_ppm_coeff(values, h6, (k_block + 1) * WID + k_cell , a, fluxlimiterscalingfactor);
69#endif
70#ifdef ACC_SEMILAG_PQM
71 Vec a[5];
72 compute_pqm_coeff(values, h8, (k_block + 1) * WID + k_cell , a, fluxlimiterscalingfactor);
73#endif
74
75
76
77 /*v_l, v_r are the left and right velocity coordinates of source cell*/
78 Vec v_l = v_min + (k_block * WID + k_cell) * dv;
79 Vec v_r = v_l + dv;
80 /*left(l) and right(r) k values (global index) in the target
81 lagrangian grid, the intersecting cells. Again old right is new left*/
82 const Veci target_gk_l = truncate_to_int((v_l - intersection_min)/intersection_dk);
83 const Veci target_gk_r = truncate_to_int((v_r - intersection_min)/intersection_dk);
84
85
86
87 Veci gk(target_gk_l);
88 while (horizontal_or(gk <= target_gk_r)){
89 //the velocity limits for the integration to put mass
90 //in the targe cell. If both v_r and v_l are in same target cell
91 //then v_int_l,v_int_r should be between v_l and v_r.
92 //v_int_norm_l and v_int_norm_r normalized to be between 0 and 1 in the cell.
93
94#ifdef DP
95 const Vec v_int_l = min( max(to_double(gk) * intersection_dk + intersection_min, v_l), v_r);
96 const Vec v_int_norm_l = (v_int_l - v_l)/dv;
97 const Vec v_int_r = min(to_double(gk + 1) * intersection_dk + intersection_min, v_r);
98 const Vec v_int_norm_r = (v_int_r - v_l)/dv;
99#else
100 const Vec v_int_l = min( max(to_float(gk) * intersection_dk + intersection_min, v_l), v_r);
101 const Vec v_int_norm_l = (v_int_l - v_l)/dv;
102 const Vec v_int_r = min(to_float(gk + 1) * intersection_dk + intersection_min, v_r);
103 const Vec v_int_norm_r = (v_int_r - v_l)/dv;
104#endif
105
106 /*compute left and right integrand*/
107#ifdef ACC_SEMILAG_PLM
108 Vec target_density_l =
109 v_int_norm_l * a[0] +
110 v_int_norm_l * v_int_norm_l * a[1];
111 Vec target_density_r =
112 v_int_norm_r * a[0] +
113 v_int_norm_r * v_int_norm_r * a[1];
114#endif
115#ifdef ACC_SEMILAG_PPM
116 Vec target_density_l =
117 v_int_norm_l * a[0] +
118 v_int_norm_l * v_int_norm_l * a[1] +
119 v_int_norm_l * v_int_norm_l * v_int_norm_l * a[2];
120 Vec target_density_r =
121 v_int_norm_r * a[0] +
122 v_int_norm_r * v_int_norm_r * a[1] +
123 v_int_norm_r * v_int_norm_r * v_int_norm_r * a[2];
124#endif
125#ifdef ACC_SEMILAG_PQM
126 Vec target_density_l =
127 v_int_norm_l * a[0] +
128 v_int_norm_l * v_int_norm_l * a[1] +
129 v_int_norm_l * v_int_norm_l * v_int_norm_l * a[2] +
130 v_int_norm_l * v_int_norm_l * v_int_norm_l * v_int_norm_l * a[3] +
131 v_int_norm_l * v_int_norm_l * v_int_norm_l * v_int_norm_l * v_int_norm_l * a[4];
132
133 Vec target_density_r =
134 v_int_norm_r * a[0] +
135 v_int_norm_r * v_int_norm_r * a[1] +
136 v_int_norm_r * v_int_norm_r * v_int_norm_r * a[2] +
137 v_int_norm_r * v_int_norm_r * v_int_norm_r * v_int_norm_r * a[3] +
138 v_int_norm_r * v_int_norm_r * v_int_norm_r * v_int_norm_r * v_int_norm_r * a[4];
139
140#endif
141
142
143 /*total value of integrand*/
144 const Vec target_density = target_density_r - target_density_l;
145
146 //store values, one element at elema time
147 for(uint elem = 0; elem < 4;elem ++ ){
148 int k_in_target = gk[elem];
149 if (k_in_target >=0 &&
150 k_in_target < blocks_per_dim * WID) {
151 const Real new_density = target[k_in_target + WID][elem] + target_density[elem];
152 target[k_in_target + WID].insert(elem, new_density);
153 }
154 }
155 gk++; //next iteration in while loop
156 }
157 }
158 }
159
160
161 /*copy target to values, and clear target array*/
162 for (unsigned int k_block = 0; k_block<blocks_per_dim;k_block++){
163 for (uint k=0; k<WID; ++k){
164 values[k_block * WID + k + WID] = target[k_block * WID + k + WID];
165 target[k_block * WID + k + WID] = 0.0;
166 }
167 }
168}
169
170void print_reconstruction(int step, Vec values[], uint blocks_per_dim, Real v_min, Real dv,
171 uint i_block, uint j_block, uint j_cell,
173 char name[256];
174 sprintf(name,"reconstructions_%05d.dat",step);
175 FILE* fp=fopen(name,"w");
176
177
178
179 /* intersection_min is the intersection z coordinate (z after
180 swaps that is) of the lowest possible z plane for each i,j
181 index (i in vector)
182 */
183 const Real intersection_min_base =
185 (i_block * WID) * intersection_di +
186 (j_block * WID + j_cell) * intersection_dj;
187
188 //const Vec intersection_min(intersection_min_base);
189 const Vec intersection_min(intersection_min_base + 0 * intersection_di,
190 intersection_min_base + 1 * intersection_di,
191 intersection_min_base + 2 * intersection_di,
192 intersection_min_base + 3 * intersection_di);
193 /*compute some initial values, that are used to set up the
194 * shifting of values as we go through all blocks in
195 * order. See comments where they are shifted for
196 * explanations of their meening*/
197 const int subcells = 50;
198 /*loop through all blocks in column and divide into subcells. Print value of reconstruction*/
199 for (unsigned int k_block = 0; k_block<blocks_per_dim;k_block++){
200 for (uint k_cell=0; k_cell<WID; ++k_cell){
201#ifdef ACC_SEMILAG_PLM
202 Vec a[2];
203 compute_plm_coeff(values, (k_block + 1) * WID + k_cell , a, fluxlimiterscalingfactor);
204#endif
205#ifdef ACC_SEMILAG_PPM
206 Vec a[3];
207 compute_ppm_coeff(values, h6, (k_block + 1) * WID + k_cell , a, fluxlimiterscalingfactor);
208#endif
209#ifdef ACC_SEMILAG_PQM
210 Vec a[5];
211 compute_pqm_coeff(values, h8, (k_block + 1) * WID + k_cell , a, fluxlimiterscalingfactor);
212#endif
213
214 Vec v_l = v_min + (k_block * WID + k_cell) * dv;
215 for (uint k_subcell=0; k_subcell< subcells; ++k_subcell){
216 Vec v_norm = (Real)(k_subcell + 0.5)/subcells; //normalized v of subcell in source cell
217 Vec v = v_l + v_norm * dv;
218
219#ifdef ACC_SEMILAG_PLM
220 Vec target =
221 a[0] +
222 2.0 * v_norm * a[1];
223#endif
224#ifdef ACC_SEMILAG_PPM
225 Vec target =
226 a[0] +
227 2.0 * v_norm * a[1] +
228 3.0 * v_norm * v_norm * a[2];
229#endif
230#ifdef ACC_SEMILAG_PQM
231 Vec target =
232 a[0] +
233 2.0 * v_norm * a[1] +
234 3.0 * v_norm * v_norm * a[2] +
235 4.0 * v_norm * v_norm * v_norm * a[3] +
236 5.0 * v_norm * v_norm * v_norm * v_norm * a[4];
237#endif
238 fprintf(fp,"%20.12g %20.12g %20.12g\n", v[0], values[k_block * WID + k_cell + WID][0], target[0]);
239 }
240 fprintf(fp,"\n"); //empty line to deay wgments in gnuplot
241 }
242 }
243
244 fclose(fp);
245}
246
247
248
249
250
251
252int main(void) {
253 const int dv = 20000;
254 const Real v_min = -4e6;
255 const int blocks_per_dim = 100;
256 const int i_block = 0; //x index of block, fixed in this simple test
257 const int j_block = 0; //y index of block, fixed in this simple test
258 const int j_cell = 0; // y index of cell within block (0..WID-1)
259
260
261 Vec values[(blocks_per_dim+2)*WID];
262
263 /*initial values*/
264
265 Real intersection = v_min - 0.1*dv;
266 Real intersection_di = 0.025 * dv;
268 Real intersection_dj = 0.0 * dv; //does not matter here, fixed j.
269
270
271 const int iterations = 1000;
272
273 /*clear target & values array*/
274 for (uint k=0; k<WID* (blocks_per_dim + 2); ++k){
275 values[k] = 0.0;
276 }
277
278 /*Add square wave*/
279 /*
280 for(int i=0; i < blocks_per_dim * WID; i++){
281 Real v=v_min + i*dv;
282 if (v > v_min + 0.8 * (blocks_per_dim * WID * dv) &
283 v < v_min + 0.9 * (blocks_per_dim * WID * dv)) {
284 values[i + WID] = Vec(1.0);
285 }
286 }
287*/
288 Real T = 500000;
289 Real rho = 1.0e18;
290 for(int i=0; i < blocks_per_dim * WID; i++){
291 Real v=v_min + i*dv;
292 values[i + WID] = rho * pow(physicalconstants::MASS_PROTON / (2.0 * M_PI * physicalconstants::K_B * T), 1.5) *
293 exp(- physicalconstants::MASS_PROTON * v * v / (2.0 * physicalconstants::K_B * T));
294 }
295
296
297// print_values(0,values,blocks_per_dim, v_min, dv);
298 print_reconstruction(0, values, blocks_per_dim, v_min, dv,
299 i_block, j_block, j_cell,
301
302 clock_t t = clock();
303/*loop over propagations*/
304 for(int step = 0; step <= iterations; step++){
305 propagate(values, blocks_per_dim, v_min, dv,
306 i_block, j_block, j_cell,
308 if (step % 10 == 0)
309 print_reconstruction(step, values, blocks_per_dim, v_min, dv,
310 i_block, j_block, j_cell,
312
313 }
314 printf("\nTime per iteration: %12.15g\n", ((double)(clock() - t)/CLOCKS_PER_SEC)/iterations);
315
316// print_values(iterations,values,blocks_per_dim, v_min, dv);
317}
fclose(file)
for i
Definition Dispersion.m:24
void propagate(Vec values[], uint blocks_per_dim, Real v_min, Real dv, uint i_block, uint j_block, uint j_cell, Real intersection, Real intersection_di, Real intersection_dj, Real intersection_dk)
Definition map_test.cpp:28
void print_values(int step, Vec *values, uint blocks_per_dim, Real v_min, Real dv)
Definition map_test.cpp:15
void print_reconstruction(int step, Vec values[], uint blocks_per_dim, Real v_min, Real dv, uint i_block, uint j_block, uint j_cell, Real intersection, Real intersection_di, Real intersection_dj, Real intersection_dk)
Definition map_test.cpp:170
int main(void)
Definition map_test.cpp:252
const int fluxlimiterscalingfactor
Definition map_test.cpp:8
#define WID
Definition common.h:514
#define MAX_BLOCKS_PER_DIM
Definition common.h:73
static void compute_plm_coeff(const Vec *const values, const uint k, Vec a[2], const Realf threshold)
static void compute_ppm_coeff(const Vec *const values, const face_estimate_order order, const uint k, Vec a[3], const Realf threshold)
static void compute_pqm_coeff(const Vec *__restrict__ values, face_estimate_order order, uint k, Vec a[5], const Realf threshold)
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 k
const Real K_B
Definition common.h:571
const Real MASS_PROTON
Definition common.h:574
An interface to a type with floating point values.
static ARCH_HOSTDEV VecSimple< T > min(VecSimple< T > const &l, VecSimple< T > const &r)
static ARCH_HOSTDEV bool horizontal_or(VecSimple< T > const &a)
static ARCH_HOSTDEV VecSimple< T > max(VecSimple< T > const &l, VecSimple< T > const &r)
static ARCH_HOSTDEV VecSimple< int > truncate_to_int(VecSimple< T > const &a)
static ARCH_HOSTDEV VecSimple< float > to_float(VecSimple< T > const &a)
static ARCH_HOSTDEV VecSimple< double > to_double(VecSimple< T > const &a)