Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
object_wrapper.cpp
Go to the documentation of this file.
1#include "object_wrapper.h"
3#include "readparameters.h"
4#include <iostream>
5#include <string>
6
8 typedef Readparameters RP;
9
10 // Parameters needed to create particle populations
11
12 if (RP::helpRequested) { // dummy name for the help message
13 RP::add("ParticlePopulations","Name of the simulated particle populations (string)","<population>");
14 } else {
15 RP::addComposing("ParticlePopulations","Name of the simulated particle populations (string)");
16 }
17
18 return true;
19}
20
22 typedef Readparameters RP;
23
24 std::vector<std::string> popNames;
25 if (RP::helpRequested) {
26 popNames.push_back(std::string("<population>"));
27 } else {
28 RP::get("ParticlePopulations", popNames);
29 }
30
31 // Create appropriate subparameters for each population
32 for(const auto& pop : popNames) {
33 species::Species newSpecies;
34 vmesh::MeshParameters newVMesh;
35
36 // Originally, there was support for species and velocity meshes to be separate.
37 // This was abandoned, since there wasn't really any use for it.
38 newSpecies.name = newVMesh.name = pop;
40
41 getObjectWrapper().particleSpecies.push_back(newSpecies);
42 vmesh::getMeshWrapper()->velocityMeshesCreation->push_back(newVMesh);
43
44 RP::add(pop + "_properties.charge", "Particle charge, in units of elementary charges (int)", 1);
45 RP::add(pop + "_properties.mass_units", "Units in which particle mass is given, either 'PROTON' or 'ELECTRON' (string)", std::string("PROTON"));
46 RP::add(pop + "_properties.mass","Particle mass in given units (float)", 1);
47
48 // Grid sparsity parameters
49 RP::add(pop + "_sparse.minValue", "Minimum value of distribution function in any cell of a velocity block for the block to be considered to have contents", 1e-15);
50 RP::add(pop + "_sparse.blockAddWidthV", "Number of layers of blocks that are kept in velocity space around the blocks with content",1);
51 RP::add(pop + "_sparse.conserve_mass", "If true, then mass is conserved by scaling the dist. func. in the remaining blocks", false);
52 RP::add(pop + "_sparse.dynamicAlgorithm", "Type of algorithm used for calculating the dynamic minValue; 0 = none, 1 = linear algorithm based on rho, 2 = linear algorithm based on Blocks, (Example linear algorithm: y = kx+b, where dynamicMinValue1=k*dynamicBulkValue1 + b, and dynamicMinValue2 = k*dynamicBulkValue2 + b", 0);
53 RP::add(pop + "_sparse.dynamicMinValue1", "The minimum value for the dynamic minValue", 1);
54 RP::add(pop + "_sparse.dynamicMinValue2", "The maximum value (value 2) for the dynamic minValue", 1);
55 RP::add(pop + "_sparse.dynamicBulkValue1", "Minimum value for the dynamic algorithm range, so for example if dynamicAlgorithm=1 then for sparse.dynamicBulkValue1 = 1e3, sparse.dynamicBulkValue2=1e5, we apply the algorithm to cells for which 1e3<cell.rho<1e5", 0);
56 RP::add(pop + "_sparse.dynamicBulkValue2", "Maximum value for the dynamic algorithm range, so for example if dynamicAlgorithm=1 then for sparse.dynamicBulkValue1 = 1e3, sparse.dynamicBulkValue2=1e5, we apply the algorithm to cells for which 1e3<cell.rho<1e5", 0);
57
58 // Grid parameters
59 RP::add(pop + "_vspace.vx_min","Minimum value for velocity mesh vx-coordinates.",0);
60 RP::add(pop + "_vspace.vx_max","Maximum value for velocity mesh vx-coordinates.",0);
61 RP::add(pop + "_vspace.vy_min","Minimum value for velocity mesh vy-coordinates.",0);
62 RP::add(pop + "_vspace.vy_max","Maximum value for velocity mesh vx-coordinates.",0);
63 RP::add(pop + "_vspace.vz_min","Minimum value for velocity mesh vz-coordinates.",0);
64 RP::add(pop + "_vspace.vz_max","Maximum value for velocity mesh vx-coordinates.",0);
65 RP::add(pop + "_vspace.vx_length","Initial number of velocity blocks in vx-direction.",1);
66 RP::add(pop + "_vspace.vy_length","Initial number of velocity blocks in vy-direction.",1);
67 RP::add(pop + "_vspace.vz_length","Initial number of velocity blocks in vz-direction.",1);
68 RP::add(pop + "_vspace.max_refinement_level","Maximum allowed mesh refinement level.", 1);
69
70 // Thermal / suprathermal parameters
71 Readparameters::add(pop + "_thermal.vx", "Center coordinate for the maxwellian distribution. Used for calculating the suprathermal moments.", -500000.0);
72 Readparameters::add(pop + "_thermal.vy", "Center coordinate for the maxwellian distribution. Used for calculating the suprathermal moments.", 0.0);
73 Readparameters::add(pop + "_thermal.vz", "Center coordinate for the maxwellian distribution. Used for calculating the suprathermal moments.", 0.0);
74 Readparameters::add(pop + "_thermal.radius", "Radius of the maxwellian distribution. Used for calculating the suprathermal moments. If set to 0 (default), the thermal/suprathermal DROs are skipped.", 0.0);
75
76 // Precipitation parameters
77 Readparameters::add(pop + "_precipitation.nChannels", "Number of energy channels for precipitation differential flux evaluation", 16);
78 Readparameters::add(pop + "_precipitation.emin", "Lowest energy channel (in eV) for precipitation differential flux evaluation", 0.1);
79 Readparameters::add(pop + "_precipitation.emax", "Highest energy channel (in eV) for precipitation differential flux evaluation", 100.0);
80 Readparameters::add(pop + "_precipitation.lossConeAngle", "Fixed loss cone opening angle (in deg) for precipitation differential flux evaluation", 10.0);
81
82 // Energy density parameters
83 Readparameters::add(pop + "_energydensity.limit1", "Lower limit of second bin for energy density, given in units of solar wind ram energy.", 5.0);
84 Readparameters::add(pop + "_energydensity.limit2", "Lower limit of third bin for energy density, given in units of solar wind ram energy.", 10.0);
85 Readparameters::add(pop + "_energydensity.solarwindspeed", "Incoming solar wind velocity magnitude in m/s. Used for calculating energy densities.", 0.0);
86 Readparameters::add(pop + "_energydensity.solarwindenergy", "Incoming solar wind ram energy in eV. Used for calculating energy densities.", 0.0);
87 }
88
89 return true;
90}
91
92
94 typedef Readparameters RP;
95
96 // Particle population parameters
97 for(unsigned int i =0; i < getObjectWrapper().particleSpecies.size(); i++) {
98
101
102 const std::string& pop = species.name;
103
104 // Sanity check name
105 if(species.name != vMesh.name) {
106 std::cerr << "ParticlePopulation parse error: Name " << species.name << " != " << vMesh.name << std::endl;
107 return false;
108 }
109
110 // Elementary particle parameters
111 RP::get(pop + "_properties.charge", species.charge);
113
114 RP::get(pop + "_properties.mass", species.mass);
115 std::string massUnit;
116 RP::get(pop + "_properties.mass_units", massUnit);
117 if(massUnit == "PROTON") {
119 } else if(massUnit == "ELECTRON") {
121 } else {
122 std::cerr << "Invalid mass unit for species " << pop << ": '" << massUnit << "'" << std::endl;
123 return false;
124 }
125
126 // sparsity parameters
127 RP::get(pop + "_sparse.minValue", species.sparseMinValue);
128 RP::get(pop + "_sparse.blockAddWidthV", species.sparseBlockAddWidthV);
129 RP::get(pop + "_sparse.conserve_mass", species.sparse_conserve_mass);
130 RP::get(pop + "_sparse.dynamicAlgorithm", species.sparseDynamicAlgorithm);
131 RP::get(pop + "_sparse.dynamicBulkValue1", species.sparseDynamicBulkValue1);
132 RP::get(pop + "_sparse.dynamicBulkValue2", species.sparseDynamicBulkValue2);
133 RP::get(pop + "_sparse.dynamicMinValue1", species.sparseDynamicMinValue1);
134 RP::get(pop + "_sparse.dynamicMinValue2", species.sparseDynamicMinValue2);
135
136
137 // Particle velocity space properties
138 RP::get(pop + "_vspace.vx_min",vMesh.meshLimits[0]);
139 RP::get(pop + "_vspace.vx_max",vMesh.meshLimits[1]);
140 RP::get(pop + "_vspace.vy_min",vMesh.meshLimits[2]);
141 RP::get(pop + "_vspace.vy_max",vMesh.meshLimits[3]);
142 RP::get(pop + "_vspace.vz_min",vMesh.meshLimits[4]);
143 RP::get(pop + "_vspace.vz_max",vMesh.meshLimits[5]);
144 RP::get(pop + "_vspace.vx_length",vMesh.gridLength[0]);
145 RP::get(pop + "_vspace.vy_length",vMesh.gridLength[1]);
146 RP::get(pop + "_vspace.vz_length",vMesh.gridLength[2]);
147 if(vMesh.gridLength[0] > MAX_BLOCKS_PER_DIM ||
148 vMesh.gridLength[1] > MAX_BLOCKS_PER_DIM ||
149 vMesh.gridLength[2] > MAX_BLOCKS_PER_DIM ) {
150
151 // Build error message as a string first, so that the cerr output hapens atomically and we don't spam
152 // thousands of unreadable lines through each other
153 std::string errormsg = "(VSPACE) ERROR: Velocity mesh for population " + species.name + " has too many blocks per dimension. Maximum defined in MAX_BLOCKS_PER_DIM is " + std::to_string(MAX_BLOCKS_PER_DIM) + " "
154 + std::string(__FILE__) + ":" + std::to_string(__LINE__) + "\n";
155 std::cerr << errormsg;
156 }
157
158 /* Special handling of WID=8; halve the number of blocks */
159 int myRank;
160 MPI_Comm_rank(MPI_COMM_WORLD,&myRank);
161 if ((WID==8 && P::adaptGPUWID)) {
162 // First verify that we can halve the value2
163 if ( (vMesh.gridLength[0]%2==0) && (vMesh.gridLength[1]%2==0) && (vMesh.gridLength[2]%2==0)) {
164 vMesh.gridLength[0] /= 2;
165 vMesh.gridLength[1] /= 2;
166 vMesh.gridLength[2] /= 2;
167 if(myRank==MASTER_RANK) {
168 std::cerr<<" Note: Using WID=8; Halving velocity block counts per dimension. Deactivate with parameter adaptGPUWID=false."<<std::endl;
169 }
170 } else {
171 if(myRank==MASTER_RANK) {
172 std::cerr<<" Warning: Using WID=8 but odd number of velocity blocks! Cannot halve the blocks count."<<std::endl;
173 }
174 }
175 }
176
177 vMesh.blockLength[0] = vMesh.blockLength[1] = vMesh.blockLength[2] = WID;
178
179 //Get thermal / suprathermal moments parameters
180 Readparameters::get(pop + "_thermal.radius", species.thermalRadius);
181 Readparameters::get(pop + "_thermal.vx", species.thermalV[0]);
182 Readparameters::get(pop + "_thermal.vy", species.thermalV[1]);
183 Readparameters::get(pop + "_thermal.vz", species.thermalV[2]);
184
185 //Get energy density parameters
186 Readparameters::get(pop + "_energydensity.limit1", species.EnergyDensityLimit1);
187 Readparameters::get(pop + "_energydensity.limit2", species.EnergyDensityLimit2);
188 Readparameters::get(pop + "_energydensity.solarwindenergy", species.SolarWindEnergy);
189 Readparameters::get(pop + "_energydensity.solarwindspeed", species.SolarWindSpeed);
190
191 const Real EPSILON = 1.e-25;
192 if (species.SolarWindEnergy < EPSILON) {
193 // Energy stored internally in SI units
194 species.SolarWindEnergy = 0.5 * species.mass * species.SolarWindSpeed * species.SolarWindSpeed;
195 } else {
196 species.SolarWindEnergy = species.SolarWindEnergy*physicalconstants::CHARGE;
197 }
198
199 // Get precipitation parameters
200 Readparameters::get(pop + "_precipitation.nChannels", species.precipitationNChannels);
201 Readparameters::get(pop + "_precipitation.emin", species.precipitationEmin);
202 Readparameters::get(pop + "_precipitation.emax", species.precipitationEmax);
203 Readparameters::get(pop + "_precipitation.lossConeAngle", species.precipitationLossConeAngle);
204 // Convert from eV to SI units
205 species.precipitationEmin = species.precipitationEmin*physicalconstants::CHARGE;
206 species.precipitationEmax = species.precipitationEmax*physicalconstants::CHARGE;
207 }
208
209 return true;
210}
for i
Definition Dispersion.m:24
static void get(const std::string &name, std::string &value)
static void add(const std::string &name, const std::string &desc, const std::string &defValue)
#define WID
Definition common.h:514
#define MASTER_RANK
Definition common.h:67
#define MAX_BLOCKS_PER_DIM
Definition common.h:73
float Real
Definition definitions.h:41
int myRank
Definition gpu_base.cpp:48
const Real CHARGE
Definition common.h:572
const Real MASS_ELECTRON
Definition common.h:573
const Real MASS_PROTON
Definition common.h:574
ARCH_HOSTDEV MeshWrapper * getMeshWrapper()
ObjectWrapper & getObjectWrapper()
Definition main.cpp:33
bool getPopulationParameters()
std::vector< species::Species > particleSpecies
bool addPopulationParameters()
static bool adaptGPUWID
Definition parameters.h:78
std::vector< vmesh::MeshParameters > * velocityMeshesCreation