diff options
-rw-r--r-- | Docs/source/usage/parameters.rst | 2 | ||||
-rw-r--r-- | Source/Particles/PhysicalParticleContainer.cpp | 32 |
2 files changed, 14 insertions, 20 deletions
diff --git a/Docs/source/usage/parameters.rst b/Docs/source/usage/parameters.rst index 87e8d0299..a965f8e8e 100644 --- a/Docs/source/usage/parameters.rst +++ b/Docs/source/usage/parameters.rst @@ -683,10 +683,10 @@ Particle initialization * ``external_file``: Inject macroparticles with properties (mass, charge, position, and momentum - :math:`\gamma \beta m c`) read from an external openPMD file. With it users can specify the additional arguments: ``<species_name>.injection_file`` (`string`) openPMD file name and - ``<species_name>.q_tot`` (`double`) optional (default is ``q_tot=0`` and no re-scaling is done, ``weight=q_p``) when specified it is used to re-scale the weight of externally loaded ``N`` physical particles, each of charge ``q_p``, to inject macroparticles of ``weight=<species_name>.q_tot/q_p/N``. ``<species_name>.charge`` (`double`) optional (default is read from openPMD file) when set this will be the charge of the physical particle represented by the injected macroparticles. ``<species_name>.mass`` (`double`) optional (default is read from openPMD file) when set this will be the charge of the physical particle represented by the injected macroparticles. ``<species_name>.z_shift`` (`double`) optional (default is no shift) when set this value will be added to the longitudinal, ``z``, position of the particles. + Warning: ``q_tot!=0`` is not supported with the ``external_file`` injection style. If a value is provided, it is ignored and no re-scaling is done. The external file must include the species ``openPMD::Record`` labeled ``position`` and ``momentum`` (`double` arrays), with dimensionality and units set via ``openPMD::setUnitDimension`` and ``setUnitSI``. If the external file also contains ``openPMD::Records`` for ``mass`` and ``charge`` (constant `double` scalars) then the species will use these, unless overwritten in the input file (see ``<species_name>.mass``, ``<species_name>.charge`` or ``<species_name>.species_type``). The ``external_file`` option is currently implemented for 2D, 3D and RZ geometries, with record components in the cartesian coordinates ``(x,y,z)`` for 3D and RZ, and ``(x,z)`` for 2D. diff --git a/Source/Particles/PhysicalParticleContainer.cpp b/Source/Particles/PhysicalParticleContainer.cpp index 51f7569a6..af50b3cf7 100644 --- a/Source/Particles/PhysicalParticleContainer.cpp +++ b/Source/Particles/PhysicalParticleContainer.cpp @@ -586,7 +586,7 @@ PhysicalParticleContainer::AddPlasmaFromFile(ParticleReal q_tot, openPMD::ParticleSpecies ps = it.particles.begin()->second; auto const npart = ps["position"]["x"].getExtent()[0]; -#if !defined(WARPX_DIM_1D_Z) +#if !defined(WARPX_DIM_1D_Z) // 2D, 3D, and RZ std::shared_ptr<ParticleReal> ptr_x = ps["position"]["x"].loadChunk<ParticleReal>(); double const position_unit_x = ps["position"]["x"].unitSI(); #endif @@ -596,6 +596,9 @@ PhysicalParticleContainer::AddPlasmaFromFile(ParticleReal q_tot, double const momentum_unit_x = ps["momentum"]["x"].unitSI(); std::shared_ptr<ParticleReal> ptr_uz = ps["momentum"]["z"].loadChunk<ParticleReal>(); double const momentum_unit_z = ps["momentum"]["z"].unitSI(); + std::shared_ptr<ParticleReal> ptr_w = ps["weighting"][openPMD::RecordComponent::SCALAR].loadChunk<ParticleReal>(); + double const w_unit = ps["weighting"][openPMD::RecordComponent::SCALAR].unitSI(); + # if !(defined(WARPX_DIM_XZ) || defined(WARPX_DIM_1D_Z)) std::shared_ptr<ParticleReal> ptr_y = ps["position"]["y"].loadChunk<ParticleReal>(); double const position_unit_y = ps["position"]["y"].unitSI(); @@ -604,32 +607,23 @@ PhysicalParticleContainer::AddPlasmaFromFile(ParticleReal q_tot, double momentum_unit_y = 1.0; if (ps["momentum"].contains("y")) { ptr_uy = ps["momentum"]["y"].loadChunk<ParticleReal>(); - momentum_unit_y = ps["momentum"]["y"].unitSI(); + momentum_unit_y = ps["momentum"]["y"].unitSI(); } series->flush(); // shared_ptr data can be read now - ParticleReal weight = 1.0_prt; // base standard: no info means "real" particles if (q_tot != 0.0) { - weight = std::abs(q_tot) / ( std::abs(charge) * ParticleReal(npart) ); - if (ps.contains("weighting")) { - std::stringstream ss; - ss << "Both '" << ps_name << ".q_tot' and '" - << ps_name << ".injection_file' specify a total charge.\n'" - << ps_name << ".q_tot' will take precedence."; - ablastr::warn_manager::WMRecordWarning("Species", ss.str()); - } - } - // ED-PIC extension? - else if (ps.contains("weighting")) { - // TODO: Add ASSERT_WITH_MESSAGE to test if weighting is a constant record - // TODO: Add ASSERT_WITH_MESSAGE for macroWeighted value in ED-PIC - ParticleReal w = ps["weighting"][openPMD::RecordComponent::SCALAR].loadChunk<ParticleReal>().get()[0]; - double const w_unit = ps["weighting"][openPMD::RecordComponent::SCALAR].unitSI(); - weight = w * w_unit; + std::stringstream warnMsg; + warnMsg << " Loading particle species from file. " << ps_name << ".q_tot is ignored."; + ablastr::warn_manager::WMRecordWarning("AddPlasmaFromFile", + warnMsg.str(), ablastr::warn_manager::WarnPriority::high); } for (auto i = decltype(npart){0}; i<npart; ++i){ + + ParticleReal const weight = ptr_w.get()[i]*w_unit; + #if !defined(WARPX_DIM_1D_Z) + ParticleReal const x = ptr_x.get()[i]*position_unit_x; #else ParticleReal const x = 0.0_prt; |