@@ -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
0 commit comments