Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,7 @@ public:
}

inline
void updatePreCondMat ( const WarpXSolverVec& a_X ) override
{
amrex::ignore_unused(a_X);
}
void updatePreCondMat () override { }

inline
void getPCMatrix ( amrex::Gpu::DeviceVector<int>& a_ridx_g,
Expand Down
2 changes: 1 addition & 1 deletion Source/FieldSolver/ImplicitSolvers/WarpXSolverVec.H
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ public:
[[nodiscard]] auto numAMRLevels () const { return m_num_amr_levels; }

// return DOFs object pointer
[[nodiscard]] inline const auto& getDOFsObject () const { return m_dofs; }
[[nodiscard]] inline static const auto& getDOFsObject () { return m_dofs; }

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function can be made static here (i.e., it can be called with WarpXSolverVec::getDOFsObject instead of requiring an instance of WarpXSolverVec) since m_dofs itself is declared as a static member (i.e. one m_dofs object per class, not per instance)


private:

Expand Down
7 changes: 2 additions & 5 deletions Source/NonlinearSolvers/CurlCurlMLMGPC.H
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class CurlCurlMLMGPC : public Preconditioner<T,Ops>
/**
* \brief Update the preconditioner
*/
void Update (const T& a_U) override;
void Update () override;

/**
* \brief Apply (solve) the preconditioner given a RHS
Expand Down Expand Up @@ -247,7 +247,7 @@ void CurlCurlMLMGPC<T,Ops>::Define ( const T& a_U,
}

template <class T, class Ops>
void CurlCurlMLMGPC<T,Ops>::Update (const T& a_U)
void CurlCurlMLMGPC<T,Ops>::Update ()
{
BL_PROFILE("CurlCurlMLMGPC::Update()");
using namespace amrex;
Expand All @@ -256,9 +256,6 @@ void CurlCurlMLMGPC<T,Ops>::Update (const T& a_U)
IsDefined(),
"CurlCurlMLMGPC::Update() called on undefined object" );

// a_U is not needed for a linear operator
amrex::ignore_unused(a_U);

// set the alpha coefficient for the curl-curl op
const RT thetaDt = m_ops->GetThetaForPC()*this->m_dt;
if (thetaDt==0.) {
Expand Down
35 changes: 24 additions & 11 deletions Source/NonlinearSolvers/JacobiPC.H
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class JacobiPC : public Preconditioner<T,Ops>

void Define (const T&, Ops*) override;

void Update (const T& a_U) override;
void Update () override;
Comment thread
JustinRayAngus marked this conversation as resolved.

/**
* \brief Solve (I + M) x = b via damped Jacobi iteration
Expand Down Expand Up @@ -110,6 +110,13 @@ class JacobiPC : public Preconditioner<T,Ops>

int m_num_amr_levels = 0;

/**
* \brief Grid layout of the solver vector, cached in Define() so that
* Update() can allocate its scratch without being handed a vector.
*/
amrex::Vector<amrex::Array<amrex::BoxArray,3>> m_grids;
amrex::Vector<amrex::Array<amrex::DistributionMapping,3>> m_dmap;

const amrex::Vector<amrex::Array<amrex::MultiFab*,3>>* m_bcoefs = nullptr;

bool m_has_offdiag = false;
Expand Down Expand Up @@ -269,13 +276,25 @@ void JacobiPC<T,Ops>::Define ( const T& a_U,
m_num_amr_levels = m_ops->numAMRLevels();
m_bcoefs = m_ops->GetMassMatricesCoeff();

// Save the grid layout of the solver vector. This is then used in
// `Update` to allocate temporary MultiFabs
const auto& u_mfarrvec = a_U.getArrayVec();
m_grids.resize(m_num_amr_levels);
m_dmap.resize(m_num_amr_levels);
for (int n = 0; n < m_num_amr_levels; n++) {
for (int dim = 0; dim < 3; dim++) {
m_grids[n][dim] = u_mfarrvec[n][dim]->boxArray();
m_dmap[n][dim] = u_mfarrvec[n][dim]->DistributionMap();
}
}

readParameters();

m_is_defined = true;
}

template <class T, class Ops>
void JacobiPC<T,Ops>::Update (const T& a_U)
void JacobiPC<T,Ops>::Update ()
{
BL_PROFILE("JacobiPC::Update()");
using namespace amrex;
Expand All @@ -285,7 +304,6 @@ void JacobiPC<T,Ops>::Update (const T& a_U)
"JacobiPC::Update() called on undefined object" );

if (m_bcoefs != nullptr && !m_work_defined) {
auto& u_mfarrvec = a_U.getArrayVec();
m_work.resize(m_num_amr_levels);
m_x_ghost.resize(m_num_amr_levels);

Expand All @@ -307,15 +325,10 @@ void JacobiPC<T,Ops>::Update (const T& a_U)
const amrex::IntVect nghost(m_stencil_width);
for (int n = 0; n < m_num_amr_levels; n++) {
for (int dim = 0; dim < 3; dim++) {
m_work[n][dim].define(
u_mfarrvec[n][dim]->boxArray(),
u_mfarrvec[n][dim]->DistributionMap(),
1, 0);
m_work[n][dim].define(m_grids[n][dim], m_dmap[n][dim], 1, 0);
if (m_has_offdiag) {
m_x_ghost[n][dim].define(
u_mfarrvec[n][dim]->boxArray(),
u_mfarrvec[n][dim]->DistributionMap(),
1, nghost);
m_x_ghost[n][dim].define(m_grids[n][dim], m_dmap[n][dim],
1, nghost);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Source/NonlinearSolvers/JacobianFunctionMF.H
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ class JacobianFunctionMF : public LinearFunction<T,Ops>
}

inline
void updatePreCondMat ( const T& a_X ) override
void updatePreCondMat () override
{
if (m_usePreCond) { m_preCond->Update(a_X); }
if (m_usePreCond) { m_preCond->Update(); }
}

inline
Expand Down
2 changes: 1 addition & 1 deletion Source/NonlinearSolvers/LinearFunction.H
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class LinearFunction
virtual void precond ( T& a_U, const T& a_X ) = 0;

//! update preconditioner
virtual void updatePreCondMat ( const T& a_X ) = 0;
virtual void updatePreCondMat () = 0;

//! get sparse matrix representation of preconditioner
virtual void getPCMatrix( amrex::Gpu::DeviceVector<int>&,
Expand Down
21 changes: 8 additions & 13 deletions Source/NonlinearSolvers/MatrixPC.H
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class MatrixPC : public Preconditioner<T,Ops>
/**
* \brief Update the preconditioner
*/
void Update (const T& a_U) override;
void Update () override;

/**
* \brief Assemble the matrix
Expand All @@ -114,7 +114,7 @@ class MatrixPC : public Preconditioner<T,Ops>
* non-zero elements (return value is difference in current number
* of nonzero elements and the desired number).
*/
int Assemble (const T& a_U);
int Assemble ();

/**
* \brief Apply (solve) the preconditioner given a RHS
Expand Down Expand Up @@ -185,6 +185,7 @@ class MatrixPC : public Preconditioner<T,Ops>

int m_ndofs_l = 0;
int m_ndofs_g = 0;

bool m_pc_diag_only = false;
int m_pc_mat_nnz = 1;
bool m_include_mass_matrices = false;
Expand Down Expand Up @@ -247,9 +248,6 @@ void MatrixPC<T,Ops>::Define ( const T& a_U,
// read preconditioner parameters
readParameters();

// a_U is not needed
amrex::ignore_unused(a_U);

// Set number of AMR levels and create geometry, grids, and
// distribution mapping vectors.
m_num_amr_levels = m_ops->numAMRLevels();
Expand Down Expand Up @@ -282,7 +280,7 @@ void MatrixPC<T,Ops>::Define ( const T& a_U,
}

template <class T, class Ops>
void MatrixPC<T,Ops>::Update (const T& a_U)
void MatrixPC<T,Ops>::Update ()
{
BL_PROFILE("MatrixPC::Update()");
using namespace amrex;
Expand All @@ -293,7 +291,7 @@ void MatrixPC<T,Ops>::Update (const T& a_U)

while(true) {

auto nnz_diff = Assemble(a_U);
auto nnz_diff = Assemble();
AMREX_ALWAYS_ASSERT(nnz_diff >= 0);
if (nnz_diff) {

Expand All @@ -315,7 +313,7 @@ void MatrixPC<T,Ops>::Update (const T& a_U)
}

template <class T, class Ops>
int MatrixPC<T,Ops>::Assemble (const T& a_U)
int MatrixPC<T,Ops>::Assemble ()
{
// Assemble the sparse matrix representation of the preconditioner
// A = curl (alpha * curl []) + M
Expand Down Expand Up @@ -347,11 +345,8 @@ int MatrixPC<T,Ops>::Assemble (const T& a_U)
<< "alpha = " << alpha << "\n";
}

// Get DOF object from a_U
const auto& dofs_obj = a_U.getDOFsObject();
const auto& dofs_mfarrvec = dofs_obj->m_array;
AMREX_ALWAYS_ASSERT(m_ndofs_l == dofs_obj->m_nDoFs_l);

@RemiLehe RemiLehe Sep 2, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR removes the AMREX_ALWAYS_ASSERT. On the other hand, I am not sure that this ASSERT was needed. Are there really configurations where m_ndofs_l could become different from dofs_obj->m_nDoFs_l?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@debog I'll let Debo answer that question. It may not be needed, but I"m not sure.

AMREX_ALWAYS_ASSERT(m_ndofs_g == dofs_obj->m_nDoFs_g);
// The DOF object is shared by every solver vector.
const auto& dofs_mfarrvec = T::getDOFsObject()->m_array;

m_r_indices_g.clear();
m_num_nz.clear();
Expand Down
2 changes: 1 addition & 1 deletion Source/NonlinearSolvers/NewtonSolver.H
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ void NewtonSolver<Vec,Ops>::Solve (Vec& a_U,
m_ops->PreLinearSolve();
m_linear_function->setBaseSolution(a_U);
m_linear_function->setBaseRHS(m_R);
m_linear_function->updatePreCondMat(a_U);
m_linear_function->updatePreCondMat();

// Solve linear system for Newton step [Jac]*dU = F
m_dU.zero();
Expand Down
2 changes: 1 addition & 1 deletion Source/NonlinearSolvers/Preconditioner.H
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class Preconditioner
/**
* \brief Update the preconditioner
*/
virtual void Update ( const T& a_U ) = 0;
virtual void Update () = 0;

/**
* \brief Apply (solve) the preconditioner given a RHS
Expand Down
2 changes: 1 addition & 1 deletion Source/NonlinearSolvers/WarpX_PETSc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ PetscErrorCode RHSFunction( SNES a_solver, Vec a_U, Vec a_F, void* ctxt)
VecAXPBY(a_F, 1.0, -1.0, a_U);

if (!context->m_fd_jac_comput) {
dynamic_cast<JacobianFunctionMF<VecType,TIType>*>(context->m_linop.get())->updatePreCondMat(context->m_U);
dynamic_cast<JacobianFunctionMF<VecType,TIType>*>(context->m_linop.get())->updatePreCondMat();
}
PetscFunctionReturn(PETSC_SUCCESS);
}
Expand Down
Loading