From 570eebaeabdda9b7a7ebb97266caa333f3e66a54 Mon Sep 17 00:00:00 2001 From: Justin Angus Date: Mon, 4 Nov 2024 12:53:04 -0800 Subject: [PATCH 1/3] added time step (m_dt) as member to ImplicitSolver. Removed passing dt to ComputeRHS(). --- .../ImplicitSolvers/ImplicitSolver.H | 6 ++++- .../ImplicitSolvers/SemiImplicitEM.H | 1 - .../ImplicitSolvers/SemiImplicitEM.cpp | 14 ++++++----- .../ImplicitSolvers/ThetaImplicitEM.H | 4 +-- .../ImplicitSolvers/ThetaImplicitEM.cpp | 25 ++++++++++--------- Source/NonlinearSolvers/JacobianFunctionMF.H | 2 +- Source/NonlinearSolvers/NewtonSolver.H | 6 ++--- Source/NonlinearSolvers/NonlinearSolver.H | 2 +- Source/NonlinearSolvers/PicardSolver.H | 3 ++- 9 files changed, 33 insertions(+), 30 deletions(-) diff --git a/Source/FieldSolver/ImplicitSolvers/ImplicitSolver.H b/Source/FieldSolver/ImplicitSolvers/ImplicitSolver.H index ea9af6e2298..94b6733d3c8 100644 --- a/Source/FieldSolver/ImplicitSolvers/ImplicitSolver.H +++ b/Source/FieldSolver/ImplicitSolvers/ImplicitSolver.H @@ -83,7 +83,6 @@ public: virtual void ComputeRHS ( WarpXSolverVec& a_RHS, const WarpXSolverVec& a_E, amrex::Real a_time, - amrex::Real a_dt, int a_nl_iter, bool a_from_jacobian ) = 0; @@ -111,6 +110,11 @@ protected: */ int m_num_amr_levels = 1; + /** + * \brief Time step + */ + mutable amrex::Real m_dt = DBL_MAX; + /** * \brief Nonlinear solver type and object */ diff --git a/Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.H b/Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.H index 6e3e5db2c74..b6c808e0ab9 100644 --- a/Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.H +++ b/Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.H @@ -64,7 +64,6 @@ public: void ComputeRHS ( WarpXSolverVec& a_RHS, const WarpXSolverVec& a_E, amrex::Real a_time, - amrex::Real a_dt, int a_nl_iter, bool a_from_jacobian ) override; diff --git a/Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.cpp b/Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.cpp index 2236118a30c..516de694eda 100644 --- a/Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.cpp +++ b/Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.cpp @@ -58,6 +58,9 @@ void SemiImplicitEM::OneStep ( amrex::Real a_time, { amrex::ignore_unused(a_step); + // Set the member time step + m_dt = a_dt; + // Fields have Eg^{n}, Bg^{n-1/2} // Particles have up^{n} and xp^{n}. @@ -68,15 +71,15 @@ void SemiImplicitEM::OneStep ( amrex::Real a_time, m_Eold.Copy( FieldType::Efield_fp ); // Advance WarpX owned Bfield_fp to t_{n+1/2} - m_WarpX->EvolveB(a_dt, DtType::Full); + m_WarpX->EvolveB(m_dt, DtType::Full); m_WarpX->ApplyMagneticFieldBCs(); - const amrex::Real half_time = a_time + 0.5_rt*a_dt; + const amrex::Real half_time = a_time + 0.5_rt*m_dt; // Solve nonlinear system for Eg at t_{n+1/2} // Particles will be advanced to t_{n+1/2} m_E.Copy(m_Eold); // initial guess for Eg^{n+1/2} - m_nlsolver->Solve( m_E, m_Eold, half_time, a_dt ); + m_nlsolver->Solve( m_E, m_Eold, half_time, m_dt ); // Update WarpX owned Efield_fp to t_{n+1/2} m_WarpX->SetElectricFieldAndApplyBCs( m_E ); @@ -94,7 +97,6 @@ void SemiImplicitEM::OneStep ( amrex::Real a_time, void SemiImplicitEM::ComputeRHS ( WarpXSolverVec& a_RHS, const WarpXSolverVec& a_E, amrex::Real a_time, - amrex::Real a_dt, int a_nl_iter, bool a_from_jacobian ) { @@ -104,8 +106,8 @@ void SemiImplicitEM::ComputeRHS ( WarpXSolverVec& a_RHS, // Update particle positions and velocities using the current state // of Eg and Bg. Deposit current density at time n+1/2 - m_WarpX->ImplicitPreRHSOp( a_time, a_dt, a_nl_iter, a_from_jacobian ); + m_WarpX->ImplicitPreRHSOp( a_time, m_dt, a_nl_iter, a_from_jacobian ); // RHS = cvac^2*0.5*dt*( curl(Bg^{n+1/2}) - mu0*Jg^{n+1/2} ) - m_WarpX->ImplicitComputeRHSE(0.5_rt*a_dt, a_RHS); + m_WarpX->ImplicitComputeRHSE(0.5_rt*m_dt, a_RHS); } diff --git a/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.H b/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.H index 69d56c6ddc5..dae942bb22d 100644 --- a/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.H +++ b/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.H @@ -74,7 +74,6 @@ public: void ComputeRHS ( WarpXSolverVec& a_RHS, const WarpXSolverVec& a_E, amrex::Real a_time, - amrex::Real a_dt, int a_nl_iter, bool a_from_jacobian ) override; @@ -101,8 +100,7 @@ private: * \brief Update the E and B fields owned by WarpX */ void UpdateWarpXFields ( const WarpXSolverVec& a_E, - amrex::Real a_time, - amrex::Real a_dt ); + amrex::Real a_time ); /** * \brief Nonlinear solver is for the time-centered values of E. After diff --git a/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.cpp b/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.cpp index e5b8431a930..40bc6dfbb6d 100644 --- a/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.cpp +++ b/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.cpp @@ -83,6 +83,9 @@ void ThetaImplicitEM::OneStep ( const amrex::Real a_time, // Fields have Eg^{n} and Bg^{n} // Particles have up^{n} and xp^{n}. + // Set the member time step + m_dt = a_dt; + // Save up and xp at the start of the time step m_WarpX->SaveParticlesAtImplicitStepStart ( ); @@ -99,21 +102,21 @@ void ThetaImplicitEM::OneStep ( const amrex::Real a_time, } } - const amrex::Real theta_time = a_time + m_theta*a_dt; + const amrex::Real theta_time = a_time + m_theta*m_dt; // Solve nonlinear system for Eg at t_{n+theta} // Particles will be advanced to t_{n+1/2} m_E.Copy(m_Eold); // initial guess for Eg^{n+theta} - m_nlsolver->Solve( m_E, m_Eold, theta_time, a_dt ); + m_nlsolver->Solve( m_E, m_Eold, theta_time, m_dt ); // Update WarpX owned Efield_fp and Bfield_fp to t_{n+theta} - UpdateWarpXFields( m_E, theta_time, a_dt ); + UpdateWarpXFields( m_E, theta_time ); // Advance particles from time n+1/2 to time n+1 m_WarpX->FinishImplicitParticleUpdate(); // Advance Eg and Bg from time n+theta to time n+1 - const amrex::Real new_time = a_time + a_dt; + const amrex::Real new_time = a_time + m_dt; FinishFieldUpdate( new_time ); } @@ -121,25 +124,23 @@ void ThetaImplicitEM::OneStep ( const amrex::Real a_time, void ThetaImplicitEM::ComputeRHS ( WarpXSolverVec& a_RHS, const WarpXSolverVec& a_E, amrex::Real a_time, - amrex::Real a_dt, int a_nl_iter, bool a_from_jacobian ) { // Update WarpX-owned Efield_fp and Bfield_fp using current state of // Eg from the nonlinear solver at time n+theta - UpdateWarpXFields( a_E, a_time, a_dt ); + UpdateWarpXFields( a_E, a_time ); // Update particle positions and velocities using the current state // of Eg and Bg. Deposit current density at time n+1/2 - m_WarpX->ImplicitPreRHSOp( a_time, a_dt, a_nl_iter, a_from_jacobian ); + m_WarpX->ImplicitPreRHSOp( a_time, m_dt, a_nl_iter, a_from_jacobian ); // RHS = cvac^2*m_theta*dt*( curl(Bg^{n+theta}) - mu0*Jg^{n+1/2} ) - m_WarpX->ImplicitComputeRHSE(m_theta*a_dt, a_RHS); + m_WarpX->ImplicitComputeRHSE( m_theta*m_dt, a_RHS); } void ThetaImplicitEM::UpdateWarpXFields ( const WarpXSolverVec& a_E, - amrex::Real a_time, - amrex::Real a_dt ) + amrex::Real a_time ) { amrex::ignore_unused(a_time); @@ -148,7 +149,7 @@ void ThetaImplicitEM::UpdateWarpXFields ( const WarpXSolverVec& a_E, // Update Bfield_fp owned by WarpX ablastr::fields::MultiLevelVectorField const& B_old = m_WarpX->m_fields.get_mr_levels_alldirs(FieldType::B_old, 0); - m_WarpX->UpdateMagneticFieldAndApplyBCs(B_old, m_theta * a_dt ); + m_WarpX->UpdateMagneticFieldAndApplyBCs( B_old, m_theta*m_dt ); } @@ -164,6 +165,6 @@ void ThetaImplicitEM::FinishFieldUpdate ( amrex::Real a_new_time ) m_E.linComb( c0, m_E, c1, m_Eold ); m_WarpX->SetElectricFieldAndApplyBCs( m_E ); ablastr::fields::MultiLevelVectorField const & B_old = m_WarpX->m_fields.get_mr_levels_alldirs(FieldType::B_old, 0); - m_WarpX->FinishMagneticFieldAndApplyBCs(B_old, m_theta ); + m_WarpX->FinishMagneticFieldAndApplyBCs( B_old, m_theta ); } diff --git a/Source/NonlinearSolvers/JacobianFunctionMF.H b/Source/NonlinearSolvers/JacobianFunctionMF.H index a3222214381..1a30dde4250 100644 --- a/Source/NonlinearSolvers/JacobianFunctionMF.H +++ b/Source/NonlinearSolvers/JacobianFunctionMF.H @@ -253,7 +253,7 @@ void JacobianFunctionMF::apply (T& a_dF, const T& a_dU) const RT eps_inv = 1.0_rt/eps; m_Z.linComb( 1.0, m_Y0, eps, a_dU ); // Z = Y0 + eps*dU - m_ops->ComputeRHS(m_R, m_Z, m_cur_time, m_dt, -1, true ); + m_ops->ComputeRHS(m_R, m_Z, m_cur_time, -1, true ); // F(Y) = Y - b - R(Y) ==> dF = dF/dY*dU = [1 - dR/dY]*dU // = dU - (R(Z)-R(Y0))/eps diff --git a/Source/NonlinearSolvers/NewtonSolver.H b/Source/NonlinearSolvers/NewtonSolver.H index 9c73c44e69e..f5147b2e4c0 100644 --- a/Source/NonlinearSolvers/NewtonSolver.H +++ b/Source/NonlinearSolvers/NewtonSolver.H @@ -169,7 +169,6 @@ private: const Vec& a_U, const Vec& a_b, amrex::Real a_time, - amrex::Real a_dt, int a_iter ) const; }; @@ -252,7 +251,7 @@ void NewtonSolver::Solve ( Vec& a_U, for (iter = 0; iter < m_maxits;) { // Compute residual: F(U) = U - b - R(U) - EvalResidual(m_F, a_U, a_b, a_time, a_dt, iter); + EvalResidual(m_F, a_U, a_b, a_time, iter); // Compute norm of the residual norm_abs = m_F.norm2(); @@ -329,11 +328,10 @@ void NewtonSolver::EvalResidual ( Vec& a_F, const Vec& a_U, const Vec& a_b, amrex::Real a_time, - amrex::Real a_dt, int a_iter ) const { - m_ops->ComputeRHS( m_R, a_U, a_time, a_dt, a_iter, false ); + m_ops->ComputeRHS( m_R, a_U, a_time, a_iter, false ); // set base U and R(U) for matrix-free Jacobian action calculation m_linear_function->setBaseSolution(a_U); diff --git a/Source/NonlinearSolvers/NonlinearSolver.H b/Source/NonlinearSolvers/NonlinearSolver.H index 6e64f1eb113..9daa3489f11 100644 --- a/Source/NonlinearSolvers/NonlinearSolver.H +++ b/Source/NonlinearSolvers/NonlinearSolver.H @@ -16,7 +16,7 @@ * This class is templated on a vector class Vec, and an operator class Ops. * * The Ops class must have the following function: - * ComputeRHS( R_vec, U_vec, time, dt, nl_iter, from_jacobian ), + * ComputeRHS( R_vec, U_vec, time, nl_iter, from_jacobian ), * where U_vec and R_vec are of type Vec. * * The Vec class must have basic math operators, such as Copy, +=, -=, diff --git a/Source/NonlinearSolvers/PicardSolver.H b/Source/NonlinearSolvers/PicardSolver.H index f6c47c4f4bc..6fe941cd48f 100644 --- a/Source/NonlinearSolvers/PicardSolver.H +++ b/Source/NonlinearSolvers/PicardSolver.H @@ -138,6 +138,7 @@ void PicardSolver::Solve ( Vec& a_U, WARPX_ALWAYS_ASSERT_WITH_MESSAGE( this->m_is_defined, "PicardSolver::Solve() called on undefined object"); + amrex::ignore_unused(a_dt); using namespace amrex::literals; // @@ -156,7 +157,7 @@ void PicardSolver::Solve ( Vec& a_U, m_Usave.Copy(a_U); // Update the solver state (a_U = a_b + m_R) - m_ops->ComputeRHS( m_R, a_U, a_time, a_dt, iter, false ); + m_ops->ComputeRHS( m_R, a_U, a_time, iter, false ); a_U.Copy(a_b); a_U += m_R; From 8375975b772eaa3433c124c09281a0c895d1f5f5 Mon Sep 17 00:00:00 2001 From: Justin Angus Date: Mon, 4 Nov 2024 13:32:01 -0800 Subject: [PATCH 2/3] dt passed to m_nlsolver->Solve() and eventually used by the PC is now the appropriate fractional time step. Removed theta() function from ImplicitSolver.H. --- Source/FieldSolver/ImplicitSolvers/ImplicitSolver.H | 4 +--- Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.cpp | 2 +- Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.H | 2 -- Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.cpp | 2 +- Source/NonlinearSolvers/CurlCurlMLMGPC.H | 5 +++-- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Source/FieldSolver/ImplicitSolvers/ImplicitSolver.H b/Source/FieldSolver/ImplicitSolvers/ImplicitSolver.H index 94b6733d3c8..f8f0390e17a 100644 --- a/Source/FieldSolver/ImplicitSolvers/ImplicitSolver.H +++ b/Source/FieldSolver/ImplicitSolvers/ImplicitSolver.H @@ -86,8 +86,6 @@ public: int a_nl_iter, bool a_from_jacobian ) = 0; - [[nodiscard]] virtual amrex::Real theta () const { return 1.0; } - [[nodiscard]] int numAMRLevels () const { return m_num_amr_levels; } [[nodiscard]] const amrex::Geometry& GetGeometry (int) const; @@ -113,7 +111,7 @@ protected: /** * \brief Time step */ - mutable amrex::Real m_dt = DBL_MAX; + mutable amrex::Real m_dt = 0.0; /** * \brief Nonlinear solver type and object diff --git a/Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.cpp b/Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.cpp index 516de694eda..117c3baecaa 100644 --- a/Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.cpp +++ b/Source/FieldSolver/ImplicitSolvers/SemiImplicitEM.cpp @@ -79,7 +79,7 @@ void SemiImplicitEM::OneStep ( amrex::Real a_time, // Solve nonlinear system for Eg at t_{n+1/2} // Particles will be advanced to t_{n+1/2} m_E.Copy(m_Eold); // initial guess for Eg^{n+1/2} - m_nlsolver->Solve( m_E, m_Eold, half_time, m_dt ); + m_nlsolver->Solve( m_E, m_Eold, half_time, 0.5_rt*m_dt ); // Update WarpX owned Efield_fp to t_{n+1/2} m_WarpX->SetElectricFieldAndApplyBCs( m_E ); diff --git a/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.H b/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.H index dae942bb22d..7461b77fb51 100644 --- a/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.H +++ b/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.H @@ -77,8 +77,6 @@ public: int a_nl_iter, bool a_from_jacobian ) override; - [[nodiscard]] amrex::Real theta () const override { return m_theta; } - private: /** diff --git a/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.cpp b/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.cpp index 40bc6dfbb6d..8ca592517ac 100644 --- a/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.cpp +++ b/Source/FieldSolver/ImplicitSolvers/ThetaImplicitEM.cpp @@ -107,7 +107,7 @@ void ThetaImplicitEM::OneStep ( const amrex::Real a_time, // Solve nonlinear system for Eg at t_{n+theta} // Particles will be advanced to t_{n+1/2} m_E.Copy(m_Eold); // initial guess for Eg^{n+theta} - m_nlsolver->Solve( m_E, m_Eold, theta_time, m_dt ); + m_nlsolver->Solve( m_E, m_Eold, theta_time, m_theta*m_dt ); // Update WarpX owned Efield_fp and Bfield_fp to t_{n+theta} UpdateWarpXFields( m_E, theta_time ); diff --git a/Source/NonlinearSolvers/CurlCurlMLMGPC.H b/Source/NonlinearSolvers/CurlCurlMLMGPC.H index 47d7310995c..b3fcc6fe38f 100644 --- a/Source/NonlinearSolvers/CurlCurlMLMGPC.H +++ b/Source/NonlinearSolvers/CurlCurlMLMGPC.H @@ -272,7 +272,8 @@ void CurlCurlMLMGPC::Update (const T& a_U) amrex::ignore_unused(a_U); // set the coefficients alpha and beta for curl-curl op - const RT alpha = (m_ops->theta()*this->m_dt*PhysConst::c) * (m_ops->theta()*this->m_dt*PhysConst::c); + // (m_dt here is actually theta<=0.5 times simulation dt) + const RT alpha = (this->m_dt*PhysConst::c) * (this->m_dt*PhysConst::c); const RT beta = RT(1.0); // currently not implemented in 1D @@ -282,7 +283,7 @@ void CurlCurlMLMGPC::Update (const T& a_U) if (m_verbose) { amrex::Print() << "Updating " << amrex::getEnumNameString(PreconditionerType::pc_curl_curl_mlmg) - << ": dt = " << this->m_dt << ", " + << ": theta*dt = " << this->m_dt << ", " << " coefficients: " << "alpha = " << alpha << ", " << "beta = " << beta << "\n"; From 72c56c280d9797fddf16cc2e614be7b08c645418 Mon Sep 17 00:00:00 2001 From: Justin Angus Date: Tue, 12 Nov 2024 14:18:41 -0800 Subject: [PATCH 3/3] incorporating changes into new strang implicit spectral time advance routine. --- .../StrangImplicitSpectralEM.H | 4 +--- .../StrangImplicitSpectralEM.cpp | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Source/FieldSolver/ImplicitSolvers/StrangImplicitSpectralEM.H b/Source/FieldSolver/ImplicitSolvers/StrangImplicitSpectralEM.H index a674dd6de76..d1587cfb9d1 100644 --- a/Source/FieldSolver/ImplicitSolvers/StrangImplicitSpectralEM.H +++ b/Source/FieldSolver/ImplicitSolvers/StrangImplicitSpectralEM.H @@ -65,7 +65,6 @@ public: void ComputeRHS ( WarpXSolverVec& a_RHS, const WarpXSolverVec& a_E, amrex::Real a_time, - amrex::Real a_dt, int a_nl_iter, bool a_from_jacobian ) override; @@ -93,8 +92,7 @@ private: * \brief Update the E and B fields owned by WarpX */ void UpdateWarpXFields ( WarpXSolverVec const& a_E, - amrex::Real a_time, - amrex::Real a_dt ); + amrex::Real a_time ); /** * \brief Nonlinear solver is for the time-centered values of E. After diff --git a/Source/FieldSolver/ImplicitSolvers/StrangImplicitSpectralEM.cpp b/Source/FieldSolver/ImplicitSolvers/StrangImplicitSpectralEM.cpp index 1d463bcb365..501cbed10eb 100644 --- a/Source/FieldSolver/ImplicitSolvers/StrangImplicitSpectralEM.cpp +++ b/Source/FieldSolver/ImplicitSolvers/StrangImplicitSpectralEM.cpp @@ -63,6 +63,9 @@ void StrangImplicitSpectralEM::OneStep ( amrex::Real a_time, // Fields have E^{n} and B^{n} // Particles have p^{n} and x^{n}. + // Set the member time step + m_dt = a_dt; + // Save the values at the start of the time step, m_WarpX->SaveParticlesAtImplicitStepStart(); @@ -73,20 +76,20 @@ void StrangImplicitSpectralEM::OneStep ( amrex::Real a_time, m_Eold.Copy( FieldType::Efield_fp ); m_E.Copy(m_Eold); // initial guess for E - amrex::Real const half_time = a_time + 0.5_rt*a_dt; + amrex::Real const half_time = a_time + 0.5_rt*m_dt; // Solve nonlinear system for E at t_{n+1/2} // Particles will be advanced to t_{n+1/2} - m_nlsolver->Solve( m_E, m_Eold, half_time, a_dt ); + m_nlsolver->Solve( m_E, m_Eold, half_time, 0.5_rt*m_dt ); // Update WarpX owned Efield_fp and Bfield_fp to t_{n+1/2} - UpdateWarpXFields( m_E, half_time, a_dt ); + UpdateWarpXFields( m_E, half_time ); // Advance particles from time n+1/2 to time n+1 m_WarpX->FinishImplicitParticleUpdate(); // Advance E and B fields from time n+1/2 to time n+1 - amrex::Real const new_time = a_time + a_dt; + amrex::Real const new_time = a_time + m_dt; FinishFieldUpdate( new_time ); // Advance the fields to time n+1 source free @@ -97,29 +100,27 @@ void StrangImplicitSpectralEM::OneStep ( amrex::Real a_time, void StrangImplicitSpectralEM::ComputeRHS ( WarpXSolverVec& a_RHS, WarpXSolverVec const & a_E, amrex::Real a_time, - amrex::Real a_dt, int a_nl_iter, bool a_from_jacobian ) { // Update WarpX-owned Efield_fp and Bfield_fp using current state of // E from the nonlinear solver at time n+1/2 - UpdateWarpXFields( a_E, a_time, a_dt ); + UpdateWarpXFields( a_E, a_time ); // Self consistently update particle positions and velocities using the // current state of the fields E and B. Deposit current density at time n+1/2. - m_WarpX->ImplicitPreRHSOp( a_time, a_dt, a_nl_iter, a_from_jacobian ); + m_WarpX->ImplicitPreRHSOp( a_time, m_dt, a_nl_iter, a_from_jacobian ); // For Strang split implicit PSATD, the RHS = -dt*mu*c**2*J bool const allow_type_mismatch = true; a_RHS.Copy(FieldType::current_fp, warpx::fields::FieldType::None, allow_type_mismatch); amrex::Real constexpr coeff = PhysConst::c * PhysConst::c * PhysConst::mu0; - a_RHS.scale(-coeff * 0.5_rt*a_dt); + a_RHS.scale(-coeff * 0.5_rt*m_dt); } void StrangImplicitSpectralEM::UpdateWarpXFields (WarpXSolverVec const & a_E, - amrex::Real /*a_time*/, - amrex::Real /*a_dt*/) + amrex::Real /*a_time*/ ) { // Update Efield_fp owned by WarpX