| 605 | } |
| 606 | |
| 607 | void |
| 608 | PhysicalParticleContainer::AddPlasmaFromFile(PlasmaInjector & plasma_injector, |
| 609 | amrex::ParticleReal q_tot, |
| 610 | amrex::ParticleReal z_shift) |
| 611 | { |
| 612 | // Declare temporary vectors on the CPU |
| 613 | amrex::Gpu::HostVector<ParticleReal> particle_x; |
| 614 | amrex::Gpu::HostVector<ParticleReal> particle_z; |
| 615 | amrex::Gpu::HostVector<ParticleReal> particle_ux; |
| 616 | amrex::Gpu::HostVector<ParticleReal> particle_uz; |
| 617 | amrex::Gpu::HostVector<ParticleReal> particle_w; |
| 618 | amrex::Gpu::HostVector<ParticleReal> particle_y; |
| 619 | amrex::Gpu::HostVector<ParticleReal> particle_uy; |
| 620 | |
| 621 | #ifdef WARPX_USE_OPENPMD |
| 622 | //TODO: Make changes for read/write in multiple MPI ranks |
| 623 | if (ParallelDescriptor::IOProcessor()) { |
| 624 | // take ownership of the series and close it when done |
| 625 | auto series = std::any_cast<openPMD::Series>(std::move(plasma_injector.m_openpmd_input_series)); |
| 626 | |
| 627 | // assumption asserts: see PlasmaInjector |
| 628 | openPMD::Iteration it = series.iterations.begin()->second; |
| 629 | const ParmParse pp_species_name(species_name); |
| 630 | pp_species_name.query("impose_t_lab_from_file", impose_t_lab_from_file); |
| 631 | double t_lab = 0._prt; |
| 632 | if (impose_t_lab_from_file) { |
| 633 | // Impose t_lab as being the time stored in the openPMD file |
| 634 | t_lab = it.time<double>() * it.timeUnitSI(); |
| 635 | } |
| 636 | std::string const ps_name = it.particles.begin()->first; |
| 637 | openPMD::ParticleSpecies ps = it.particles.begin()->second; |
| 638 | |
| 639 | auto const npart = ps["position"]["x"].getExtent()[0]; |
| 640 | #if !defined(WARPX_DIM_1D_Z) // 2D, 3D, RZ, 1D_R |
| 641 | const std::shared_ptr<ParticleReal> ptr_x = ps["position"]["x"].loadChunk<ParticleReal>(); |
| 642 | const std::shared_ptr<ParticleReal> ptr_offset_x = ps["positionOffset"]["x"].loadChunk<ParticleReal>(); |
| 643 | auto const position_unit_x = static_cast<ParticleReal>(ps["position"]["x"].unitSI()); |
| 644 | auto const position_offset_unit_x = static_cast<ParticleReal>(ps["positionOffset"]["x"].unitSI()); |
| 645 | #endif |
| 646 | #if !(defined(WARPX_DIM_XZ) || defined(WARPX_DIM_1D_Z)) |
| 647 | const std::shared_ptr<ParticleReal> ptr_y = ps["position"]["y"].loadChunk<ParticleReal>(); |
| 648 | const std::shared_ptr<ParticleReal> ptr_offset_y = ps["positionOffset"]["y"].loadChunk<ParticleReal>(); |
| 649 | auto const position_unit_y = static_cast<ParticleReal>(ps["position"]["y"].unitSI()); |
| 650 | auto const position_offset_unit_y = static_cast<ParticleReal>(ps["positionOffset"]["y"].unitSI()); |
| 651 | #endif |
| 652 | #if !defined(WARPX_DIM_RCYLINDER) |
| 653 | const std::shared_ptr<ParticleReal> ptr_z = ps["position"]["z"].loadChunk<ParticleReal>(); |
| 654 | const std::shared_ptr<ParticleReal> ptr_offset_z = ps["positionOffset"]["z"].loadChunk<ParticleReal>(); |
| 655 | auto const position_unit_z = static_cast<ParticleReal>(ps["position"]["z"].unitSI()); |
| 656 | auto const position_offset_unit_z = static_cast<ParticleReal>(ps["positionOffset"]["z"].unitSI()); |
| 657 | #endif |
| 658 | |
| 659 | const std::shared_ptr<ParticleReal> ptr_ux = ps["momentum"]["x"].loadChunk<ParticleReal>(); |
| 660 | auto const momentum_unit_x = static_cast<ParticleReal>(ps["momentum"]["x"].unitSI()); |
| 661 | const std::shared_ptr<ParticleReal> ptr_uz = ps["momentum"]["z"].loadChunk<ParticleReal>(); |
| 662 | auto const momentum_unit_z = static_cast<ParticleReal>(ps["momentum"]["z"].unitSI()); |
| 663 | const std::shared_ptr<ParticleReal> ptr_w = ps["weighting"][openPMD::RecordComponent::SCALAR].loadChunk<ParticleReal>(); |
| 664 | auto const w_unit = static_cast<ParticleReal>(ps["weighting"][openPMD::RecordComponent::SCALAR].unitSI()); |