Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
Dispersion.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
23#include <cstdlib>
24#include <iostream>
25#include <iomanip>
26#include <cmath>
27
28#include "../../common.h"
34
35#include "Dispersion.h"
36
38
39using namespace std;
40using namespace spatial_cell;
41
42namespace projects {
45
47
49 typedef Readparameters RP;
50 RP::add("Dispersion.B0", "Guide magnetic field strength (T)", 1.0e-9);
51 RP::add("Dispersion.magXPertAbsAmp", "Absolute amplitude of the magnetic perturbation along x (T)", 1.0e-9);
52 RP::add("Dispersion.magYPertAbsAmp", "Absolute amplitude of the magnetic perturbation along y (T)", 1.0e-9);
53 RP::add("Dispersion.magZPertAbsAmp", "Absolute amplitude of the magnetic perturbation along z (T)", 1.0e-9);
54 RP::add("Dispersion.maxwCutoff", "Cutoff for the maxwellian distribution", 1e-12);
55 RP::add("Dispersion.angleXY", "Orientation of the guide magnetic field with respect to the x-axis in x-y plane (rad)", 0.001);
56 RP::add("Dispersion.angleXZ", "Orientation of the guide magnetic field with respect to the x-axis in x-z plane (rad)", 0.001);
57
58 // Per-population parameters
59 for(uint i=0; i< getObjectWrapper().particleSpecies.size(); i++) {
60 const std::string& pop = getObjectWrapper().particleSpecies[i].name;
61 RP::add(pop + "_Dispersion.VX0", "Bulk velocity (m/s)", 0.0);
62 RP::add(pop + "_Dispersion.VY0", "Bulk velocity (m/s)", 0.0);
63 RP::add(pop + "_Dispersion.VZ0", "Bulk velocity (m/s)", 0.0);
64 RP::add(pop + "_Dispersion.rho", "Number density (m^-3)", 1.0e7);
65 RP::add(pop + "_Dispersion.Temperature", "Temperature (K)", 2.0e6);
66 RP::add(pop + "_Dispersion.densityPertRelAmp", "Relative amplitude of the density perturbation", 0.1);
67 RP::add(pop + "_Dispersion.velocityPertAbsAmp", "Absolute amplitude of the velocity perturbation", 1.0e6);
68 }
69 }
70
73 typedef Readparameters RP;
75 RP::get("Dispersion.B0", this->B0);
76 RP::get("Dispersion.magXPertAbsAmp", this->magXPertAbsAmp);
77 RP::get("Dispersion.magYPertAbsAmp", this->magYPertAbsAmp);
78 RP::get("Dispersion.magZPertAbsAmp", this->magZPertAbsAmp);
79 RP::get("Dispersion.maxwCutoff", this->maxwCutoff);
80 RP::get("Dispersion.angleXY", this->angleXY);
81 RP::get("Dispersion.angleXZ", this->angleXZ);
82
83 // Per-population parameters
84 for(uint i=0; i< getObjectWrapper().particleSpecies.size(); i++) {
85 const std::string& pop = getObjectWrapper().particleSpecies[i].name;
87 RP::get(pop + "_Dispersion.VX0", sP.VX0);
88 RP::get(pop + "_Dispersion.VY0", sP.VY0);
89 RP::get(pop + "_Dispersion.VZ0", sP.VZ0);
90 RP::get(pop + "_Dispersion.rho", sP.DENSITY);
91 RP::get(pop + "_Dispersion.Temperature", sP.TEMPERATURE);
92 RP::get(pop + "_Dispersion.densityPertRelAmp", sP.densityPertRelAmp);
93 RP::get(pop + "_Dispersion.velocityPertAbsAmp", sP.velocityPertAbsAmp);
94
95 speciesParams.push_back(sP);
96 }
97 }
98
100 cuint& stage,
101 const dccrg::Dccrg<spatial_cell::SpatialCell, dccrg::Cartesian_Geometry>& mpiGrid,
104 ) const {
105 /*
106 if(hook::END_OF_TIME_STEP == stage) {
107 int myRank;
108 MPI_Comm_rank(MPI_COMM_WORLD,&myRank);
109
110 vector<Real> localRhom(P::xcells_ini, 0.0), outputRhom(P::xcells_ini, 0.0);
111
112 const vector<CellID>& cells = getLocalCells();
113
114 for(uint i=0; i<cells.size(); i++) {
115 if(cells[i] <= P::xcells_ini) {
116 localRhom[cells[i] - 1] = mpiGrid[cells[i]]->parameters[CellParams::RHOM];
117 }
118 }
119
120 MPI_Reduce(&(localRhom[0]), &(outputRhom[0]), P::xcells_ini, MPI_DOUBLE, MPI_SUM, MASTER_RANK, MPI_COMM_WORLD);
121
122 vector<Real> localPerBx(P::xcells_ini, 0.0);
123 vector<Real> localPerBy(P::xcells_ini, 0.0);
124 vector<Real> localPerBz(P::xcells_ini, 0.0);
125 vector<Real> outputPerBx(P::xcells_ini, 0.0);
126 vector<Real> outputPerBy(P::xcells_ini, 0.0);
127 vector<Real> outputPerBz(P::xcells_ini, 0.0);
128
129 const auto* localSize = &fsgrid.getLocalSize()[0];
130 const auto& localStart = fsgrid.getLocalStart();
131 for (auto x = 0; x < localSize[0]; ++x) {
132 const auto stencil = fsgrid.makeStencil(x, 0, 0);
133 localPerBx[x + localStart[0]] = perb[stencil.ooo()][fsgrids::bfield::PERBX];
134 localPerBy[x + localStart[0]] = perb[stencil.ooo()][fsgrids::bfield::PERBY];
135 localPerBz[x + localStart[0]] = perb[stencil.ooo()][fsgrids::bfield::PERBZ];
136 }
137
138 MPI_Reduce(&(localPerBx[0]), &(outputPerBx[0]), P::xcells_ini, MPI_DOUBLE, MPI_SUM, MASTER_RANK, MPI_COMM_WORLD);
139 MPI_Reduce(&(localPerBy[0]), &(outputPerBy[0]), P::xcells_ini, MPI_DOUBLE, MPI_SUM, MASTER_RANK, MPI_COMM_WORLD);
140 MPI_Reduce(&(localPerBz[0]), &(outputPerBz[0]), P::xcells_ini, MPI_DOUBLE, MPI_SUM, MASTER_RANK, MPI_COMM_WORLD);
141
142 if(myRank == MASTER_RANK) {
143 FILE* outputFile = fopen("perBxt.bin", "ab");
144 fwrite(&(outputPerBx[0]), sizeof(outputPerBx[0]), P::xcells_ini, outputFile);
145 fclose(outputFile);
146 outputFile = fopen("perByt.bin", "ab");
147 fwrite(&(outputPerBy[0]), sizeof(outputPerBy[0]), P::xcells_ini, outputFile);
148 fclose(outputFile);
149 outputFile = fopen("perBzt.bin", "ab");
150 fwrite(&(outputPerBz[0]), sizeof(outputPerBz[0]), P::xcells_ini, outputFile);
151 fclose(outputFile);
152 outputFile = fopen("rhomt.bin", "ab");
153 fwrite(&(outputRhom[0]), sizeof(outputRhom[0]), P::xcells_ini, outputFile);
154 fclose(outputFile);
155 }
156 }
157 */
158 }
159
161 const uint popID,
162 const uint nRequested
163 ) const {
165 const Real mass = getObjectWrapper().particleSpecies[popID].mass;
166 Real initT = sP.TEMPERATURE;
167 Real initRho = sP.DENSITY * (1.0 + sP.densityPertRelAmp * (0.5 - this->rndRho));
168 const Real initV0X = sP.VX0 + sP.velocityPertAbsAmp * (0.5 - this->rndVel[0]);
169 const Real initV0Y = sP.VY0 + sP.velocityPertAbsAmp * (0.5 - this->rndVel[1]);
170 const Real initV0Z = sP.VZ0 + sP.velocityPertAbsAmp * (0.5 - this->rndVel[2]);
171
172 // cerr << cell->parameters[CellParams::XCRD] << " " << this->rndRho << " " << this->rndVel[0] << " " << this->rndVel[1] << " " << this->rndVel[2] << endl;
173
174 #ifdef USE_GPU
177 #else
180 #endif
181 // Loop over blocks
182 Realf rhosum = 0;
184 {WID, WID, WID, nRequested},
185 ARCH_LOOP_LAMBDA (const uint i, const uint j, const uint k, const uint initIndex, Realf *lsum ) {
186 vmesh::GlobalID *GIDlist = vmesh->getGrid()->data();
187 Realf* bufferData = VBC->getData();
188 const vmesh::GlobalID blockGID = GIDlist[initIndex];
189 // Calculate parameters for new block
190 Real blockCoords[6];
191 vmesh->getBlockInfo(blockGID,&blockCoords[0]);
192 creal vxBlock = blockCoords[0];
193 creal vyBlock = blockCoords[1];
194 creal vzBlock = blockCoords[2];
195 creal dvxCell = blockCoords[3];
196 creal dvyCell = blockCoords[4];
197 creal dvzCell = blockCoords[5];
198 ARCH_INNER_BODY(i, j, k, initIndex, lsum) {
199 creal vx = vxBlock + (i+0.5)*dvxCell - initV0X;
200 creal vy = vyBlock + (j+0.5)*dvyCell - initV0Y;
201 creal vz = vzBlock + (k+0.5)*dvzCell - initV0Z;
202 Realf value = MaxwellianPhaseSpaceDensity(vx,vy,vz,initT,initRho,mass);
203 bufferData[initIndex*WID3 + k*WID2 + j*WID + i] = value;
204 //lsum[0] += value;
205 };
206 }, rhosum);
207 return rhosum;
208 }
209
211 std::default_random_engine rndState;
212 setRandomCellSeed(cell,rndState);
213
214 this->rndRho=getRandomNumber(rndState);
215
216 this->rndVel[0]=getRandomNumber(rndState);
217 this->rndVel[1]=getRandomNumber(rndState);
218 this->rndVel[2]=getRandomNumber(rndState);
219 }
220
225 ) {
226 ConstantField bgField;
227 bgField.initialize(this->B0 * cos(this->angleXY) * cos(this->angleXZ),
228 this->B0 * sin(this->angleXY) * cos(this->angleXZ),
229 this->B0 * sin(this->angleXZ));
230
231 setBackgroundField(bgField, bgb, technical, fsgrid);
232
233 if(!P::isRestart) {
234 // local copies for lambda capture
235 const auto magXPertAbsAmp_l = this->magXPertAbsAmp;
236 const auto magYPertAbsAmp_l = this->magYPertAbsAmp;
237 const auto magZPertAbsAmp_l = this->magZPertAbsAmp;
238 const auto seed = this->seed;
239
240 fsgrid.parallel_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
241 phiprof::initializeTimer("setProjectBField"), technical,
242 [=](const fsgrid::Coordinates &coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
243 const std::array<Real, 3> xyz = coordinates.getPhysicalCoords(stencil.i, stencil.j, stencil.k);
244 auto& cell = perb[stencil.ooo()];
245
246 const auto seedmodifier = coordinates.globalIDFromLocalCoordinates(stencil.i, stencil.j, stencil.k);
247 std::default_random_engine rndState_l;
248 rndState_l.seed(seed+seedmodifier);
249 Real rndBuffer[3];
250 rndBuffer[0] = std::uniform_real_distribution<>(-0.5,0.5)(rndState_l);
251 rndBuffer[1] = std::uniform_real_distribution<>(-0.5,0.5)(rndState_l);
252 rndBuffer[2] = std::uniform_real_distribution<>(-0.5,0.5)(rndState_l);
253
254 cell[fsgrids::bfield::PERBX] = magXPertAbsAmp_l * rndBuffer[0];
255 cell[fsgrids::bfield::PERBY] = magYPertAbsAmp_l * rndBuffer[1];
256 cell[fsgrids::bfield::PERBZ] = magZPertAbsAmp_l * rndBuffer[2];
257 });
258 }
259 }
260} // namespace projects
for i
Definition Dispersion.m:24
#define ARCH_INNER_BODY(...)
#define ARCH_LOOP_LAMBDA
void setBackgroundField(const FieldFunction &bgFunction, fsgrids::bgbspan bgb, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid, bool append)
void initialize(const double Bx, const double By, const double Bz)
virtual void calcCellParameters(spatial_cell::SpatialCell *cell, creal &t) override
virtual void setProjectBField(fsgrids::perbspan perb, fsgrids::bgbspan bgb, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid) override
static void addParameters(void)
virtual Realf fillPhaseSpace(spatial_cell::SpatialCell *cell, const uint popID, const uint nRequested) const override
virtual bool initialize(void) override
static Real rndVel[3]
Definition Dispersion.h:77
static Real rndRho
Definition Dispersion.h:77
virtual void getParameters(void) override
std::vector< DispersionSpeciesParameters > speciesParams
Definition Dispersion.h:74
virtual void hook(cuint &stage, const dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, fsgrids::perbspan perb, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid) const override
Real getRandomNumber(std::default_random_engine &randGen) const
Definition project.cpp:317
virtual bool initialize()
Definition project.cpp:113
virtual void getParameters()
Definition project.cpp:103
void setRandomCellSeed(spatial_cell::SpatialCell *cell, std::default_random_engine &randGen) const
Definition project.cpp:336
vmesh::VelocityMesh * get_velocity_mesh(const size_t &popID)
vmesh::VelocityBlockContainer * get_velocity_blocks(const size_t &popID)
vmesh::VelocityBlockContainer * dev_get_velocity_blocks(const size_t &popID)
vmesh::VelocityMesh * dev_get_velocity_mesh(const size_t &popID)
#define WID
Definition common.h:514
const int WID3
Definition common.h:517
const int WID2
Definition common.h:516
const uint32_t cuint
Definition definitions.h:50
float Real
Definition definitions.h:41
float Realf
Definition definitions.h:33
fsgrid::FsGrid< FS_STENCIL_WIDTH > FieldSolverGrid
Definition definitions.h:78
const float creal
Definition definitions.h:42
const int j
const int k
ObjectWrapper & getObjectWrapper()
Definition main.cpp:33
static void parallel_reduce(const uint(&limits)[NDim], Lambda loop_body, T &sum)
std::span< std::array< Real, fsgrids::bfield::N_BFIELD > > perbspan
Definition common.h:434
std::span< technical > technicalspan
Definition common.h:452
std::span< std::array< Real, bgbfield::N_BGB > > bgbspan
Definition common.h:444
@ PERBY
Definition common.h:276
@ PERBZ
Definition common.h:277
@ PERBX
Definition common.h:275
ARCH_HOSTDEV Realf MaxwellianPhaseSpaceDensity(creal &vx, creal &vy, creal &vz, creal &T, creal &rho, creal &mass)
Definition project.h:45
uint32_t GlobalID
Definition definitions.h:59
std::vector< species::Species > particleSpecies
static bool isRestart
Definition parameters.h:176