Skip to content

Commit 7b31142

Browse files
author
Marco Garten
committed
Implement Reviewer suggestions
1 parent c2d52bb commit 7b31142

File tree

7 files changed

+101
-113
lines changed

7 files changed

+101
-113
lines changed

src/picongpu/include/particles/ionization/byCollision/ThomasFermi/AlgorithmThomasFermi.hpp

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@
2020

2121
#pragma once
2222

23-
#include "pmacc_types.hpp"
2423
#include "simulation_defines.hpp"
2524
#include "particles/traits/GetAtomicNumbers.hpp"
2625
#include "traits/attribute/GetChargeState.hpp"
26+
2727
#include "algorithms/math/floatMath/floatingPoint.tpp"
28-
#include "particles/ionization/byCollision/ThomasFermi/TFFittingParameters.def"
2928

3029
/** \file AlgorithmThomasFermi.hpp
3130
*
@@ -48,11 +47,13 @@ namespace ionization
4847
* \brief calculation for the Thomas-Fermi pressure ionization model
4948
*
5049
* This model uses local density and "temperature" values as input
51-
* parameters. To be able to speak of a "temperature" an equilibrium state
52-
* would be required. Typical high power laser-plasma interaction is highly
50+
* parameters. A physical temperature requires a defined equilibrium state.
51+
* Typical high power laser-plasma interaction is highly
5352
* non-equilibrated, though. The name "temperature" is kept to illustrate
5453
* the origination from the Thomas-Fermi model. It is nevertheless
55-
* more accurate to think of it as an averaged kinetic energy.
54+
* more accurate to think of it as an averaged kinetic energy
55+
* which is not backed by the model and should therefore only be used with
56+
* a certain suspicion in such Non-LTE scenarios.
5657
*/
5758
struct AlgorithmThomasFermi
5859
{
@@ -68,86 +69,87 @@ namespace ionization
6869
* \param randNr random number
6970
*/
7071
template<typename KinEnergyDensityType, typename DensityType, typename ParticleType >
71-
HDINLINE void
72+
HDINLINE float_X
7273
operator()( const KinEnergyDensityType kinEnergyDensity, const DensityType density, ParticleType& parentIon, float_X randNr )
7374
{
7475

7576
/* @TODO replace the float_64 with float_X and make sure the values are scaled to PIConGPU units */
76-
const float_64 protonNumber = GetAtomicNumbers<ParticleType>::type::numberOfProtons;
77-
const float_64 neutronNumber = GetAtomicNumbers<ParticleType>::type::numberOfNeutrons;
77+
float_64 constexpr protonNumber = GetAtomicNumbers<ParticleType>::type::numberOfProtons;
78+
float_64 constexpr neutronNumber = GetAtomicNumbers<ParticleType>::type::numberOfNeutrons;
7879
float_64 chargeState = attribute::getChargeState(parentIon);
7980

8081
/* ionization condition */
8182
if (chargeState < protonNumber)
8283
{
8384
/* atomic mass number (usually A) A = N + Z */
84-
float_64 massNumber = neutronNumber + protonNumber;
85+
float_64 constexpr massNumber = neutronNumber + protonNumber;
8586

8687
/** @TODO replace the static_cast<float_64> by casts to float_X
8788
* or leave out entirely and compute everything in PIConGPU scaled units
8889
*/
89-
float_64 const densityUnit = static_cast<float_64>(particleToGrid::derivedAttributes::Density().getUnit()[0]);
90-
float_64 const kinEnergyDensityUnit = static_cast<float_64>(particleToGrid::derivedAttributes::EnergyDensity().getUnit()[0]);
90+
float_64 constexpr densityUnit = static_cast<float_64>(particleToGrid::derivedAttributes::Density().getUnit()[0]);
91+
float_64 constexpr kinEnergyDensityUnit = static_cast<float_64>(particleToGrid::derivedAttributes::EnergyDensity().getUnit()[0]);
9192
/* convert from kinetic energy density to average kinetic energy per particle */
92-
float_64 kinEnergy = (kinEnergyDensity / density) * (kinEnergyDensityUnit / densityUnit);
93+
float_64 constexpr kinEnergyUnit = kinEnergyDensityUnit / densityUnit;
94+
float_64 const kinEnergy = (kinEnergyDensity / density) * kinEnergyUnit;
9395
/** convert kinetic energy in J to "temperature" in eV by assuming an ideal electron gas
9496
* E_kin = 3/2 k*T
9597
*/
96-
float_64 temperature = kinEnergy * UNITCONV_Joule_to_keV * float_64(1.e3) * float_64(2./3.);
98+
float_64 constexpr convKinEnergyToTemperature = UNITCONV_Joule_to_keV * float_64(1.e3) * float_64(2./3.);
99+
float_64 const temperature = kinEnergy * convKinEnergyToTemperature;
97100

98-
float_64 T_0 = temperature/math::pow(protonNumber,float_64(4./3.));
101+
float_64 const T_0 = temperature/math::pow(protonNumber,float_64(4./3.));
99102

100-
float_64 T_F = T_0 / (float_64(1.) + T_0);
103+
float_64 const T_F = T_0 / (float_64(1.) + T_0);
101104

102-
/* for all the fitting parameters @see TFFittingParameters.def */
105+
/* for all the fitting parameters @see ionizerConfig.param */
103106

104107
/** this is weird - I have to define temporary variables because
105108
* otherwise the math::pow function won't recognize those at the
106109
* exponent position */
107-
float_64 TFA2_temp = TFA2;
108-
float_64 TFA4_temp = TFA4;
109-
float_64 TFBeta_temp = TFBeta;
110+
float_64 constexpr TFA2_temp = TFA2;
111+
float_64 constexpr TFA4_temp = TFA4;
112+
float_64 constexpr TFBeta_temp = TFBeta;
110113

111-
float_64 A = TFA1 * math::pow(T_0,TFA2_temp) + TFA3 * math::pow(T_0,TFA4_temp);
114+
float_64 const A = TFA1 * math::pow(T_0,TFA2_temp) + TFA3 * math::pow(T_0,TFA4_temp);
112115

113-
float_64 B = -math::exp(TFB0 + TFB1*T_F + TFB2*math::pow(T_F,float_64(7.)));
116+
float_64 const B = -math::exp(TFB0 + TFB1*T_F + TFB2*math::pow(T_F,float_64(7.)));
114117

115-
float_64 C = TFC1 * T_F + TFC2;
118+
float_64 const C = TFC1 * T_F + TFC2;
116119

117-
/** requires mass density in g/cm^3
118-
* @TODO relocate constants to param file or leave out and calculate unitless
119-
*/
120-
float_64 const nAvogadro = 6.022e23;
121-
float_64 const convM3ToCM3 = 1.e6;
120+
/* requires mass density in g/cm^3 */
121+
float_64 constexpr nAvogadro = SI::N_AVOGADRO;
122+
float_64 constexpr convM3ToCM3 = 1.e6;
122123

123-
float_64 massDensity = density * densityUnit * massNumber / nAvogadro / convM3ToCM3;
124-
float_64 R = massDensity/(protonNumber * massNumber);
124+
float_64 constexpr convToMassDensity = densityUnit * massNumber / nAvogadro / convM3ToCM3;
125+
float_64 const massDensity = density * convToMassDensity;
125126

126-
float_64 Q_1 = A * math::pow(R,B);
127+
float_64 constexpr atomicTimesMassNumber = protonNumber * massNumber;
128+
float_64 const R = massDensity/atomicTimesMassNumber;
127129

128-
float_64 Q = math::pow(math::pow(R,C) + math::pow(Q_1,C), float_64(1.)/C);
130+
float_64 const Q_1 = A * math::pow(R,B);
129131

130-
float_64 x = TFAlpha * math::pow(Q,TFBeta_temp);
132+
float_64 const Q = math::pow(math::pow(R,C) + math::pow(Q_1,C), float_64(1.)/C);
133+
134+
float_64 const x = TFAlpha * math::pow(Q,TFBeta_temp);
131135

132136
/* Thomas-Fermi average ionization state */
133-
float_64 ZStar = protonNumber * x / (float_64(1.) + x + math::sqrt(float_64(1.) + float_64(2.)*x));
137+
float_64 const ZStar = protonNumber * x / (float_64(1.) + x + math::sqrt(float_64(1.) + float_64(2.)*x));
134138

135139
/* integral part of the charge state */
136140
float_64 intZStar;
137141
/* fractional part of the charge state */
138142
float_X fracZStar = static_cast<float_X>(math::modf(ZStar,&intZStar));
139143

140144
/* determine charge state */
141-
float_X chargeState = static_cast<float_X>(intZStar) + float_X(1.0)*(randNr < fracZStar);
145+
float_X const chargeState = static_cast<float_X>(intZStar) + float_X(1.0)*(randNr < fracZStar);
142146

143147
/** determine the new number of bound electrons from the TF ionization state
144148
* @TODO introduce partial macroparticle ionization / ionization distribution at some point
145149
*/
146-
float_X newBoundElectrons = protonNumber - chargeState;
147-
/* safety check to avoid double counting since recombination is not yet implemented */
148-
if (newBoundElectrons < parentIon[boundElectrons_])
149-
/* update the particle attribute only if more free electrons are to be created */
150-
parentIon[boundElectrons_] = newBoundElectrons;
150+
float_X const newBoundElectrons = protonNumber - chargeState;
151+
152+
return newBoundElectrons;
151153
}
152154

153155
}

src/picongpu/include/particles/ionization/byCollision/ThomasFermi/TFFittingParameters.def

Lines changed: 0 additions & 54 deletions
This file was deleted.

src/picongpu/include/particles/ionization/byCollision/ThomasFermi/ThomasFermi.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ namespace ionization
4040
struct ThomasFermi_Impl;
4141

4242
/** Thomas-Fermi impact ionization model
43-
*
4443
*
4544
* This ionization model describes the atom inside the Thomas-Fermi framework
4645
* in a self-consistent way. There the electrons are modeled as a density

src/picongpu/include/particles/ionization/byCollision/ThomasFermi/ThomasFermi_Impl.hpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,26 @@
2020

2121
#pragma once
2222

23-
#include <boost/type_traits/integral_constant.hpp>
24-
2523
#include "simulation_defines.hpp"
2624
#include "traits/Resolve.hpp"
2725
#include "traits/UsesRNG.hpp"
28-
#include "mappings/kernel/AreaMapping.hpp"
2926

3027
#include "fields/FieldTmp.hpp"
3128

3229
#include "particles/ionization/byCollision/ThomasFermi/ThomasFermi.def"
3330
#include "particles/ionization/byCollision/ThomasFermi/AlgorithmThomasFermi.hpp"
3431
#include "particles/ionization/ionization.hpp"
35-
36-
#include "compileTime/conversion/TypeToPointerPair.hpp"
37-
#include "memory/boxes/DataBox.hpp"
38-
3932
#include "particles/ionization/ionizationMethods.hpp"
4033

4134
#include "random/methods/XorMin.hpp"
4235
#include "random/distributions/Uniform.hpp"
4336
#include "random/RNGProvider.hpp"
37+
#include "dataManagement/DataConnector.hpp"
38+
#include "compileTime/conversion/TypeToPointerPair.hpp"
39+
#include "memory/boxes/DataBox.hpp"
40+
#include "mappings/kernel/AreaMapping.hpp"
41+
42+
#include <boost/type_traits/integral_constant.hpp>
4443

4544
namespace picongpu
4645
{
@@ -72,8 +71,8 @@ namespace ionization
7271
struct ThomasFermi_Impl
7372
{
7473

75-
typedef T_DestSpecies DestSpecies;
76-
typedef T_SrcSpecies SrcSpecies;
74+
using DestSpecies = T_DestSpecies;
75+
using SrcSpecies = T_SrcSpecies;
7776

7877
typedef typename SrcSpecies::FrameType FrameType;
7978

@@ -106,7 +105,7 @@ namespace ionization
106105
typedef typename RNGFactory::GetRandomType<Distribution>::type RandomGen;
107106
RandomGen randomGen;
108107

109-
typedef MappingDesc::SuperCellSize TVec;
108+
using SuperCellSize = MappingDesc::SuperCellSize;
110109

111110
typedef FieldTmp::ValueType ValueType_Rho;
112111
typedef FieldTmp::ValueType ValueType_Ene;
@@ -234,10 +233,10 @@ namespace ionization
234233
/* alias for the single macro-particle */
235234
auto particle = ionFrame[localIdx];
236235
/* particle position, used for field-to-particle interpolation */
237-
floatD_X pos = particle[position_];
238-
const int particleCellIdx = particle[localCellIdx_];
236+
floatD_X const pos = particle[position_];
237+
int const particleCellIdx = particle[localCellIdx_];
239238
/* multi-dim coordinate of the local cell inside the super cell */
240-
DataSpace<TVec::dim> localCell(DataSpaceOperations<TVec::dim>::template map<TVec > (particleCellIdx));
239+
DataSpace<SuperCellSize::dim> localCell(DataSpaceOperations<SuperCellSize::dim>::template map<SuperCellSize > (particleCellIdx));
241240
/* interpolation of density */
242241
const fieldSolver::numericalCellType::traits::FieldPosition<FieldTmp> fieldPosRho;
243242
ValueType_Rho densityV = Field2ParticleInterpolation()
@@ -257,14 +256,19 @@ namespace ionization
257256

258257
/* this is the point where actual ionization takes place */
259258
IonizationAlgorithm ionizeAlgo;
260-
ionizeAlgo(
259+
float_X newBoundElectrons = ionizeAlgo(
261260
kinEnergyDensity, density,
262261
particle, this->randomGen()
263262
);
264263

265-
/* determine number of new macro electrons to be created */
266-
newMacroElectrons = prevBoundElectrons - particle[boundElectrons_];
264+
particle[boundElectrons_] = newBoundElectrons;
267265

266+
/* safety check to avoid double counting since recombination is not yet implemented */
267+
if (prevBoundElectrons > newBoundElectrons)
268+
{
269+
/* determine number of new macro electrons to be created */
270+
newMacroElectrons = static_cast<unsigned int>(prevBoundElectrons - newBoundElectrons);
271+
}
268272
}
269273

270274
};

src/picongpu/include/particles/ionization/byCollision/collisionalIonizationCalc.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ namespace particles
3535
namespace ionization
3636
{
3737

38-
struct AlgorithmNone;
39-
4038
struct AlgorithmThomasFermi;
4139

4240
} // namespace ionization

src/picongpu/include/simulation_defines/param/ionizerConfig.param

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,34 @@ namespace picongpu
5959
6.665,
6060
6.665
6161
);
62-
}
62+
63+
namespace particles
64+
{
65+
namespace ionization
66+
{
67+
68+
/* Fitting parameters to average ionization degree Z* = 4/3*pi*R_0^3 * n(R_0)
69+
* as an extension towards arbitrary atoms and temperatures
70+
*
71+
* See table IV of
72+
* \url http://www.sciencedirect.com/science/article/pii/S0065219908601451
73+
* doi:10.1016/S0065-2199(08)60145-1
74+
*/
75+
float_X constexpr TFAlpha = 14.3139;
76+
float_X constexpr TFBeta = 0.6624;
77+
78+
float_X constexpr TFA1 = 3.323e-3;
79+
float_X constexpr TFA2 = 9.718e-1;
80+
float_X constexpr TFA3 = 9.26148e-5;
81+
float_X constexpr TFA4 = 3.10165;
82+
83+
float_X constexpr TFB0 = -1.7630;
84+
float_X constexpr TFB1 = 1.43175;
85+
float_X constexpr TFB2 = 0.31546;
86+
87+
float_X constexpr TFC1 = -0.366667;
88+
float_X constexpr TFC2 = 0.983333;
89+
90+
} // namespace ionization
91+
} // namespace particles
92+
} // namespace picongpu

src/picongpu/include/simulation_defines/param/physicalConstants.param

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@ namespace picongpu
6363
* 150 attoseconds (classical electron orbit time in hydrogen) / 2 PI
6464
*/
6565
constexpr float_64 ATOMIC_UNIT_TIME = 2.4189e-17;
66+
67+
/** Avogadro number
68+
* unit: mol^-1
69+
*
70+
* Y. Azuma et al. Improved measurement results for the Avogadro
71+
* constant using a 28-Si-enriched crystal, Metrologie 52, 2015, 360-375
72+
* doi:10.1088/0026-1394/52/2/360
73+
*/
74+
constexpr float_64 N_AVOGADRO = 6.02214076e23;
6675
}
6776

6877
// converts

0 commit comments

Comments
 (0)