diff options
-rw-r--r-- | Docs/source/usage/parameters.rst | 2 | ||||
-rw-r--r-- | Examples/Tests/SilverMueller/inputs_2d_x | 4 | ||||
-rw-r--r-- | Examples/Tests/SilverMueller/inputs_2d_z | 5 | ||||
-rw-r--r-- | Examples/Tests/SilverMueller/inputs_rz_z | 7 | ||||
-rw-r--r-- | Source/BoundaryConditions/WarpXFieldBoundaries.cpp | 36 | ||||
-rw-r--r-- | Source/Evolve/WarpXEvolve.cpp | 21 | ||||
-rw-r--r-- | Source/FieldSolver/WarpXPushFieldsEM.cpp | 24 | ||||
-rw-r--r-- | Source/Python/WarpXWrappers.cpp | 4 | ||||
-rw-r--r-- | Source/Python/WarpXWrappers.h | 3 | ||||
-rw-r--r-- | Source/Utils/WarpXAlgorithmSelection.H | 3 | ||||
-rw-r--r-- | Source/Utils/WarpXAlgorithmSelection.cpp | 1 | ||||
-rw-r--r-- | Source/Utils/WarpXUtil.cpp | 32 | ||||
-rw-r--r-- | Source/WarpX.H | 8 | ||||
-rw-r--r-- | Source/WarpX.cpp | 23 |
14 files changed, 125 insertions, 48 deletions
diff --git a/Docs/source/usage/parameters.rst b/Docs/source/usage/parameters.rst index d4ab472dc..722568377 100644 --- a/Docs/source/usage/parameters.rst +++ b/Docs/source/usage/parameters.rst @@ -224,6 +224,8 @@ Domain Boundary Conditions * ``pml`` (default): This option can be used to add Perfectly Matched Layers (PML) around the simulation domain. It will override the user-defined value provided for ``warpx.do_pml``. See the :ref:`PML theory section <theory-bc>` for more details. Additional pml algorithms can be explored using the parameters ``warpx.do_pml_in_domain``, ``warpx.do_particles_in_pml``, and ``warpx.do_pml_j_damping``. + * ``absorbing_silver_mueller``: This option can be used to set the Silver-Mueller absorbing boundary conditions. These boundary conditions are simpler and less computationally expensive than the pml, but are also less effective at absorbing the field. They only work with the Yee Maxwell solver. + * ``damped``: This is the recommended option in the moving direction when using the spectral solver with moving window (currently only supported along z). This boundary condition applies a damping factor to the electric and magnetic fields in the outer half of the guard cells, using a sine squared profile. As the spectral solver is by nature periodic, the damping prevents fields from wrapping around to the other end of the domain when the periodicity is not desired. This boundary condition is only valid when using the spectral solver. * ``pec``: This option can be used to set a Perfect Electric Conductor at the simulation boundary. For the electromagnetic solve, at PEC, the tangential electric field and the normal magnetic field are set to 0. This boundary can be used to model a dielectric or metallic surface. In the guard-cell region, the tangential electric field is set equal and opposite to the respective field component in the mirror location across the PEC boundary, and the normal electric field is set equal to the field component in the mirror location in the domain across the PEC boundary. Similarly, the tangential (and normal) magnetic field components are set equal (and opposite) to the respective magnetic field components in the mirror locations across the PEC boundary. Note that PEC boundary is invalid at `r=0` for the RZ solver. Please use ``none`` option. This boundary condition does not work with the spectral solver. diff --git a/Examples/Tests/SilverMueller/inputs_2d_x b/Examples/Tests/SilverMueller/inputs_2d_x index 708fcd0fe..bbfa1aad1 100644 --- a/Examples/Tests/SilverMueller/inputs_2d_x +++ b/Examples/Tests/SilverMueller/inputs_2d_x @@ -13,9 +13,10 @@ amr.max_level = 0 # Geometry geometry.coord_sys = 0 -geometry.is_periodic = 0 0 0 geometry.prob_lo = -20.e-6 -40.e-6 geometry.prob_hi = 20.e-6 40.e-6 +boundary.field_lo = absorbing_silver_mueller absorbing_silver_mueller +boundary.field_hi = absorbing_silver_mueller absorbing_silver_mueller # Verbosity warpx.verbose = 1 @@ -23,7 +24,6 @@ warpx.verbose = 1 # Algorithms warpx.cfl = 1.0 warpx.do_pml = 0 -warpx.do_silver_mueller = 1 warpx.use_filter = 0 warpx.do_moving_window = 0 diff --git a/Examples/Tests/SilverMueller/inputs_2d_z b/Examples/Tests/SilverMueller/inputs_2d_z index e14f35ecf..cf3ff3147 100644 --- a/Examples/Tests/SilverMueller/inputs_2d_z +++ b/Examples/Tests/SilverMueller/inputs_2d_z @@ -13,9 +13,11 @@ amr.max_level = 0 # Geometry geometry.coord_sys = 0 -geometry.is_periodic = 0 0 0 geometry.prob_lo = -40.e-6 -20.e-6 geometry.prob_hi = 40.e-6 20.e-6 +boundary.field_lo = absorbing_silver_mueller absorbing_silver_mueller +boundary.field_hi = absorbing_silver_mueller absorbing_silver_mueller + # Verbosity warpx.verbose = 1 @@ -23,7 +25,6 @@ warpx.verbose = 1 # Algorithms warpx.cfl = 1.0 warpx.do_pml = 0 -warpx.do_silver_mueller = 1 warpx.use_filter = 0 warpx.do_moving_window = 0 diff --git a/Examples/Tests/SilverMueller/inputs_rz_z b/Examples/Tests/SilverMueller/inputs_rz_z index 1b4e846b0..d3308dac7 100644 --- a/Examples/Tests/SilverMueller/inputs_rz_z +++ b/Examples/Tests/SilverMueller/inputs_rz_z @@ -13,10 +13,14 @@ amr.max_level = 0 # Geometry geometry.coord_sys = 1 -geometry.is_periodic = 0 0 0 geometry.prob_lo = 0.e-6 -20.e-6 geometry.prob_hi = 40.e-6 20.e-6 +boundary.field_lo = none absorbing_silver_mueller +boundary.field_hi = absorbing_silver_mueller absorbing_silver_mueller + + + # Verbosity warpx.verbose = 1 warpx.n_rz_azimuthal_modes = 2 @@ -24,7 +28,6 @@ warpx.n_rz_azimuthal_modes = 2 # Algorithms warpx.cfl = 1.0 warpx.do_pml = 0 -warpx.do_silver_mueller = 1 warpx.use_filter = 0 warpx.do_moving_window = 0 diff --git a/Source/BoundaryConditions/WarpXFieldBoundaries.cpp b/Source/BoundaryConditions/WarpXFieldBoundaries.cpp index 2e69dc3d5..b7f625c8a 100644 --- a/Source/BoundaryConditions/WarpXFieldBoundaries.cpp +++ b/Source/BoundaryConditions/WarpXFieldBoundaries.cpp @@ -1,14 +1,25 @@ #include "WarpX.H" - +#include "FieldSolver/FiniteDifferenceSolver/FiniteDifferenceSolver.H" +#include "Evolve/WarpXDtType.H" #include "WarpX_PEC.H" #include <AMReX_REAL.H> #include <AMReX_Vector.H> - +#include <AMReX_Print.H> #include <array> #include <memory> +#include <AMReX.H> +#include <AMReX_Geometry.H> +#include <AMReX_IntVect.H> +#include <AMReX_Print.H> +#include <AMReX_REAL.H> +#include <AMReX_Vector.H> + +#include <algorithm> +#include <memory> using namespace amrex::literals; +using namespace amrex; void WarpX::ApplyEfieldBoundary(const int lev, PatchType patch_type) { @@ -21,7 +32,7 @@ void WarpX::ApplyEfieldBoundary(const int lev, PatchType patch_type) } } -void WarpX::ApplyBfieldBoundary (const int lev, PatchType patch_type) +void WarpX::ApplyBfieldBoundary (const int lev, PatchType patch_type, DtType a_dt_type) { if (PEC::isAnyBoundaryPEC()) { if (patch_type == PatchType::fine) { @@ -30,5 +41,22 @@ void WarpX::ApplyBfieldBoundary (const int lev, PatchType patch_type) PEC::ApplyPECtoBfield( Bfield_cp[lev], lev, patch_type); } } -} + // Silver-Mueller boundaries are only applied on the first half-push of B + // This is because the formula used for Silver-Mueller assumes that + // E and B are staggered in time, which is only true after the first half-push + if (lev == 0) { + if (a_dt_type == DtType::FirstHalf) { + bool applySilverMueller = false; + for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) { + if ( (WarpX::field_boundary_lo[idim] == FieldBoundaryType::Absorbing_SilverMueller) || + (WarpX::field_boundary_hi[idim] == FieldBoundaryType::Absorbing_SilverMueller) ) { + applySilverMueller = true; + } + } + if(applySilverMueller) m_fdtd_solver_fp[0]->ApplySilverMuellerBoundary( + Efield_fp[lev], Bfield_fp[lev], + Geom(lev).Domain(), dt[lev]); + } + } +} diff --git a/Source/Evolve/WarpXEvolve.cpp b/Source/Evolve/WarpXEvolve.cpp index 02bb1e1a1..eae665d44 100644 --- a/Source/Evolve/WarpXEvolve.cpp +++ b/Source/Evolve/WarpXEvolve.cpp @@ -412,9 +412,8 @@ WarpX::OneStep_nosub (Real cur_time) EvolveG(0.5_rt * dt[0], DtType::FirstHalf); FillBoundaryF(guard_cells.ng_FieldSolverF); FillBoundaryG(guard_cells.ng_FieldSolverG); - EvolveB(0.5_rt * dt[0]); // We now have B^{n+1/2} + EvolveB(0.5_rt * dt[0], DtType::FirstHalf); // We now have B^{n+1/2} - if (do_silver_mueller) ApplySilverMuellerBoundary( dt[0] ); FillBoundaryB(guard_cells.ng_FieldSolver); if (WarpX::em_solver_medium == MediumForEM::Vacuum) { @@ -430,7 +429,7 @@ WarpX::OneStep_nosub (Real cur_time) FillBoundaryE(guard_cells.ng_FieldSolver); EvolveF(0.5_rt * dt[0], DtType::SecondHalf); EvolveG(0.5_rt * dt[0], DtType::SecondHalf); - EvolveB(0.5_rt * dt[0]); // We now have B^{n+1} + EvolveB(0.5_rt * dt[0], DtType::SecondHalf); // We now have B^{n+1} // Synchronize E and B fields on nodal points NodalSyncE(); @@ -616,7 +615,7 @@ WarpX::OneStep_sub1 (Real curtime) ApplyFilterandSumBoundaryRho(fine_lev, PatchType::fine, 0, 2*ncomps); NodalSyncRho(fine_lev, PatchType::fine, 0, 2); - EvolveB(fine_lev, PatchType::fine, 0.5_rt*dt[fine_lev]); + EvolveB(fine_lev, PatchType::fine, 0.5_rt*dt[fine_lev], DtType::FirstHalf); EvolveF(fine_lev, PatchType::fine, 0.5_rt*dt[fine_lev], DtType::FirstHalf); FillBoundaryB(fine_lev, PatchType::fine, guard_cells.ng_FieldSolver); FillBoundaryF(fine_lev, PatchType::fine, guard_cells.ng_alloc_F); @@ -624,7 +623,7 @@ WarpX::OneStep_sub1 (Real curtime) EvolveE(fine_lev, PatchType::fine, dt[fine_lev]); FillBoundaryE(fine_lev, PatchType::fine, guard_cells.ng_FieldGather); - EvolveB(fine_lev, PatchType::fine, 0.5_rt*dt[fine_lev]); + EvolveB(fine_lev, PatchType::fine, 0.5_rt*dt[fine_lev], DtType::SecondHalf); EvolveF(fine_lev, PatchType::fine, 0.5_rt*dt[fine_lev], DtType::SecondHalf); if (do_pml) { @@ -643,7 +642,7 @@ WarpX::OneStep_sub1 (Real curtime) AddCurrentFromFineLevelandSumBoundary(coarse_lev); AddRhoFromFineLevelandSumBoundary(coarse_lev, 0, ncomps); - EvolveB(fine_lev, PatchType::coarse, dt[fine_lev]); + EvolveB(fine_lev, PatchType::coarse, dt[fine_lev], DtType::FirstHalf); EvolveF(fine_lev, PatchType::coarse, dt[fine_lev], DtType::FirstHalf); FillBoundaryB(fine_lev, PatchType::coarse, guard_cells.ng_FieldGather); FillBoundaryF(fine_lev, PatchType::coarse, guard_cells.ng_FieldSolverF); @@ -651,7 +650,7 @@ WarpX::OneStep_sub1 (Real curtime) EvolveE(fine_lev, PatchType::coarse, dt[fine_lev]); FillBoundaryE(fine_lev, PatchType::coarse, guard_cells.ng_FieldGather); - EvolveB(coarse_lev, PatchType::fine, 0.5_rt*dt[coarse_lev]); + EvolveB(coarse_lev, PatchType::fine, 0.5_rt*dt[coarse_lev], DtType::FirstHalf); EvolveF(coarse_lev, PatchType::fine, 0.5_rt*dt[coarse_lev], DtType::FirstHalf); FillBoundaryB(coarse_lev, PatchType::fine, guard_cells.ng_FieldGather); FillBoundaryF(coarse_lev, PatchType::fine, guard_cells.ng_FieldSolverF); @@ -674,7 +673,7 @@ WarpX::OneStep_sub1 (Real curtime) ApplyFilterandSumBoundaryRho(fine_lev, PatchType::fine, 0, ncomps); NodalSyncRho(fine_lev, PatchType::fine, 0, 2); - EvolveB(fine_lev, PatchType::fine, 0.5_rt*dt[fine_lev]); + EvolveB(fine_lev, PatchType::fine, 0.5_rt*dt[fine_lev], DtType::FirstHalf); EvolveF(fine_lev, PatchType::fine, 0.5_rt*dt[fine_lev], DtType::FirstHalf); FillBoundaryB(fine_lev, PatchType::fine, guard_cells.ng_FieldSolver); FillBoundaryF(fine_lev, PatchType::fine, guard_cells.ng_FieldSolverF); @@ -682,7 +681,7 @@ WarpX::OneStep_sub1 (Real curtime) EvolveE(fine_lev, PatchType::fine, dt[fine_lev]); FillBoundaryE(fine_lev, PatchType::fine, guard_cells.ng_FieldSolver); - EvolveB(fine_lev, PatchType::fine, 0.5_rt*dt[fine_lev]); + EvolveB(fine_lev, PatchType::fine, 0.5_rt*dt[fine_lev], DtType::SecondHalf); EvolveF(fine_lev, PatchType::fine, 0.5_rt*dt[fine_lev], DtType::SecondHalf); if (do_pml) { @@ -703,7 +702,7 @@ WarpX::OneStep_sub1 (Real curtime) EvolveE(fine_lev, PatchType::coarse, dt[fine_lev]); FillBoundaryE(fine_lev, PatchType::coarse, guard_cells.ng_FieldSolver); - EvolveB(fine_lev, PatchType::coarse, dt[fine_lev]); + EvolveB(fine_lev, PatchType::coarse, dt[fine_lev], DtType::SecondHalf); EvolveF(fine_lev, PatchType::coarse, dt[fine_lev], DtType::SecondHalf); if (do_pml) { @@ -720,7 +719,7 @@ WarpX::OneStep_sub1 (Real curtime) EvolveE(coarse_lev, PatchType::fine, 0.5_rt*dt[coarse_lev]); FillBoundaryE(coarse_lev, PatchType::fine, guard_cells.ng_FieldSolver); - EvolveB(coarse_lev, PatchType::fine, 0.5_rt*dt[coarse_lev]); + EvolveB(coarse_lev, PatchType::fine, 0.5_rt*dt[coarse_lev], DtType::SecondHalf); EvolveF(coarse_lev, PatchType::fine, 0.5_rt*dt[coarse_lev], DtType::SecondHalf); if (do_pml) { diff --git a/Source/FieldSolver/WarpXPushFieldsEM.cpp b/Source/FieldSolver/WarpXPushFieldsEM.cpp index a36d21e08..29d244d12 100644 --- a/Source/FieldSolver/WarpXPushFieldsEM.cpp +++ b/Source/FieldSolver/WarpXPushFieldsEM.cpp @@ -404,33 +404,33 @@ WarpX::PushPSATD () } ApplyEfieldBoundary(lev, PatchType::fine); if (lev > 0) ApplyEfieldBoundary(lev, PatchType::coarse); - ApplyBfieldBoundary(lev, PatchType::fine); - if (lev > 0) ApplyBfieldBoundary(lev, PatchType::coarse); + ApplyBfieldBoundary(lev, PatchType::fine, DtType::FirstHalf); + if (lev > 0) ApplyBfieldBoundary(lev, PatchType::coarse, DtType::FirstHalf); } #endif } void -WarpX::EvolveB (amrex::Real a_dt) +WarpX::EvolveB (amrex::Real a_dt, DtType a_dt_type) { for (int lev = 0; lev <= finest_level; ++lev) { - EvolveB(lev, a_dt); + EvolveB(lev, a_dt, a_dt_type); } } void -WarpX::EvolveB (int lev, amrex::Real a_dt) +WarpX::EvolveB (int lev, amrex::Real a_dt, DtType a_dt_type) { WARPX_PROFILE("WarpX::EvolveB()"); - EvolveB(lev, PatchType::fine, a_dt); + EvolveB(lev, PatchType::fine, a_dt, a_dt_type); if (lev > 0) { - EvolveB(lev, PatchType::coarse, a_dt); + EvolveB(lev, PatchType::coarse, a_dt, a_dt_type); } } void -WarpX::EvolveB (int lev, PatchType patch_type, amrex::Real a_dt) +WarpX::EvolveB (int lev, PatchType patch_type, amrex::Real a_dt, DtType a_dt_type) { // Evolve B field in regular cells @@ -453,15 +453,9 @@ WarpX::EvolveB (int lev, PatchType patch_type, amrex::Real a_dt) } } - ApplyBfieldBoundary(lev, patch_type); + ApplyBfieldBoundary(lev, patch_type, a_dt_type); } -void -WarpX::ApplySilverMuellerBoundary (amrex::Real a_dt) { - // Only apply to level 0 - m_fdtd_solver_fp[0]->ApplySilverMuellerBoundary( - Efield_fp[0], Bfield_fp[0], Geom(0).Domain(), a_dt ); -} void WarpX::EvolveE (amrex::Real a_dt) diff --git a/Source/Python/WarpXWrappers.cpp b/Source/Python/WarpXWrappers.cpp index 47942a55b..3a7a91a55 100644 --- a/Source/Python/WarpXWrappers.cpp +++ b/Source/Python/WarpXWrappers.cpp @@ -434,9 +434,9 @@ extern "C" WarpX& warpx = WarpX::GetInstance(); warpx.EvolveE (dt); } - void warpx_EvolveB (amrex::Real dt) { + void warpx_EvolveB (amrex::Real dt, DtType a_dt_type) { WarpX& warpx = WarpX::GetInstance(); - warpx.EvolveB (dt); + warpx.EvolveB (dt, a_dt_type); } void warpx_FillBoundaryE () { WarpX& warpx = WarpX::GetInstance(); diff --git a/Source/Python/WarpXWrappers.h b/Source/Python/WarpXWrappers.h index 30fa81968..f98600707 100644 --- a/Source/Python/WarpXWrappers.h +++ b/Source/Python/WarpXWrappers.h @@ -8,6 +8,7 @@ #ifndef WARPX_WRAPPERS_H_ #define WARPX_WRAPPERS_H_ +#include "Evolve/WarpXDtType.H" #include <AMReX_Config.H> #include <AMReX_REAL.H> @@ -95,7 +96,7 @@ extern "C" { void warpx_MoveWindow (int step, bool move_j); void warpx_EvolveE (amrex::Real dt); - void warpx_EvolveB (amrex::Real dt); + void warpx_EvolveB (amrex::Real dt, DtType a_dt_type); void warpx_FillBoundaryE (); void warpx_FillBoundaryB (); void warpx_SyncCurrent (); diff --git a/Source/Utils/WarpXAlgorithmSelection.H b/Source/Utils/WarpXAlgorithmSelection.H index 7ee95eff7..dd2c552a4 100644 --- a/Source/Utils/WarpXAlgorithmSelection.H +++ b/Source/Utils/WarpXAlgorithmSelection.H @@ -103,7 +103,8 @@ struct FieldBoundaryType { PMC = 3, //!< perfect magnetic conductor (PMC) with B_tangential=0 Damped = 4, // Fields in the guard cells are damped for PSATD //in the moving window direction - None = 5 // The fields values at the boundary are not updated. This is + Absorbing_SilverMueller = 5, // Silver-Mueller boundary condition + None = 6 // The fields values at the boundary are not updated. This is // useful for RZ simulations, at r=0. }; }; diff --git a/Source/Utils/WarpXAlgorithmSelection.cpp b/Source/Utils/WarpXAlgorithmSelection.cpp index e250a92c1..085d3e777 100644 --- a/Source/Utils/WarpXAlgorithmSelection.cpp +++ b/Source/Utils/WarpXAlgorithmSelection.cpp @@ -86,6 +86,7 @@ const std::map<std::string, int> FieldBCType_algo_to_int = { {"pec", FieldBoundaryType::PEC}, {"pmc", FieldBoundaryType::PMC}, {"damped", FieldBoundaryType::Damped}, + {"absorbing_silver_mueller", FieldBoundaryType::Absorbing_SilverMueller}, {"none", FieldBoundaryType::None}, {"default", FieldBoundaryType::PML} }; diff --git a/Source/Utils/WarpXUtil.cpp b/Source/Utils/WarpXUtil.cpp index 4ea0f14c0..70aec4253 100644 --- a/Source/Utils/WarpXUtil.cpp +++ b/Source/Utils/WarpXUtil.cpp @@ -568,6 +568,38 @@ void ReadBCParams () } } } + // temporarily check : If silver mueller is selected for one boundary, it should be + // selected at all valid boundaries. + for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) { + if (WarpX::field_boundary_lo[idim] == FieldBoundaryType::Absorbing_SilverMueller || + WarpX::field_boundary_hi[idim] == FieldBoundaryType::Absorbing_SilverMueller){ +#if (AMREX_SPACEDIM == 3) + AMREX_ALWAYS_ASSERT_WITH_MESSAGE( + (WarpX::field_boundary_lo[0] == FieldBoundaryType::Absorbing_SilverMueller)&& + (WarpX::field_boundary_hi[0] == FieldBoundaryType::Absorbing_SilverMueller)&& + (WarpX::field_boundary_lo[1] == FieldBoundaryType::Absorbing_SilverMueller)&& + (WarpX::field_boundary_hi[1] == FieldBoundaryType::Absorbing_SilverMueller)&& + (WarpX::field_boundary_lo[2] == FieldBoundaryType::Absorbing_SilverMueller)&& + (WarpX::field_boundary_hi[2] == FieldBoundaryType::Absorbing_SilverMueller) + , " The current implementation requires silver-mueller boundary condition to be applied at all boundaries!"); +#else +#ifndef WARPX_DIM_RZ + AMREX_ALWAYS_ASSERT_WITH_MESSAGE( + (WarpX::field_boundary_lo[0] == FieldBoundaryType::Absorbing_SilverMueller)&& + (WarpX::field_boundary_hi[0] == FieldBoundaryType::Absorbing_SilverMueller)&& + (WarpX::field_boundary_lo[1] == FieldBoundaryType::Absorbing_SilverMueller)&& + (WarpX::field_boundary_hi[1] == FieldBoundaryType::Absorbing_SilverMueller) + , " The current implementation requires silver-mueller boundary condition to be applied at all boundaries!"); +#else + AMREX_ALWAYS_ASSERT_WITH_MESSAGE( + (WarpX::field_boundary_hi[0] == FieldBoundaryType::Absorbing_SilverMueller)&& + (WarpX::field_boundary_lo[1] == FieldBoundaryType::Absorbing_SilverMueller)&& + (WarpX::field_boundary_hi[1] == FieldBoundaryType::Absorbing_SilverMueller) + , " The current implementation requires silver-mueller boundary condition to be applied at all boundaries!"); +#endif +#endif + } + } #ifdef WARPX_DIM_RZ // Ensure code aborts if PEC is specified at r=0 for RZ AMREX_ALWAYS_ASSERT_WITH_MESSAGE( WarpX::field_boundary_lo[0] == FieldBoundaryType::None, diff --git a/Source/WarpX.H b/Source/WarpX.H index b3263fc74..bd1851ca6 100644 --- a/Source/WarpX.H +++ b/Source/WarpX.H @@ -355,13 +355,13 @@ public: void ResetProbDomain (const amrex::RealBox& rb); void EvolveE ( amrex::Real dt); void EvolveE (int lev, amrex::Real dt); - void EvolveB ( amrex::Real dt); - void EvolveB (int lev, amrex::Real dt); + void EvolveB ( amrex::Real dt, DtType dt_type); + void EvolveB (int lev, amrex::Real dt, DtType dt_type); void EvolveF ( amrex::Real dt, DtType dt_type); void EvolveF (int lev, amrex::Real dt, DtType dt_type); void EvolveG ( amrex::Real dt, DtType dt_type); void EvolveG (int lev, amrex::Real dt, DtType dt_type); - void EvolveB (int lev, PatchType patch_type, amrex::Real dt); + void EvolveB (int lev, PatchType patch_type, amrex::Real dt, DtType dt_type); void EvolveE (int lev, PatchType patch_type, amrex::Real dt); void EvolveF (int lev, PatchType patch_type, amrex::Real dt, DtType dt_type); void EvolveG (int lev, PatchType patch_type, amrex::Real dt, DtType dt_type); @@ -423,7 +423,7 @@ public: #endif void ApplyEfieldBoundary (const int lev, PatchType patch_type); - void ApplyBfieldBoundary (const int lev, PatchType patch_type); + void ApplyBfieldBoundary (const int lev, PatchType patch_type, DtType dt_type); void DampPML (); void DampPML (int lev); diff --git a/Source/WarpX.cpp b/Source/WarpX.cpp index 3c5604a8b..027317501 100644 --- a/Source/WarpX.cpp +++ b/Source/WarpX.cpp @@ -642,11 +642,26 @@ WarpX::ReadParameters () quantum_xi_c2 = static_cast<amrex::Real>(quantum_xi * PhysConst::c * PhysConst::c); } - pp_warpx.query("do_pml", do_pml); - pp_warpx.query("do_silver_mueller", do_silver_mueller); - if ( (do_pml==1)&&(do_silver_mueller==1) ) { - amrex::Abort("PML and Silver-Mueller boundary conditions cannot be activated at the same time."); + for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) { + if ( ( WarpX::field_boundary_lo[idim] == FieldBoundaryType::PML && + WarpX::field_boundary_lo[idim] == FieldBoundaryType::Absorbing_SilverMueller ) || + ( WarpX::field_boundary_hi[idim] == FieldBoundaryType::PML && + WarpX::field_boundary_hi[idim] == FieldBoundaryType::Absorbing_SilverMueller ) ) + { + amrex::Abort("PML and Silver-Mueller boundary conditions cannot be activated at the same time."); + } + + if (WarpX::field_boundary_lo[idim] == FieldBoundaryType::Absorbing_SilverMueller || + WarpX::field_boundary_hi[idim] == FieldBoundaryType::Absorbing_SilverMueller) + { + // SilverMueller is implemented for Yee + if (maxwell_solver_id != MaxwellSolverAlgo::Yee) { + amrex::Abort("The Silver-Mueller boundary condition can only be used with the Yee solver."); + } + } } + + pp_warpx.query("do_pml", do_pml); pp_warpx.query("pml_ncell", pml_ncell); pp_warpx.query("pml_delta", pml_delta); pp_warpx.query("pml_has_particles", pml_has_particles); |