@@ -25,6 +25,7 @@ using namespace amrex;
2525void FiniteDifferenceSolver::EvolveB (
2626 std::array< std::unique_ptr<amrex::MultiFab>, 3 >& Bfield,
2727 std::array< std::unique_ptr<amrex::MultiFab>, 3 > const & Efield,
28+ std::unique_ptr<amrex::MultiFab> const & Gfield,
2829 std::array< std::unique_ptr<amrex::MultiFab>, 3 > const & face_areas,
2930 int lev, amrex::Real const dt ) {
3031
@@ -38,21 +39,20 @@ void FiniteDifferenceSolver::EvolveB (
3839#else
3940 if (m_do_nodal) {
4041
41- EvolveBCartesian <CartesianNodalAlgorithm> ( Bfield, Efield, face_areas, lev, dt );
42+ EvolveBCartesian <CartesianNodalAlgorithm> ( Bfield, Efield, Gfield, face_areas, lev, dt );
4243
4344 } else if (m_fdtd_algo == MaxwellSolverAlgo::Yee) {
4445
45- EvolveBCartesian <CartesianYeeAlgorithm> ( Bfield, Efield, face_areas, lev, dt );
46+ EvolveBCartesian <CartesianYeeAlgorithm> ( Bfield, Efield, Gfield, face_areas, lev, dt );
4647
4748 } else if (m_fdtd_algo == MaxwellSolverAlgo::CKC) {
4849
49- EvolveBCartesian <CartesianCKCAlgorithm> ( Bfield, Efield, face_areas, lev, dt );
50+ EvolveBCartesian <CartesianCKCAlgorithm> ( Bfield, Efield, Gfield, face_areas, lev, dt );
5051
5152#endif
5253 } else {
5354 amrex::Abort (" EvolveB: Unknown algorithm" );
5455 }
55-
5656}
5757
5858
@@ -62,6 +62,7 @@ template<typename T_Algo>
6262void FiniteDifferenceSolver::EvolveBCartesian (
6363 std::array< std::unique_ptr<amrex::MultiFab>, 3 >& Bfield,
6464 std::array< std::unique_ptr<amrex::MultiFab>, 3 > const & Efield,
65+ std::unique_ptr<amrex::MultiFab> const & Gfield,
6566 std::array< std::unique_ptr<amrex::MultiFab>, 3 > const & face_areas,
6667 int lev, amrex::Real const dt ) {
6768
@@ -71,6 +72,8 @@ void FiniteDifferenceSolver::EvolveBCartesian (
7172
7273 amrex::LayoutData<amrex::Real>* cost = WarpX::getCosts (lev);
7374
75+ Real constexpr c2 = PhysConst::c * PhysConst::c;
76+
7477 // Loop through the grids, and over the tiles within each grid
7578#ifdef AMREX_USE_OMP
7679#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
@@ -138,9 +141,32 @@ void FiniteDifferenceSolver::EvolveBCartesian (
138141 Bz (i, j, k) += dt * T_Algo::UpwardDy (Ex, coefs_y, n_coefs_y, i, j, k)
139142 - dt * T_Algo::UpwardDx (Ey, coefs_x, n_coefs_x, i, j, k);
140143 }
141-
142144 );
143145
146+ // div(B) cleaning correction for errors in magnetic Gauss law (div(B) = 0)
147+ if (Gfield)
148+ {
149+ // Extract field data for this grid/tile
150+ Array4<Real> G = Gfield->array (mfi);
151+
152+ // Loop over cells and update G
153+ amrex::ParallelFor (tbx, tby, tbz,
154+
155+ [=] AMREX_GPU_DEVICE (int i, int j, int k)
156+ {
157+ Bx (i,j,k) += c2 * dt * T_Algo::DownwardDx (G, coefs_x, n_coefs_x, i, j, k);
158+ },
159+ [=] AMREX_GPU_DEVICE (int i, int j, int k)
160+ {
161+ By (i,j,k) += c2 * dt * T_Algo::DownwardDy (G, coefs_y, n_coefs_y, i, j, k);
162+ },
163+ [=] AMREX_GPU_DEVICE (int i, int j, int k)
164+ {
165+ Bz (i,j,k) += c2 * dt * T_Algo::DownwardDz (G, coefs_z, n_coefs_z, i, j, k);
166+ }
167+ );
168+ }
169+
144170 if (cost && WarpX::load_balance_costs_update_algo == LoadBalanceCostsUpdateAlgo::Timers)
145171 {
146172 amrex::Gpu::synchronize ();
0 commit comments