Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
particle_post_pusher.cpp
Go to the documentation of this file.
1/*
2 * This file is part of Vlasiator.
3 * Copyright 2010-2016 Finnish Meteorological Institute
4 *
5 * For details of usage, see the COPYING file and read the "Rules of the Road"
6 * at http://www.physics.helsinki.fi/vlasiator/
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Postprocessing particle trajectory analyzer
23 * for Vlasiator
24 *
25 */
26#include <mpi.h>
27#include <iostream>
28#include <random>
29#include <string.h>
30#include "particles.h"
31#include "field.h"
32#include "physconst.h"
33#include "readfields.h"
34#include "distribution.h"
35#include "particleparameters.h"
36#include "../readparameters.h"
37#include "scenario.h"
38#include "boundaries.h"
39
40#define cross_product(av,bv) (av).cross(bv)
41#define dot_product(av,bv) (av).dot(bv)
42#define vector_length(v) (v).norm()
43#define normalize_vector(v) (v).normalized()
44
45int main(int argc, char** argv) {
46
47 MPI_Init(&argc, &argv);
48
49 /* Parse commandline and config*/
50 Readparameters parameters(argc, argv);
52 parameters.parse(false); // Parse parameters and don't require run_config
54 std::cerr << "Parsing parameters failed, aborting." << std::endl;
55 std::cerr << "Did you add a --run_config=file.cfg parameter?" << std::endl;
56 return 1;
57 }
58
59 /* Read starting fields from specified input file */
60 std::string filename_pattern = ParticleParameters::input_filename_pattern;
61 char filename_buffer[256];
62
64 Field E[2],B[2],V;
65 std::cerr << "Loading first file with index " << ParticleParameters::start_time / ParticleParameters::input_dt
66 << std::endl;
67 snprintf(filename_buffer,256,filename_pattern.c_str(),input_file_counter-1);
68 E[0].dimension[0] = E[1].dimension[0] = B[0].dimension[0] = B[1].dimension[0] = V.dimension[0] = ParticleParameters::boundary_behaviour_x;
69 E[0].dimension[1] = E[1].dimension[1] = B[0].dimension[1] = B[1].dimension[1] = V.dimension[1] = ParticleParameters::boundary_behaviour_y;
70 E[0].dimension[2] = E[1].dimension[2] = B[0].dimension[2] = B[1].dimension[2] = V.dimension[2] = ParticleParameters::boundary_behaviour_z;
71 readfields(filename_buffer,E[1],B[1],V);
72 E[0]=E[1]; B[0]=B[1];
73
74 // Set boundary conditions based on sizes
75 if(B[0].dimension[0]->cells <= 1) {
78 }
79 if(B[0].dimension[1]->cells <= 1) {
82 }
83 if(B[0].dimension[2]->cells <= 1) {
86 }
87
88 // Make sure updated boundary conditions are also correctly known to the fields
89 E[0].dimension[0] = E[1].dimension[0] = B[0].dimension[0] = B[1].dimension[0] = V.dimension[0] = ParticleParameters::boundary_behaviour_x;
90 E[0].dimension[1] = E[1].dimension[1] = B[0].dimension[1] = B[1].dimension[1] = V.dimension[1] = ParticleParameters::boundary_behaviour_y;
91 E[0].dimension[2] = E[1].dimension[2] = B[0].dimension[2] = B[1].dimension[2] = V.dimension[2] = ParticleParameters::boundary_behaviour_z;
92
93 ParticleParameters::boundary_behaviour_x->setExtent(B[0].dimension[0]->min, B[0].dimension[0]->max, B[0].dimension[0]->cells);
94 ParticleParameters::boundary_behaviour_y->setExtent(B[0].dimension[1]->min, B[0].dimension[1]->max, B[0].dimension[1]->cells);
95 ParticleParameters::boundary_behaviour_z->setExtent(B[0].dimension[2]->min, B[0].dimension[2]->max, B[0].dimension[2]->cells);
96
97 /* Init particles */
100 int maxsteps = maxtime/dt;
101
103 ParticleContainer particles = scenario->initialParticles(E[0],B[0],V);
104
105 std::cerr << "Pushing " << particles.size() << " particles for " << maxsteps << " steps..." << std::endl;
106 std::cerr << "[ ]\x0d[";
107
108 /* Push them around */
109 for(int step=0; step<maxsteps; step++) {
110
111 bool newfile;
112 /* Load newer fields, if neccessary */
113 if(step >= 0) {
114 newfile = readNextTimestep(filename_pattern, ParticleParameters::start_time + step*dt, 1,E[0], E[1],
115 B[0], B[1], V, scenario->needV, input_file_counter);
116 } else {
117 newfile = readNextTimestep(filename_pattern, ParticleParameters::start_time + step*dt, -1,E[1], E[0],
118 B[1], B[0], V, scenario->needV, input_file_counter);
119 }
120
123
124 // If a new timestep has been opened, add a new bunch of particles
125 if(newfile) {
126 scenario->newTimestep(input_file_counter, step, step*dt, particles, cur_E, cur_B, V);
127 }
128
129 scenario->beforePush(particles,cur_E,cur_B,V);
130
131 #pragma omp parallel for
132 for(unsigned int i=0; i< particles.size(); i++) {
133
134 if(!isfinite(vector_length(particles[i].x))) {
135 // Skip disabled particles.
136 continue;
137 }
138
139 /* Get E- and B-Field at their position */
140 Vec3d Eval,Bval;
141
142 Eval = cur_E(particles[i].x);
143 Bval = cur_B(particles[i].x);
144
145 if(dt < 0) {
146 // If propagating backwards in time, flip B-field pseudovector
147 Bval *= -1;
148 }
149
150 /* Push them around */
151 particles[i].push(Bval,Eval,dt);
152
153 }
154
155 // Remove all particles that have left the simulation box after this step
156 // (unfortunately, this can not be done in parallel, so it better be fast!)
157 for(auto i = particles.begin(); i != particles.end(); ) {
158
159 // Boundaries are allowed to mangle the particles here.
160 // If they return false, particles are deleted.
161 bool do_erase = false;
162 if(!ParticleParameters::boundary_behaviour_x->handleParticle(*i)) {
163 do_erase = true;
164 }
165 if(!ParticleParameters::boundary_behaviour_y->handleParticle(*i)) {
166 do_erase = true;
167 }
168 if(!ParticleParameters::boundary_behaviour_z->handleParticle(*i)) {
169 do_erase = true;
170 }
171 if(do_erase) {
172 particles.erase(i);
173 } else {
174 i++;
175 }
176 }
177
178 scenario->afterPush(step, step*dt, particles, cur_E, cur_B, V);
179
180 /* Draw progress bar */
181 if((step % (maxsteps/71))==0) {
182 std::cerr << "=";
183 }
184 }
185
186 scenario->finalize(particles,E[1],B[1],V);
187
188 std::cerr << std::endl;
189
190 MPI_Finalize();
191 return 0;
192}
for i
Definition Dispersion.m:24
Numerical propagation V
Definition Dispersion.m:98
dt
Definition Dispersion.m:39
Boundary * createBoundary(int dimension)
Definition boundaries.h:181
static bool parse(const bool needsRunConfig=true, const bool allowUnknown=true)
#define Vec3d
#define vector_length(v)
std::vector< Particle, aligned_allocator< Particle, 32 > > ParticleContainer
Definition particles.h:45
bool readNextTimestep(const std::string &filename_pattern, double t, int step, Field &E0, Field &E1, Field &B0, Field &B1, Field &V, bool doV, int &input_file_counter)
Definition readfields.h:272
void readfields(const char *filename, Field &E, Field &B, Field &V, bool doV=true)
Definition readfields.h:396
Scenario * createScenario()
Definition scenario.h:135
Definition field.h:34
Boundary * dimension[3]
Definition field.h:42
static Boundary * boundary_behaviour_x
static std::string mode
static Boundary * boundary_behaviour_z
static std::string input_filename_pattern
static Boundary * boundary_behaviour_y
virtual void finalize(ParticleContainer &particles, Field &E, Field &B, Field &V)
Definition scenario.h:52
virtual void afterPush(int step, double time, ParticleContainer &particles, Field &E, Field &B, Field &V)
Definition scenario.h:49
virtual void beforePush(ParticleContainer &particles, Field &E, Field &B, Field &V)
Definition scenario.h:46
virtual void newTimestep(int input_file_counter, int step, double time, ParticleContainer &particles, Field &E, Field &B, Field &V)
Definition scenario.h:42
bool needV
Definition scenario.h:55
virtual ParticleContainer initialParticles(Field &E, Field &B, Field &V)
Definition scenario.h:39
int main()
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)
static ARCH_HOSTDEV VecSimple< T > floor(VecSimple< T > const &a)