diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/Diagnostics/FieldIO.H | 1 | ||||
-rw-r--r-- | Source/Diagnostics/FieldIO.cpp | 184 | ||||
-rw-r--r-- | Source/Diagnostics/WarpXIO.cpp | 23 | ||||
-rw-r--r-- | Source/Evolve/WarpXEvolveEM.cpp | 27 | ||||
-rw-r--r-- | Source/FortranInterface/WarpX_f.H | 3 | ||||
-rw-r--r-- | Source/FortranInterface/WarpX_picsar.F90 | 59 | ||||
-rw-r--r-- | Source/Initialization/PlasmaInjector.cpp | 6 | ||||
-rw-r--r-- | Source/Parallelization/WarpXComm.cpp | 90 | ||||
-rw-r--r-- | Source/Parallelization/WarpXRegrid.cpp | 66 | ||||
-rw-r--r-- | Source/Particles/MultiParticleContainer.cpp | 2 | ||||
-rw-r--r-- | Source/Particles/PhysicalParticleContainer.H | 1 | ||||
-rw-r--r-- | Source/Particles/PhysicalParticleContainer.cpp | 11 | ||||
-rw-r--r-- | Source/Particles/RigidInjectedParticleContainer.cpp | 3 | ||||
-rw-r--r-- | Source/Particles/WarpXParticleContainer.H | 3 | ||||
-rw-r--r-- | Source/Particles/WarpXParticleContainer.cpp | 27 | ||||
-rw-r--r-- | Source/WarpX.H | 4 | ||||
-rw-r--r-- | Source/WarpX.cpp | 112 |
17 files changed, 435 insertions, 187 deletions
diff --git a/Source/Diagnostics/FieldIO.H b/Source/Diagnostics/FieldIO.H index 1a3b45580..24fd6abb6 100644 --- a/Source/Diagnostics/FieldIO.H +++ b/Source/Diagnostics/FieldIO.H @@ -15,6 +15,7 @@ PackPlotDataPtrs (Vector<const MultiFab*>& pmf, void AverageAndPackVectorField( MultiFab& mf_avg, const std::array< std::unique_ptr<MultiFab>, 3 >& vector_field, + const DistributionMapping& dm, const int dcomp, const int ngrow ); void diff --git a/Source/Diagnostics/FieldIO.cpp b/Source/Diagnostics/FieldIO.cpp index 5c523804e..a1fd61b25 100644 --- a/Source/Diagnostics/FieldIO.cpp +++ b/Source/Diagnostics/FieldIO.cpp @@ -204,6 +204,20 @@ WriteOpenPMDFields( const std::string& filename, } #endif // WARPX_USE_OPENPMD +void +ConstructTotalRZField(std::array< std::unique_ptr<MultiFab>, 3 >& mf_total, + const std::array< std::unique_ptr<MultiFab>, 3 >& vector_field) +{ + // Sum over the real components, giving quantity at theta=0 + MultiFab::Copy(*mf_total[0], *vector_field[0], 0, 0, 1, vector_field[0]->nGrowVect()); + MultiFab::Copy(*mf_total[1], *vector_field[1], 0, 0, 1, vector_field[1]->nGrowVect()); + MultiFab::Copy(*mf_total[2], *vector_field[2], 0, 0, 1, vector_field[2]->nGrowVect()); + for (int ic=2 ; ic < vector_field[0]->nComp() ; ic += 2) { + MultiFab::Add(*mf_total[0], *vector_field[0], ic, 0, 1, vector_field[0]->nGrowVect()); + MultiFab::Add(*mf_total[1], *vector_field[1], ic, 0, 1, vector_field[1]->nGrowVect()); + MultiFab::Add(*mf_total[2], *vector_field[2], ic, 0, 1, vector_field[2]->nGrowVect()); + } +} void PackPlotDataPtrs (Vector<const MultiFab*>& pmf, @@ -228,6 +242,7 @@ PackPlotDataPtrs (Vector<const MultiFab*>& pmf, void AverageAndPackVectorField( MultiFab& mf_avg, const std::array< std::unique_ptr<MultiFab>, 3 >& vector_field, + const DistributionMapping& dm, const int dcomp, const int ngrow ) { // The object below is temporary, and is needed because @@ -256,23 +271,101 @@ AverageAndPackVectorField( MultiFab& mf_avg, // - Face centered, in the same way as B on a Yee grid } else if ( vector_field[0]->is_nodal(0) ){ - PackPlotDataPtrs(srcmf, vector_field); - amrex::average_face_to_cellcenter( mf_avg, dcomp, srcmf, ngrow); + // Note that average_face_to_cellcenter operates only on the number of + // arrays equal to the number of dimensions. So, for 2D, PackPlotDataPtrs + // packs in the x and z (or r and z) arrays, which are then cell averaged. + // The Copy code then copies the z from the 2nd to the 3rd field, + // and copies over directly the y (or theta) component (which is + // already cell centered). + if (vector_field[0]->nComp() > 1) { +#ifdef WARPX_RZ + // When there are more than one components, the total + // fields needs to be constructed in temporary MultiFabs + // Note that mf_total is declared in the same way as + // vector_field so that it can be passed into PackPlotDataPtrs. + std::array<std::unique_ptr<MultiFab>,3> mf_total; + mf_total[0].reset(new MultiFab(vector_field[0]->boxArray(), dm, 1, vector_field[0]->nGrowVect())); + mf_total[1].reset(new MultiFab(vector_field[1]->boxArray(), dm, 1, vector_field[1]->nGrowVect())); + mf_total[2].reset(new MultiFab(vector_field[2]->boxArray(), dm, 1, vector_field[2]->nGrowVect())); + ConstructTotalRZField(mf_total, vector_field); + PackPlotDataPtrs(srcmf, mf_total); + amrex::average_face_to_cellcenter( mf_avg, dcomp, srcmf, ngrow); + MultiFab::Copy( mf_avg, mf_avg, dcomp+1, dcomp+2, 1, ngrow); + MultiFab::Copy( mf_avg, *mf_total[1], 0, dcomp+1, 1, ngrow); + // Also add the real and imaginary parts of each mode. + /* Not supported yet + for (int i=0 ; i < vector_field[0]->nComp() ; i++) { + MultiFab v_comp0(*vector_field[0], amrex::make_alias, i, 1); + MultiFab v_comp1(*vector_field[1], amrex::make_alias, i, 1); + MultiFab v_comp2(*vector_field[2], amrex::make_alias, i, 1); + srcmf[0] = &v_comp0; + srcmf[1] = &v_comp2; + int id = dcomp + 3*(i + 1); + amrex::average_face_to_cellcenter( mf_avg, id, srcmf, ngrow); + MultiFab::Copy( mf_avg, mf_avg, id+1, id+2, 1, ngrow); + MultiFab::Copy( mf_avg, v_comp1, 0, id+1, 1, ngrow); + } + */ +#else + amrex::Abort("AverageAndPackVectorField not implemented for ncomp > 1"); +#endif + } else { + PackPlotDataPtrs(srcmf, vector_field); + amrex::average_face_to_cellcenter( mf_avg, dcomp, srcmf, ngrow); #if (AMREX_SPACEDIM == 2) - MultiFab::Copy( mf_avg, mf_avg, dcomp+1, dcomp+2, 1, ngrow); - MultiFab::Copy( mf_avg, *vector_field[1], 0, dcomp+1, 1, ngrow); + MultiFab::Copy( mf_avg, mf_avg, dcomp+1, dcomp+2, 1, ngrow); + MultiFab::Copy( mf_avg, *vector_field[1], 0, dcomp+1, 1, ngrow); #endif + } // - Edge centered, in the same way as E on a Yee grid } else if ( !vector_field[0]->is_nodal(0) ){ - PackPlotDataPtrs(srcmf, vector_field); - amrex::average_edge_to_cellcenter( mf_avg, dcomp, srcmf, ngrow); + // See comment above, though here, the y (or theta) component + // has node centering. + if (vector_field[0]->nComp() > 1) { +#ifdef WARPX_RZ + // When there are more than one components, the total + // fields needs to be constructed in temporary MultiFabs + // Note that mf_total is declared in the same way as + // vector_field so that it can be passed into PackPlotDataPtrs. + std::array<std::unique_ptr<MultiFab>,3> mf_total; + mf_total[0].reset(new MultiFab(vector_field[0]->boxArray(), dm, 1, vector_field[0]->nGrowVect())); + mf_total[1].reset(new MultiFab(vector_field[1]->boxArray(), dm, 1, vector_field[1]->nGrowVect())); + mf_total[2].reset(new MultiFab(vector_field[2]->boxArray(), dm, 1, vector_field[2]->nGrowVect())); + ConstructTotalRZField(mf_total, vector_field); + PackPlotDataPtrs(srcmf, mf_total); + amrex::average_edge_to_cellcenter( mf_avg, dcomp, srcmf, ngrow); + MultiFab::Copy( mf_avg, mf_avg, dcomp+1, dcomp+2, 1, ngrow); + amrex::average_node_to_cellcenter( mf_avg, dcomp+1, + *mf_total[1], 0, 1, ngrow); + // Also add the real and imaginary parts of each mode. + /* Not supported yet + for (int i=0 ; i < vector_field[0]->nComp() ; i++) { + MultiFab v_comp0(*vector_field[0], amrex::make_alias, i, 1); + MultiFab v_comp1(*vector_field[1], amrex::make_alias, i, 1); + MultiFab v_comp2(*vector_field[2], amrex::make_alias, i, 1); + srcmf[0] = &v_comp0; + srcmf[1] = &v_comp2; + int id = dcomp + 3*(i + 1); + amrex::average_edge_to_cellcenter( mf_avg, id, srcmf, ngrow); + MultiFab::Copy( mf_avg, mf_avg, id+1, id+2, 1, ngrow); + amrex::average_node_to_cellcenter( mf_avg, id+1, + v_comp1, 0, 1, ngrow); + } + */ +#else + amrex::Abort("AverageAndPackVectorField not implemented for ncomp > 1"); +#endif + } else { + PackPlotDataPtrs(srcmf, vector_field); + amrex::average_edge_to_cellcenter( mf_avg, dcomp, srcmf, ngrow); #if (AMREX_SPACEDIM == 2) - MultiFab::Copy( mf_avg, mf_avg, dcomp+1, dcomp+2, 1, ngrow); - amrex::average_node_to_cellcenter( mf_avg, dcomp+1, - *vector_field[1], 0, 1, ngrow); + MultiFab::Copy( mf_avg, mf_avg, dcomp+1, dcomp+2, 1, ngrow); + amrex::average_node_to_cellcenter( mf_avg, dcomp+1, + *vector_field[1], 0, 1, ngrow); #endif + } } else { amrex::Abort("Unknown staggering."); @@ -305,6 +398,35 @@ AverageAndPackScalarField( MultiFab& mf_avg, } } +/** \brief Add variable names to the list. + * If there are more that one mode, add the + * name of the total field and then the + * names of the real and imaginary parts of each + * mode. + */ +void +AddToVarNames( Vector<std::string>& varnames, + std::string name, std::string suffix, + int n_rz_azimuthal_modes ) { + auto coords = {"x", "y", "z"}; + for(auto coord:coords) varnames.push_back(name+coord+suffix); + /* Not supported yet + auto coordsRZ = {"r", "theta", "z"}; + if (n_rz_azimuthal_modes > 1) { + // Note that the names are added in the same order as the fields + // are packed in AverageAndPackVectorField + for (int i = 0 ; i < n_rz_azimuthal_modes ; i++) { + for(auto coord:coordsRZ) { + varnames.push_back(name + coord + suffix + std::to_string(i) + "_real"); + } + for(auto coord:coordsRZ) { + varnames.push_back(name + coord + suffix + std::to_string(i) + "_imag"); + } + } + } + */ +} + /** \brief Write the different fields that are meant for output, * into the vector of MultiFab `mf_avg` (one MultiFab per level) * after averaging them to the cell centers. @@ -313,6 +435,14 @@ void WarpX::AverageAndPackFields ( Vector<std::string>& varnames, amrex::Vector<MultiFab>& mf_avg, const int ngrow) const { + // Factor to account for quantities that have multiple components. + // If n_rz_azimuthal_modes > 1, allow space for total field and the real and + // imaginary part of each node. For now, also include the + // imaginary part of mode 0 for code symmetry, even though + // it is always zero. + int modes_factor = 1; + if (n_rz_azimuthal_modes > 1) modes_factor = 2*n_rz_azimuthal_modes + 1; + // Count how many different fields should be written (ncomp) const int ncomp = fields_to_plot.size() + static_cast<int>(plot_finepatch)*6 @@ -333,17 +463,17 @@ WarpX::AverageAndPackFields ( Vector<std::string>& varnames, // Allocate temp MultiFab with 3 components mf_tmp_E = MultiFab(grids[lev], dmap[lev], 3, ngrow); // Fill MultiFab mf_tmp_E with averaged E - AverageAndPackVectorField(mf_tmp_E, Efield_aux[lev], 0, ngrow); + AverageAndPackVectorField(mf_tmp_E, Efield_aux[lev], dmap[lev], 0, ngrow); } // Same for B if (is_in_vector(fields_to_plot, {"Bx", "By", "Bz"} )){ mf_tmp_B = MultiFab(grids[lev], dmap[lev], 3, ngrow); - AverageAndPackVectorField(mf_tmp_B, Bfield_aux[lev], 0, ngrow); + AverageAndPackVectorField(mf_tmp_B, Bfield_aux[lev], dmap[lev], 0, ngrow); } // Same for J if (is_in_vector(fields_to_plot, {"jx", "jy", "jz"} )){ mf_tmp_J = MultiFab(grids[lev], dmap[lev], 3, ngrow); - AverageAndPackVectorField(mf_tmp_J, current_fp[lev], 0, ngrow); + AverageAndPackVectorField(mf_tmp_J, current_fp[lev], dmap[lev], 0, ngrow); } int dcomp; @@ -437,12 +567,12 @@ WarpX::AverageAndPackFields ( Vector<std::string>& varnames, } if (plot_finepatch) { - AverageAndPackVectorField( mf_avg[lev], Efield_fp[lev], dcomp, ngrow ); - if(lev==0) for(auto name:{"Ex_fp","Ey_fp","Ez_fp"}) varnames.push_back(name); - dcomp += 3; - AverageAndPackVectorField( mf_avg[lev], Bfield_fp[lev], dcomp, ngrow ); - if(lev==0) for(auto name:{"Bx_fp","By_fp","Bz_fp"}) varnames.push_back(name); - dcomp += 3; + AverageAndPackVectorField( mf_avg[lev], Efield_fp[lev], dmap[lev], dcomp, ngrow ); + if (lev == 0) AddToVarNames(varnames, "E", "_fp", n_rz_azimuthal_modes); + dcomp += 3*modes_factor; + AverageAndPackVectorField( mf_avg[lev], Bfield_fp[lev], dmap[lev], dcomp, ngrow ); + if (lev == 0) AddToVarNames(varnames, "B", "_fp", n_rz_azimuthal_modes); + dcomp += 3*modes_factor; } if (plot_crsepatch) @@ -455,11 +585,11 @@ WarpX::AverageAndPackFields ( Vector<std::string>& varnames, { if (do_nodal) amrex::Abort("TODO: do_nodal && plot_crsepatch"); std::array<std::unique_ptr<MultiFab>, 3> E = getInterpolatedE(lev); - AverageAndPackVectorField( mf_avg[lev], E, dcomp, ngrow ); + AverageAndPackVectorField( mf_avg[lev], E, dmap[lev], dcomp, ngrow ); } - if(lev==0) for(auto name:{"Ex_cp","Ey_cp","Ez_cp"}) varnames.push_back(name); - dcomp += 3; + if (lev == 0) AddToVarNames(varnames, "E", "_cp", n_rz_azimuthal_modes); + dcomp += 3*modes_factor; // now the magnetic field if (lev == 0) @@ -470,10 +600,10 @@ WarpX::AverageAndPackFields ( Vector<std::string>& varnames, { if (do_nodal) amrex::Abort("TODO: do_nodal && plot_crsepatch"); std::array<std::unique_ptr<MultiFab>, 3> B = getInterpolatedB(lev); - AverageAndPackVectorField( mf_avg[lev], B, dcomp, ngrow ); + AverageAndPackVectorField( mf_avg[lev], B, dmap[lev], dcomp, ngrow ); } - if(lev==0) for(auto name:{"Bx_cp","By_cp","Bz_cp"}) varnames.push_back(name); - dcomp += 3; + if (lev == 0) AddToVarNames(varnames, "B", "_cp", n_rz_azimuthal_modes); + dcomp += 3*modes_factor; } if (costs[0] != nullptr) @@ -535,8 +665,8 @@ WriteRawField( const MultiFab& F, const DistributionMapping& dm, VisMF::Write(F, prefix); } else { // Copy original MultiFab into one that does not have guard cells - MultiFab tmpF( F.boxArray(), dm, 1, 0); - MultiFab::Copy(tmpF, F, 0, 0, 1, 0); + MultiFab tmpF( F.boxArray(), dm, F.nComp(), 0); + MultiFab::Copy(tmpF, F, 0, 0, F.nComp(), 0); VisMF::Write(tmpF, prefix); } @@ -558,7 +688,7 @@ WriteZeroRawField( const MultiFab& F, const DistributionMapping& dm, std::string prefix = amrex::MultiFabFileFullPrefix(lev, filename, level_prefix, field_name); - MultiFab tmpF(F.boxArray(), dm, 1, ng); + MultiFab tmpF(F.boxArray(), dm, F.nComp(), ng); tmpF.setVal(0.); VisMF::Write(tmpF, prefix); } diff --git a/Source/Diagnostics/WarpXIO.cpp b/Source/Diagnostics/WarpXIO.cpp index 38399bf9e..2ea8a7fd7 100644 --- a/Source/Diagnostics/WarpXIO.cpp +++ b/Source/Diagnostics/WarpXIO.cpp @@ -415,20 +415,28 @@ WarpX::GetCellCenteredData() { Vector<std::unique_ptr<MultiFab> > cc(finest_level+1); + // Factor to account for quantities that have multiple components. + // If n_rz_azimuthal_modes > 1, allow space for total field and the real and + // imaginary part of each node. For now, also include the + // imaginary part of mode 0 for code symmetry, even though + // it is always zero. + int modes_factor = 1; + if (n_rz_azimuthal_modes > 1) modes_factor = 2*n_rz_azimuthal_modes + 1; + for (int lev = 0; lev <= finest_level; ++lev) { cc[lev].reset( new MultiFab(grids[lev], dmap[lev], nc, ng) ); int dcomp = 0; // first the electric field - AverageAndPackVectorField( *cc[lev], Efield_aux[lev], dcomp, ng ); - dcomp += 3; + AverageAndPackVectorField( *cc[lev], Efield_aux[lev], dmap[lev], dcomp, ng ); + dcomp += 3*modes_factor; // then the magnetic field - AverageAndPackVectorField( *cc[lev], Bfield_aux[lev], dcomp, ng ); - dcomp += 3; + AverageAndPackVectorField( *cc[lev], Bfield_aux[lev], dmap[lev], dcomp, ng ); + dcomp += 3*modes_factor; // then the current density - AverageAndPackVectorField( *cc[lev], current_fp[lev], dcomp, ng ); - dcomp += 3; + AverageAndPackVectorField( *cc[lev], current_fp[lev], dmap[lev], dcomp, ng ); + dcomp += 3*modes_factor; // then the charge density const std::unique_ptr<MultiFab>& charge_density = mypc->GetChargeDensity(lev); AverageAndPackScalarField( *cc[lev], *charge_density, dcomp, ng ); @@ -582,7 +590,8 @@ WarpX::WritePlotFile () const if (F_fp[lev]) WriteRawField( *F_fp[lev], dm, raw_pltname, level_prefix, "F_fp", lev, plot_raw_fields_guards); if (plot_rho) { // Use the component 1 of `rho_fp`, i.e. rho_new for time synchronization - MultiFab rho_new(*rho_fp[lev], amrex::make_alias, 1, 1); + // If nComp > 1, this is the upper half of the list of components. + MultiFab rho_new(*rho_fp[lev], amrex::make_alias, rho_fp[lev]->nComp()/2, rho_fp[lev]->nComp()/2); WriteRawField( rho_new, dm, raw_pltname, level_prefix, "rho_fp", lev, plot_raw_fields_guards); } } diff --git a/Source/Evolve/WarpXEvolveEM.cpp b/Source/Evolve/WarpXEvolveEM.cpp index 170a8f604..a532a22fd 100644 --- a/Source/Evolve/WarpXEvolveEM.cpp +++ b/Source/Evolve/WarpXEvolveEM.cpp @@ -349,7 +349,7 @@ WarpX::OneStep_sub1 (Real curtime) RestrictRhoFromFineToCoarsePatch(fine_lev); ApplyFilterandSumBoundaryJ(fine_lev, PatchType::fine); NodalSyncJ(fine_lev, PatchType::fine); - ApplyFilterandSumBoundaryRho(fine_lev, PatchType::fine, 0, 2); + ApplyFilterandSumBoundaryRho(fine_lev, PatchType::fine, 0, 2*n_rz_azimuthal_modes); NodalSyncRho(fine_lev, PatchType::fine, 0, 2); EvolveB(fine_lev, PatchType::fine, 0.5*dt[fine_lev]); @@ -376,7 +376,7 @@ WarpX::OneStep_sub1 (Real curtime) PushParticlesandDepose(coarse_lev, curtime); StoreCurrent(coarse_lev); AddCurrentFromFineLevelandSumBoundary(coarse_lev); - AddRhoFromFineLevelandSumBoundary(coarse_lev, 0, 1); + AddRhoFromFineLevelandSumBoundary(coarse_lev, 0, n_rz_azimuthal_modes); EvolveB(fine_lev, PatchType::coarse, dt[fine_lev]); EvolveF(fine_lev, PatchType::coarse, dt[fine_lev], DtType::FirstHalf); @@ -403,7 +403,7 @@ WarpX::OneStep_sub1 (Real curtime) RestrictRhoFromFineToCoarsePatch(fine_lev); ApplyFilterandSumBoundaryJ(fine_lev, PatchType::fine); NodalSyncJ(fine_lev, PatchType::fine); - ApplyFilterandSumBoundaryRho(fine_lev, PatchType::fine, 0, 2); + ApplyFilterandSumBoundaryRho(fine_lev, PatchType::fine, 0, 2*n_rz_azimuthal_modes); NodalSyncRho(fine_lev, PatchType::fine, 0, 2); EvolveB(fine_lev, PatchType::fine, 0.5*dt[fine_lev]); @@ -429,7 +429,7 @@ WarpX::OneStep_sub1 (Real curtime) // by only half a coarse step (second half) RestoreCurrent(coarse_lev); AddCurrentFromFineLevelandSumBoundary(coarse_lev); - AddRhoFromFineLevelandSumBoundary(coarse_lev, 1, 1); + AddRhoFromFineLevelandSumBoundary(coarse_lev, n_rz_azimuthal_modes, n_rz_azimuthal_modes); EvolveE(fine_lev, PatchType::coarse, dt[fine_lev]); FillBoundaryE(fine_lev, PatchType::coarse); @@ -506,8 +506,23 @@ WarpX::ComputeDt () if (maxwell_fdtd_solver_id == 0) { // CFL time step Yee solver #ifdef WARPX_DIM_RZ - // Derived semi-analytically by R. Lehe - deltat = cfl * 1./( std::sqrt((1+0.2105)/(dx[0]*dx[0]) + 1./(dx[1]*dx[1])) * PhysConst::c ); + // In the rz case, the Courant limit has been evaluated + // semi-analytically by R. Lehe, and resulted in the following + // coefficients. For an explanation, see (not officially published) + // www.normalesup.org/~lehe/Disp_relation_Circ.pdf + // NB : Here the coefficient for m=1 as compared to this document, + // as it was observed in practice that this coefficient was not + // high enough (The simulation became unstable). + Real multimode_coeffs[6] = { 0.2105, 1.0, 3.5234, 8.5104, 15.5059, 24.5037 }; + Real multimode_alpha; + if (n_rz_azimuthal_modes < 7) { + // Use the table of the coefficients + multimode_alpha = multimode_coeffs[n_rz_azimuthal_modes-1]; + } else { + // Use a realistic extrapolation + multimode_alpha = (n_rz_azimuthal_modes - 1)*(n_rz_azimuthal_modes - 1) - 0.4; + } + deltat = cfl * 1./( std::sqrt((1+multimode_alpha)/(dx[0]*dx[0]) + 1./(dx[1]*dx[1])) * PhysConst::c ); #else deltat = cfl * 1./( std::sqrt(AMREX_D_TERM( 1./(dx[0]*dx[0]), + 1./(dx[1]*dx[1]), diff --git a/Source/FortranInterface/WarpX_f.H b/Source/FortranInterface/WarpX_f.H index aac23f781..6dff3469d 100644 --- a/Source/FortranInterface/WarpX_f.H +++ b/Source/FortranInterface/WarpX_f.H @@ -80,6 +80,7 @@ extern "C" amrex::Real* jx, const long* jx_ng, const int* jx_ntot, amrex::Real* jy, const long* jy_ng, const int* jy_ntot, amrex::Real* jz, const long* jz_ng, const int* jz_ntot, + const long* n_rz_azimuthal_modes, const long* np, const amrex::Real* xp, const amrex::Real* yp, const amrex::Real* zp, const amrex::Real* uxp, const amrex::Real* uyp,const amrex::Real* uzp, @@ -144,6 +145,7 @@ extern "C" const int* xlo, const int* xhi, const int* ylo, const int* yhi, const int* zlo, const int* zhi, + const long* n_rz_azimuthal_modes, BL_FORT_FAB_ARG_3D(ex), BL_FORT_FAB_ARG_3D(ey), BL_FORT_FAB_ARG_3D(ez), @@ -164,6 +166,7 @@ extern "C" const int* xlo, const int* xhi, const int* ylo, const int* yhi, const int* zlo, const int* zhi, + const long* n_rz_azimuthal_modes, const BL_FORT_FAB_ARG_3D(ex), const BL_FORT_FAB_ARG_3D(ey), const BL_FORT_FAB_ARG_3D(ez), diff --git a/Source/FortranInterface/WarpX_picsar.F90 b/Source/FortranInterface/WarpX_picsar.F90 index 34084d753..3a9f8f41e 100644 --- a/Source/FortranInterface/WarpX_picsar.F90 +++ b/Source/FortranInterface/WarpX_picsar.F90 @@ -74,17 +74,25 @@ contains !> @param[in] charge_depo_algo algorithm choice for the charge deposition !> subroutine warpx_current_deposition( & - jx,jx_ng,jx_ntot,jy,jy_ng,jy_ntot,jz,jz_ng,jz_ntot, & + jx,jx_ng,jx_ntot,jy,jy_ng,jy_ntot,jz,jz_ng,jz_ntot,n_rz_azimuthal_modes, & np,xp,yp,zp,uxp,uyp,uzp,gaminv,w,q,xmin,ymin,zmin,dt,dx,dy,dz,nox,noy,noz,& l_nodal,lvect,current_depo_algo) & bind(C, name="warpx_current_deposition") integer, intent(in) :: jx_ntot(AMREX_SPACEDIM), jy_ntot(AMREX_SPACEDIM), jz_ntot(AMREX_SPACEDIM) integer(c_long), intent(in) :: jx_ng, jy_ng, jz_ng + integer(c_long), intent(IN) :: n_rz_azimuthal_modes integer(c_long), intent(IN) :: np integer(c_long), intent(IN) :: nox,noy,noz integer(c_int), intent(in) :: l_nodal + +#ifdef WARPX_RZ + real(amrex_real), intent(IN OUT):: jx(jx_ntot(1),jx_ntot(2),2,n_rz_azimuthal_modes) + real(amrex_real), intent(IN OUT):: jy(jy_ntot(1),jy_ntot(2),2,n_rz_azimuthal_modes) + real(amrex_real), intent(IN OUT):: jz(jz_ntot(1),jz_ntot(2),2,n_rz_azimuthal_modes) +#else real(amrex_real), intent(IN OUT):: jx(*), jy(*), jz(*) +#endif real(amrex_real), intent(IN) :: q real(amrex_real), intent(IN) :: dx,dy,dz real(amrex_real), intent(IN) :: dt @@ -96,6 +104,13 @@ contains integer(c_long), intent(IN) :: current_depo_algo logical(pxr_logical) :: pxr_l_nodal +#ifdef WARPX_RZ + logical(pxr_logical) :: l_particles_weight = .true. + integer(c_long) :: type_rz_depose = 1 + complex(amrex_real), allocatable, dimension(:,:,:) :: jr_c, jt_c, jz_c + integer :: alloc_status +#endif + ! Compute the number of valid cells and guard cells integer(c_long) :: jx_nvalid(AMREX_SPACEDIM), jy_nvalid(AMREX_SPACEDIM), jz_nvalid(AMREX_SPACEDIM), & jx_nguards(AMREX_SPACEDIM), jy_nguards(AMREX_SPACEDIM), jz_nguards(AMREX_SPACEDIM) @@ -118,13 +133,53 @@ contains nox,noy,noz,pxr_l_nodal,current_depo_algo) ! Dimension 2 #elif (AMREX_SPACEDIM==2) - CALL WRPX_PXR_CURRENT_DEPOSITION( & +#ifdef WARPX_RZ + if (n_rz_azimuthal_modes > 1) then + + allocate(jr_c(jx_ntot(1),jx_ntot(2),n_rz_azimuthal_modes), & + jt_c(jy_ntot(1),jy_ntot(2),n_rz_azimuthal_modes), & + jz_c(jz_ntot(1),jz_ntot(2),n_rz_azimuthal_modes), stat=alloc_status) + if (alloc_status /= 0) then + print*,"Error: warpx_current_deposition: complex arrays could not be allocated" + stop + endif + + jr_c = 0._amrex_real + jt_c = 0._amrex_real + jz_c = 0._amrex_real + + CALL pxr_depose_jrjtjz_esirkepov_n_2d_circ( & + jr_c,jx_nguards,jx_nvalid, & + jt_c,jy_nguards,jy_nvalid, & + jz_c,jz_nguards,jz_nvalid, & + n_rz_azimuthal_modes, & + np,xp,yp,zp,uxp,uyp,uzp,gaminv,w,q, & + xmin,zmin,dt,dx,dz, & + nox,noz,l_particles_weight,type_rz_depose) + + jx(:,:,1,:) = jx(:,:,1,:) + real(jr_c) + jx(:,:,2,:) = jx(:,:,2,:) + aimag(jr_c) + jy(:,:,1,:) = jy(:,:,1,:) + real(jt_c) + jy(:,:,2,:) = jy(:,:,2,:) + aimag(jt_c) + jz(:,:,1,:) = jz(:,:,1,:) + real(jz_c) + jz(:,:,2,:) = jz(:,:,2,:) + aimag(jz_c) + + deallocate(jr_c) + deallocate(jt_c) + deallocate(jz_c) + + else +#endif + CALL WRPX_PXR_CURRENT_DEPOSITION( & jx,jx_nguards,jx_nvalid, & jy,jy_nguards,jy_nvalid, & jz,jz_nguards,jz_nvalid, & np,xp,yp,zp,uxp,uyp,uzp,gaminv,w,q, & xmin,zmin,dt,dx,dz,nox,noz,pxr_l_nodal, & lvect,current_depo_algo) +#ifdef WARPX_RZ + endif +#endif #endif end subroutine warpx_current_deposition diff --git a/Source/Initialization/PlasmaInjector.cpp b/Source/Initialization/PlasmaInjector.cpp index 541999789..5a5c190c6 100644 --- a/Source/Initialization/PlasmaInjector.cpp +++ b/Source/Initialization/PlasmaInjector.cpp @@ -143,9 +143,11 @@ PlasmaInjector::PlasmaInjector (int ispecies, const std::string& name) parseDensity(pp); parseMomentum(pp); } else if (part_pos_s == "nuniformpercell") { - num_particles_per_cell_each_dim.resize(3); + // Note that for RZ, three numbers are expected, r, theta, and z. + // For 2D, only two are expected. The third is overwritten with 1. + num_particles_per_cell_each_dim.assign(3, 1); pp.getarr("num_particles_per_cell_each_dim", num_particles_per_cell_each_dim); -#if ( AMREX_SPACEDIM == 2 ) +#if ( AMREX_SPACEDIM == 2 ) && !defined(WARPX_RZ) num_particles_per_cell_each_dim[2] = 1; #endif // Construct InjectorPosition from InjectorPositionRegular. diff --git a/Source/Parallelization/WarpXComm.cpp b/Source/Parallelization/WarpXComm.cpp index 9d85783b0..0ca1e8a5d 100644 --- a/Source/Parallelization/WarpXComm.cpp +++ b/Source/Parallelization/WarpXComm.cpp @@ -59,24 +59,24 @@ WarpX::UpdateAuxilaryData () // B field { - MultiFab dBx(Bfield_cp[lev][0]->boxArray(), dm, 1, ng); - MultiFab dBy(Bfield_cp[lev][1]->boxArray(), dm, 1, ng); - MultiFab dBz(Bfield_cp[lev][2]->boxArray(), dm, 1, ng); + MultiFab dBx(Bfield_cp[lev][0]->boxArray(), dm, Bfield_cp[lev][0]->nComp(), ng); + MultiFab dBy(Bfield_cp[lev][1]->boxArray(), dm, Bfield_cp[lev][1]->nComp(), ng); + MultiFab dBz(Bfield_cp[lev][2]->boxArray(), dm, Bfield_cp[lev][2]->nComp(), ng); dBx.setVal(0.0); dBy.setVal(0.0); dBz.setVal(0.0); - dBx.ParallelCopy(*Bfield_aux[lev-1][0], 0, 0, 1, ng, ng, crse_period); - dBy.ParallelCopy(*Bfield_aux[lev-1][1], 0, 0, 1, ng, ng, crse_period); - dBz.ParallelCopy(*Bfield_aux[lev-1][2], 0, 0, 1, ng, ng, crse_period); + dBx.ParallelCopy(*Bfield_aux[lev-1][0], 0, 0, Bfield_aux[lev-1][0]->nComp(), ng, ng, crse_period); + dBy.ParallelCopy(*Bfield_aux[lev-1][1], 0, 0, Bfield_aux[lev-1][1]->nComp(), ng, ng, crse_period); + dBz.ParallelCopy(*Bfield_aux[lev-1][2], 0, 0, Bfield_aux[lev-1][2]->nComp(), ng, ng, crse_period); if (Bfield_cax[lev][0]) { - MultiFab::Copy(*Bfield_cax[lev][0], dBx, 0, 0, 1, ng); - MultiFab::Copy(*Bfield_cax[lev][1], dBy, 0, 0, 1, ng); - MultiFab::Copy(*Bfield_cax[lev][2], dBz, 0, 0, 1, ng); + MultiFab::Copy(*Bfield_cax[lev][0], dBx, 0, 0, Bfield_cax[lev][0]->nComp(), ng); + MultiFab::Copy(*Bfield_cax[lev][1], dBy, 0, 0, Bfield_cax[lev][1]->nComp(), ng); + MultiFab::Copy(*Bfield_cax[lev][2], dBz, 0, 0, Bfield_cax[lev][2]->nComp(), ng); } - MultiFab::Subtract(dBx, *Bfield_cp[lev][0], 0, 0, 1, ng); - MultiFab::Subtract(dBy, *Bfield_cp[lev][1], 0, 0, 1, ng); - MultiFab::Subtract(dBz, *Bfield_cp[lev][2], 0, 0, 1, ng); + MultiFab::Subtract(dBx, *Bfield_cp[lev][0], 0, 0, Bfield_cp[lev][0]->nComp(), ng); + MultiFab::Subtract(dBy, *Bfield_cp[lev][1], 0, 0, Bfield_cp[lev][1]->nComp(), ng); + MultiFab::Subtract(dBz, *Bfield_cp[lev][2], 0, 0, Bfield_cp[lev][2]->nComp(), ng); const Real* dx = Geom(lev-1).CellSize(); const int refinement_ratio = refRatio(lev-1)[0]; @@ -134,24 +134,24 @@ WarpX::UpdateAuxilaryData () // E field { - MultiFab dEx(Efield_cp[lev][0]->boxArray(), dm, 1, ng); - MultiFab dEy(Efield_cp[lev][1]->boxArray(), dm, 1, ng); - MultiFab dEz(Efield_cp[lev][2]->boxArray(), dm, 1, ng); + MultiFab dEx(Efield_cp[lev][0]->boxArray(), dm, Efield_cp[lev][0]->nComp(), ng); + MultiFab dEy(Efield_cp[lev][1]->boxArray(), dm, Efield_cp[lev][1]->nComp(), ng); + MultiFab dEz(Efield_cp[lev][2]->boxArray(), dm, Efield_cp[lev][2]->nComp(), ng); dEx.setVal(0.0); dEy.setVal(0.0); dEz.setVal(0.0); - dEx.ParallelCopy(*Efield_aux[lev-1][0], 0, 0, 1, ng, ng, crse_period); - dEy.ParallelCopy(*Efield_aux[lev-1][1], 0, 0, 1, ng, ng, crse_period); - dEz.ParallelCopy(*Efield_aux[lev-1][2], 0, 0, 1, ng, ng, crse_period); + dEx.ParallelCopy(*Efield_aux[lev-1][0], 0, 0, Efield_aux[lev-1][0]->nComp(), ng, ng, crse_period); + dEy.ParallelCopy(*Efield_aux[lev-1][1], 0, 0, Efield_aux[lev-1][1]->nComp(), ng, ng, crse_period); + dEz.ParallelCopy(*Efield_aux[lev-1][2], 0, 0, Efield_aux[lev-1][2]->nComp(), ng, ng, crse_period); if (Efield_cax[lev][0]) { - MultiFab::Copy(*Efield_cax[lev][0], dEx, 0, 0, 1, ng); - MultiFab::Copy(*Efield_cax[lev][1], dEy, 0, 0, 1, ng); - MultiFab::Copy(*Efield_cax[lev][2], dEz, 0, 0, 1, ng); + MultiFab::Copy(*Efield_cax[lev][0], dEx, 0, 0, Efield_cax[lev][0]->nComp(), ng); + MultiFab::Copy(*Efield_cax[lev][1], dEy, 0, 0, Efield_cax[lev][1]->nComp(), ng); + MultiFab::Copy(*Efield_cax[lev][2], dEz, 0, 0, Efield_cax[lev][2]->nComp(), ng); } - MultiFab::Subtract(dEx, *Efield_cp[lev][0], 0, 0, 1, ng); - MultiFab::Subtract(dEy, *Efield_cp[lev][1], 0, 0, 1, ng); - MultiFab::Subtract(dEz, *Efield_cp[lev][2], 0, 0, 1, ng); + MultiFab::Subtract(dEx, *Efield_cp[lev][0], 0, 0, Efield_cp[lev][0]->nComp(), ng); + MultiFab::Subtract(dEy, *Efield_cp[lev][1], 0, 0, Efield_cp[lev][1]->nComp(), ng); + MultiFab::Subtract(dEz, *Efield_cp[lev][2], 0, 0, Efield_cp[lev][2]->nComp(), ng); const int refinement_ratio = refRatio(lev-1)[0]; #ifdef _OPEMP @@ -199,8 +199,8 @@ WarpX::UpdateAuxilaryData () FArrayBox& aux = (*Efield_aux[lev][idim])[mfi]; FArrayBox& fp = (*Efield_fp[lev][idim])[mfi]; const Box& bx = aux.box(); - aux.copy(fp, bx, 0, bx, 0, 1); - aux.plus(efab[idim], bx, bx, 0, 0, 1); + aux.copy(fp, bx, 0, bx, 0, Efield_fp[lev][idim]->nComp()); + aux.plus(efab[idim], bx, bx, 0, 0, Efield_fp[lev][idim]->nComp()); } } } @@ -409,7 +409,7 @@ WarpX::SyncCurrent (const std::array<const amrex::MultiFab*,3>& fine, ffab.resize(fbx); fbx &= (*fine[idim])[mfi].box(); ffab.setVal(0.0); - ffab.copy((*fine[idim])[mfi], fbx, 0, fbx, 0, 1); + ffab.copy((*fine[idim])[mfi], fbx, 0, fbx, 0, fine[idim]->nComp()); WRPX_SYNC_CURRENT(bx.loVect(), bx.hiVect(), BL_TO_FORTRAN_ANYD((*crse[idim])[mfi]), BL_TO_FORTRAN_ANYD(ffab), @@ -505,11 +505,11 @@ WarpX::ApplyFilterandSumBoundaryJ (int lev, PatchType patch_type) if (use_filter) { IntVect ng = j[idim]->nGrowVect(); ng += bilinear_filter.stencil_length_each_dir-1; - MultiFab jf(j[idim]->boxArray(), j[idim]->DistributionMap(), 1, ng); + MultiFab jf(j[idim]->boxArray(), j[idim]->DistributionMap(), j[idim]->nComp(), ng); bilinear_filter.ApplyStencil(jf, *j[idim]); - WarpXSumGuardCells(*(j[idim]), jf, period); + WarpXSumGuardCells(*(j[idim]), jf, period, 0, (j[idim])->nComp()); } else { - WarpXSumGuardCells(*(j[idim]), period); + WarpXSumGuardCells(*(j[idim]), period, 0, (j[idim])->nComp()); } } } @@ -539,7 +539,7 @@ WarpX::AddCurrentFromFineLevelandSumBoundary (int lev) const auto& period = Geom(lev).periodicity(); for (int idim = 0; idim < 3; ++idim) { MultiFab mf(current_fp[lev][idim]->boxArray(), - current_fp[lev][idim]->DistributionMap(), 1, 0); + current_fp[lev][idim]->DistributionMap(), current_fp[lev][idim]->nComp(), 0); mf.setVal(0.0); if (use_filter && current_buf[lev+1][idim]) { @@ -547,18 +547,18 @@ WarpX::AddCurrentFromFineLevelandSumBoundary (int lev) IntVect ng = current_cp[lev+1][idim]->nGrowVect(); ng += bilinear_filter.stencil_length_each_dir-1; MultiFab jfc(current_cp[lev+1][idim]->boxArray(), - current_cp[lev+1][idim]->DistributionMap(), 1, ng); + current_cp[lev+1][idim]->DistributionMap(), current_cp[lev+1][idim]->nComp(), ng); bilinear_filter.ApplyStencil(jfc, *current_cp[lev+1][idim]); // buffer patch of fine level MultiFab jfb(current_buf[lev+1][idim]->boxArray(), - current_buf[lev+1][idim]->DistributionMap(), 1, ng); + current_buf[lev+1][idim]->DistributionMap(), current_buf[lev+1][idim]->nComp(), ng); bilinear_filter.ApplyStencil(jfb, *current_buf[lev+1][idim]); - MultiFab::Add(jfb, jfc, 0, 0, 1, ng); - mf.ParallelAdd(jfb, 0, 0, 1, ng, IntVect::TheZeroVector(), period); + MultiFab::Add(jfb, jfc, 0, 0, current_buf[lev+1][idim]->nComp(), ng); + mf.ParallelAdd(jfb, 0, 0, current_buf[lev+1][idim]->nComp(), ng, IntVect::TheZeroVector(), period); - WarpXSumGuardCells(*current_cp[lev+1][idim], jfc, period); + WarpXSumGuardCells(*current_cp[lev+1][idim], jfc, period, 0, current_cp[lev+1][idim]->nComp()); } else if (use_filter) // but no buffer { @@ -566,29 +566,29 @@ WarpX::AddCurrentFromFineLevelandSumBoundary (int lev) IntVect ng = current_cp[lev+1][idim]->nGrowVect(); ng += bilinear_filter.stencil_length_each_dir-1; MultiFab jf(current_cp[lev+1][idim]->boxArray(), - current_cp[lev+1][idim]->DistributionMap(), 1, ng); + current_cp[lev+1][idim]->DistributionMap(), current_cp[lev+1][idim]->nComp(), ng); bilinear_filter.ApplyStencil(jf, *current_cp[lev+1][idim]); - mf.ParallelAdd(jf, 0, 0, 1, ng, IntVect::TheZeroVector(), period); - WarpXSumGuardCells(*current_cp[lev+1][idim], jf, period); + mf.ParallelAdd(jf, 0, 0, current_cp[lev+1][idim]->nComp(), ng, IntVect::TheZeroVector(), period); + WarpXSumGuardCells(*current_cp[lev+1][idim], jf, period, 0, current_cp[lev+1][idim]->nComp()); } else if (current_buf[lev+1][idim]) // but no filter { MultiFab::Copy(*current_buf[lev+1][idim], - *current_cp [lev+1][idim], 0, 0, 1, + *current_cp [lev+1][idim], 0, 0, current_buf[lev+1][idim]->nComp(), current_cp[lev+1][idim]->nGrow()); - mf.ParallelAdd(*current_buf[lev+1][idim], 0, 0, 1, + mf.ParallelAdd(*current_buf[lev+1][idim], 0, 0, current_buf[lev+1][idim]->nComp(), current_buf[lev+1][idim]->nGrowVect(), IntVect::TheZeroVector(), period); - WarpXSumGuardCells(*(current_cp[lev+1][idim]), period); + WarpXSumGuardCells(*(current_cp[lev+1][idim]), period, 0, current_cp[lev+1][idim]->nComp()); } else // no filter, no buffer { - mf.ParallelAdd(*current_cp[lev+1][idim], 0, 0, 1, + mf.ParallelAdd(*current_cp[lev+1][idim], 0, 0, current_cp[lev+1][idim]->nComp(), current_cp[lev+1][idim]->nGrowVect(), IntVect::TheZeroVector(), period); - WarpXSumGuardCells(*(current_cp[lev+1][idim]), period); + WarpXSumGuardCells(*(current_cp[lev+1][idim]), period, 0, current_cp[lev+1][idim]->nComp()); } - MultiFab::Add(*current_fp[lev][idim], mf, 0, 0, 1, 0); + MultiFab::Add(*current_fp[lev][idim], mf, 0, 0, current_fp[lev+1][idim]->nComp(), 0); } NodalSyncJ(lev+1, PatchType::coarse); } diff --git a/Source/Parallelization/WarpXRegrid.cpp b/Source/Parallelization/WarpXRegrid.cpp index 8d7873041..eb119d4a2 100644 --- a/Source/Parallelization/WarpXRegrid.cpp +++ b/Source/Parallelization/WarpXRegrid.cpp @@ -46,21 +46,21 @@ WarpX::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMa { const IntVect& ng = Bfield_fp[lev][idim]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Bfield_fp[lev][idim]->boxArray(), - dm, 1, ng)); - pmf->Redistribute(*Bfield_fp[lev][idim], 0, 0, 1, ng); + dm, Bfield_fp[lev][idim]->nComp(), ng)); + pmf->Redistribute(*Bfield_fp[lev][idim], 0, 0, Bfield_fp[lev][idim]->nComp(), ng); Bfield_fp[lev][idim] = std::move(pmf); } { const IntVect& ng = Efield_fp[lev][idim]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Efield_fp[lev][idim]->boxArray(), - dm, 1, ng)); - pmf->Redistribute(*Efield_fp[lev][idim], 0, 0, 1, ng); + dm, Efield_fp[lev][idim]->nComp(), ng)); + pmf->Redistribute(*Efield_fp[lev][idim], 0, 0, Efield_fp[lev][idim]->nComp(), ng); Efield_fp[lev][idim] = std::move(pmf); } { const IntVect& ng = current_fp[lev][idim]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(current_fp[lev][idim]->boxArray(), - dm, 1, ng)); + dm, current_fp[lev][idim]->nComp(), ng)); current_fp[lev][idim] = std::move(pmf); current_fp_owner_masks[lev][idim] = std::move(current_fp[lev][idim]->OwnerMask(period)); } @@ -68,7 +68,7 @@ WarpX::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMa { const IntVect& ng = current_store[lev][idim]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(current_store[lev][idim]->boxArray(), - dm, 1, ng)); + dm, current_store[lev][idim]->nComp(), ng)); // no need to redistribute current_store[lev][idim] = std::move(pmf); } @@ -77,8 +77,8 @@ WarpX::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMa if (F_fp[lev] != nullptr) { const IntVect& ng = F_fp[lev]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(F_fp[lev]->boxArray(), - dm, 1, ng)); - pmf->Redistribute(*F_fp[lev], 0, 0, 1, ng); + dm, F_fp[lev]->nComp(), ng)); + pmf->Redistribute(*F_fp[lev], 0, 0, F_fp[lev]->nComp(), ng); F_fp[lev] = std::move(pmf); } @@ -96,8 +96,8 @@ WarpX::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMa if (lev == 0) { for (int idim = 0; idim < 3; ++idim) { - Bfield_aux[lev][idim].reset(new MultiFab(*Bfield_fp[lev][idim], amrex::make_alias, 0, 1)); - Efield_aux[lev][idim].reset(new MultiFab(*Efield_fp[lev][idim], amrex::make_alias, 0, 1)); + Bfield_aux[lev][idim].reset(new MultiFab(*Bfield_fp[lev][idim], amrex::make_alias, 0, Bfield_aux[lev][idim]->nComp())); + Efield_aux[lev][idim].reset(new MultiFab(*Efield_fp[lev][idim], amrex::make_alias, 0, Efield_aux[lev][idim]->nComp())); } } else { for (int idim=0; idim < 3; ++idim) @@ -105,15 +105,15 @@ WarpX::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMa { const IntVect& ng = Bfield_aux[lev][idim]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Bfield_aux[lev][idim]->boxArray(), - dm, 1, ng)); - // pmf->Redistribute(*Bfield_aux[lev][idim], 0, 0, 1, ng); + dm, Bfield_aux[lev][idim]->nComp(), ng)); + // pmf->Redistribute(*Bfield_aux[lev][idim], 0, 0, Bfield_aux[lev][idim]->nComp(), ng); Bfield_aux[lev][idim] = std::move(pmf); } { const IntVect& ng = Efield_aux[lev][idim]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Efield_aux[lev][idim]->boxArray(), - dm, 1, ng)); - // pmf->Redistribute(*Efield_aux[lev][idim], 0, 0, 1, ng); + dm, Efield_aux[lev][idim]->nComp(), ng)); + // pmf->Redistribute(*Efield_aux[lev][idim], 0, 0, Efield_aux[lev][idim]->nComp(), ng); Efield_aux[lev][idim] = std::move(pmf); } } @@ -127,21 +127,21 @@ WarpX::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMa { const IntVect& ng = Bfield_cp[lev][idim]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Bfield_cp[lev][idim]->boxArray(), - dm, 1, ng)); - pmf->Redistribute(*Bfield_cp[lev][idim], 0, 0, 1, ng); + dm, Bfield_cp[lev][idim]->nComp(), ng)); + pmf->Redistribute(*Bfield_cp[lev][idim], 0, 0, Bfield_cp[lev][idim]->nComp(), ng); Bfield_cp[lev][idim] = std::move(pmf); } { const IntVect& ng = Efield_cp[lev][idim]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Efield_cp[lev][idim]->boxArray(), - dm, 1, ng)); - pmf->Redistribute(*Efield_cp[lev][idim], 0, 0, 1, ng); + dm, Efield_cp[lev][idim]->nComp(), ng)); + pmf->Redistribute(*Efield_cp[lev][idim], 0, 0, Efield_cp[lev][idim]->nComp(), ng); Efield_cp[lev][idim] = std::move(pmf); } { const IntVect& ng = current_cp[lev][idim]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>( new MultiFab(current_cp[lev][idim]->boxArray(), - dm, 1, ng)); + dm, current_cp[lev][idim]->nComp(), ng)); current_cp[lev][idim] = std::move(pmf); current_cp_owner_masks[lev][idim] = std::move( current_cp[lev][idim]->OwnerMask(cperiod)); @@ -151,8 +151,8 @@ WarpX::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMa if (F_cp[lev] != nullptr) { const IntVect& ng = F_cp[lev]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(F_cp[lev]->boxArray(), - dm, 1, ng)); - pmf->Redistribute(*F_cp[lev], 0, 0, 1, ng); + dm, F_cp[lev]->nComp(), ng)); + pmf->Redistribute(*F_cp[lev], 0, 0, F_cp[lev]->nComp(), ng); F_cp[lev] = std::move(pmf); } @@ -173,24 +173,24 @@ WarpX::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMa { const IntVect& ng = Bfield_cax[lev][idim]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Bfield_cax[lev][idim]->boxArray(), - dm, 1, ng)); - // pmf->ParallelCopy(*Bfield_cax[lev][idim], 0, 0, 1, ng, ng); + dm, Bfield_cax[lev][idim]->nComp(), ng)); + // pmf->ParallelCopy(*Bfield_cax[lev][idim], 0, 0, Bfield_cax[lev][idim]->nComp(), ng, ng); Bfield_cax[lev][idim] = std::move(pmf); } if (Efield_cax[lev][idim]) { const IntVect& ng = Efield_cax[lev][idim]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(Efield_cax[lev][idim]->boxArray(), - dm, 1, ng)); - // pmf->ParallelCopy(*Efield_cax[lev][idim], 0, 0, 1, ng, ng); + dm, Efield_cax[lev][idim]->nComp(), ng)); + // pmf->ParallelCopy(*Efield_cax[lev][idim], 0, 0, Efield_cax[lev][idim]->nComp(), ng, ng); Efield_cax[lev][idim] = std::move(pmf); } if (current_buf[lev][idim]) { const IntVect& ng = current_buf[lev][idim]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(current_buf[lev][idim]->boxArray(), - dm, 1, ng)); - // pmf->ParallelCopy(*current_buf[lev][idim], 0, 0, 1, ng, ng); + dm, current_buf[lev][idim]->nComp(), ng)); + // pmf->ParallelCopy(*current_buf[lev][idim], 0, 0, current_buf[lev][idim]->nComp(), ng, ng); current_buf[lev][idim] = std::move(pmf); } } @@ -198,24 +198,24 @@ WarpX::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMa { const IntVect& ng = charge_buf[lev]->nGrowVect(); auto pmf = std::unique_ptr<MultiFab>(new MultiFab(charge_buf[lev]->boxArray(), - dm, 1, ng)); - // pmf->ParallelCopy(*charge_buf[lev][idim], 0, 0, 1, ng, ng); + dm, charge_buf[lev]->nComp(), ng)); + // pmf->ParallelCopy(*charge_buf[lev][idim], 0, 0, charge_buf[lev]->nComp(), ng, ng); charge_buf[lev] = std::move(pmf); } if (current_buffer_masks[lev]) { const IntVect& ng = current_buffer_masks[lev]->nGrowVect(); auto pmf = std::unique_ptr<iMultiFab>(new iMultiFab(current_buffer_masks[lev]->boxArray(), - dm, 1, ng)); - // pmf->ParallelCopy(*current_buffer_masks[lev], 0, 0, 1, ng, ng); + dm, current_buffer_masks[lev]->nComp(), ng)); + // pmf->ParallelCopy(*current_buffer_masks[lev], 0, 0, current_buffer_masks[lev]->nComp(), ng, ng); current_buffer_masks[lev] = std::move(pmf); } if (gather_buffer_masks[lev]) { const IntVect& ng = gather_buffer_masks[lev]->nGrowVect(); auto pmf = std::unique_ptr<iMultiFab>(new iMultiFab(gather_buffer_masks[lev]->boxArray(), - dm, 1, ng)); - // pmf->ParallelCopy(*gather_buffer_masks[lev], 0, 0, 1, ng, ng); + dm, gather_buffer_masks[lev]->nComp(), ng)); + // pmf->ParallelCopy(*gather_buffer_masks[lev], 0, 0, gather_buffer_masks[lev]->nComp(), ng, ng); gather_buffer_masks[lev] = std::move(pmf); } } diff --git a/Source/Particles/MultiParticleContainer.cpp b/Source/Particles/MultiParticleContainer.cpp index 982e04e39..6a1294ddf 100644 --- a/Source/Particles/MultiParticleContainer.cpp +++ b/Source/Particles/MultiParticleContainer.cpp @@ -274,7 +274,7 @@ MultiParticleContainer::GetChargeDensity (int lev, bool local) std::unique_ptr<MultiFab> rho = allcontainers[0]->GetChargeDensity(lev, true); for (unsigned i = 1, n = allcontainers.size(); i < n; ++i) { std::unique_ptr<MultiFab> rhoi = allcontainers[i]->GetChargeDensity(lev, true); - MultiFab::Add(*rho, *rhoi, 0, 0, 1, rho->nGrow()); + MultiFab::Add(*rho, *rhoi, 0, 0, rho->nComp(), rho->nGrow()); } if (!local) { const Geometry& gm = allcontainers[0]->Geom(lev); diff --git a/Source/Particles/PhysicalParticleContainer.H b/Source/Particles/PhysicalParticleContainer.H index b80619733..ebd4eac2b 100644 --- a/Source/Particles/PhysicalParticleContainer.H +++ b/Source/Particles/PhysicalParticleContainer.H @@ -53,6 +53,7 @@ public: amrex::FArrayBox const * byfab, amrex::FArrayBox const * bzfab, const int ngE, const int e_is_nodal, + const long n_rz_azimuthal_modes, const long offset, const long np_to_gather, int thread_num, diff --git a/Source/Particles/PhysicalParticleContainer.cpp b/Source/Particles/PhysicalParticleContainer.cpp index d10390204..c44a9a8b7 100644 --- a/Source/Particles/PhysicalParticleContainer.cpp +++ b/Source/Particles/PhysicalParticleContainer.cpp @@ -899,7 +899,8 @@ PhysicalParticleContainer::FieldGather (int lev, int e_is_nodal = Ex.is_nodal() and Ey.is_nodal() and Ez.is_nodal(); FieldGather(pti, Exp, Eyp, Ezp, Bxp, Byp, Bzp, &exfab, &eyfab, &ezfab, &bxfab, &byfab, &bzfab, - Ex.nGrow(), e_is_nodal, 0, np, thread_num, lev, lev); + Ex.nGrow(), e_is_nodal, WarpX::n_rz_azimuthal_modes, + 0, np, thread_num, lev, lev); if (cost) { const Box& tbx = pti.tilebox(); @@ -1175,7 +1176,8 @@ PhysicalParticleContainer::Evolve (int lev, BL_PROFILE_VAR_START(blp_pxr_fg); FieldGather(pti, Exp, Eyp, Ezp, Bxp, Byp, Bzp, exfab, eyfab, ezfab, bxfab, byfab, bzfab, - Ex.nGrow(), e_is_nodal, 0, np_gather, thread_num, lev, lev); + Ex.nGrow(), e_is_nodal, WarpX::n_rz_azimuthal_modes, + 0, np_gather, thread_num, lev, lev); if (np_gather < np) { @@ -1248,6 +1250,7 @@ PhysicalParticleContainer::Evolve (int lev, cexfab, ceyfab, cezfab, cbxfab, cbyfab, cbzfab, cEx->nGrow(), e_is_nodal, + WarpX::n_rz_azimuthal_modes, nfine_gather, np-nfine_gather, thread_num, lev, lev-1); } @@ -1591,7 +1594,8 @@ PhysicalParticleContainer::PushP (int lev, Real dt, int e_is_nodal = Ex.is_nodal() and Ey.is_nodal() and Ez.is_nodal(); FieldGather(pti, Exp, Eyp, Ezp, Bxp, Byp, Bzp, &exfab, &eyfab, &ezfab, &bxfab, &byfab, &bzfab, - Ex.nGrow(), e_is_nodal, 0, np, thread_num, lev, lev); + Ex.nGrow(), e_is_nodal, WarpX::n_rz_azimuthal_modes, + 0, np, thread_num, lev, lev); // This wraps the momentum advance so that inheritors can modify the call. // Extract pointers to the different particle quantities @@ -1831,6 +1835,7 @@ PhysicalParticleContainer::FieldGather (WarpXParIter& pti, const int ngE, const int e_is_nodal, const long offset, const long np_to_gather, + const long n_rz_azimuthal_modes, int thread_num, int lev, int gather_lev) diff --git a/Source/Particles/RigidInjectedParticleContainer.cpp b/Source/Particles/RigidInjectedParticleContainer.cpp index 36cb9d224..695955e15 100644 --- a/Source/Particles/RigidInjectedParticleContainer.cpp +++ b/Source/Particles/RigidInjectedParticleContainer.cpp @@ -426,7 +426,8 @@ RigidInjectedParticleContainer::PushP (int lev, Real dt, int e_is_nodal = Ex.is_nodal() and Ey.is_nodal() and Ez.is_nodal(); FieldGather(pti, Exp, Eyp, Ezp, Bxp, Byp, Bzp, &exfab, &eyfab, &ezfab, &bxfab, &byfab, &bzfab, - Ex.nGrow(), e_is_nodal, 0, np, thread_num, lev, lev); + Ex.nGrow(), e_is_nodal, WarpX::n_rz_azimuthal_modes, + 0, np, thread_num, lev, lev); // Save the position and momenta, making copies auto uxp_save = uxp; diff --git a/Source/Particles/WarpXParticleContainer.H b/Source/Particles/WarpXParticleContainer.H index ac5b47ada..ee263c27b 100644 --- a/Source/Particles/WarpXParticleContainer.H +++ b/Source/Particles/WarpXParticleContainer.H @@ -42,6 +42,9 @@ namespace ParticleStringNames {"Bx", PIdx::Bx }, {"By", PIdx::By }, {"Bz", PIdx::Bz } +#ifdef WARPX_RZ + ,{"theta", PIdx::theta} +#endif }; } diff --git a/Source/Particles/WarpXParticleContainer.cpp b/Source/Particles/WarpXParticleContainer.cpp index befa5cfed..0ff80941d 100644 --- a/Source/Particles/WarpXParticleContainer.cpp +++ b/Source/Particles/WarpXParticleContainer.cpp @@ -356,9 +356,9 @@ WarpXParticleContainer::DepositCurrentFortran(WarpXParIter& pti, tby.grow(ngJ); tbz.grow(ngJ); - local_jx[thread_num].resize(tbx); - local_jy[thread_num].resize(tby); - local_jz[thread_num].resize(tbz); + local_jx[thread_num].resize(tbx, jx->nComp()); + local_jy[thread_num].resize(tby, jy->nComp()); + local_jz[thread_num].resize(tbz, jz->nComp()); Real* jx_ptr = local_jx[thread_num].dataPtr(); Real* jy_ptr = local_jy[thread_num].dataPtr(); @@ -381,6 +381,7 @@ WarpXParticleContainer::DepositCurrentFortran(WarpXParIter& pti, jx_ptr, &ngJ, jxntot.getVect(), jy_ptr, &ngJ, jyntot.getVect(), jz_ptr, &ngJ, jzntot.getVect(), + &WarpX::n_rz_azimuthal_modes, &np_to_depose, m_xp[thread_num].dataPtr() + offset, m_yp[thread_num].dataPtr() + offset, @@ -401,9 +402,9 @@ WarpXParticleContainer::DepositCurrentFortran(WarpXParIter& pti, BL_PROFILE_VAR_START(blp_accumulate); // CPU, tiling: atomicAdd local_jx into jx // (same for jx and jz) - (*jx)[pti].atomicAdd(local_jx[thread_num], tbx, tbx, 0, 0, 1); - (*jy)[pti].atomicAdd(local_jy[thread_num], tby, tby, 0, 0, 1); - (*jz)[pti].atomicAdd(local_jz[thread_num], tbz, tbz, 0, 0, 1); + (*jx)[pti].atomicAdd(local_jx[thread_num], tbx, tbx, 0, 0, local_jx[thread_num].nComp()); + (*jy)[pti].atomicAdd(local_jy[thread_num], tby, tby, 0, 0, local_jy[thread_num].nComp()); + (*jz)[pti].atomicAdd(local_jz[thread_num], tbz, tbz, 0, 0, local_jz[thread_num].nComp()); BL_PROFILE_VAR_STOP(blp_accumulate); #endif } @@ -585,23 +586,23 @@ WarpXParticleContainer::DepositCharge (WarpXParIter& pti, RealVector& wp, tilebox.grow(ngRho); + const int nc = (rhomf->nComp() == 1 ? 1 : rhomf->nComp()/2); + #ifdef AMREX_USE_GPU // No tiling on GPU: rho_arr points to the full rho array. - MultiFab rhoi(*rho, amrex::make_alias, icomp, 1); + MultiFab rhoi(*rho, amrex::make_alias, icomp*nc, nc); Array4<Real> const& rho_arr = rhoi.array(pti); #else // Tiling is on: rho_arr points to local_rho[thread_num] const Box tb = amrex::convert(tilebox, IntVect::TheUnitVector()); - local_rho[thread_num].resize(tb); + local_rho[thread_num].resize(tb, nc); // local_rho[thread_num] is set to zero local_rho[thread_num].setVal(0.0); Array4<Real> const& rho_arr = local_rho[thread_num].array(); #endif - // GPU, no tiling: deposit directly in rho - // CPU, tiling: deposit into local_rho Real* AMREX_RESTRICT xp = m_xp[thread_num].dataPtr() + offset; Real* AMREX_RESTRICT zp = m_zp[thread_num].dataPtr() + offset; @@ -629,7 +630,7 @@ WarpXParticleContainer::DepositCharge (WarpXParIter& pti, RealVector& wp, #ifndef AMREX_USE_GPU BL_PROFILE_VAR_START(blp_accumulate); - (*rho)[pti].atomicAdd(local_rho[thread_num], tb, tb, 0, icomp, 1); + (*rho)[pti].atomicAdd(local_rho[thread_num], tb, tb, 0, icomp*nc, nc); BL_PROFILE_VAR_STOP(blp_accumulate); #endif @@ -683,7 +684,7 @@ WarpXParticleContainer::DepositCharge (Vector<std::unique_ptr<MultiFab> >& rho, BoxArray coarsened_fine_BA = fine_BA; coarsened_fine_BA.coarsen(m_gdb->refRatio(lev)); - MultiFab coarsened_fine_data(coarsened_fine_BA, fine_dm, 1, 0); + MultiFab coarsened_fine_data(coarsened_fine_BA, fine_dm, rho[lev+1]->nComp(), 0); coarsened_fine_data.setVal(0.0); IntVect ratio(AMREX_D_DECL(2, 2, 2)); // FIXME @@ -712,7 +713,7 @@ WarpXParticleContainer::GetChargeDensity (int lev, bool local) const int ng = WarpX::nox; - auto rho = std::unique_ptr<MultiFab>(new MultiFab(nba,dm,1,ng)); + auto rho = std::unique_ptr<MultiFab>(new MultiFab(nba,dm,WarpX::ncomps,ng)); rho->setVal(0.0); #ifdef _OPENMP diff --git a/Source/WarpX.H b/Source/WarpX.H index 927cc1f32..cc44541ee 100644 --- a/Source/WarpX.H +++ b/Source/WarpX.H @@ -95,6 +95,10 @@ public: static long noy; static long noz; + // Number of modes for the RZ multimode version + static long n_rz_azimuthal_modes; + static long ncomps; + static bool use_fdtd_nci_corr; static int l_lower_order_in_v; diff --git a/Source/WarpX.cpp b/Source/WarpX.cpp index a6a7a3399..2d6df625f 100644 --- a/Source/WarpX.cpp +++ b/Source/WarpX.cpp @@ -45,6 +45,9 @@ long WarpX::field_gathering_algo; long WarpX::particle_pusher_algo; int WarpX::maxwell_fdtd_solver_id; +long WarpX::n_rz_azimuthal_modes = 1; +long WarpX::ncomps = 1; + long WarpX::nox = 1; long WarpX::noy = 1; long WarpX::noz = 1; @@ -499,6 +502,10 @@ WarpX::ReadParameters () // Use same shape factors in all directions, for gathering l_lower_order_in_v = false; } + + // Only needs to be set with WARPX_RZ, otherwise defaults to 1. + pp.query("n_rz_azimuthal_modes", n_rz_azimuthal_modes); + } { @@ -768,20 +775,31 @@ void WarpX::AllocLevelMFs (int lev, const BoxArray& ba, const DistributionMapping& dm, const IntVect& ngE, const IntVect& ngJ, const IntVect& ngRho, int ngF) { + +#if defined WARPX_RZ + if (n_rz_azimuthal_modes > 1) { + // There is a real and imaginary component for each mode + ncomps = n_rz_azimuthal_modes*2; + } else { + // With only mode 0, only reals are used + ncomps = 1; + } +#endif + // // The fine patch // - Bfield_fp[lev][0].reset( new MultiFab(amrex::convert(ba,Bx_nodal_flag),dm,1,ngE)); - Bfield_fp[lev][1].reset( new MultiFab(amrex::convert(ba,By_nodal_flag),dm,1,ngE)); - Bfield_fp[lev][2].reset( new MultiFab(amrex::convert(ba,Bz_nodal_flag),dm,1,ngE)); + Bfield_fp[lev][0].reset( new MultiFab(amrex::convert(ba,Bx_nodal_flag),dm,ncomps,ngE)); + Bfield_fp[lev][1].reset( new MultiFab(amrex::convert(ba,By_nodal_flag),dm,ncomps,ngE)); + Bfield_fp[lev][2].reset( new MultiFab(amrex::convert(ba,Bz_nodal_flag),dm,ncomps,ngE)); - Efield_fp[lev][0].reset( new MultiFab(amrex::convert(ba,Ex_nodal_flag),dm,1,ngE)); - Efield_fp[lev][1].reset( new MultiFab(amrex::convert(ba,Ey_nodal_flag),dm,1,ngE)); - Efield_fp[lev][2].reset( new MultiFab(amrex::convert(ba,Ez_nodal_flag),dm,1,ngE)); + Efield_fp[lev][0].reset( new MultiFab(amrex::convert(ba,Ex_nodal_flag),dm,ncomps,ngE)); + Efield_fp[lev][1].reset( new MultiFab(amrex::convert(ba,Ey_nodal_flag),dm,ncomps,ngE)); + Efield_fp[lev][2].reset( new MultiFab(amrex::convert(ba,Ez_nodal_flag),dm,ncomps,ngE)); - current_fp[lev][0].reset( new MultiFab(amrex::convert(ba,jx_nodal_flag),dm,1,ngJ)); - current_fp[lev][1].reset( new MultiFab(amrex::convert(ba,jy_nodal_flag),dm,1,ngJ)); - current_fp[lev][2].reset( new MultiFab(amrex::convert(ba,jz_nodal_flag),dm,1,ngJ)); + current_fp[lev][0].reset( new MultiFab(amrex::convert(ba,jx_nodal_flag),dm,ncomps,ngJ)); + current_fp[lev][1].reset( new MultiFab(amrex::convert(ba,jy_nodal_flag),dm,ncomps,ngJ)); + current_fp[lev][2].reset( new MultiFab(amrex::convert(ba,jz_nodal_flag),dm,ncomps,ngJ)); const auto& period = Geom(lev).periodicity(); current_fp_owner_masks[lev][0] = std::move(current_fp[lev][0]->OwnerMask(period)); @@ -790,25 +808,25 @@ WarpX::AllocLevelMFs (int lev, const BoxArray& ba, const DistributionMapping& dm if (do_dive_cleaning || plot_rho) { - rho_fp[lev].reset(new MultiFab(amrex::convert(ba,IntVect::TheUnitVector()),dm,2,ngRho)); + rho_fp[lev].reset(new MultiFab(amrex::convert(ba,IntVect::TheUnitVector()),dm,2*ncomps,ngRho)); rho_fp_owner_masks[lev] = std::move(rho_fp[lev]->OwnerMask(period)); } if (do_subcycling == 1 && lev == 0) { - current_store[lev][0].reset( new MultiFab(amrex::convert(ba,jx_nodal_flag),dm,1,ngJ)); - current_store[lev][1].reset( new MultiFab(amrex::convert(ba,jy_nodal_flag),dm,1,ngJ)); - current_store[lev][2].reset( new MultiFab(amrex::convert(ba,jz_nodal_flag),dm,1,ngJ)); + current_store[lev][0].reset( new MultiFab(amrex::convert(ba,jx_nodal_flag),dm,ncomps,ngJ)); + current_store[lev][1].reset( new MultiFab(amrex::convert(ba,jy_nodal_flag),dm,ncomps,ngJ)); + current_store[lev][2].reset( new MultiFab(amrex::convert(ba,jz_nodal_flag),dm,ncomps,ngJ)); } if (do_dive_cleaning) { - F_fp[lev].reset (new MultiFab(amrex::convert(ba,IntVect::TheUnitVector()),dm,1, ngF)); + F_fp[lev].reset (new MultiFab(amrex::convert(ba,IntVect::TheUnitVector()),dm,ncomps, ngF)); } #ifdef WARPX_USE_PSATD else { - rho_fp[lev].reset(new MultiFab(amrex::convert(ba,IntVect::TheUnitVector()),dm,2,ngRho)); + rho_fp[lev].reset(new MultiFab(amrex::convert(ba,IntVect::TheUnitVector()),dm,2*ncomps,ngRho)); rho_fp_owner_masks[lev] = std::move(rho_fp[lev]->OwnerMask(period)); } if (fft_hybrid_mpi_decomposition == false){ @@ -834,19 +852,19 @@ WarpX::AllocLevelMFs (int lev, const BoxArray& ba, const DistributionMapping& dm if (lev == 0) { for (int idir = 0; idir < 3; ++idir) { - Efield_aux[lev][idir].reset(new MultiFab(*Efield_fp[lev][idir], amrex::make_alias, 0, 1)); - Bfield_aux[lev][idir].reset(new MultiFab(*Bfield_fp[lev][idir], amrex::make_alias, 0, 1)); + Efield_aux[lev][idir].reset(new MultiFab(*Efield_fp[lev][idir], amrex::make_alias, 0, ncomps)); + Bfield_aux[lev][idir].reset(new MultiFab(*Bfield_fp[lev][idir], amrex::make_alias, 0, ncomps)); } } else { - Bfield_aux[lev][0].reset( new MultiFab(amrex::convert(ba,Bx_nodal_flag),dm,1,ngE)); - Bfield_aux[lev][1].reset( new MultiFab(amrex::convert(ba,By_nodal_flag),dm,1,ngE)); - Bfield_aux[lev][2].reset( new MultiFab(amrex::convert(ba,Bz_nodal_flag),dm,1,ngE)); + Bfield_aux[lev][0].reset( new MultiFab(amrex::convert(ba,Bx_nodal_flag),dm,ncomps,ngE)); + Bfield_aux[lev][1].reset( new MultiFab(amrex::convert(ba,By_nodal_flag),dm,ncomps,ngE)); + Bfield_aux[lev][2].reset( new MultiFab(amrex::convert(ba,Bz_nodal_flag),dm,ncomps,ngE)); - Efield_aux[lev][0].reset( new MultiFab(amrex::convert(ba,Ex_nodal_flag),dm,1,ngE)); - Efield_aux[lev][1].reset( new MultiFab(amrex::convert(ba,Ey_nodal_flag),dm,1,ngE)); - Efield_aux[lev][2].reset( new MultiFab(amrex::convert(ba,Ez_nodal_flag),dm,1,ngE)); + Efield_aux[lev][0].reset( new MultiFab(amrex::convert(ba,Ex_nodal_flag),dm,ncomps,ngE)); + Efield_aux[lev][1].reset( new MultiFab(amrex::convert(ba,Ey_nodal_flag),dm,ncomps,ngE)); + Efield_aux[lev][2].reset( new MultiFab(amrex::convert(ba,Ez_nodal_flag),dm,ncomps,ngE)); } // @@ -858,19 +876,19 @@ WarpX::AllocLevelMFs (int lev, const BoxArray& ba, const DistributionMapping& dm cba.coarsen(refRatio(lev-1)); // Create the MultiFabs for B - Bfield_cp[lev][0].reset( new MultiFab(amrex::convert(cba,Bx_nodal_flag),dm,1,ngE)); - Bfield_cp[lev][1].reset( new MultiFab(amrex::convert(cba,By_nodal_flag),dm,1,ngE)); - Bfield_cp[lev][2].reset( new MultiFab(amrex::convert(cba,Bz_nodal_flag),dm,1,ngE)); + Bfield_cp[lev][0].reset( new MultiFab(amrex::convert(cba,Bx_nodal_flag),dm,ncomps,ngE)); + Bfield_cp[lev][1].reset( new MultiFab(amrex::convert(cba,By_nodal_flag),dm,ncomps,ngE)); + Bfield_cp[lev][2].reset( new MultiFab(amrex::convert(cba,Bz_nodal_flag),dm,ncomps,ngE)); // Create the MultiFabs for E - Efield_cp[lev][0].reset( new MultiFab(amrex::convert(cba,Ex_nodal_flag),dm,1,ngE)); - Efield_cp[lev][1].reset( new MultiFab(amrex::convert(cba,Ey_nodal_flag),dm,1,ngE)); - Efield_cp[lev][2].reset( new MultiFab(amrex::convert(cba,Ez_nodal_flag),dm,1,ngE)); + Efield_cp[lev][0].reset( new MultiFab(amrex::convert(cba,Ex_nodal_flag),dm,ncomps,ngE)); + Efield_cp[lev][1].reset( new MultiFab(amrex::convert(cba,Ey_nodal_flag),dm,ncomps,ngE)); + Efield_cp[lev][2].reset( new MultiFab(amrex::convert(cba,Ez_nodal_flag),dm,ncomps,ngE)); // Create the MultiFabs for the current - current_cp[lev][0].reset( new MultiFab(amrex::convert(cba,jx_nodal_flag),dm,1,ngJ)); - current_cp[lev][1].reset( new MultiFab(amrex::convert(cba,jy_nodal_flag),dm,1,ngJ)); - current_cp[lev][2].reset( new MultiFab(amrex::convert(cba,jz_nodal_flag),dm,1,ngJ)); + current_cp[lev][0].reset( new MultiFab(amrex::convert(cba,jx_nodal_flag),dm,ncomps,ngJ)); + current_cp[lev][1].reset( new MultiFab(amrex::convert(cba,jy_nodal_flag),dm,ncomps,ngJ)); + current_cp[lev][2].reset( new MultiFab(amrex::convert(cba,jz_nodal_flag),dm,ncomps,ngJ)); const auto& cperiod = Geom(lev-1).periodicity(); current_cp_owner_masks[lev][0] = std::move(current_cp[lev][0]->OwnerMask(cperiod)); @@ -878,17 +896,17 @@ WarpX::AllocLevelMFs (int lev, const BoxArray& ba, const DistributionMapping& dm current_cp_owner_masks[lev][2] = std::move(current_cp[lev][2]->OwnerMask(cperiod)); if (do_dive_cleaning || plot_rho){ - rho_cp[lev].reset(new MultiFab(amrex::convert(cba,IntVect::TheUnitVector()),dm,2,ngRho)); + rho_cp[lev].reset(new MultiFab(amrex::convert(cba,IntVect::TheUnitVector()),dm,2*ncomps,ngRho)); rho_cp_owner_masks[lev] = std::move(rho_cp[lev]->OwnerMask(cperiod)); } if (do_dive_cleaning) { - F_cp[lev].reset (new MultiFab(amrex::convert(cba,IntVect::TheUnitVector()),dm,1, ngF)); + F_cp[lev].reset (new MultiFab(amrex::convert(cba,IntVect::TheUnitVector()),dm,ncomps, ngF)); } #ifdef WARPX_USE_PSATD else { - rho_cp[lev].reset(new MultiFab(amrex::convert(cba,IntVect::TheUnitVector()),dm,2,ngRho)); + rho_cp[lev].reset(new MultiFab(amrex::convert(cba,IntVect::TheUnitVector()),dm,2*ncomps,ngRho)); rho_cp_owner_masks[lev] = std::move(rho_cp[lev]->OwnerMask(cperiod)); } #endif @@ -904,28 +922,28 @@ WarpX::AllocLevelMFs (int lev, const BoxArray& ba, const DistributionMapping& dm if (n_field_gather_buffer > 0) { // Create the MultiFabs for B - Bfield_cax[lev][0].reset( new MultiFab(amrex::convert(cba,Bx_nodal_flag),dm,1,ngE)); - Bfield_cax[lev][1].reset( new MultiFab(amrex::convert(cba,By_nodal_flag),dm,1,ngE)); - Bfield_cax[lev][2].reset( new MultiFab(amrex::convert(cba,Bz_nodal_flag),dm,1,ngE)); + Bfield_cax[lev][0].reset( new MultiFab(amrex::convert(cba,Bx_nodal_flag),dm,ncomps,ngE)); + Bfield_cax[lev][1].reset( new MultiFab(amrex::convert(cba,By_nodal_flag),dm,ncomps,ngE)); + Bfield_cax[lev][2].reset( new MultiFab(amrex::convert(cba,Bz_nodal_flag),dm,ncomps,ngE)); // Create the MultiFabs for E - Efield_cax[lev][0].reset( new MultiFab(amrex::convert(cba,Ex_nodal_flag),dm,1,ngE)); - Efield_cax[lev][1].reset( new MultiFab(amrex::convert(cba,Ey_nodal_flag),dm,1,ngE)); - Efield_cax[lev][2].reset( new MultiFab(amrex::convert(cba,Ez_nodal_flag),dm,1,ngE)); + Efield_cax[lev][0].reset( new MultiFab(amrex::convert(cba,Ex_nodal_flag),dm,ncomps,ngE)); + Efield_cax[lev][1].reset( new MultiFab(amrex::convert(cba,Ey_nodal_flag),dm,ncomps,ngE)); + Efield_cax[lev][2].reset( new MultiFab(amrex::convert(cba,Ez_nodal_flag),dm,ncomps,ngE)); - gather_buffer_masks[lev].reset( new iMultiFab(ba, dm, 1, 1) ); + gather_buffer_masks[lev].reset( new iMultiFab(ba, dm, ncomps, 1) ); // Gather buffer masks have 1 ghost cell, because of the fact // that particles may move by more than one cell when using subcycling. } if (n_current_deposition_buffer > 0) { - current_buf[lev][0].reset( new MultiFab(amrex::convert(cba,jx_nodal_flag),dm,1,ngJ)); - current_buf[lev][1].reset( new MultiFab(amrex::convert(cba,jy_nodal_flag),dm,1,ngJ)); - current_buf[lev][2].reset( new MultiFab(amrex::convert(cba,jz_nodal_flag),dm,1,ngJ)); + current_buf[lev][0].reset( new MultiFab(amrex::convert(cba,jx_nodal_flag),dm,ncomps,ngJ)); + current_buf[lev][1].reset( new MultiFab(amrex::convert(cba,jy_nodal_flag),dm,ncomps,ngJ)); + current_buf[lev][2].reset( new MultiFab(amrex::convert(cba,jz_nodal_flag),dm,ncomps,ngJ)); if (do_dive_cleaning || plot_rho) { - charge_buf[lev].reset( new MultiFab(amrex::convert(cba,IntVect::TheUnitVector()),dm,2,ngRho)); + charge_buf[lev].reset( new MultiFab(amrex::convert(cba,IntVect::TheUnitVector()),dm,2*ncomps,ngRho)); } - current_buffer_masks[lev].reset( new iMultiFab(ba, dm, 1, 1) ); + current_buffer_masks[lev].reset( new iMultiFab(ba, dm, ncomps, 1) ); // Current buffer masks have 1 ghost cell, because of the fact // that particles may move by more than one cell when using subcycling. } |