Skip to content

Commit e62eaa8

Browse files
committed
Add gaussian_parse_momentum_function
1 parent f6cb58d commit e62eaa8

File tree

11 files changed

+221
-9
lines changed

11 files changed

+221
-9
lines changed

Docs/source/usage/parameters.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,17 @@ Particle initialization
908908
``<species_name>.momentum_function_uy(x,y,z)`` and ``<species_name>.momentum_function_uz(x,y,z)``,
909909
which gives the distribution of each component of the momentum as a function of space.
910910

911+
* ``gaussian_parse_momentum_function``: Gaussian momentum distribution where the mean momentum :math:`u = (u_{x},u_{y},u_{z})=(\gamma v_{x}/c,\gamma v_{y}/c,\gamma v_{z}/c)` and the standard deviation are given by functions of position in the input file.
912+
It requires the following arguments which specify the distribution of each component of the mean momentum
913+
and standard deviation as a function of space.
914+
915+
* ``<species_name>.momentum_function_ux_m(x,y,z)``: mean :math:`u_{x}`
916+
* ``<species_name>.momentum_function_uy_m(x,y,z)``: mean :math:`u_{y}`
917+
* ``<species_name>.momentum_function_uz_m(x,y,z)``: mean :math:`u_{z}`
918+
* ``<species_name>.momentum_function_ux_th(x,y,z)``: standard deviation of :math:`u_{x}`
919+
* ``<species_name>.momentum_function_uy_th(x,y,z)``: standard deviation of :math:`u_{y}`
920+
* ``<species_name>.momentum_function_uz_th(x,y,z)``: standard deviation of :math:`u_{z}`
921+
911922
* ``<species_name>.theta_distribution_type`` (`string`) optional (default ``constant``)
912923
Only read if ``<species_name>.momentum_distribution_type`` is ``maxwell_boltzmann`` or ``maxwell_juttner``.
913924
See documentation for these distributions (above) for constraints on values of theta. Temperatures less than zero are not allowed.

Examples/Tests/initial_distribution/analysis_distribution.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,34 @@
261261
assert(f7_error < tolerance)
262262

263263

264+
#============================================
265+
# Gaussian with parser mean and standard deviation
266+
#============================================
267+
268+
# load data
269+
bin_value_ux, bin_data_ux = read_reduced_diags_histogram("h9x.txt")[2:]
270+
bin_value_uy, bin_data_uy = read_reduced_diags_histogram("h9y.txt")[2:]
271+
bin_value_uz, bin_data_uz = read_reduced_diags_histogram("h9z.txt")[2:]
272+
273+
def Gaussian(mean, sigma, u):
274+
V = 8.0 # volume in m^3
275+
n = 1.0e21 # number density in 1/m^3
276+
return (n*V/(sigma*np.sqrt(2.*np.pi)))*np.exp(-(u - mean)**2/(2.*sigma**2))
277+
278+
du = 2./50
279+
f_ux = Gaussian(0.1 , 0.2 , bin_value_ux)*du
280+
f_uy = Gaussian(0.12, 0.21, bin_value_uy)*du
281+
f_uz = Gaussian(0.14, 0.22, bin_value_uz)*du
282+
283+
f9_error = np.sum(np.abs(f_ux - bin_data_ux)/f_ux.max()
284+
+np.abs(f_uy - bin_data_uy)/f_ux.max()
285+
+np.abs(f_uz - bin_data_uz)/f_uz.max()) / bin_value_ux.size
286+
287+
print('gaussian_parse_momentum_function velocity difference:', f9_error)
288+
289+
assert(f9_error < tolerance)
290+
291+
264292
#============================================
265293
# Cuboid distribution in momentum space
266294
#============================================

Examples/Tests/initial_distribution/inputs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ algo.particle_shape = 1
2929
#################################
3030
############ PLASMA #############
3131
#################################
32-
particles.species_names = gaussian maxwell_boltzmann maxwell_juttner beam maxwell_juttner_parser velocity_constant velocity_parser uniform
32+
particles.species_names = gaussian maxwell_boltzmann maxwell_juttner beam maxwell_juttner_parser velocity_constant velocity_parser uniform gaussian_parser
3333
particles.rigid_injected_species = beam
3434

3535
gaussian.charge = -q_e
@@ -119,6 +119,20 @@ velocity_parser.beta_distribution_type = "parser"
119119
velocity_parser.beta_function(x,y,z) = "-0.2 + 0.4 * heaviside(z,0)"
120120
velocity_parser.bulk_vel_dir = -y
121121

122+
gaussian_parser.charge = -q_e
123+
gaussian_parser.mass = m_e
124+
gaussian_parser.injection_style = "NRandomPerCell"
125+
gaussian_parser.num_particles_per_cell = 1000
126+
gaussian_parser.profile = constant
127+
gaussian_parser.density = 1.0e21
128+
gaussian_parser.momentum_distribution_type = "gaussian_parse_momentum_function"
129+
gaussian_parser.momentum_function_ux_m(x,y,z) = 0.1*z
130+
gaussian_parser.momentum_function_uy_m(x,y,z) = 0.12*z
131+
gaussian_parser.momentum_function_uz_m(x,y,z) = 0.14*z
132+
gaussian_parser.momentum_function_ux_th(x,y,z) = 0.2*z
133+
gaussian_parser.momentum_function_uy_th(x,y,z) = 0.21*z
134+
gaussian_parser.momentum_function_uz_th(x,y,z) = 0.22*z
135+
122136
uniform.charge = q_e
123137
uniform.mass = m_e
124138
uniform.injection_style = "NRandomPerCell"
@@ -144,7 +158,7 @@ uniform.uz_max = 11.2
144158
# 6 for maxwell-boltzmann with constant velocity
145159
# 7 for maxwell-boltzmann with parser velocity
146160
# 8 for cuboid in momentum space
147-
warpx.reduced_diags_names = h1x h1y h1z h2x h2y h2z h3 h3_filtered h4x h4y h4z bmmntr h5_neg h5_pos h6 h6uy h7 h7uy_pos h7uy_neg h8x h8y h8z
161+
warpx.reduced_diags_names = h1x h1y h1z h2x h2y h2z h3 h3_filtered h4x h4y h4z bmmntr h5_neg h5_pos h6 h6uy h7 h7uy_pos h7uy_neg h8x h8y h8z h9x h9y h9z
148162

149163
h1x.type = ParticleHistogram
150164
h1x.intervals = 1
@@ -350,6 +364,33 @@ h8z.bin_min = 0
350364
h8z.bin_max = 15
351365
h8z.histogram_function(t,x,y,z,ux,uy,uz) = "uz"
352366

367+
h9x.type = ParticleHistogram
368+
h9x.intervals = 1
369+
h9x.path = "./"
370+
h9x.species = gaussian_parser
371+
h9x.bin_number = 50
372+
h9x.bin_min = -1
373+
h9x.bin_max = 1
374+
h9x.histogram_function(t,x,y,z,ux,uy,uz) = "ux/z"
375+
376+
h9y.type = ParticleHistogram
377+
h9y.intervals = 1
378+
h9y.path = "./"
379+
h9y.species = gaussian_parser
380+
h9y.bin_number = 50
381+
h9y.bin_min = -1
382+
h9y.bin_max = 1
383+
h9y.histogram_function(t,x,y,z,ux,uy,uz) = "uy/z"
384+
385+
h9z.type = ParticleHistogram
386+
h9z.intervals = 1
387+
h9z.path = "./"
388+
h9z.species = gaussian_parser
389+
h9z.bin_number = 50
390+
h9z.bin_min = -1
391+
h9z.bin_max = 1
392+
h9z.histogram_function(t,x,y,z,ux,uy,uz) = "uz/z"
393+
353394
# our little beam monitor
354395
bmmntr.type = BeamRelevant
355396
bmmntr.intervals = 1

Source/Fluids/WarpXFluidContainer.H

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ protected:
174174
std::unique_ptr<amrex::Parser> ux_parser;
175175
std::unique_ptr<amrex::Parser> uy_parser;
176176
std::unique_ptr<amrex::Parser> uz_parser;
177+
std::unique_ptr<amrex::Parser> ux_th_parser;
178+
std::unique_ptr<amrex::Parser> uy_th_parser;
179+
std::unique_ptr<amrex::Parser> uz_th_parser;
177180

178181
// Keep a pointer to TemperatureProperties to ensure the lifetime of the
179182
// contained Parser

Source/Fluids/WarpXFluidContainer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ WarpXFluidContainer::WarpXFluidContainer(int nlevs_max, int ispecies, const std:
2929
const ParmParse pp_species_name(species_name);
3030
SpeciesUtils::parseDensity(species_name, h_inj_rho, density_parser);
3131
SpeciesUtils::parseMomentum(species_name, "none", h_inj_mom,
32-
ux_parser, uy_parser, uz_parser, h_mom_temp, h_mom_vel);
32+
ux_parser, uy_parser, uz_parser, ux_th_parser, uy_th_parser, uz_th_parser, h_mom_temp, h_mom_vel);
3333
if (h_inj_rho) {
3434
#ifdef AMREX_USE_GPU
3535
d_inj_rho = static_cast<InjectorDensity*>

Source/Initialization/InjectorMomentum.H

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,45 @@ struct InjectorMomentumParser
504504
amrex::ParserExecutor<3> m_ux_parser, m_uy_parser, m_uz_parser;
505505
};
506506

507+
// struct whose getMomentumm returns local momentum and thermal spread computed from parser.
508+
struct InjectorMomentumGaussianParser
509+
{
510+
InjectorMomentumGaussianParser (amrex::ParserExecutor<3> const& a_ux_m_parser,
511+
amrex::ParserExecutor<3> const& a_uy_m_parser,
512+
amrex::ParserExecutor<3> const& a_uz_m_parser,
513+
amrex::ParserExecutor<3> const& a_ux_th_parser,
514+
amrex::ParserExecutor<3> const& a_uy_th_parser,
515+
amrex::ParserExecutor<3> const& a_uz_th_parser) noexcept
516+
: m_ux_m_parser(a_ux_m_parser), m_uy_m_parser(a_uy_m_parser), m_uz_m_parser(a_uz_m_parser),
517+
m_ux_th_parser(a_ux_th_parser), m_uy_th_parser(a_uy_th_parser), m_uz_th_parser(a_uz_th_parser) {}
518+
519+
AMREX_GPU_HOST_DEVICE
520+
amrex::XDim3
521+
getMomentum (amrex::Real x, amrex::Real y, amrex::Real z,
522+
amrex::RandomEngine const& engine) const noexcept
523+
{
524+
amrex::Real const ux_m = m_ux_m_parser(x,y,z);
525+
amrex::Real const uy_m = m_uy_m_parser(x,y,z);
526+
amrex::Real const uz_m = m_uz_m_parser(x,y,z);
527+
amrex::Real const ux_th = m_ux_th_parser(x,y,z);
528+
amrex::Real const uy_th = m_uy_th_parser(x,y,z);
529+
amrex::Real const uz_th = m_uz_th_parser(x,y,z);
530+
return amrex::XDim3{amrex::RandomNormal(ux_m, ux_th, engine),
531+
amrex::RandomNormal(uy_m, uy_th, engine),
532+
amrex::RandomNormal(uz_m, uz_th, engine)};
533+
}
534+
535+
AMREX_GPU_HOST_DEVICE
536+
amrex::XDim3
537+
getBulkMomentum (amrex::Real x, amrex::Real y, amrex::Real z) const noexcept
538+
{
539+
return amrex::XDim3{m_ux_m_parser(x,y,z), m_uy_m_parser(x,y,z), m_uz_m_parser(x,y,z)};
540+
}
541+
542+
amrex::ParserExecutor<3> m_ux_m_parser, m_uy_m_parser, m_uz_m_parser;
543+
amrex::ParserExecutor<3> m_ux_th_parser, m_uy_th_parser, m_uz_th_parser;
544+
};
545+
507546
// Base struct for momentum injector.
508547
// InjectorMomentum contains a union (called Object) that holds any one
509548
// instance of:
@@ -512,6 +551,7 @@ struct InjectorMomentumParser
512551
// - InjectorMomentumGaussianFlux : to generate v*gaussian distribution;
513552
// - InjectorMomentumRadialExpansion: to generate radial expansion;
514553
// - InjectorMomentumParser : to generate momentum from parser;
554+
// - InjectorMomentumGaussianParser : to generate momentum and thermal spread from parser;
515555
// The choice is made at runtime, depending in the constructor called.
516556
// This mimics virtual functions.
517557
struct InjectorMomentum
@@ -532,6 +572,19 @@ struct InjectorMomentum
532572
object(t, a_ux_parser, a_uy_parser, a_uz_parser)
533573
{ }
534574

575+
// This constructor stores a InjectorMomentumGaussianParser in union object.
576+
InjectorMomentum (InjectorMomentumGaussianParser* t,
577+
amrex::ParserExecutor<3> const& a_ux_m_parser,
578+
amrex::ParserExecutor<3> const& a_uy_m_parser,
579+
amrex::ParserExecutor<3> const& a_uz_m_parser,
580+
amrex::ParserExecutor<3> const& a_ux_th_parser,
581+
amrex::ParserExecutor<3> const& a_uy_th_parser,
582+
amrex::ParserExecutor<3> const& a_uz_th_parser)
583+
: type(Type::gaussianparser),
584+
object(t, a_ux_m_parser, a_uy_m_parser, a_uz_m_parser,
585+
a_ux_th_parser, a_uy_th_parser, a_uz_th_parser)
586+
{ }
587+
535588
// This constructor stores a InjectorMomentumGaussian in union object.
536589
InjectorMomentum (InjectorMomentumGaussian* t,
537590
amrex::Real a_ux_m, amrex::Real a_uy_m, amrex::Real a_uz_m,
@@ -606,6 +659,10 @@ struct InjectorMomentum
606659
{
607660
return object.gaussian.getMomentum(x,y,z,engine);
608661
}
662+
case Type::gaussianparser:
663+
{
664+
return object.gaussianparser.getMomentum(x,y,z,engine);
665+
}
609666
case Type::gaussianflux:
610667
{
611668
return object.gaussianflux.getMomentum(x,y,z,engine);
@@ -654,6 +711,10 @@ struct InjectorMomentum
654711
{
655712
return object.gaussian.getBulkMomentum(x,y,z);
656713
}
714+
case Type::gaussianparser:
715+
{
716+
return object.gaussianparser.getBulkMomentum(x,y,z);
717+
}
657718
case Type::gaussianflux:
658719
{
659720
return object.gaussianflux.getBulkMomentum(x,y,z);
@@ -686,7 +747,7 @@ struct InjectorMomentum
686747
}
687748
}
688749

689-
enum struct Type { constant, gaussian, gaussianflux, uniform, boltzmann, juttner, radial_expansion, parser };
750+
enum struct Type { constant, gaussian, gaussianflux, uniform, boltzmann, juttner, radial_expansion, parser, gaussianparser };
690751
Type type;
691752

692753
private:
@@ -728,14 +789,24 @@ private:
728789
amrex::ParserExecutor<3> const& a_uy_parser,
729790
amrex::ParserExecutor<3> const& a_uz_parser) noexcept
730791
: parser(a_ux_parser, a_uy_parser, a_uz_parser) {}
792+
Object (InjectorMomentumGaussianParser*,
793+
amrex::ParserExecutor<3> const& a_ux_m_parser,
794+
amrex::ParserExecutor<3> const& a_uy_m_parser,
795+
amrex::ParserExecutor<3> const& a_uz_m_parser,
796+
amrex::ParserExecutor<3> const& a_ux_th_parser,
797+
amrex::ParserExecutor<3> const& a_uy_th_parser,
798+
amrex::ParserExecutor<3> const& a_uz_th_parser) noexcept
799+
: gaussianparser(a_ux_m_parser, a_uy_m_parser, a_uz_m_parser,
800+
a_ux_th_parser, a_uy_th_parser, a_uz_th_parser) {}
731801
InjectorMomentumConstant constant;
732802
InjectorMomentumGaussian gaussian;
733803
InjectorMomentumGaussianFlux gaussianflux;
734804
InjectorMomentumUniform uniform;
735805
InjectorMomentumBoltzmann boltzmann;
736806
InjectorMomentumJuttner juttner;
737807
InjectorMomentumRadialExpansion radial_expansion;
738-
InjectorMomentumParser parser;
808+
InjectorMomentumParser parser;
809+
InjectorMomentumGaussianParser gaussianparser;
739810
};
740811
Object object;
741812
};

Source/Initialization/InjectorMomentum.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ void InjectorMomentum::clear ()
1515
{
1616
case Type::parser:
1717
case Type::gaussian:
18+
case Type::gaussianparser:
1819
case Type::gaussianflux:
1920
case Type::uniform:
2021
case Type::boltzmann:

Source/Initialization/PlasmaInjector.H

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ protected:
173173
std::unique_ptr<amrex::Parser> ux_parser;
174174
std::unique_ptr<amrex::Parser> uy_parser;
175175
std::unique_ptr<amrex::Parser> uz_parser;
176+
std::unique_ptr<amrex::Parser> ux_th_parser;
177+
std::unique_ptr<amrex::Parser> uy_th_parser;
178+
std::unique_ptr<amrex::Parser> uz_th_parser;
176179

177180
// Keep a pointer to TemperatureProperties to ensure the lifetime of the
178181
// contained Parser

Source/Initialization/PlasmaInjector.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,9 @@ void PlasmaInjector::setupGaussianBeam (const amrex::ParmParse& pp_species_name)
248248
"Error: Symmetrization only supported to orders 4 or 8 ");
249249
gaussian_beam = true;
250250
SpeciesUtils::parseMomentum(species_name, "gaussian_beam", h_inj_mom,
251-
ux_parser, uy_parser, uz_parser, h_mom_temp, h_mom_vel);
251+
ux_parser, uy_parser, uz_parser,
252+
ux_th_parser, uy_th_parser, uz_th_parser,
253+
h_mom_temp, h_mom_vel);
252254
#if defined(WARPX_DIM_XZ)
253255
WARPX_ALWAYS_ASSERT_WITH_MESSAGE( y_rms > 0._rt,
254256
"Error: Gaussian beam y_rms must be strictly greater than 0 in 2D "
@@ -289,7 +291,9 @@ void PlasmaInjector::setupNRandomPerCell (const amrex::ParmParse& pp_species_nam
289291
#endif
290292
SpeciesUtils::parseDensity(species_name, h_inj_rho, density_parser);
291293
SpeciesUtils::parseMomentum(species_name, "nrandompercell", h_inj_mom,
292-
ux_parser, uy_parser, uz_parser, h_mom_temp, h_mom_vel);
294+
ux_parser, uy_parser, uz_parser,
295+
ux_th_parser, uy_th_parser, uz_th_parser,
296+
h_mom_temp, h_mom_vel);
293297
}
294298

295299
void PlasmaInjector::setupNFluxPerCell (const amrex::ParmParse& pp_species_name)
@@ -367,7 +371,10 @@ void PlasmaInjector::setupNFluxPerCell (const amrex::ParmParse& pp_species_name)
367371

368372
parseFlux(pp_species_name);
369373
SpeciesUtils::parseMomentum(species_name, "nfluxpercell", h_inj_mom,
370-
ux_parser, uy_parser, uz_parser, h_mom_temp, h_mom_vel, flux_normal_axis, flux_direction);
374+
ux_parser, uy_parser, uz_parser,
375+
ux_th_parser, uy_th_parser, uz_th_parser,
376+
h_mom_temp, h_mom_vel,
377+
flux_normal_axis, flux_direction);
371378
}
372379

373380
void PlasmaInjector::setupNuniformPerCell (const amrex::ParmParse& pp_species_name)
@@ -420,7 +427,9 @@ void PlasmaInjector::setupNuniformPerCell (const amrex::ParmParse& pp_species_na
420427
num_particles_per_cell_each_dim[2];
421428
SpeciesUtils::parseDensity(species_name, h_inj_rho, density_parser);
422429
SpeciesUtils::parseMomentum(species_name, "nuniformpercell", h_inj_mom,
423-
ux_parser, uy_parser, uz_parser, h_mom_temp, h_mom_vel);
430+
ux_parser, uy_parser, uz_parser,
431+
ux_th_parser, uy_th_parser, uz_th_parser,
432+
h_mom_temp, h_mom_vel);
424433
}
425434

426435
void PlasmaInjector::setupExternalFile (const amrex::ParmParse& pp_species_name)

Source/Utils/SpeciesUtils.H

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ namespace SpeciesUtils {
3030
std::unique_ptr<amrex::Parser>& ux_parser,
3131
std::unique_ptr<amrex::Parser>& uy_parser,
3232
std::unique_ptr<amrex::Parser>& uz_parser,
33+
std::unique_ptr<amrex::Parser>& ux_th_parser,
34+
std::unique_ptr<amrex::Parser>& uy_th_parser,
35+
std::unique_ptr<amrex::Parser>& uz_th_parser,
3336
std::unique_ptr<TemperatureProperties>& h_mom_temp,
3437
std::unique_ptr<VelocityProperties>& h_mom_vel,
3538
int flux_normal_axis=0, int flux_direction=0);

0 commit comments

Comments
 (0)