Skip to content

Commit 89899fe

Browse files
committed
Allow integrating hypre AMS/ADS in FSPs
1 parent fa0c190 commit 89899fe

2 files changed

Lines changed: 31 additions & 12 deletions

File tree

src/numerics/petsc_preconditioner.C

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,6 @@ void PetscPreconditioner<T>::set_petsc_aux_data(PC & pc, System & sys, const uns
183183
// If not ams/ads, we quit with nothing to do
184184
if (std::string(hypre_type) == "ams")
185185
{
186-
// If multiple variables, we error out as senseless
187-
libmesh_error_msg_if(sys.n_vars() > 1,
188-
"Error applying hypre AMS to a system with multiple "
189-
"variables");
190186
// If not a 1st order Nédélec or a 2d 1st order Raviart-Thomas system, we
191187
// error out as we do not support anything else at the moment
192188
libmesh_error_msg_if(sys.variable(v).type() != FEType(1, NEDELEC_ONE) &&
@@ -199,10 +195,6 @@ void PetscPreconditioner<T>::set_petsc_aux_data(PC & pc, System & sys, const uns
199195
}
200196
else if (std::string(hypre_type) == "ads")
201197
{
202-
// If multiple variables, we error out as senseless
203-
libmesh_error_msg_if(sys.n_vars() > 1,
204-
"Error applying hypre ADS to a system with multiple "
205-
"variables");
206198
// If not a 3d 1st order Raviart-Thomas system, we error out as we do not
207199
// support anything else at the moment
208200
libmesh_error_msg_if(sys.variable(v).type() != FEType(1, RAVIART_THOMAS) ||
@@ -213,6 +205,31 @@ void PetscPreconditioner<T>::set_petsc_aux_data(PC & pc, System & sys, const uns
213205
set_hypre_ads_data(pc, sys, v);
214206
}
215207
}
208+
else if (pc_type && std::string(pc_type) == PCFIELDSPLIT)
209+
{
210+
// Annoyingly, if using Schur complement preconditioning, we need to call PCSetUp()
211+
auto pmatrix = cast_ptr<PetscMatrixBase<T> *>(sys.request_matrix("System Matrix"));
212+
pmatrix->close();
213+
Mat mat = pmatrix->mat();
214+
LibmeshPetscCallA(comm, PCSetOperators(pc, mat, mat));
215+
LibmeshPetscCallA(comm, PCSetUp(pc));
216+
217+
// Get sub KSP contexts for all splits
218+
PetscInt n_splits;
219+
KSP * subksps;
220+
LibmeshPetscCallA(comm, PCFieldSplitGetSubKSP(pc, &n_splits, &subksps));
221+
222+
// Get the sub PC context for each split and recursively call this function
223+
for (auto s : make_range(n_splits))
224+
{
225+
PC subpc;
226+
LibmeshPetscCallA(comm, KSPGetPC(subksps[s], &subpc));
227+
set_petsc_aux_data(subpc, sys, s);
228+
}
229+
230+
// Free the array of sub KSP contexts
231+
LibmeshPetscCallA(comm, PetscFree(subksps));
232+
}
216233
}
217234

218235

src/solvers/petsc_nonlinear_solver.C

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,12 @@ extern "C"
514514
Jac->close();
515515
}
516516

517+
KSP kspc;
518+
PC pcc;
519+
LibmeshPetscCall2(sys.comm(), SNESGetKSP(snes, &kspc));
520+
LibmeshPetscCall2(sys.comm(), KSPGetPC(kspc, &pcc));
521+
PetscPreconditioner<Number>::set_petsc_aux_data(pcc, sys);
522+
517523
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS);
518524
}
519525

@@ -985,10 +991,6 @@ PetscNonlinearSolver<T>::solve (SparseMatrix<T> & pre_in, // System Preconditi
985991
#endif
986992
LibmeshPetscCall(SNESSetFromOptions(_snes));
987993

988-
PC pc;
989-
LibmeshPetscCall(KSPGetPC(ksp, &pc));
990-
PetscPreconditioner<T>::set_petsc_aux_data(pc, this->system());
991-
992994
#if defined(LIBMESH_HAVE_PETSC_HYPRE) && PETSC_VERSION_LESS_THAN(3, 23, 0) && \
993995
!PETSC_VERSION_LESS_THAN(3, 12, 0) && defined(PETSC_HAVE_HYPRE_DEVICE)
994996
{

0 commit comments

Comments
 (0)