Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
MultiPeak.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"
33
34
35#include "MultiPeak.h"
36
37using namespace std;
38using namespace spatial_cell;
39
40
42
43namespace projects {
45
47
49 return Project::initialize();
50 }
51
53 typedef Readparameters RP;
54
55 RP::add("MultiPeak.Bx", "Magnetic field x component (T)", 0.0);
56 RP::add("MultiPeak.By", "Magnetic field y component (T)", 0.0);
57 RP::add("MultiPeak.Bz", "Magnetic field z component (T)", 0.0);
58 RP::add("MultiPeak.dBx", "Magnetic field x component cosine perturbation amplitude (T)", 0.0);
59 RP::add("MultiPeak.dBy", "Magnetic field y component cosine perturbation amplitude (T)", 0.0);
60 RP::add("MultiPeak.dBz", "Magnetic field z component cosine perturbation amplitude (T)", 0.0);
61 RP::add("MultiPeak.magXPertAbsAmp", "Absolute amplitude of the random magnetic perturbation along x (T)", 1.0e-9);
62 RP::add("MultiPeak.magYPertAbsAmp", "Absolute amplitude of the random magnetic perturbation along y (T)", 1.0e-9);
63 RP::add("MultiPeak.magZPertAbsAmp", "Absolute amplitude of the random magnetic perturbation along z (T)", 1.0e-9);
64 RP::add("MultiPeak.lambda", "B cosine perturbation wavelength (m)", 1.0);
65 RP::add("MultiPeak.densityModel","Which spatial density model is used?",string("uniform"));
66
67 // Per-population parameters
68 for(uint i=0; i< getObjectWrapper().particleSpecies.size(); i++) {
69 const std::string& pop = getObjectWrapper().particleSpecies[i].name;
70 RP::add(pop+"_MultiPeak.n", "Number of peaks to create", 0);
71 RP::addComposing(pop+"_MultiPeak.rho", "Number density (m^-3)");
72 RP::addComposing(pop+"_MultiPeak.Tx", "Temperature (K)");
73 RP::addComposing(pop+"_MultiPeak.Ty", "Temperature");
74 RP::addComposing(pop+"_MultiPeak.Tz", "Temperature");
75 RP::addComposing(pop+"_MultiPeak.Vx", "Bulk velocity x component (m/s)");
76 RP::addComposing(pop+"_MultiPeak.Vy", "Bulk velocity y component (m/s)");
77 RP::addComposing(pop+"_MultiPeak.Vz", "Bulk velocity z component (m/s)");
78 RP::addComposing(pop+"_MultiPeak.rhoPertAbsAmp", "Absolute amplitude of the density perturbation");
79 }
80 }
81
83
84 typedef Readparameters RP;
86 RP::get("MultiPeak.Bx", this->Bx);
87 RP::get("MultiPeak.By", this->By);
88 RP::get("MultiPeak.Bz", this->Bz);
89 RP::get("MultiPeak.magXPertAbsAmp", this->magXPertAbsAmp);
90 RP::get("MultiPeak.magYPertAbsAmp", this->magYPertAbsAmp);
91 RP::get("MultiPeak.magZPertAbsAmp", this->magZPertAbsAmp);
92 RP::get("MultiPeak.dBx", this->dBx);
93 RP::get("MultiPeak.dBy", this->dBy);
94 RP::get("MultiPeak.dBz", this->dBz);
95 RP::get("MultiPeak.lambda", this->lambda);
96
97 // Per-population parameters
98 for(uint i=0; i< getObjectWrapper().particleSpecies.size(); i++) {
99 const std::string& pop = getObjectWrapper().particleSpecies[i].name;
100
102 RP::get(pop + "_MultiPeak.n", sP.numberOfPeaks);
103 RP::get(pop + "_MultiPeak.rho",sP.rho);
104 RP::get(pop + "_MultiPeak.Tx", sP.Tx);
105 RP::get(pop + "_MultiPeak.Ty", sP.Ty);
106 RP::get(pop + "_MultiPeak.Tz", sP.Tz);
107 RP::get(pop + "_MultiPeak.Vx", sP.Vx);
108 RP::get(pop + "_MultiPeak.Vy", sP.Vy);
109 RP::get(pop + "_MultiPeak.Vz", sP.Vz);
110
111 RP::get(pop + "_MultiPeak.rhoPertAbsAmp", sP.rhoPertAbsAmp);
112 if(!sP.isConsistent()) {
113 cerr << "You should define all parameters (MultiPeak.rho, MultiPeak.Tx, MultiPeak.Ty, MultiPeak.Tz, MultiPeak.Vx, MultiPeak.Vy, MultiPeak.Vz, MultiPeak.rhoPertAbsAmp) for all " << sP.numberOfPeaks << " peaks of population " << pop << "." << endl;
114 abort();
115 }
116
117 speciesParams.push_back(sP);
118 }
119
120 string densModelString;
121 RP::get("MultiPeak.densityModel",densModelString);
122
123 if (densModelString == "uniform") densityModel = Uniform;
124 else if (densModelString == "testcase") densityModel = TestCase;
125 }
126
128 const uint popID,
129 const uint nRequested
130 ) const {
131 const MultiPeakSpeciesParameters& sP = speciesParams[popID];
132 // Fetch spatial cell center coordinates
133 const Real x = cell->parameters[CellParams::XCRD] + 0.5*cell->parameters[CellParams::DX];
134 const Real y = cell->parameters[CellParams::YCRD] + 0.5*cell->parameters[CellParams::DY];
135 const Real z = cell->parameters[CellParams::ZCRD] + 0.5*cell->parameters[CellParams::DZ];
136
137 const Real mass = getObjectWrapper().particleSpecies[popID].mass;
138
139 Real rhoFactor = 1.0;
140 switch (densityModel) {
141 case Uniform:
142 rhoFactor = 1.0;
143 break;
144 case TestCase:
145 rhoFactor = 1.0;
146 if ((x >= 3.9e5 && x <= 6.1e5) && (y >= 3.9e5 && y <= 6.1e5)) {
147 rhoFactor = 1.5;
148 }
149 break;
150 default:
151 rhoFactor = 1.0;
152 break;
153 }
154 // device-accessable variables
155 const Real rhoRndDev = rhoRnd;
156 uint nPeaks = sP.numberOfPeaks;
157 #define MAXPEAKS 10
158 if (nPeaks > MAXPEAKS) {
159 std::cerr<<" ERROR in "<<__FILE__<<":"<<__LINE__<<": max number of supported peaks is "<<MAXPEAKS<<" (got "<<nPeaks<<")"<<std::endl;
160 std::cerr<<" Truncating peaks at "<<MAXPEAKS<<"!"<<std::endl;
161 nPeaks = MAXPEAKS;
162 }
163 Real VxDev[MAXPEAKS], VyDev[MAXPEAKS], VzDev[MAXPEAKS], TxDev[MAXPEAKS], TyDev[MAXPEAKS], TzDev[MAXPEAKS], rhoDev[MAXPEAKS], rhoPertAbsAmpDev[MAXPEAKS];
164 for (uint i=0; i<MAXPEAKS; ++i) {
165 if (i >= nPeaks) {
166 break;
167 }
168 VxDev[i] = sP.Vx[i];
169 VyDev[i] = sP.Vy[i];
170 VzDev[i] = sP.Vz[i];
171 TxDev[i] = sP.Tx[i];
172 TyDev[i] = sP.Ty[i];
173 TzDev[i] = sP.Tz[i];
174 rhoDev[i] = sP.rho[i];
175 rhoPertAbsAmpDev[i] = sP.rhoPertAbsAmp[i];
176 }
177
178 #ifdef USE_GPU
181 #else
184 #endif
185 // Loop over blocks
186 Realf rhosum = 0;
188 {WID, WID, WID, nRequested},
189 ARCH_LOOP_LAMBDA (const uint i, const uint j, const uint k, const uint initIndex, Realf *lsum ) {
190 vmesh::GlobalID *GIDlist = vmesh->getGrid()->data();
191 Realf* bufferData = VBC->getData();
192 const vmesh::GlobalID blockGID = GIDlist[initIndex];
193 // Calculate parameters for new block
194 Real blockCoords[6];
195 vmesh->getBlockInfo(blockGID,&blockCoords[0]);
196 creal vxBlock = blockCoords[0];
197 creal vyBlock = blockCoords[1];
198 creal vzBlock = blockCoords[2];
199 creal dvxCell = blockCoords[3];
200 creal dvyCell = blockCoords[4];
201 creal dvzCell = blockCoords[5];
202 ARCH_INNER_BODY(i, j, k, initIndex, lsum) {
203 Realf value = 0;
204 for (uint ipeak=0; ipeak<nPeaks; ++ipeak) {
205 creal vx = vxBlock + (i+0.5)*dvxCell - VxDev[ipeak];
206 creal vy = vyBlock + (j+0.5)*dvyCell - VyDev[ipeak];
207 creal vz = vzBlock + (k+0.5)*dvzCell - VzDev[ipeak];
209 vx,vy,vz,
210 TxDev[ipeak],TyDev[ipeak],TzDev[ipeak],
211 (rhoDev[ipeak] + rhoPertAbsAmpDev[ipeak] * rhoRndDev) * rhoFactor,
212 mass);
213 }
214 bufferData[initIndex*WID3 + k*WID2 + j*WID + i] = value;
215 //lsum[0] += value;
216 };
217 }, rhosum);
218 return rhosum;
219 }
220
221 /* Evaluates local SpatialCell properties for the project and population,
222 then evaluates the phase-space density at the given coordinates.
223 Used as a probe for projectTriAxisSearch.
224 */
226 const uint popID,
227 Real vx_in, Real vy_in, Real vz_in
228 ) const {
229 const MultiPeakSpeciesParameters& sP = speciesParams[popID];
230 // Fetch spatial cell center coordinates
231 const Real x = cell->parameters[CellParams::XCRD] + 0.5*cell->parameters[CellParams::DX];
232 const Real y = cell->parameters[CellParams::YCRD] + 0.5*cell->parameters[CellParams::DY];
233 const Real z = cell->parameters[CellParams::ZCRD] + 0.5*cell->parameters[CellParams::DZ];
234
235 const Real mass = getObjectWrapper().particleSpecies[popID].mass;
236
237 Real rhoFactor = 1.0;
238 switch (densityModel) {
239 case Uniform:
240 rhoFactor = 1.0;
241 break;
242 case TestCase:
243 rhoFactor = 1.0;
244 if ((x >= 3.9e5 && x <= 6.1e5) && (y >= 3.9e5 && y <= 6.1e5)) {
245 rhoFactor = 1.5;
246 }
247 break;
248 default:
249 rhoFactor = 1.0;
250 break;
251 }
252
253 Realf value = 0;
254 for (uint i=0; i<sP.numberOfPeaks; ++i) {
255 creal vx = vx_in - sP.Vx[i];
256 creal vy = vy_in - sP.Vy[i];
257 creal vz = vz_in - sP.Vz[i];
259 vx,vy,vz,
260 sP.Tx[i],sP.Ty[i],sP.Tz[i],
261 sP.rho[i] + sP.rhoPertAbsAmp[i] * rhoRnd * rhoFactor,
262 mass);
263 }
264 return value;
265 }
266
268 std::default_random_engine rndState;
269 setRandomCellSeed(cell,rndState);
270 rhoRnd = 0.5 - getRandomNumber(rndState);
271 }
272
277 ) {
278 ConstantField bgField;
279 bgField.initialize(this->Bx,
280 this->By,
281 this->Bz);
282
283 setBackgroundField(bgField, bgb, technical, fsgrid);
284
285 if(!P::isRestart) {
286 // local copies for lambda capture
287 const auto dBx_l = this->dBx;
288 const auto dBy_l = this->dBy;
289 const auto dBz_l = this->dBz;
290 const auto lambda_l = this->lambda;
291 const auto magXPertAbsAmp_l = this->magXPertAbsAmp;
292 const auto magYPertAbsAmp_l = this->magYPertAbsAmp;
293 const auto magZPertAbsAmp_l = this->magZPertAbsAmp;
294 const auto seed = this->seed;
295
296 fsgrid.parallel_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
297 phiprof::initializeTimer("setProjectBField-loop"), technical,
298 [=](const fsgrid::Coordinates &coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
299 const std::array<Real, 3> xyz = coordinates.getPhysicalCoords(stencil.i, stencil.j, stencil.k);
300 auto& cell = perb[stencil.ooo()];
301
302 const auto seedmodifier = coordinates.globalIDFromLocalCoordinates(stencil.i, stencil.j, stencil.k);
303 std::default_random_engine rndState_l;
304 rndState_l.seed(seed+seedmodifier);
305 Real rndBuffer[3];
306 rndBuffer[0] = std::uniform_real_distribution<>(-0.5,0.5)(rndState_l);
307 rndBuffer[1] = std::uniform_real_distribution<>(-0.5,0.5)(rndState_l);
308 rndBuffer[2] = std::uniform_real_distribution<>(-0.5,0.5)(rndState_l);
309
310 cell[fsgrids::bfield::PERBX] = dBx_l * cos(2.0 * M_PI * xyz[0] / lambda_l) + magXPertAbsAmp_l * rndBuffer[0];
311 cell[fsgrids::bfield::PERBY] = dBy_l * sin(2.0 * M_PI * xyz[0] / lambda_l) + magYPertAbsAmp_l * rndBuffer[1];
312 cell[fsgrids::bfield::PERBZ] = dBz_l * cos(2.0 * M_PI * xyz[0] / lambda_l) + magZPertAbsAmp_l * rndBuffer[2];
313 });
314 }
315 }
316
317 std::vector<std::array<Real, 3> > MultiPeak::getV0(
318 creal x,
319 creal y,
320 creal z,
321 const uint popID
322 ) const {
323 const MultiPeakSpeciesParameters& sP = speciesParams[popID];
324 vector<std::array<Real, 3> > centerPoints;
325 for(uint i=0; i<sP.numberOfPeaks; i++) {
326 array<Real, 3> point {{sP.Vx[i], sP.Vy[i], sP.Vz[i]}};
327 centerPoints.push_back(point);
328 }
329 return centerPoints;
330 }
331
332}// namespace projects
for i
Definition Dispersion.m:24
#define MAXPEAKS
#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 std::vector< std::array< Real, 3 > > getV0(creal x, creal y, creal z, const uint popID) const override
Return a vector containing the velocity coordinate of the centre of each ion population in the distri...
static void addParameters(void)
Definition MultiPeak.cpp:52
static Real rhoRnd
Definition MultiPeak.h:85
virtual void calcCellParameters(spatial_cell::SpatialCell *cell, creal &t) override
std::vector< MultiPeakSpeciesParameters > speciesParams
Definition MultiPeak.h:70
virtual Realf fillPhaseSpace(spatial_cell::SpatialCell *cell, const uint popID, const uint nRequested) const override
enum projects::MultiPeak::densitymodel densityModel
virtual bool initialize(void) override
Definition MultiPeak.cpp:48
virtual Realf probePhaseSpace(spatial_cell::SpatialCell *cell, const uint popID, Real vx_in, Real vy_in, Real vz_in) const override
virtual void setProjectBField(fsgrids::perbspan perb, fsgrids::bgbspan bgb, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid) override
virtual void getParameters(void) override
Definition MultiPeak.cpp:82
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)
std::array< Real, CellParams::N_SPATIAL_CELL_PARAMS > parameters
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 TriMaxwellianPhaseSpaceDensity(creal &vx, creal &vy, creal &vz, creal &Tx, creal &Ty, creal &Tz, creal &rho, creal &mass)
Definition project.h:66
uint32_t GlobalID
Definition definitions.h:59
std::vector< species::Species > particleSpecies
static bool isRestart
Definition parameters.h:176
std::vector< Real > rhoPertAbsAmp
Definition MultiPeak.h:41