diff --git a/Source/FieldSolver/FiniteDifferenceSolver/FiniteDifferenceSolver.H b/Source/FieldSolver/FiniteDifferenceSolver/FiniteDifferenceSolver.H index 8d68f7310b1..488c73d84a0 100644 --- a/Source/FieldSolver/FiniteDifferenceSolver/FiniteDifferenceSolver.H +++ b/Source/FieldSolver/FiniteDifferenceSolver/FiniteDifferenceSolver.H @@ -1,7 +1,10 @@ -/* Copyright 2020 Remi Lehe +/* Copyright 2020-2024 The WarpX Community * * This file is part of WarpX. * + * Authors: Remi Lehe (LBNL) + * S. Eric Clark (Helion Energy) + * * License: BSD-3-Clause-LBNL */ diff --git a/Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.H b/Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.H index 4fda1e74b6e..1b5ccd1bb74 100644 --- a/Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.H +++ b/Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.H @@ -1,8 +1,9 @@ -/* Copyright 2023 The WarpX Community +/* Copyright 2023-2024 The WarpX Community * * This file is part of WarpX. * * Authors: Roelof Groenewald (TAE Technologies) + * S. Eric Clark (Helion Energy) * * License: BSD-3-Clause-LBNL */ @@ -12,6 +13,8 @@ #include "HybridPICModel_fwd.H" +#include "Fields.H" + #include "Utils/WarpXAlgorithmSelection.H" #include "FieldSolver/FiniteDifferenceSolver/FiniteDifferenceSolver.H" @@ -42,8 +45,8 @@ public: void ReadParameters (); /** Allocate hybrid-PIC specific multifabs. Called in constructor. */ - void AllocateLevelMFs (ablastr::fields::MultiFabRegister & fields, - + void AllocateLevelMFs ( + ablastr::fields::MultiFabRegister & fields, int lev, const amrex::BoxArray& ba, const amrex::DistributionMapping& dm, @@ -72,41 +75,19 @@ public: * external current multifab. Note the external current can be a function * of time and therefore this should be re-evaluated at every step. */ - void GetCurrentExternal ( - ablastr::fields::MultiLevelVectorField const& edge_lengths - ); + void GetCurrentExternal (bool skip_check = false); - void GetCurrentExternal ( - ablastr::fields::VectorField const& edge_lengths, - int lev - ); - - void GetFieldsExternal ( - amrex::Vector, 3>> const& edge_lengths - ); - - void GetFieldsExternal ( - amrex::Vector, 3>> const& edge_lengths, - amrex::Real t); - - void GetFieldsExternal ( - std::array< std::unique_ptr, 3> const& edge_lengths, - int lev - ); + void GetFieldsExternal (amrex::Real t); void GetExternalFieldFromExpression ( - std::array< std::unique_ptr, 3> const& field, + warpx::fields::FieldType field_type, std::array< amrex::ParserExecutor<4>, 3> const& expression, - std::array< std::unique_ptr, 3> const& edge_lengths, - int lev - ); - + int lev); + void GetExternalFieldFromExpression ( - std::array< std::unique_ptr, 3> const& field, + warpx::fields::FieldType field_type, std::array< amrex::ParserExecutor<4>, 3> const& expression, - std::array< std::unique_ptr, 3> const& edge_lengths, - int lev, amrex::Real t - ); + int lev, amrex::Real t); /** * \brief @@ -252,35 +233,35 @@ public: std::array< amrex::ParserExecutor<4>, 3> m_E_external; // Declare multifabs specifically needed for the hybrid-PIC model - amrex::Vector< std::unique_ptr > rho_fp_temp; - amrex::Vector, 3 > > current_fp_temp; - amrex::Vector, 3 > > current_fp_ampere; - amrex::Vector, 3 > > current_fp_external; - amrex::Vector< std::unique_ptr > electron_pressure_fp; - - amrex::Vector, 3 > > Bfield_hyb_external; - amrex::Vector, 3 > > Efield_hyb_external; + // amrex::Vector< std::unique_ptr > rho_fp_temp; + // amrex::Vector, 3 > > current_fp_temp; + // amrex::Vector, 3 > > current_fp_ampere; + // amrex::Vector, 3 > > current_fp_external; + // amrex::Vector< std::unique_ptr > electron_pressure_fp; + + // amrex::Vector, 3 > > Bfield_hyb_external; + // amrex::Vector, 3 > > Efield_hyb_external; // amrex::Vector, 3 > > Bfield_hyb_self; // amrex::Vector, 3 > > Efield_hyb_self; - // Helper functions to retrieve hybrid-PIC multifabs - [[nodiscard]] amrex::MultiFab* - get_pointer_current_fp_ampere (int lev, int direction) const - { - return current_fp_ampere[lev][direction].get(); - } - - [[nodiscard]] amrex::MultiFab* - get_pointer_current_fp_external (int lev, int direction) const - { - return current_fp_external[lev][direction].get(); - } - - [[nodiscard]] amrex::MultiFab* - get_pointer_electron_pressure_fp (int lev) const - { - return electron_pressure_fp[lev].get(); - } + // // Helper functions to retrieve hybrid-PIC multifabs + // [[nodiscard]] amrex::MultiFab* + // get_pointer_current_fp_ampere (int lev, int direction) const + // { + // return current_fp_ampere[lev][direction].get(); + // } + + // [[nodiscard]] amrex::MultiFab* + // get_pointer_current_fp_external (int lev, int direction) const + // { + // return current_fp_external[lev][direction].get(); + // } + + // [[nodiscard]] amrex::MultiFab* + // get_pointer_electron_pressure_fp (int lev) const + // { + // return electron_pressure_fp[lev].get(); + // } /** Gpu Vector with index type of the Jx multifab */ amrex::GpuArray Jx_IndexType; diff --git a/Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.cpp b/Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.cpp index a7faa79ca60..9373ff2bdf2 100644 --- a/Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.cpp +++ b/Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.cpp @@ -1,8 +1,9 @@ -/* Copyright 2023 The WarpX Community +/* Copyright 2023-2024 The WarpX Community * * This file is part of WarpX. * * Authors: Roelof Groenewald (TAE Technologies) + * S. Eric Clark (Helion Energy) * * License: BSD-3-Clause-LBNL */ @@ -10,7 +11,7 @@ #include "HybridPICModel.H" #include "EmbeddedBoundary/Enabled.H" -#include "FieldSolver/Fields.H" +#include "Fields.H" #include "Particles/MultiParticleContainer.H" #include "WarpX.H" @@ -68,30 +69,8 @@ void HybridPICModel::ReadParameters () } } -void HybridPICModel::AllocateLevelMFs (ablastr::fields::MultiFabRegister & fields, - int lev, const BoxArray& ba, const DistributionMapping& dm, - const int ncomps, const IntVect& ngJ, const IntVect& ngRho, - const IntVect& jx_nodal_flag, - const IntVect& jy_nodal_flag, - const IntVect& jz_nodal_flag, - const IntVect& rho_nodal_flag) -void HybridPICModel::AllocateMFs (int nlevs_max) -{ - electron_pressure_fp.resize(nlevs_max); - rho_fp_temp.resize(nlevs_max); - current_fp_temp.resize(nlevs_max); - current_fp_ampere.resize(nlevs_max); - current_fp_external.resize(nlevs_max); - - if (m_add_external_fields) { - Bfield_hyb_external.resize(nlevs_max); - Efield_hyb_external.resize(nlevs_max); - // Bfield_hyb_self.resize(nlevs_max); - // Efield_hyb_self.resize(nlevs_max); - } -} - void HybridPICModel::AllocateLevelMFs ( + ablastr::fields::MultiFabRegister & fields, int lev, const BoxArray& ba, const DistributionMapping& dm, const int ncomps, const IntVect& ngJ, const IntVect& ngRho, @@ -158,18 +137,24 @@ void HybridPICModel::AllocateLevelMFs ( if (m_add_external_fields) { // These are nodal to match when B-field is added in evaluation of Ohm's law - WarpX::AllocInitMultiFab(Bfield_hyb_external[lev][0], amrex::convert(ba, Bx_nodal_flag), - dm, ncomps, ngB, lev, "Bfield_hyb_external[x]", 0.0_rt); - WarpX::AllocInitMultiFab(Bfield_hyb_external[lev][1], amrex::convert(ba, By_nodal_flag), - dm, ncomps, ngB, lev, "Bfield_hyb_external[y]", 0.0_rt); - WarpX::AllocInitMultiFab(Bfield_hyb_external[lev][2], amrex::convert(ba, Bz_nodal_flag), - dm, ncomps, ngB, lev, "Bfield_hyb_external[z]", 0.0_rt); - WarpX::AllocInitMultiFab(Efield_hyb_external[lev][0], amrex::convert(ba, Ex_nodal_flag), - dm, ncomps, ngE, lev, "Efield_hyb_external[x]", 0.0_rt); - WarpX::AllocInitMultiFab(Efield_hyb_external[lev][1], amrex::convert(ba, Ey_nodal_flag), - dm, ncomps, ngE, lev, "Efield_hyb_external[y]", 0.0_rt); - WarpX::AllocInitMultiFab(Efield_hyb_external[lev][2], amrex::convert(ba, Ez_nodal_flag), - dm, ncomps, ngE, lev, "Efield_hyb_external[z]", 0.0_rt); + fields.alloc_init(FieldType::hybrid_B_fp_external, Direction{0}, + lev, amrex::convert(ba, Bx_nodal_flag), + dm, ncomps, ngB, 0.0_rt); + fields.alloc_init(FieldType::hybrid_B_fp_external, Direction{1}, + lev, amrex::convert(ba, By_nodal_flag), + dm, ncomps, ngB, 0.0_rt); + fields.alloc_init(FieldType::hybrid_B_fp_external, Direction{2}, + lev, amrex::convert(ba, Bz_nodal_flag), + dm, ncomps, ngB, 0.0_rt); + fields.alloc_init(FieldType::hybrid_E_fp_external, Direction{0}, + lev, amrex::convert(ba, Ex_nodal_flag), + dm, ncomps, ngE, 0.0_rt); + fields.alloc_init(FieldType::hybrid_E_fp_external, Direction{1}, + lev, amrex::convert(ba, Ey_nodal_flag), + dm, ncomps, ngE, 0.0_rt); + fields.alloc_init(FieldType::hybrid_E_fp_external, Direction{2}, + lev, amrex::convert(ba, Ez_nodal_flag), + dm, ncomps, ngE, 0.0_rt); } #ifdef WARPX_DIM_RZ @@ -179,21 +164,6 @@ void HybridPICModel::AllocateLevelMFs ( #endif } -void HybridPICModel::ClearLevel (int lev) -{ - electron_pressure_fp[lev].reset(); - rho_fp_temp[lev].reset(); - for (int i = 0; i < 3; ++i) { - current_fp_temp[lev][i].reset(); - current_fp_ampere[lev][i].reset(); - current_fp_external[lev][i].reset(); - if (m_add_external_fields) { - Bfield_hyb_external[lev][i].reset(); - Efield_hyb_external[lev][i].reset(); - } - } -} - void HybridPICModel::InitData () { m_resistivity_parser = std::make_unique( @@ -315,96 +285,60 @@ void HybridPICModel::InitData () // Initialize external current - note that this approach skips the check // if the current is time dependent which is what needs to be done to // write time independent fields on the first step. - for (int lev = 0; lev <= warpx.finestLevel(); ++lev) { - auto edge_lengths = std::array, 3>(); -#ifdef AMREX_USE_EB - if (EB::enabled()) { - using ablastr::fields::Direction; - auto const & edge_lengths_x = *warpx.m_fields.get(FieldType::edge_lengths, Direction{0}, lev); - auto const & edge_lengths_y = *warpx.m_fields.get(FieldType::edge_lengths, Direction{1}, lev); - auto const & edge_lengths_z = *warpx.m_fields.get(FieldType::edge_lengths, Direction{2}, lev); - - edge_lengths = std::array< std::unique_ptr, 3 >{ - std::make_unique( - edge_lengths_x, amrex::make_alias, 0, edge_lengths_x.nComp()), - std::make_unique( - edge_lengths_y, amrex::make_alias, 0, edge_lengths_y.nComp()), - std::make_unique( - edge_lengths_z, amrex::make_alias, 0, edge_lengths_z.nComp()) - }; - } -#endif - GetCurrentExternal(ablastr::fields::a2m(edge_lengths), lev); - GetFieldsExternal(ablastr::fields::a2m(edge_lengths), lev); - } + GetCurrentExternal(true); + GetFieldsExternal(warpx.gett_new(0)); } -void HybridPICModel::GetCurrentExternal ( - ablastr::fields::MultiLevelVectorField const& edge_lengths) +void HybridPICModel::GetCurrentExternal (bool skip_check /*=false*/) { - if (!m_external_field_has_time_dependence) { return; } + if (!skip_check && !m_external_field_has_time_dependence) { return; } auto& warpx = WarpX::GetInstance(); for (int lev = 0; lev <= warpx.finestLevel(); ++lev) { - GetExternalFieldFromExpression(current_fp_external[lev], m_J_external, edge_lengths[lev], lev); + GetExternalFieldFromExpression(FieldType::hybrid_current_fp_external, m_J_external, lev); } } -void HybridPICModel::GetCurrentExternal ( - ablastr::fields::VectorField const& edge_lengths, - int lev) -{ - if (!m_external_field_has_time_dependence) { return; } - GetExternalFieldFromExpression(current_fp_external[lev], m_J_external, edge_lengths, lev); -} - -void HybridPICModel::GetFieldsExternal ( - amrex::Vector, 3>> const& edge_lengths, - amrex::Real t) +void HybridPICModel::GetFieldsExternal (amrex::Real t) { auto& warpx = WarpX::GetInstance(); for (int lev = 0; lev <= warpx.finestLevel(); ++lev) { - GetExternalFieldFromExpression(Bfield_hyb_external[lev], m_B_external, edge_lengths[lev], lev, t); - GetExternalFieldFromExpression(Efield_hyb_external[lev], m_E_external, edge_lengths[lev], lev, t); + GetExternalFieldFromExpression( + FieldType::hybrid_B_fp_external, + m_B_external, lev, t); + GetExternalFieldFromExpression( + FieldType::hybrid_E_fp_external, + m_E_external, lev, t); } } -void HybridPICModel::GetFieldsExternal ( - std::array< std::unique_ptr, 3> const& edge_lengths, - int lev) -{ - GetExternalFieldFromExpression(Bfield_hyb_external[lev], m_B_external, edge_lengths, lev); - GetExternalFieldFromExpression(Efield_hyb_external[lev], m_E_external, edge_lengths, lev); -} - void HybridPICModel::GetExternalFieldFromExpression ( - std::array< std::unique_ptr, 3> const& field, + FieldType field_type, std::array< amrex::ParserExecutor<4>, 3> const& expression, - std::array< std::unique_ptr, 3> const& edge_lengths, int lev) { auto & warpx = WarpX::GetInstance(); - auto t = warpx.gett_new(lev); - GetExternalFieldFromExpression(field, expression, edge_lengths, lev, t); + GetExternalFieldFromExpression(field_type, expression, lev, warpx.gett_new(lev)); } void HybridPICModel::GetExternalFieldFromExpression ( - std::array< std::unique_ptr, 3> const& field, + FieldType field_type, std::array< amrex::ParserExecutor<4>, 3> const& expression, - std::array< std::unique_ptr, 3> const& edge_lengths, int lev, amrex::Real t) { + using ablastr::fields::Direction; + // This logic matches closely to WarpX::InitializeExternalFieldsOnGridUsingParser // except that the parsers include time dependence. auto & warpx = WarpX::GetInstance(); auto dx_lev = warpx.Geom(lev).CellSizeArray(); const RealBox& real_box = warpx.Geom(lev).ProbDomain(); - auto& mfx = field[0]; - auto& mfy = field[1]; - auto& mfz = field[2]; + auto const& mfx = warpx.m_fields.get(field_type, Direction{0}, lev); + auto const& mfy = warpx.m_fields.get(field_type, Direction{1}, lev); + auto const& mfz = warpx.m_fields.get(field_type, Direction{2}, lev); const amrex::IntVect x_nodal_flag = mfx->ixType().toIntVect(); const amrex::IntVect y_nodal_flag = mfy->ixType().toIntVect(); @@ -427,9 +361,9 @@ void HybridPICModel::GetExternalFieldFromExpression ( amrex::Array4 lx, ly, lz; if (EB::enabled()) { - lx = edge_lengths[0]->array(mfi); - ly = edge_lengths[1]->array(mfi); - lz = edge_lengths[2]->array(mfi); + lx = warpx.m_fields.get(FieldType::edge_lengths, Direction{0}, lev)->array(mfi); + ly = warpx.m_fields.get(FieldType::edge_lengths, Direction{1}, lev)->array(mfi); + lz = warpx.m_fields.get(FieldType::edge_lengths, Direction{2}, lev)->array(mfi); } amrex::ParallelFor (tbx, tby, tbz, diff --git a/Source/FieldSolver/FiniteDifferenceSolver/HybridPICSolveE.cpp b/Source/FieldSolver/FiniteDifferenceSolver/HybridPICSolveE.cpp index 9f82d6c965d..97f436bfe76 100644 --- a/Source/FieldSolver/FiniteDifferenceSolver/HybridPICSolveE.cpp +++ b/Source/FieldSolver/FiniteDifferenceSolver/HybridPICSolveE.cpp @@ -23,6 +23,7 @@ #include using namespace amrex; +using warpx::fields::FieldType; void FiniteDifferenceSolver::CalculateCurrentAmpere ( ablastr::fields::VectorField & Jfield, @@ -423,8 +424,10 @@ void FiniteDifferenceSolver::HybridPICSolveECylindrical ( const bool include_hyper_resistivity_term = (eta_h > 0.0) && solve_for_Faraday; const bool include_external_fields = hybrid_model->m_add_external_fields; - auto const& Bfield_external = hybrid_model->Bfield_hyb_external[0]; // lev=0 - auto const& Efield_external = hybrid_model->Efield_hyb_external[0]; // lev=0 + + auto const& warpx = WarpX::GetInstance(); + ablastr::fields::ConstVectorField Bfield_external = warpx.m_fields.get_alldirs(FieldType::hybrid_B_fp_external, 0); // lev=0 + ablastr::fields::ConstVectorField Efield_external = warpx.m_fields.get_alldirs(FieldType::hybrid_E_fp_external, 0); // lev=0 // Index type required for interpolating fields from their respective // staggering to the Ex, Ey, Ez locations @@ -762,8 +765,10 @@ void FiniteDifferenceSolver::HybridPICSolveECartesian ( const bool include_hyper_resistivity_term = (eta_h > 0.) && solve_for_Faraday; const bool include_external_fields = hybrid_model->m_add_external_fields; - auto const& Bfield_external = hybrid_model->Bfield_hyb_external[0]; // lev=0 - auto const& Efield_external = hybrid_model->Efield_hyb_external[0]; // lev=0 + + auto const& warpx = WarpX::GetInstance(); + ablastr::fields::ConstVectorField Bfield_external = warpx.m_fields.get_alldirs(FieldType::hybrid_B_fp_external, 0); // lev=0 + ablastr::fields::ConstVectorField Efield_external = warpx.m_fields.get_alldirs(FieldType::hybrid_E_fp_external, 0); // lev=0 // Index type required for interpolating fields from their respective // staggering to the Ex, Ey, Ez locations diff --git a/Source/FieldSolver/WarpXPushFieldsHybridPIC.cpp b/Source/FieldSolver/WarpXPushFieldsHybridPIC.cpp index e8605c25b2f..15f94c30f81 100644 --- a/Source/FieldSolver/WarpXPushFieldsHybridPIC.cpp +++ b/Source/FieldSolver/WarpXPushFieldsHybridPIC.cpp @@ -1,8 +1,9 @@ -/* Copyright 2023 The WarpX Community +/* Copyright 2023-2024 The WarpX Community * * This file is part of WarpX. * * Authors: Roelof Groenewald (TAE Technologies) + * S. Eric Clark (Helion Energy) * * License: BSD-3-Clause-LBNL */ @@ -71,30 +72,27 @@ void WarpX::HybridPICEvolveFields () amrex::Real sub_dt = 0.5_rt*dt[0]/sub_steps; const bool add_external_fields = m_hybrid_pic_model->m_add_external_fields; - auto const& Bfield_hyb_external = m_hybrid_pic_model->Bfield_hyb_external; - auto const& Efield_hyb_external = m_hybrid_pic_model->Efield_hyb_external; // Handle field splitting for Hybrid field push if (add_external_fields) { // Get the external fields - m_hybrid_pic_model->GetFieldsExternal(m_edge_lengths, t_eval); + m_hybrid_pic_model->GetFieldsExternal(t_eval); // If using split fields, subtract the external field at the old time for (int lev = 0; lev <= finest_level; ++lev) { for (int idim = 0; idim < 3; ++idim) { MultiFab::Subtract( - *Bfield_fp[lev][idim], - *Bfield_hyb_external[lev][idim], + *m_fields.get(FieldType::Bfield_fp, Direction{idim}, lev), + *m_fields.get(FieldType::hybrid_B_fp_external, Direction{idim}, lev), 0, 0, 1, - Bfield_hyb_external[lev][idim]->nGrowVect()); + m_fields.get(FieldType::hybrid_B_fp_external, Direction{idim}, lev)->nGrowVect()); } } FillBoundaryB(guard_cells.ng_FieldSolver, WarpX::sync_nodal_points); } // Get the external current - m_hybrid_pic_model->GetCurrentExternal( - m_fields.get_mr_levels_alldirs(FieldType::edge_lengths, finest_level)); + m_hybrid_pic_model->GetCurrentExternal(); // Reference hybrid-PIC multifabs ablastr::fields::MultiLevelScalarField rho_fp_temp = m_fields.get_mr_levels(FieldType::hybrid_rho_fp_temp, finest_level); @@ -157,7 +155,7 @@ void WarpX::HybridPICEvolveFields () if (add_external_fields) { // Get the external fields - m_hybrid_pic_model->GetFieldsExternal(m_fields.get_mr_levels_alldirs(FieldType::edge_lengths, finest_level), t_eval); + m_hybrid_pic_model->GetFieldsExternal(t_eval); } // Now push the B field from t=n+1/2 to t=n+1 using the n+1/2 quantities @@ -212,21 +210,21 @@ void WarpX::HybridPICEvolveFields () // Handle field splitting for Hybrid field push if (add_external_fields) { - m_hybrid_pic_model->GetFieldsExternal(m_edge_lengths, t_eval); + m_hybrid_pic_model->GetFieldsExternal(t_eval); // If using split fields, add the external field at the new time for (int lev = 0; lev <= finest_level; ++lev) { for (int idim = 0; idim < 3; ++idim) { MultiFab::Add( - *Bfield_fp[lev][idim], - *Bfield_hyb_external[lev][idim], + *m_fields.get(FieldType::Bfield_fp, Direction{idim}, lev), + *m_fields.get(FieldType::hybrid_B_fp_external, Direction{idim}, lev), 0, 0, 1, - Bfield_hyb_external[lev][idim]->nGrowVect()); + m_fields.get(FieldType::hybrid_B_fp_external, Direction{idim}, lev)->nGrowVect()); MultiFab::Add( - *Efield_fp[lev][idim], - *Efield_hyb_external[lev][idim], - 0, 0, 1, - Efield_hyb_external[lev][idim]->nGrowVect()); + *m_fields.get(FieldType::Efield_fp, Direction{idim}, lev), + *m_fields.get(FieldType::hybrid_E_fp_external, Direction{idim}, lev), + 0, 0, 1, + m_fields.get(FieldType::hybrid_E_fp_external, Direction{idim}, lev)->nGrowVect()); } } FillBoundaryB(guard_cells.ng_FieldSolver, WarpX::sync_nodal_points); diff --git a/Source/Fields.H b/Source/Fields.H index 0aa3cbdd0c0..8b753bc1008 100644 --- a/Source/Fields.H +++ b/Source/Fields.H @@ -45,6 +45,8 @@ namespace warpx::fields hybrid_current_fp_temp, hybrid_current_fp_ampere, hybrid_current_fp_external, + hybrid_B_fp_external, + hybrid_E_fp_external, Efield_cp, //!< Only used with MR. The field that is updated by the field solver at each timestep, on the coarse patch of each level Bfield_cp, //!< Only used with MR. The field that is updated by the field solver at each timestep, on the coarse patch of each level current_cp, //!< Only used with MR. The current that is used as a source for the field solver, on the coarse patch of each level @@ -97,6 +99,8 @@ namespace warpx::fields FieldType::hybrid_current_fp_temp, FieldType::hybrid_current_fp_ampere, FieldType::hybrid_current_fp_external, + FieldType::hybrid_B_fp_external, + FieldType::hybrid_E_fp_external, FieldType::Efield_cp, FieldType::Bfield_cp, FieldType::current_cp,