Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
KHB.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 <cmath>
26
27#include "../../common.h"
31
32#include "KHB.h"
33
34namespace projects {
35 using namespace std;
38
39 bool KHB::initialize(void) {return Project::initialize();}
40
42 typedef Readparameters RP;
43 RP::add("KHB.P", "Constant total pressure (thermal+magnetic), used to determine the temperature profile (Pa)", 0.0);
44 RP::add("KHB.rho1", "Number density, this->TOP state (m^-3)", 0.0);
45 RP::add("KHB.rho2", "Number density, this->BOTTOM state (m^-3)", 0.0);
46 RP::add("KHB.Vx1", "Bulk velocity x component, this->TOP state (m/s)", 0.0);
47 RP::add("KHB.Vx2", "Bulk velocity x component, this->BOTTOM state (m/s)", 0.0);
48 RP::add("KHB.Vy1", "Bulk velocity y component, this->TOP state (m/s)", 0.0);
49 RP::add("KHB.Vy2", "Bulk velocity y component, this->BOTTOM state (m/s)", 0.0);
50 RP::add("KHB.Vz1", "Bulk velocity z component, this->TOP state (m/s)", 0.0);
51 RP::add("KHB.Vz2", "Bulk velocity z component, this->BOTTOM state (m/s)", 0.0);
52 RP::add("KHB.Bx1", "Magnetic field x component, this->TOP state (T)", 0.0);
53 RP::add("KHB.Bx2", "Magnetic field x component, this->BOTTOM state (T)", 0.0);
54 RP::add("KHB.By1", "Magnetic field y component, this->TOP state (T)", 0.0);
55 RP::add("KHB.By2", "Magnetic field y component, this->BOTTOM state (T)", 0.0);
56 RP::add("KHB.Bz1", "Magnetic field z component, this->TOP state (T)", 0.0);
57 RP::add("KHB.Bz2", "Magnetic field z component, this->BOTTOM state (T)", 0.0);
58 RP::add("KHB.lambda", "Initial perturbation wavelength (m)", 0.0);
59 RP::add("KHB.amp", "Initial velocity perturbation amplitude (m s^-1)", 0.0);
60 RP::add("KHB.offset", "Boundaries offset from 0 (m)", 0.0);
61 RP::add("KHB.transitionWidth", "Width of tanh transition for all changing values", 0.0);
62 RP::add("KHB.harmonics", "Number of harmonics of lambda included in the initial perturbation", 0);
63 RP::add("KHB.randomPhase", "If true, set a random phase for each mode of the initial perturbation. Seed set via project_common.seed", 0);
64 }
65
68 typedef Readparameters RP;
69
70 if(getObjectWrapper().particleSpecies.size() > 1) {
71 std::cerr << "The selected project does not support multiple particle populations! Aborting in " << __FILE__ << " line " << __LINE__ << std::endl;
72 abort();
73 }
74
75 RP::get("KHB.P", this->P);
76 RP::get("KHB.rho1", this->rho[this->TOP]);
77 RP::get("KHB.rho2", this->rho[this->BOTTOM]);
78 RP::get("KHB.Vx1", this->Vx[this->TOP]);
79 RP::get("KHB.Vx2", this->Vx[this->BOTTOM]);
80 RP::get("KHB.Vy1", this->Vy[this->TOP]);
81 RP::get("KHB.Vy2", this->Vy[this->BOTTOM]);
82 RP::get("KHB.Vz1", this->Vz[this->TOP]);
83 RP::get("KHB.Vz2", this->Vz[this->BOTTOM]);
84 RP::get("KHB.Bx1", this->Bx[this->TOP]);
85 RP::get("KHB.Bx2", this->Bx[this->BOTTOM]);
86 RP::get("KHB.By1", this->By[this->TOP]);
87 RP::get("KHB.By2", this->By[this->BOTTOM]);
88 RP::get("KHB.Bz1", this->Bz[this->TOP]);
89 RP::get("KHB.Bz2", this->Bz[this->BOTTOM]);
90 RP::get("KHB.lambda", this->lambda);
91 RP::get("KHB.amp", this->amp);
92 RP::get("KHB.offset", this->offset);
93 RP::get("KHB.transitionWidth", this->transitionWidth);
94 RP::get("KHB.harmonics", this->harmonics);
95 RP::get("KHB.randomPhase", this->randomPhase);
96 }
97
98
99 Real KHB::profile(creal top, creal bottom, creal x) const {
100 if(top == bottom) {
101 return top;
102 }
103 if(this->offset != 0.0) {
104 return 0.5 * ((top-bottom) * (
105 tanh((x + this->offset)/this->transitionWidth) -
106 tanh((x - this->offset)/this->transitionWidth) -1) + top+bottom);
107 } else {
108 return 0.5 * ((top-bottom) * tanh(x/this->transitionWidth) + top+bottom);
109 }
110 }
111
112 inline vector<std::array<Real, 3> > KHB::getV0(
113 creal x,
114 creal y,
115 creal z,
116 const uint popID
117 ) const {
118 Real Vx = profile(this->Vx[this->BOTTOM], this->Vx[this->TOP], x);
119 Real Vy = profile(this->Vy[this->BOTTOM], this->Vy[this->TOP], x);
120 Real Vz = profile(this->Vz[this->BOTTOM], this->Vz[this->TOP], x);
121
122 // add an initial velocity perturbation to Vx
123 // initialize RNG for calculating random phases for the initial perturbation
124 std::default_random_engine rndState;
125 setRandomSeed(0,rndState);
126 Real phase = 0.0;
127
128 // add each mode to the initial perturbation
129 for (int i=0; i<=this->harmonics; i++) {
130 if (this->randomPhase) {
131 phase = 2.0 * M_PI * getRandomNumber(rndState);
132 }
133
134 if (this->offset != 0.0) {
135 Vx += this->amp * sin(2.0 * (i + 1) * M_PI * y / this->lambda + phase) * (exp(-pow((x + this->offset) / this->transitionWidth,2)) + exp(-pow((x - this->offset) / this->transitionWidth,2)));
136 } else {
137 Vx += this->amp * sin(2.0 * (i + 1) * M_PI * y / this->lambda + phase) * exp(-pow(x / this->transitionWidth,2));
138 }
139 }
140
141 vector<std::array<Real, 3> > centerPoints;
142 std::array<Real, 3> V0 {{Vx,Vy,Vz}};
143 centerPoints.push_back(V0);
144 return centerPoints;
145 }
146
148 const uint popID,
149 const uint nRequested
150 ) const {
151 //const speciesParameters& sP = this->speciesParams[popID];
152 // Fetch spatial cell center coordinates
153 const Real x = cell->parameters[CellParams::XCRD] + 0.5*cell->parameters[CellParams::DX];
154 const Real y = cell->parameters[CellParams::YCRD] + 0.5*cell->parameters[CellParams::DY];
155 const Real z = cell->parameters[CellParams::ZCRD] + 0.5*cell->parameters[CellParams::DZ];
156
157 const Real mass = getObjectWrapper().particleSpecies[popID].mass;
158 Real initRho = profile(this->rho[this->BOTTOM], this->rho[this->TOP], x);
159 std::array<Real, 3> initV0 = this->getV0(x, y, z, popID)[0];
160 const Real initV0X = initV0[0];
161 const Real initV0Y = initV0[1];
162 const Real initV0Z = initV0[2];
163
164 // calculate the temperature such that the total pressure is constant across the domain
166 creal Bx = profile(this->Bx[this->BOTTOM], this->Bx[this->TOP], x);
167 creal By = profile(this->By[this->BOTTOM], this->By[this->TOP], x);
168 creal Bz = profile(this->Bz[this->BOTTOM], this->Bz[this->TOP], x);
169 creal initT = (this->P - 0.5 * (Bx * Bx + By * By + Bz * Bz) / mu0) / initRho / physicalconstants::K_B;
170
171 #ifdef USE_GPU
174 #else
177 #endif
178 // Loop over blocks
179 Realf rhosum = 0;
181 {WID, WID, WID, nRequested},
182 ARCH_LOOP_LAMBDA (const uint i, const uint j, const uint k, const uint initIndex, Realf *lsum ) {
183 vmesh::GlobalID *GIDlist = vmesh->getGrid()->data();
184 Realf* bufferData = VBC->getData();
185 const vmesh::GlobalID blockGID = GIDlist[initIndex];
186 // Calculate parameters for new block
187 Real blockCoords[6];
188 vmesh->getBlockInfo(blockGID,&blockCoords[0]);
189 creal vxBlock = blockCoords[0];
190 creal vyBlock = blockCoords[1];
191 creal vzBlock = blockCoords[2];
192 creal dvxCell = blockCoords[3];
193 creal dvyCell = blockCoords[4];
194 creal dvzCell = blockCoords[5];
195 ARCH_INNER_BODY(i, j, k, initIndex, lsum) {
196 creal vx = vxBlock + (i+0.5)*dvxCell - initV0X;
197 creal vy = vyBlock + (j+0.5)*dvyCell - initV0Y;
198 creal vz = vzBlock + (k+0.5)*dvzCell - initV0Z;
199 const Realf value = MaxwellianPhaseSpaceDensity(vx,vy,vz,initT,initRho,mass);
200 bufferData[initIndex*WID3 + k*WID2 + j*WID + i] = value;
201 //lsum[0] += value;
202 };
203 }, rhosum);
204 return rhosum;
205 }
206
207 /* Evaluates local SpatialCell properties for the project and population,
208 then evaluates the phase-space density at the given coordinates.
209 Used as a probe for projectTriAxisSearch.
210 */
212 const uint popID,
213 Real vx_in, Real vy_in, Real vz_in
214 ) const {
215 // Fetch spatial cell center coordinates
216 const Real x = cell->parameters[CellParams::XCRD] + 0.5*cell->parameters[CellParams::DX];
217 const Real y = cell->parameters[CellParams::YCRD] + 0.5*cell->parameters[CellParams::DY];
218 const Real z = cell->parameters[CellParams::ZCRD] + 0.5*cell->parameters[CellParams::DZ];
219
220 const Real mass = getObjectWrapper().particleSpecies[popID].mass;
221 Real initRho = profile(this->rho[this->BOTTOM], this->rho[this->TOP], x);
222 std::array<Real, 3> initV0 = this->getV0(x, y, z, popID)[0];
223 const Real initV0X = initV0[0];
224 const Real initV0Y = initV0[1];
225 const Real initV0Z = initV0[2];
226
227 // calculate the temperature such that the total pressure is constant across the domain
229 creal Bx = profile(this->Bx[this->BOTTOM], this->Bx[this->TOP], x);
230 creal By = profile(this->By[this->BOTTOM], this->By[this->TOP], x);
231 creal Bz = profile(this->Bz[this->BOTTOM], this->Bz[this->TOP], x);
232 creal initT = (this->P - 0.5 * (Bx * Bx + By * By + Bz * Bz) / mu0) / initRho / physicalconstants::K_B;
233
234 creal vx = vx_in - initV0X;
235 creal vy = vy_in - initV0Y;
236 creal vz = vz_in - initV0Z;
237 const Realf value = MaxwellianPhaseSpaceDensity(vx,vy,vz,initT,initRho,mass);
238 return value;
239 }
240
242
246 setBackgroundFieldToZero(fsgrid, technical, bgb);
247
248 if(!P::isRestart) {
249 // local copies for lambda capture
250 const auto Bx_l = this->Bx;
251 const auto By_l = this->By;
252 const auto Bz_l = this->Bz;
253 const auto BOTTOM_l = this->BOTTOM;
254 const auto TOP_l = this->TOP;
255 // needs *this because of profile() at the moment.
256 fsgrid.parallel_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
257 phiprof::initializeTimer("setProjectBField-loop"), technical,
258 [=, *this](const fsgrid::Coordinates &coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
259 const std::array<Real, 3> xyz = coordinates.getPhysicalCoords(stencil.i, stencil.j, stencil.k);
260 const std::array<Real, 3> gridSpacing = coordinates.physicalGridSpacing;
261 auto& cell = perb[stencil.ooo()];
262
264 profile(Bx_l[BOTTOM_l], Bx_l[TOP_l], xyz[0] + 0.5 * gridSpacing[0]);
266 profile(By_l[BOTTOM_l], By_l[TOP_l], xyz[0] + 0.5 * gridSpacing[0]);
268 profile(Bz_l[BOTTOM_l], Bz_l[TOP_l], xyz[0] + 0.5 * gridSpacing[0]);
269 });
270 }
271 }
272
273} // namespace projects
mu0
Definition Dispersion.m:50
for i
Definition Dispersion.m:24
#define ARCH_INNER_BODY(...)
#define ARCH_LOOP_LAMBDA
void setBackgroundFieldToZero(FieldSolverGrid &fsgrid, fsgrids::technicalspan technical, fsgrids::bgbspan bgb)
Real Bx[2]
Definition KHB.h:62
virtual Realf probePhaseSpace(spatial_cell::SpatialCell *cell, const uint popID, Real vx_in, Real vy_in, Real vz_in) const override
Definition KHB.cpp:211
virtual void setProjectBField(fsgrids::perbspan perb, fsgrids::bgbspan bgb, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid) override
Definition KHB.cpp:243
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 KHB.cpp:112
Real amp
Definition KHB.h:66
Real Vz[2]
Definition KHB.h:61
bool randomPhase
Definition KHB.h:70
Real offset
Definition KHB.h:67
virtual void calcCellParameters(spatial_cell::SpatialCell *cell, creal &t) override
Definition KHB.cpp:241
Real profile(creal top, creal bottom, creal x) const
Definition KHB.cpp:99
virtual ~KHB()
Definition KHB.cpp:37
Real By[2]
Definition KHB.h:63
Real P
Definition KHB.h:57
static void addParameters(void)
Definition KHB.cpp:41
Real rho[2]
Definition KHB.h:58
Real Vy[2]
Definition KHB.h:60
Real Vx[2]
Definition KHB.h:59
Real Bz[2]
Definition KHB.h:64
Real lambda
Definition KHB.h:65
virtual bool initialize(void) override
Definition KHB.cpp:39
int harmonics
Definition KHB.h:69
virtual Realf fillPhaseSpace(spatial_cell::SpatialCell *cell, const uint popID, const uint nRequested) const override
Definition KHB.cpp:147
Real transitionWidth
Definition KHB.h:68
virtual void getParameters(void) override
Definition KHB.cpp:66
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 setRandomSeed(uint64_t seedModifier, std::default_random_engine &randGen) const
Definition project.cpp:326
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
const Real K_B
Definition common.h:571
const Real MU_0
Definition common.h:570
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