@@ -976,58 +976,9 @@ WarpXParticleContainer::DepositCharge (amrex::Vector<std::unique_ptr<amrex::Mult
976
976
int const finest_level = rho.size () - 1 ;
977
977
for (int lev = 0 ; lev <= finest_level; ++lev)
978
978
{
979
- // Reset the rho array if reset is True
980
- int const nc = WarpX::ncomps;
981
- if (reset) rho[lev]->setVal (0 ., icomp*nc, nc, rho[lev]->nGrowVect ());
982
-
983
- // Loop over particle tiles and deposit charge on each level
984
- #ifdef AMREX_USE_OMP
985
- #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
986
- {
987
- const int thread_num = omp_get_thread_num ();
988
- #else
989
- const int thread_num = 0 ;
990
- #endif
991
- for (WarpXParIter pti (*this , lev); pti.isValid (); ++pti)
992
- {
993
- const long np = pti.numParticles ();
994
- auto const & wp = pti.GetAttribs (PIdx::w);
995
-
996
- int * AMREX_RESTRICT ion_lev = nullptr ;
997
- if (do_field_ionization)
998
- {
999
- ion_lev = pti.GetiAttribs (particle_icomps[" ionizationLevel" ]).dataPtr ();
1000
- }
1001
-
1002
- DepositCharge (pti, wp, ion_lev, rho[lev].get (), icomp, 0 , np, thread_num, lev, lev);
1003
- }
1004
- #ifdef AMREX_USE_OMP
1005
- }
1006
- #endif
1007
-
1008
- #ifdef WARPX_DIM_RZ
1009
- if (apply_boundary_and_scale_volume)
1010
- {
1011
- WarpX::GetInstance ().ApplyInverseVolumeScalingToChargeDensity (rho[lev].get (), lev);
1012
- }
1013
- #endif
1014
-
1015
- // Exchange guard cells
1016
- if (!local) {
1017
- // Possible performance optimization:
1018
- // pass less than `rho[lev]->nGrowVect()` in the fifth input variable `dst_ng`
1019
- ablastr::utils::communication::SumBoundary (
1020
- *rho[lev], 0 , rho[lev]->nComp (), rho[lev]->nGrowVect (), rho[lev]->nGrowVect (),
1021
- WarpX::do_single_precision_comms, m_gdb->Geom (lev).periodicity ());
1022
- }
1023
-
1024
- #ifndef WARPX_DIM_RZ
1025
- if (apply_boundary_and_scale_volume)
1026
- {
1027
- // Reflect density over PEC boundaries, if needed.
1028
- WarpX::GetInstance ().ApplyRhofieldBoundary (lev, rho[lev].get (), PatchType::fine);
1029
- }
1030
- #endif
979
+ DepositCharge (
980
+ rho[lev], lev, local, reset, apply_boundary_and_scale_volume, icomp
981
+ );
1031
982
}
1032
983
1033
984
// Now that the charge has been deposited at each level,
@@ -1053,72 +1004,90 @@ WarpXParticleContainer::DepositCharge (amrex::Vector<std::unique_ptr<amrex::Mult
1053
1004
}
1054
1005
}
1055
1006
1056
- std::unique_ptr<MultiFab>
1057
- WarpXParticleContainer::GetChargeDensity (int lev, bool local)
1007
+ void
1008
+ WarpXParticleContainer::DepositCharge (std::unique_ptr<amrex::MultiFab>& rho,
1009
+ const int lev, const bool local, const bool reset,
1010
+ const bool apply_boundary_and_scale_volume,
1011
+ const int icomp)
1058
1012
{
1059
- const auto & gm = m_gdb->Geom (lev);
1060
- const auto & ba = m_gdb->ParticleBoxArray (lev);
1061
- const auto & dm = m_gdb->DistributionMap (lev);
1062
- BoxArray nba = ba;
1063
-
1064
- #ifdef WARPX_DIM_RZ
1065
- const bool is_PSATD_RZ =
1066
- (WarpX::electromagnetic_solver_id == ElectromagneticSolverAlgo::PSATD);
1067
- #else
1068
- const bool is_PSATD_RZ = false ;
1069
- #endif
1070
- if ( !is_PSATD_RZ )
1071
- nba.surroundingNodes ();
1072
-
1073
- // Number of guard cells for local deposition of rho
1074
- const WarpX& warpx = WarpX::GetInstance ();
1075
- const int ng_rho = warpx.get_ng_depos_rho ().max ();
1076
-
1077
- auto rho = std::make_unique<MultiFab>(nba,dm,WarpX::ncomps,ng_rho);
1078
- rho->setVal (0.0 );
1013
+ // Reset the rho array if reset is True
1014
+ int const nc = WarpX::ncomps;
1015
+ if (reset) rho->setVal (0 ., icomp*nc, nc, rho->nGrowVect ());
1079
1016
1017
+ // Loop over particle tiles and deposit charge on each level
1080
1018
#ifdef AMREX_USE_OMP
1081
1019
#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
1082
1020
{
1083
- #endif
1084
- #ifdef AMREX_USE_OMP
1085
- const int thread_num = omp_get_thread_num ();
1021
+ const int thread_num = omp_get_thread_num ();
1086
1022
#else
1087
- const int thread_num = 0 ;
1023
+ const int thread_num = 0 ;
1088
1024
#endif
1025
+ for (WarpXParIter pti (*this , lev); pti.isValid (); ++pti)
1026
+ {
1027
+ const long np = pti.numParticles ();
1028
+ auto const & wp = pti.GetAttribs (PIdx::w);
1089
1029
1090
- for (WarpXParIter pti (*this , lev); pti.isValid (); ++pti)
1030
+ int * AMREX_RESTRICT ion_lev = nullptr ;
1031
+ if (do_field_ionization)
1091
1032
{
1092
- const long np = pti.numParticles ();
1093
- auto & wp = pti.GetAttribs (PIdx::w);
1094
-
1095
- const int * const AMREX_RESTRICT ion_lev = (do_field_ionization)?
1096
- pti.GetiAttribs (particle_icomps[" ionizationLevel" ]).dataPtr ():nullptr ;
1097
-
1098
- DepositCharge (pti, wp, ion_lev, rho.get (), 0 , 0 , np,
1099
- thread_num, lev, lev);
1033
+ ion_lev = pti.GetiAttribs (particle_icomps[" ionizationLevel" ]).dataPtr ();
1100
1034
}
1035
+
1036
+ DepositCharge (pti, wp, ion_lev, rho.get (), icomp, 0 , np, thread_num, lev, lev);
1037
+ }
1101
1038
#ifdef AMREX_USE_OMP
1102
1039
}
1103
1040
#endif
1104
1041
1105
1042
#ifdef WARPX_DIM_RZ
1106
- WarpX::GetInstance ().ApplyInverseVolumeScalingToChargeDensity (rho.get (), lev);
1043
+ if (apply_boundary_and_scale_volume)
1044
+ {
1045
+ WarpX::GetInstance ().ApplyInverseVolumeScalingToChargeDensity (rho.get (), lev);
1046
+ }
1107
1047
#endif
1108
1048
1109
- if (!local) {
1049
+ // Exchange guard cells
1050
+ if ( !local ) {
1110
1051
// Possible performance optimization:
1111
1052
// pass less than `rho->nGrowVect()` in the fifth input variable `dst_ng`
1112
1053
ablastr::utils::communication::SumBoundary (
1113
1054
*rho, 0 , rho->nComp (), rho->nGrowVect (), rho->nGrowVect (),
1114
- WarpX::do_single_precision_comms, gm.periodicity ());
1055
+ WarpX::do_single_precision_comms,
1056
+ m_gdb->Geom (lev).periodicity ()
1057
+ );
1115
1058
}
1116
1059
1117
1060
#ifndef WARPX_DIM_RZ
1118
- // Reflect density over PEC boundaries, if needed.
1119
- WarpX::GetInstance ().ApplyRhofieldBoundary (lev, rho.get (), PatchType::fine);
1061
+ if (apply_boundary_and_scale_volume)
1062
+ {
1063
+ // Reflect density over PEC boundaries, if needed.
1064
+ WarpX::GetInstance ().ApplyRhofieldBoundary (lev, rho.get (), PatchType::fine);
1065
+ }
1120
1066
#endif
1067
+ }
1068
+
1069
+ std::unique_ptr<MultiFab>
1070
+ WarpXParticleContainer::GetChargeDensity (int lev, bool local)
1071
+ {
1072
+ const auto & ba = m_gdb->ParticleBoxArray (lev);
1073
+ const auto & dm = m_gdb->DistributionMap (lev);
1074
+ BoxArray nba = ba;
1075
+
1076
+ #ifdef WARPX_DIM_RZ
1077
+ const bool is_PSATD_RZ =
1078
+ (WarpX::electromagnetic_solver_id == ElectromagneticSolverAlgo::PSATD);
1079
+ #else
1080
+ const bool is_PSATD_RZ = false ;
1081
+ #endif
1082
+ if ( !is_PSATD_RZ )
1083
+ nba.surroundingNodes ();
1084
+
1085
+ // Number of guard cells for local deposition of rho
1086
+ const WarpX& warpx = WarpX::GetInstance ();
1087
+ const int ng_rho = warpx.get_ng_depos_rho ().max ();
1121
1088
1089
+ auto rho = std::make_unique<MultiFab>(nba, dm, WarpX::ncomps,ng_rho);
1090
+ DepositCharge (rho, lev, local, true , true , 0 );
1122
1091
return rho;
1123
1092
}
1124
1093
0 commit comments