12 if (RP::helpRequested) {
13 RP::add(
"ParticlePopulations",
"Name of the simulated particle populations (string)",
"<population>");
15 RP::addComposing(
"ParticlePopulations",
"Name of the simulated particle populations (string)");
24 std::vector<std::string> popNames;
25 if (RP::helpRequested) {
26 popNames.push_back(std::string(
"<population>"));
28 RP::get(
"ParticlePopulations", popNames);
32 for(
const auto& pop : popNames) {
38 newSpecies.
name = newVMesh.
name = pop;
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);
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);
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);
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);
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);
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);
102 const std::string& pop =
species.name;
106 std::cerr <<
"ParticlePopulation parse error: Name " <<
species.name <<
" != " << vMesh.
name << std::endl;
111 RP::get(pop +
"_properties.charge",
species.charge);
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") {
122 std::cerr <<
"Invalid mass unit for species " << pop <<
": '" << massUnit <<
"'" << std::endl;
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);
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]);
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;
160 MPI_Comm_rank(MPI_COMM_WORLD,&
myRank);
168 std::cerr<<
" Note: Using WID=8; Halving velocity block counts per dimension. Deactivate with parameter adaptGPUWID=false."<<std::endl;
172 std::cerr<<
" Warning: Using WID=8 but odd number of velocity blocks! Cannot halve the blocks count."<<std::endl;
191 const Real EPSILON = 1.e-25;
192 if (
species.SolarWindEnergy < EPSILON) {
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 MAX_BLOCKS_PER_DIM
ARCH_HOSTDEV MeshWrapper * getMeshWrapper()
ObjectWrapper & getObjectWrapper()
bool getPopulationParameters()
std::vector< species::Species > particleSpecies
bool addPopulationParameters()
vmesh::LocalID gridLength[3]
vmesh::LocalID blockLength[3]
std::vector< vmesh::MeshParameters > * velocityMeshesCreation