Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
LossCone.cpp
Go to the documentation of this file.
1/*
2 * This file is part of Vlasiator.
3 * Copyright 2010-2016 Finnish Meteorological Institute
4 * 2017-2025 University of Helsinki
5 *
6 * For details of usage, see the COPYING file and read the "Rules of the Road"
7 * at http://www.physics.helsinki.fi/vlasiator/
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24#include <cstdlib>
25#include <iostream>
26#include <iomanip>
27#include <cmath>
28
29#include "../../common.h"
34
35#include "LossCone.h"
36
37using namespace spatial_cell;
38
40
41
42namespace projects {
46
48 typedef Readparameters RP;
49 RP::add("LossCone.BX0", "Background field value (T)", 1.0e-9);
50 RP::add("LossCone.BY0", "Background field value (T)", 2.0e-9);
51 RP::add("LossCone.BZ0", "Background field value (T)", 3.0e-9);
52 RP::add("LossCone.magXPertAbsAmp", "Amplitude of the magnetic perturbation along x", 1.0e-9);
53 RP::add("LossCone.magYPertAbsAmp", "Amplitude of the magnetic perturbation along y", 1.0e-9);
54 RP::add("LossCone.magZPertAbsAmp", "Amplitude of the magnetic perturbation along z", 1.0e-9);
55
56 // Per-population parameters
57 for(uint i=0; i< getObjectWrapper().particleSpecies.size(); i++) {
58 const std::string& pop = getObjectWrapper().particleSpecies[i].name;
59
60 RP::add(pop + "_LossCone.rho", "Number density (m^-3)", 1.0e7);
61 RP::add(pop + "_LossCone.TemperatureX", "Temperature (K)", 2.0e6);
62 RP::add(pop + "_LossCone.TemperatureY", "Temperature (K)", 2.0e6);
63 RP::add(pop + "_LossCone.TemperatureZ", "Temperature (K)", 2.0e6);
64 RP::add(pop + "_LossCone.densityPertRelAmp", "Amplitude factor of the density perturbation", 0.1);
65 RP::add(pop + "_LossCone.VX0", "Initial bulk velocity in x-direction", 0.0);
66 RP::add(pop + "_LossCone.VY0", "Initial bulk velocity in y-direction", 0.0);
67 RP::add(pop + "_LossCone.VZ0", "Initial bulk velocity in z-direction", 0.0);
68 RP::add(pop + "_LossCone.velocityPertAbsAmp", "Amplitude of the velocity perturbation", 1.0e6);
69 RP::add(pop + "_LossCone.muLimit", "Cutoff value for pitch-cosine mu positive and negative)", 0.5);
70 }
71 }
72
75 typedef Readparameters RP;
77 RP::get("LossCone.BX0", this->BX0);
78 RP::get("LossCone.BY0", this->BY0);
79 RP::get("LossCone.BZ0", this->BZ0);
80 RP::get("LossCone.magXPertAbsAmp", this->magXPertAbsAmp);
81 RP::get("LossCone.magYPertAbsAmp", this->magYPertAbsAmp);
82 RP::get("LossCone.magZPertAbsAmp", this->magZPertAbsAmp);
83
84 // Per-population parameters
85 for(uint i=0; i< getObjectWrapper().particleSpecies.size(); i++) {
86 const std::string& pop = getObjectWrapper().particleSpecies[i].name;
88 RP::get(pop + "_LossCone.rho", sP.DENSITY);
89 RP::get(pop + "_LossCone.VX0", sP.V0[0]);
90 RP::get(pop + "_LossCone.VY0", sP.V0[1]);
91 RP::get(pop + "_LossCone.VZ0", sP.V0[2]);
92 RP::get(pop + "_LossCone.TemperatureX", sP.TEMPERATUREX);
93 RP::get(pop + "_LossCone.TemperatureY", sP.TEMPERATUREY);
94 RP::get(pop + "_LossCone.TemperatureZ", sP.TEMPERATUREZ);
95 RP::get(pop + "_LossCone.densityPertRelAmp", sP.densityPertRelAmp);
96 RP::get(pop + "_LossCone.velocityPertAbsAmp", sP.velocityPertAbsAmp);
97 RP::get(pop + "_LossCone.muLimit", sP.muLimit);
98 speciesParams.push_back(sP);
99 }
100 }
101
103 const uint popID,
104 const uint nRequested
105 ) const {
106 const LossConeSpeciesParameters& sP = speciesParams[popID];
107 // Fetch spatial cell center coordinates
108 // const Real x = cell->parameters[CellParams::XCRD] + 0.5*cell->parameters[CellParams::DX];
109 // const Real y = cell->parameters[CellParams::YCRD] + 0.5*cell->parameters[CellParams::DY];
110 // const Real z = cell->parameters[CellParams::ZCRD] + 0.5*cell->parameters[CellParams::DZ];
111
112 const Real mass = getObjectWrapper().particleSpecies[popID].mass;
113 const Real initRho = sP.DENSITY * (1.0 + sP.densityPertRelAmp * (0.5 - rndRho));
114 const Real initTx = sP.TEMPERATUREX;
115 const Real initTy = sP.TEMPERATUREY;
116 const Real initTz = sP.TEMPERATUREZ;
117 const Real initV0X = sP.V0[0] + sP.velocityPertAbsAmp * (0.5 - rndVel[0] );
118 const Real initV0Y = sP.V0[1] + sP.velocityPertAbsAmp * (0.5 - rndVel[1] );
119 const Real initV0Z = sP.V0[2] + sP.velocityPertAbsAmp * (0.5 - rndVel[2] );
120 const Real muLimit = abs(sP.muLimit);
121
122 #ifdef USE_GPU
125 #else
128 #endif
129 // Loop over blocks
130 Realf rhosum = 0;
132 {WID, WID, WID, nRequested},
133 ARCH_LOOP_LAMBDA (const uint i, const uint j, const uint k, const uint initIndex, Realf *lsum ) {
134 vmesh::GlobalID *GIDlist = vmesh->getGrid()->data();
135 Realf* bufferData = VBC->getData();
136 const vmesh::GlobalID blockGID = GIDlist[initIndex];
137 // Calculate parameters for new block
138 Real blockCoords[6];
139 vmesh->getBlockInfo(blockGID,&blockCoords[0]);
140 creal vxBlock = blockCoords[0];
141 creal vyBlock = blockCoords[1];
142 creal vzBlock = blockCoords[2];
143 creal dvxCell = blockCoords[3];
144 creal dvyCell = blockCoords[4];
145 creal dvzCell = blockCoords[5];
146 ARCH_INNER_BODY(i, j, k, initIndex, lsum) {
147 creal vx = vxBlock + (i+0.5)*dvxCell - initV0X;
148 creal vy = vyBlock + (j+0.5)*dvyCell - initV0Y;
149 creal vz = vzBlock + (k+0.5)*dvzCell - initV0Z;
150
151 // TODO: Use Eigen vectors, get magnetic field as well and calculate components from that
152 Real vpara = vx;
153 // Real vperp = sqrt(vy*vy + vz*vz);
154 Real modv = sqrt(vx*vx + vy*vy + vz*vz);
155 Real mu = vpara / modv;
156
157 Real value = 0;
158 // Only fill outside losscone
159 if (mu > -muLimit && mu < muLimit) {
160 value += TriMaxwellianPhaseSpaceDensity(vx,vy,vz,initTx,initTy,initTz,initRho,mass);
161 }
162 bufferData[initIndex*WID3 + k*WID2 + j*WID + i] = value;
163 //lsum[0] += value;
164 };
165 }, rhosum);
166 return rhosum;
167 }
168
169 /* Evaluates local SpatialCell properties for the project and population,
170 then evaluates the phase-space density at the given coordinates.
171 Used as a probe for projectTriAxisSearch.
172 */
174 const uint popID,
175 Real vx_in, Real vy_in, Real vz_in
176 ) const {
177 const LossConeSpeciesParameters& sP = speciesParams[popID];
178 // Fetch spatial cell center coordinates
179 // const Real x = cell->parameters[CellParams::XCRD] + 0.5*cell->parameters[CellParams::DX];
180 // const Real y = cell->parameters[CellParams::YCRD] + 0.5*cell->parameters[CellParams::DY];
181 // const Real z = cell->parameters[CellParams::ZCRD] + 0.5*cell->parameters[CellParams::DZ];
182
183 const Real mass = getObjectWrapper().particleSpecies[popID].mass;
184 const Real initRho = sP.DENSITY * (1.0 + sP.densityPertRelAmp * (0.5 - rndRho));
185 const Real initTx = sP.TEMPERATUREX;
186 const Real initTy = sP.TEMPERATUREY;
187 const Real initTz = sP.TEMPERATUREZ;
188 const Real initV0X = sP.V0[0] + sP.velocityPertAbsAmp * (0.5 - rndVel[0] );
189 const Real initV0Y = sP.V0[1] + sP.velocityPertAbsAmp * (0.5 - rndVel[1] );
190 const Real initV0Z = sP.V0[2] + sP.velocityPertAbsAmp * (0.5 - rndVel[2] );
191 const Real muLimit = abs(sP.muLimit);
192 creal vx = vx_in - initV0X;
193 creal vy = vy_in - initV0Y;
194 creal vz = vz_in - initV0Z;
195
196 // Probe function should not account for mu Limit
197 Real value = TriMaxwellianPhaseSpaceDensity(vx,vy,vz,initTx,initTy,initTz,initRho,mass);
198 return value;
199 }
200
202 Real* cellParams = cell->get_cell_parameters();
203 creal x = cellParams[CellParams::XCRD];
204 creal dx = cellParams[CellParams::DX];
205 creal y = cellParams[CellParams::YCRD];
206 creal dy = cellParams[CellParams::DY];
207 creal z = cellParams[CellParams::ZCRD];
208 creal dz = cellParams[CellParams::DZ];
209
210 CellID cellID = (int) ((x - Parameters::xmin) / dx) +
211 (int) ((y - Parameters::ymin) / dy) * Parameters::xcells_ini +
213
214 std::default_random_engine rndState;
215 setRandomCellSeed(cell,rndState);
216
217 this->rndRho=getRandomNumber(rndState);
218
219 this->rndVel[0]=getRandomNumber(rndState);
220 this->rndVel[1]=getRandomNumber(rndState);
221 this->rndVel[2]=getRandomNumber(rndState);
222 }
223
227 fsgrids::technicalspan technical,
229 ) {
230 ConstantField bgField;
231 bgField.initialize(this->BX0,
232 this->BY0,
233 this->BZ0);
234
235 setBackgroundField(bgField, bgb, technical, fsgrid);
236
237 if(!P::isRestart) {
238 // local copies for lambda capture
239 const auto magXPertAbsAmp_l = this->magXPertAbsAmp;
240 const auto magYPertAbsAmp_l = this->magYPertAbsAmp;
241 const auto magZPertAbsAmp_l = this->magZPertAbsAmp;
242 const auto seed = this->seed;
243
244 fsgrid.parallel_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
245 phiprof::initializeTimer("setProjectBField"), technical,
246 [=](const fsgrid::Coordinates &coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
247 auto& cell = perb[stencil.ooo()];
248
249 const auto seedmodifier = coordinates.globalIDFromLocalCoordinates(stencil.i, stencil.j, stencil.k);
250 std::default_random_engine rndState_l;
251 rndState_l.seed(seed+seedmodifier);
252 Real rndBuffer[3];
253 rndBuffer[0] = std::uniform_real_distribution<>(-0.5,0.5)(rndState_l);
254 rndBuffer[1] = std::uniform_real_distribution<>(-0.5,0.5)(rndState_l);
255 rndBuffer[2] = std::uniform_real_distribution<>(-0.5,0.5)(rndState_l);
256
257 cell[fsgrids::bfield::PERBX] = magXPertAbsAmp_l * rndBuffer[0];
258 cell[fsgrids::bfield::PERBY] = magYPertAbsAmp_l * rndBuffer[1];
259 cell[fsgrids::bfield::PERBZ] = magZPertAbsAmp_l * rndBuffer[2];
260
261 });
262 }
263 }
264
265 std::vector<std::array<Real, 3> > LossCone::getV0(
266 creal x,
267 creal y,
268 creal z,
269 const uint popID
270 ) const {
271 std::array<Real, 3> V0 {{0.0, 0.0, 0.0}};
272 std::vector<std::array<Real, 3> > centerPoints;
273 centerPoints.push_back(V0);
274 return centerPoints;
275 }
276
277} // namespace projects
for i
Definition Dispersion.m:24
dx
Definition Dispersion.m:38
sqrt(1.0+vA *vA/(c *c))) % Ion-acoustic wave cS
#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 ~LossCone()
Definition LossCone.cpp:44
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...
Definition LossCone.cpp:265
static Real rndRho
Definition LossCone.h:82
virtual bool initialize(void) override
Definition LossCone.cpp:45
virtual void calcCellParameters(spatial_cell::SpatialCell *cell, creal &t) override
Definition LossCone.cpp:201
virtual Realf probePhaseSpace(spatial_cell::SpatialCell *cell, const uint popID, Real vx_in, Real vy_in, Real vz_in) const override
Definition LossCone.cpp:173
virtual Realf fillPhaseSpace(spatial_cell::SpatialCell *cell, const uint popID, const uint nRequested) const override
Definition LossCone.cpp:102
std::vector< LossConeSpeciesParameters > speciesParams
Definition LossCone.h:80
static void addParameters(void)
Definition LossCone.cpp:47
static Real rndVel[3]
Definition LossCone.h:82
virtual void setProjectBField(fsgrids::perbspan perb, fsgrids::bgbspan bgb, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid) override
Definition LossCone.cpp:224
virtual void getParameters(void) override
Definition LossCone.cpp:73
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
uint64_t CellID
Definition definitions.h:54
float Realf
Definition definitions.h:33
fsgrid::FsGrid< FS_STENCIL_WIDTH > FieldSolverGrid
Definition definitions.h:78
const float creal
Definition definitions.h:42
const Real mu
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 Real ymin
Definition parameters.h:40
static uint ycells_ini
Definition parameters.h:49
static uint xcells_ini
Definition parameters.h:48
static Real xmin
Definition parameters.h:38
static bool isRestart
Definition parameters.h:176
static Real zmin
Definition parameters.h:42
static ARCH_HOSTDEV VecSimple< T > abs(const VecSimple< T > &l)