Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
IPShock.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%
23Interplanetary shock project by Markus Battarbee (markus.battarbee@gmail.com)
24Based on SilvaShock project by Urs Ganse
25Previous development version name was UtuShock
26*/
27
28#include <cstdlib>
29#include <iostream>
30#include <iomanip>
31#include <cmath>
32
33#include <vector>
34
35#include "../../common.h"
39
40#include "IPShock.h"
41
42using namespace std;
43using namespace spatial_cell;
44
45namespace projects {
48
50 return Project::initialize();
51 }
52
54 typedef Readparameters RP;
55 // Common (field / etc.) parameters
56 RP::add("IPShock.BX0u", "Upstream mag. field value (T)", 1.0e-9);
57 RP::add("IPShock.BY0u", "Upstream mag. field value (T)", 2.0e-9);
58 RP::add("IPShock.BZ0u", "Upstream mag. field value (T)", 3.0e-9);
59 RP::add("IPShock.BX0d", "Downstream mag. field value (T)", 1.0e-9);
60 RP::add("IPShock.BY0d", "Downstream mag. field value (T)", 2.0e-9);
61 RP::add("IPShock.BZ0d", "Downstream mag. field value (T)", 3.0e-9);
62 RP::add("IPShock.Width", "Shock Width (m)", 50000);
63
64 RP::add("IPShock.AMR_L1width", "L1 AMR region width (m)", 0);
65 RP::add("IPShock.AMR_L2width", "L2 AMR region width (m)", 0);
66 RP::add("IPShock.AMR_L3width", "L3 AMR region width (m)", 0);
67 RP::add("IPShock.AMR_L4width", "L4 AMR region width (m)", 0);
68
69 // Per-population parameters
70 for(uint i=0; i< getObjectWrapper().particleSpecies.size(); i++) {
71 const std::string& pop = getObjectWrapper().particleSpecies[i].name;
72 RP::add(pop + "_IPShock.VX0u", "Upstream Bulk velocity in x", 0.0);
73 RP::add(pop + "_IPShock.VY0u", "Upstream Bulk velocity in y", 0.0);
74 RP::add(pop + "_IPShock.VZ0u", "Upstream Bulk velocuty in z", 0.0);
75 RP::add(pop + "_IPShock.rhou", "Upstream Number density (m^-3)", 1.0e7);
76 RP::add(pop + "_IPShock.Temperatureu", "Upstream Temperature (K)", 2.0e6);
77
78 RP::add(pop + "_IPShock.VX0d", "Downstream Bulk velocity in x", 0.0);
79 RP::add(pop + "_IPShock.VY0d", "Downstream Bulk velocity in y", 0.0);
80 RP::add(pop + "_IPShock.VZ0d", "Downstream Bulk velocuty in z", 0.0);
81 RP::add(pop + "_IPShock.rhod", "Downstream Number density (m^-3)", 1.0e7);
82 RP::add(pop + "_IPShock.Temperatured", "Downstream Temperature (K)", 2.0e6);
83
84 RP::add(pop + "_IPShock.maxwCutoff", "Cutoff for the maxwellian distribution", 1e-12);
85 }
86
87 }
88
91
92 typedef Readparameters RP;
93 RP::get("IPShock.BX0u", this->B0u[0]);
94 RP::get("IPShock.BY0u", this->B0u[1]);
95 RP::get("IPShock.BZ0u", this->B0u[2]);
96 RP::get("IPShock.BX0d", this->B0d[0]);
97 RP::get("IPShock.BY0d", this->B0d[1]);
98 RP::get("IPShock.BZ0d", this->B0d[2]);
99 RP::get("IPShock.Width", this->Shockwidth);
100
101 RP::get("IPShock.AMR_L1width", this->AMR_L1width);
102 RP::get("IPShock.AMR_L2width", this->AMR_L2width);
103 RP::get("IPShock.AMR_L3width", this->AMR_L3width);
104 RP::get("IPShock.AMR_L4width", this->AMR_L4width);
105
106 // Per-population parameters
107 for(uint i=0; i< getObjectWrapper().particleSpecies.size(); i++) {
108 const std::string& pop = getObjectWrapper().particleSpecies[i].name;
110
111 RP::get(pop + "_IPShock.VX0u", sP.V0u[0]);
112 RP::get(pop + "_IPShock.VY0u", sP.V0u[1]);
113 RP::get(pop + "_IPShock.VZ0u", sP.V0u[2]);
114 RP::get(pop + "_IPShock.rhou", sP.DENSITYu);
115 RP::get(pop + "_IPShock.Temperatureu", sP.TEMPERATUREu);
116
117 RP::get(pop + "_IPShock.VX0d", sP.V0d[0]);
118 RP::get(pop + "_IPShock.VY0d", sP.V0d[1]);
119 RP::get(pop + "_IPShock.VZ0d", sP.V0d[2]);
120 RP::get(pop + "_IPShock.rhod", sP.DENSITYd);
121 RP::get(pop + "_IPShock.Temperatured", sP.TEMPERATUREd);
122
123 RP::get(pop + "_IPShock.maxwCutoff", sP.maxwCutoff);
124
125 speciesParams.push_back(sP);
126 }
127
128 int myRank;
129
130 MPI_Comm_rank(MPI_COMM_WORLD,&myRank);
131
132 /*
133 if(myRank == MASTER_RANK) {
134 std::cerr << "B0x u = " << this->B0u[0] << std::endl;
135 std::cerr << "B0y u = " << this->B0u[1] << std::endl;
136 std::cerr << "B0z u = " << this->B0u[2] << std::endl;
137 std::cerr << "B0x d = " << this->B0d[0] << std::endl;
138 std::cerr << "B0y d = " << this->B0d[1] << std::endl;
139 std::cerr << "B0z d = " << this->B0d[2] << std::endl;
140 //std::cerr << "V0x u = " << this->V0u[0] << std::endl;
141 //std::cerr << "V0y u = " << this->V0u[1] << std::endl;
142 //std::cerr << "V0z u = " << this->V0u[2] << std::endl;
143 //std::cerr << "V0x d = " << this->V0d[0] << std::endl;
144 //std::cerr << "V0y d = " << this->V0d[1] << std::endl;
145 //std::cerr << "V0z d = " << this->V0d[2] << std::endl;
146
147 //std::cerr << "rhou = " << this->DENSITYu << std::endl;
148 //std::cerr << "rhod = " << this->DENSITYd << std::endl;
149 //std::cerr << "tempu = " << this->TEMPERATUREu << std::endl;
150 //std::cerr << "tempd = " << this->TEMPERATUREd << std::endl;
151
152 //std::cerr << "maxwCutoff = " << this->maxwCutoff << std::endl;
153 //std::cerr << "Width = " << this->Shockwidth << std::endl;
154 }
155 */
156
157 /*
158 Now allows flow and field both in z and y -directions. As assuming we're
159 in the dHT frame, all flow and magnetic field should be in a single plane.
160 */
161
162 /* Magnitude of tangential B-field and flow components */
163 this->B0utangential = sqrt(this->B0u[1]*this->B0u[1] + this->B0u[2]*this->B0u[2]);
164 this->B0dtangential = sqrt(this->B0d[1]*this->B0d[1] + this->B0d[2]*this->B0d[2]);
165 for(auto& sP : speciesParams) {
166 sP.V0utangential = sqrt(sP.V0u[1]*sP.V0u[1] + sP.V0u[2]*sP.V0u[2]);
167 sP.V0dtangential = sqrt(sP.V0d[1]*sP.V0d[1] + sP.V0d[2]*sP.V0d[2]);
168 }
169
170 /* Check direction of upstream and downstream flows and fields
171 Define y-z-directional angle phi so that
172 By = cos(phi_B)*B_tang
173 Bz = sin(phi_B)*B_tang
174 Vy = cos(phi_V)*V_tang
175 Vz = sin(phi_V)*V_tang
176 If we're in the dHT frame, phi_B and phi_V should be the same, and also the same
177 both in the upstream and in the downstream.
178 */
179 this->Bucosphi = abs(this->B0u[1])/this->B0utangential;
180 this->Bdcosphi = abs(this->B0d[1])/this->B0dtangential;
181 for(auto& sP : speciesParams) {
182 sP.Vucosphi = abs(sP.V0u[1])/sP.V0utangential;
183 sP.Vdcosphi = abs(sP.V0d[1])/sP.V0dtangential;
184 }
185
186 /* Save signs as well for reconstruction during interpolation.
187 For both components of B and V, upstream and downstream signs should be the same. */
188 this->Byusign=0;
189 if (this->B0u[1] < 0) this->Byusign=-1;
190 if (this->B0u[1] > 0) this->Byusign=+1;
191 this->Bzusign=0;
192 if (this->B0u[2] < 0) this->Bzusign=-1;
193 if (this->B0u[2] > 0) this->Bzusign=+1;
194 this->Bydsign=0;
195 if (this->B0d[1] < 0) this->Bydsign=-1;
196 if (this->B0d[1] > 0) this->Bydsign=+1;
197 this->Bzdsign=0;
198 if (this->B0d[2] < 0) this->Bzdsign=-1;
199 if (this->B0d[2] > 0) this->Bzdsign=+1;
200
201 for(auto& sP : speciesParams) {
202 sP.Vyusign=0;
203 if (sP.V0u[1] < 0) sP.Vyusign=-1;
204 if (sP.V0u[1] > 0) sP.Vyusign=+1;
205 sP.Vzusign=0;
206 if (sP.V0u[2] < 0) sP.Vzusign=-1;
207 if (sP.V0u[2] > 0) sP.Vzusign=+1;
208 sP.Vydsign=0;
209 if (sP.V0d[1] < 0) sP.Vydsign=-1;
210 if (sP.V0d[1] > 0) sP.Vydsign=+1;
211 sP.Vzdsign=0;
212 if (sP.V0d[2] < 0) sP.Vzdsign=-1;
213 if (sP.V0d[2] > 0) sP.Vzdsign=+1;
214
215 /* Check that upstream and downstream values both are separately parallel */
216 if ( (abs(this->Bucosphi)-abs(sP.Vucosphi) > 1e-10) || (this->Byusign*this->Bzusign != sP.Vyusign*sP.Vzusign) )
217 {
218 if(myRank == MASTER_RANK) {
219 std::cout<<" Warning: Upstream B and V not parallel"<<std::endl;
220 std::cout<<" Bucosphi "<<Bucosphi<<" Vucosphi "<<sP.Vucosphi<<" Byusign "<<Byusign<<" Bzusign "<<Bzusign<<" Vyusign "<<sP.Vyusign<<" Vzusign "<<sP.Vzusign<<std::endl;
221 }
222 }
223 if ( (abs(this->Bdcosphi)-abs(sP.Vdcosphi) > 1e-10) || (this->Bydsign*this->Bzdsign != sP.Vydsign*sP.Vzdsign) )
224 {
225 if(myRank == MASTER_RANK) {
226 std::cout<<" Warning: Downstream B and V not parallel"<<std::endl;
227 std::cout<<" Bdcosphi "<<Bdcosphi<<" Vdcosphi "<<sP.Vdcosphi<<" Bydsign "<<Bydsign<<" Bzdsign "<<Bzdsign<<" Vydsign "<<sP.Vydsign<<" Vzdsign "<<sP.Vzdsign<<std::endl;
228 }
229 }
230 /* Verify that upstream and downstream flows are in a plane */
231 if ( (abs(this->Bdcosphi)-abs(this->Bucosphi) > 1e-10) && (this->Bydsign*this->Bzdsign != this->Byusign*this->Bzusign) )
232 {
233 if(myRank == MASTER_RANK) {
234 std::cout<<" Warning: Upstream and downstream B_tangentials not in same plane"<<std::endl;
235 std::cout<<" Bdcosphi "<<Bdcosphi<<" Bucosphi "<<Bucosphi<<" Bydsign "<<Bydsign<<" Bzdsign "<<Bzdsign<<" Byusign "<<Byusign<<" Bzusign "<<Bzusign<<std::endl;
236 }
237 }
238 if ( (abs(sP.Vdcosphi)-abs(sP.Vucosphi) > 1e-10) && (sP.Vydsign*sP.Vzdsign != sP.Vyusign*sP.Vzusign) )
239 {
240 if(myRank == MASTER_RANK) {
241 std::cout<<" Warning: Upstream and downstream V_tangentials not in same plane"<<std::endl;
242 std::cout<<" Vdcosphi "<<sP.Vdcosphi<<" Vucosphi "<<sP.Vucosphi<<" Vydsign "<<sP.Vydsign<<" Vzdsign "<<sP.Vzdsign<<" Vyusign "<<sP.Vyusign<<" Vzusign "<<sP.Vzusign<<std::endl;
243 }
244 }
245 }
246
247 }
248
250 const uint popID,
251 const uint nRequested
252 ) const {
253 const IPShockSpeciesParameters& sP = this->speciesParams[popID];
254 const Real mass = getObjectWrapper().particleSpecies[popID].mass;
256 // Fetch spatial cell center coordinates
257 const Real x = cell->parameters[CellParams::XCRD] + 0.5*cell->parameters[CellParams::DX];
258 const Real y = cell->parameters[CellParams::YCRD] + 0.5*cell->parameters[CellParams::DY];
259 const Real z = cell->parameters[CellParams::ZCRD] + 0.5*cell->parameters[CellParams::DZ];
260
261 // Interpolate density between upstream and downstream
262 // All other values are calculated from jump conditions
263 Real DENSITY = interpolate(sP.DENSITYu,sP.DENSITYd, x);
264 if (DENSITY < 1e-20) {
265 std::cout<<"density too low! "<<DENSITY<<" x "<<x<<" y "<<y<<" z "<<z<<std::endl;
266 }
267
268 // Solve tangential components for B and V
269 Real hereVX = sP.DENSITYu * sP.V0u[0] / DENSITY;
270 Real hereBX = this->B0u[0];
271 Real MAsq = std::pow((sP.V0u[0]/this->B0u[0]), 2) * sP.DENSITYu * mass * mu0;
272 Real hereBtang = this->B0u[2] * (MAsq - 1.0)/(MAsq*hereVX/sP.V0u[0] -1.0);
273 Real hereVtang = hereVX * hereBtang / hereBX;
274
275 /* Reconstruct Y and Z components using cos(phi) values and signs. Tangential variables are always positive. */
276 //Real hereBY = hereBtang * this->Bucosphi * this->Byusign;
277 //Real hereBZ = hereBtang * sqrt(1. - this->Bucosphi * this->Bucosphi) * this->Bzusign;
278 Real hereVY = abs(hereVtang) * sP.Vucosphi * sP.Vyusign;
279 Real hereVZ = abs(hereVtang) * sqrt(1. - sP.Vucosphi * sP.Vucosphi) * sP.Vzusign;
280
281 // Old incorrect temperature - just interpolate for now
282 //Real adiab = 5./3.;
283 //Real TEMPERATURE = this->TEMPERATUREu + (mass*(adiab-1.0)/(2.0*KB*adiab)) *
284 // ( std::pow(this->V0u[0],2) + std::pow(this->V0u[2],2) - std::pow(hereVX,2) - std::pow(hereVZ,2) );
286
287 Real initRho = DENSITY;
288 Real initT = TEMPERATURE;
289 const Real initV0X = hereVX;
290 const Real initV0Y = hereVY;
291 const Real initV0Z = hereVZ;
292
293 #ifdef USE_GPU
296 #else
299 #endif
300 // Loop over blocks
301 Realf rhosum = 0;
303 {WID, WID, WID, nRequested},
304 ARCH_LOOP_LAMBDA (const uint i, const uint j, const uint k, const uint initIndex, Realf *lsum ) {
305 vmesh::GlobalID *GIDlist = vmesh->getGrid()->data();
306 Realf* bufferData = VBC->getData();
307 const vmesh::GlobalID blockGID = GIDlist[initIndex];
308 // Calculate parameters for new block
309 Real blockCoords[6];
310 vmesh->getBlockInfo(blockGID,&blockCoords[0]);
311 creal vxBlock = blockCoords[0];
312 creal vyBlock = blockCoords[1];
313 creal vzBlock = blockCoords[2];
314 creal dvxCell = blockCoords[3];
315 creal dvyCell = blockCoords[4];
316 creal dvzCell = blockCoords[5];
317 ARCH_INNER_BODY(i, j, k, initIndex, lsum) {
318 creal vx = vxBlock + (i+0.5)*dvxCell - initV0X;
319 creal vy = vyBlock + (j+0.5)*dvyCell - initV0Y;
320 creal vz = vzBlock + (k+0.5)*dvzCell - initV0Z;
321 const Realf value = MaxwellianPhaseSpaceDensity(vx,vy,vz,initT,initRho,mass);
322 bufferData[initIndex*WID3 + k*WID2 + j*WID + i] = value;
323 //lsum[0] += value;
324 };
325 }, rhosum);
326 return rhosum;
327 }
328
329 /* Evaluates local SpatialCell properties for the project and population,
330 then evaluates the phase-space density at the given coordinates.
331 Used as a probe for projectTriAxisSearch.
332 */
334 const uint popID,
335 Real vx_in, Real vy_in, Real vz_in
336 ) const {
337 const IPShockSpeciesParameters& sP = this->speciesParams[popID];
338 // Fetch spatial cell center coordinates
339 const Real x = cell->parameters[CellParams::XCRD] + 0.5*cell->parameters[CellParams::DX];
340 const Real y = cell->parameters[CellParams::YCRD] + 0.5*cell->parameters[CellParams::DY];
341 const Real z = cell->parameters[CellParams::ZCRD] + 0.5*cell->parameters[CellParams::DZ];
342
344 const Real mass = getObjectWrapper().particleSpecies[popID].mass;
345 Real DENSITY = interpolate(sP.DENSITYu,sP.DENSITYd, x);
346 if (DENSITY < 1e-20) {
347 std::cout<<"density too low! "<<DENSITY<<" x "<<x<<" y "<<y<<" z "<<z<<std::endl;
348 }
349 Real hereVX = sP.DENSITYu * sP.V0u[0] / DENSITY;
350 Real hereBX = this->B0u[0];
351 Real MAsq = std::pow((sP.V0u[0]/this->B0u[0]), 2) * sP.DENSITYu * mass * mu0;
352 Real hereBtang = this->B0u[2] * (MAsq - 1.0)/(MAsq*hereVX/sP.V0u[0] -1.0);
353 Real hereVtang = hereVX * hereBtang / hereBX;
354 Real hereVY = abs(hereVtang) * sP.Vucosphi * sP.Vyusign;
355 Real hereVZ = abs(hereVtang) * sqrt(1. - sP.Vucosphi * sP.Vucosphi) * sP.Vzusign;
357 Real initRho = DENSITY;
358 Real initT = TEMPERATURE;
359 const Real initV0X = hereVX;
360 const Real initV0Y = hereVY;
361 const Real initV0Z = hereVZ;
362
363 creal vx = vx_in - initV0X;
364 creal vy = vy_in - initV0Y;
365 creal vz = vz_in - initV0Z;
366 const Realf value = MaxwellianPhaseSpaceDensity(vx,vy,vz,initT,initRho,mass);
367 return value;
368 }
369
370 std::vector<std::array<Real, 3>> IPShock::getV0(creal x, creal y, creal z, const uint popID) const {
371 Real mass = getObjectWrapper().particleSpecies[popID].mass;
373 const IPShockSpeciesParameters& sP = this->speciesParams[popID];
374
375 // Interpolate density between upstream and downstream
376 // All other values are calculated from jump conditions
377 Real DENSITY = interpolate(sP.DENSITYu,sP.DENSITYd, x);
378 if (DENSITY < 1e-20) {
379 std::cout<<"density too low! "<<DENSITY<<" x "<<x<<" y "<<y<<" z "<<z<<std::endl;
380 }
381
382 // Solve tangential components for B and V
383 Real VX = sP.DENSITYu * sP.V0u[0] / DENSITY;
384 Real BX = this->B0u[0];
385 Real MAsq = std::pow((sP.V0u[0]/this->B0u[0]), 2) * sP.DENSITYu * mass * mu0;
386 Real Btang = this->B0utangential * (MAsq - 1.0)/(MAsq*VX/sP.V0u[0] -1.0);
387 Real Vtang = VX * Btang / BX;
388
389 /* Reconstruct Y and Z components using cos(phi) values and signs. Tangential variables are always positive. */
390 //Real BY = Btang * this->Bucosphi * this->Byusign;
391 //Real BZ = Btang * sqrt(1. - this->Bucosphi * this->Bucosphi) * this->Bzusign;
392 Real VY = abs(Vtang) * sP.Vucosphi * sP.Vyusign;
393 Real VZ = abs(Vtang) * sqrt(1. - sP.Vucosphi * sP.Vucosphi) * sP.Vzusign;
394
395 // Disable compiler warnings: (unused variables but the function is inherited)
396 (void)y;
397 (void)z;
398
399 std::array<Real, 3> V0 {{VX, VY, VZ}};
400 std::vector<std::array<Real, 3>> retval;
401 retval.push_back(V0);
402
403 return retval;
404 }
405
407
408 Real IPShock::interpolate(Real upstream, Real downstream, Real x) const {
409 Real coord = 0.5 + x/this->Shockwidth; //Now shock will be from 0 to 1
410 //x /= 0.5 * this->Shockwidth;
411 Real a = 0.0;
412 if (coord <= 0.0) a = downstream;
413 if (coord >= 1.0) a = upstream;
414 if ((coord > 0.0) && (coord < 1.0)) {
415 // Ken Perlin Smootherstep
416 Real interpolation = ( 6.0 * coord * coord - 15.0 * coord +10. ) * coord * coord * coord;
417 a = upstream * interpolation + downstream * (1. - interpolation);
418 }
419 return a;
420 }
421
425 setBackgroundFieldToZero(fsgrid, technical, bgb);
426
427 if (!P::isRestart) {
428 const auto B0u_l = this->B0u; // copies for lambda capture
429 const auto B0utangential_l = this->B0utangential;
430 const auto Bucosphi_l = this->Bucosphi;
431 const auto Byusign_l = this->Byusign;
432 const auto Bzusign_l = this->Bzusign;
433 const auto speciesParams_l = speciesParams;
434 // needs *this because of interpolate() at least atm.
435 fsgrid.parallel_for([](int timerId) -> phiprof::Timer { return phiprof::Timer{timerId}; },
436 phiprof::initializeTimer("setProjectBField-loop"), technical,
437 [=, *this](const fsgrid::Coordinates &coordinates, const fsgrid::FsStencil& stencil, cuint sysBoundaryFlag, cuint sysBoundaryLayer) {
438 const std::array<Real, 3> xyz = coordinates.getPhysicalCoords(stencil.i, stencil.j, stencil.k);
439 auto& cell = perb[stencil.ooo()];
440
441 /* Maintain all values in BPERT for simplicity */
443
444 // Interpolate density between upstream and downstream
445 // All other values are calculated from jump conditions
446 Real MassDensity = 0.;
447 Real MassDensityU = 0.;
448 Real EffectiveVu0 = 0.;
449 for (uint i = 0; i < getObjectWrapper().particleSpecies.size(); i++) {
450 const IPShockSpeciesParameters& sP = speciesParams_l[i];
451 Real mass = getObjectWrapper().particleSpecies[i].mass;
452
453 MassDensity += mass * interpolate(sP.DENSITYu, sP.DENSITYd, xyz[0]);
454 MassDensityU += mass * sP.DENSITYu;
455 EffectiveVu0 += sP.V0u[0] * mass * sP.DENSITYu;
456 }
457 EffectiveVu0 /= MassDensityU;
458
459 // Solve tangential components for B and V
460 Real VX = MassDensityU * EffectiveVu0 / MassDensity;
461 Real BX = B0u_l[0];
462 Real MAsq = std::pow((EffectiveVu0 / B0u_l[0]), 2) * MassDensityU * mu0;
463 Real Btang = B0utangential_l * (MAsq - 1.0) / (MAsq * VX / EffectiveVu0 - 1.0);
464
465 /* Reconstruct Y and Z components using cos(phi) values and signs. Tangential variables are always
466 * positive. */
467 Real BY = abs(Btang) * Bucosphi_l * Byusign_l;
468 Real BZ = abs(Btang) * sqrt(1. - Bucosphi_l * Bucosphi_l) * Bzusign_l;
469 // Real Vtang = VX * Btang / BX;
470 // Real VY = Vtang * this->Vucosphi * this->Vyusign;
471 // Real VZ = Vtang * sqrt(1. - this->Vucosphi * this->Vucosphi) * this->Vzusign;
472
473 cell[fsgrids::bfield::PERBX] = BX;
474 cell[fsgrids::bfield::PERBY] = BY;
475 cell[fsgrids::bfield::PERBZ] = BZ;
476 });
477 }
478 }
479
480 bool IPShock::refineSpatialCells( dccrg::Dccrg<spatial_cell::SpatialCell,dccrg::Cartesian_Geometry>& mpiGrid ) const {
481
482 int myRank;
483 MPI_Comm_rank(MPI_COMM_WORLD,&myRank);
484
485 std::vector<CellID> refinedCells;
486
487 if(myRank == MASTER_RANK) std::cout << "Maximum refinement level is " << mpiGrid.mapping.get_maximum_refinement_level() << std::endl;
488
489 // Leave boundary cells and a bit of safety margin
490// const int bw = 2* VLASOV_STENCIL_WIDTH;
491// const int bw2 = 2*(bw + VLASOV_STENCIL_WIDTH);
492// const int bw3 = 2*(bw2 + VLASOV_STENCIL_WIDTH);
493
494 // Calculate regions for refinement
496 // L1 refinement.
497 for (uint i = 0; i < P::xcells_ini; ++i) {
498 for (uint j = 0; j < P::ycells_ini; ++j) {
499 for (uint k = 0; k < P::zcells_ini; ++k) {
500
501 std::array<double,3> xyz;
502 xyz[0] = P::xmin + (i+0.5)*P::dx_ini;
503 xyz[1] = P::ymin + (j+0.5)*P::dy_ini;
504 xyz[2] = P::zmin + (k+0.5)*P::dz_ini;
505
506 if (abs(xyz[0]) < AMR_L1width)
507 {
508 CellID myCell = mpiGrid.get_existing_cell(xyz);
509 mpiGrid.refine_completely(myCell);
510 }
511 }
512 }
513 }
514 refinedCells = mpiGrid.stop_refining();
515 if(myRank == MASTER_RANK) std::cout << "Finished first level of refinement" << endl;
516 // Don't do LB, as this function is called only before v-spaces have been created
517 //mpiGrid.balance_load();
518 }
519
521 // L2 refinement.
522 for (uint i = 0; i < 2*P::xcells_ini; ++i) {
523 for (uint j = 0; j < 2*P::ycells_ini; ++j) {
524 for (uint k = 0; k < 2*P::zcells_ini; ++k) {
525
526 std::array<double,3> xyz;
527 xyz[0] = P::xmin + (i+0.5)*0.5*P::dx_ini;
528 xyz[1] = P::ymin + (j+0.5)*0.5*P::dy_ini;
529 xyz[2] = P::zmin + (k+0.5)*0.5*P::dz_ini;
530
531 if (abs(xyz[0]) < AMR_L2width)
532 {
533 CellID myCell = mpiGrid.get_existing_cell(xyz);
534 mpiGrid.refine_completely(myCell);
535 }
536 }
537 }
538 }
539 refinedCells = mpiGrid.stop_refining();
540 if(myRank == MASTER_RANK) std::cout << "Finished second level of refinement" << endl;
541 // Don't do LB, as this function is called only before v-spaces have been created
542 //mpiGrid.balance_load();
543 }
544
546 // L3 refinement.
547 for (uint i = 0; i < 4*P::xcells_ini; ++i) {
548 for (uint j = 0; j < 4*P::ycells_ini; ++j) {
549 for (uint k = 0; k < 4*P::zcells_ini; ++k) {
550
551 std::array<double,3> xyz;
552 xyz[0] = P::xmin + (i+0.5)*0.25*P::dx_ini;
553 xyz[1] = P::ymin + (j+0.5)*0.25*P::dy_ini;
554 xyz[2] = P::zmin + (k+0.5)*0.25*P::dz_ini;
555
556 if (abs(xyz[0]) < AMR_L3width)
557 {
558 CellID myCell = mpiGrid.get_existing_cell(xyz);
559 mpiGrid.refine_completely(myCell);
560 }
561 }
562 }
563 }
564 refinedCells = mpiGrid.stop_refining();
565 if(myRank == MASTER_RANK) std::cout << "Finished third level of refinement" << endl;
566 // Don't do LB, as this function is called only before v-spaces have been created
567 //mpiGrid.balance_load();
568 }
569
571 // L4 refinement.
572 for (uint i = 0; i < 8*P::xcells_ini; ++i) {
573 for (uint j = 0; j < 8*P::ycells_ini; ++j) {
574 for (uint k = 0; k < 8*P::zcells_ini; ++k) {
575
576 std::array<double,3> xyz;
577 xyz[0] = P::xmin + (i+0.5)*0.125*P::dx_ini;
578 xyz[1] = P::ymin + (j+0.5)*0.125*P::dy_ini;
579 xyz[2] = P::zmin + (k+0.5)*0.125*P::dz_ini;
580
581 if (abs(xyz[0]) < AMR_L4width)
582 {
583 CellID myCell = mpiGrid.get_existing_cell(xyz);
584 mpiGrid.refine_completely(myCell);
585 }
586 }
587 }
588 }
589 refinedCells = mpiGrid.stop_refining();
590 if(myRank == MASTER_RANK) std::cout << "Finished fourth level of refinement" << endl;
591 // Don't do LB, as this function is called only before v-spaces have been created
592 //mpiGrid.balance_load();
593 }
594
595 return true;
596 }
597
598}//namespace projects
mu0
Definition Dispersion.m:50
for i
Definition Dispersion.m:24
sqrt(1.0+vA *vA/(c *c))) % Ion-acoustic wave cS
#define ARCH_INNER_BODY(...)
#define ARCH_LOOP_LAMBDA
void setBackgroundFieldToZero(FieldSolverGrid &fsgrid, fsgrids::technicalspan technical, fsgrids::bgbspan bgb)
std::vector< IPShockSpeciesParameters > speciesParams
Definition IPShock.h:100
virtual Realf fillPhaseSpace(spatial_cell::SpatialCell *cell, const uint popID, const uint nRequested) const override
Definition IPShock.cpp:249
static void addParameters(void)
Definition IPShock.cpp:53
Real interpolate(Real u, Real d, Real x) const
Definition IPShock.cpp:408
virtual bool initialize(void) override
Definition IPShock.cpp:49
virtual Realf probePhaseSpace(spatial_cell::SpatialCell *cell, const uint popID, Real vx_in, Real vy_in, Real vz_in) const override
Definition IPShock.cpp:333
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 IPShock.cpp:370
virtual void getParameters(void) override
Definition IPShock.cpp:89
virtual void setProjectBField(fsgrids::perbspan perb, fsgrids::bgbspan bgb, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid) override
Definition IPShock.cpp:422
virtual void calcCellParameters(spatial_cell::SpatialCell *cell, creal &t) override
Definition IPShock.cpp:406
virtual ~IPShock()
Definition IPShock.cpp:47
bool refineSpatialCells(dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid) const override
Definition IPShock.cpp:480
virtual bool initialize()
Definition project.cpp:113
virtual void getParameters()
Definition project.cpp:103
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)
@ TEMPERATURE
Definition common.h:469
#define WID
Definition common.h:514
#define MASTER_RANK
Definition common.h:67
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
int myRank
Definition gpu_base.cpp:48
const Real VY
const Real VZ
const int j
const Real VX
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 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 Real dz_ini
Definition parameters.h:46
static Real dx_ini
Definition parameters.h:44
static uint zcells_ini
Definition parameters.h:50
static int amrMaxSpatialRefLevel
Definition parameters.h:190
static Real ymin
Definition parameters.h:40
static uint ycells_ini
Definition parameters.h:49
static int amrMaxAllowedSpatialRefLevel
Definition parameters.h:191
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 Real dy_ini
Definition parameters.h:45
static ARCH_HOSTDEV VecSimple< T > abs(const VecSimple< T > &l)