xref: /petsc/src/snes/impls/patch/snespatch.c (revision 6c270751dfd48312996ae463f583bd124603f97b)
1561742edSMatthew G. Knepley /*
2561742edSMatthew G. Knepley       Defines a SNES that can consist of a collection of SNESes on patches of the domain
3561742edSMatthew G. Knepley */
4561742edSMatthew G. Knepley #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/
5561742edSMatthew G. Knepley #include <petsc/private/pcpatchimpl.h> /* We need internal access to PCPatch right now, until that part is moved to Plex */
6561742edSMatthew G. Knepley 
7561742edSMatthew G. Knepley typedef struct {
8561742edSMatthew G. Knepley   PC pc; /* The linear patch preconditioner */
9561742edSMatthew G. Knepley   SNESCompositeType type;
10561742edSMatthew G. Knepley } SNES_Patch;
11561742edSMatthew G. Knepley 
12561742edSMatthew G. Knepley static PetscErrorCode SNESPatchComputeResidual_Private(SNES snes, Vec x, Vec F, void *ctx)
13561742edSMatthew G. Knepley {
14561742edSMatthew G. Knepley   SNES           patchsolver = (SNES) ctx;
15561742edSMatthew G. Knepley   SNES_Patch    *patch       = (SNES_Patch *) patchsolver->data;
16561742edSMatthew G. Knepley   PC_PATCH      *pcpatch     = (PC_PATCH *) patch->pc->data;
17561742edSMatthew G. Knepley   PetscErrorCode ierr;
18561742edSMatthew G. Knepley 
19561742edSMatthew G. Knepley   PetscFunctionBegin;
20561742edSMatthew G. Knepley   ierr = PCPatchComputeFunction_Internal(patch->pc, x, F, pcpatch->currentPatch);CHKERRQ(ierr);
21561742edSMatthew G. Knepley   PetscFunctionReturn(0);
22561742edSMatthew G. Knepley }
23561742edSMatthew G. Knepley 
24561742edSMatthew G. Knepley static PetscErrorCode SNESPatchComputeJacobian_Private(SNES snes, Vec x, Mat J, Mat M, void *ctx)
25561742edSMatthew G. Knepley {
26561742edSMatthew G. Knepley   SNES           patchsolver = (SNES) ctx;
27561742edSMatthew G. Knepley   SNES_Patch    *patch       = (SNES_Patch *) patchsolver->data;
28561742edSMatthew G. Knepley   PC_PATCH      *pcpatch     = (PC_PATCH *) patch->pc->data;
29561742edSMatthew G. Knepley   PetscErrorCode ierr;
30561742edSMatthew G. Knepley 
31561742edSMatthew G. Knepley   PetscFunctionBegin;
3234d8b122SPatrick Farrell   ierr = PCPatchComputeOperator_Internal(patch->pc, x, M, pcpatch->currentPatch, PETSC_FALSE);CHKERRQ(ierr);
33561742edSMatthew G. Knepley   PetscFunctionReturn(0);
34561742edSMatthew G. Knepley }
35561742edSMatthew G. Knepley 
36561742edSMatthew G. Knepley static PetscErrorCode PCSetUp_PATCH_Nonlinear(PC pc)
37561742edSMatthew G. Knepley {
38561742edSMatthew G. Knepley   PC_PATCH      *patch = (PC_PATCH *) pc->data;
39561742edSMatthew G. Knepley   const char    *prefix;
40561742edSMatthew G. Knepley   PetscInt       i;
41561742edSMatthew G. Knepley   PetscErrorCode ierr;
42561742edSMatthew G. Knepley 
43561742edSMatthew G. Knepley   PetscFunctionBegin;
44561742edSMatthew G. Knepley   if (!pc->setupcalled) {
45561742edSMatthew G. Knepley     ierr = PetscMalloc1(patch->npatch, &patch->solver);CHKERRQ(ierr);
46561742edSMatthew G. Knepley     ierr = PCGetOptionsPrefix(pc, &prefix);CHKERRQ(ierr);
47561742edSMatthew G. Knepley     for (i = 0; i < patch->npatch; ++i) {
48561742edSMatthew G. Knepley       SNES snes;
49561742edSMatthew G. Knepley       KSP  subksp;
50561742edSMatthew G. Knepley 
51561742edSMatthew G. Knepley       ierr = SNESCreate(PETSC_COMM_SELF, &snes);CHKERRQ(ierr);
52561742edSMatthew G. Knepley       ierr = SNESSetOptionsPrefix(snes, prefix);CHKERRQ(ierr);
53561742edSMatthew G. Knepley       ierr = SNESAppendOptionsPrefix(snes, "sub_");CHKERRQ(ierr);
54561742edSMatthew G. Knepley       ierr = PetscObjectIncrementTabLevel((PetscObject) snes, (PetscObject) pc, 1);CHKERRQ(ierr);
55561742edSMatthew G. Knepley       ierr = SNESGetKSP(snes, &subksp);CHKERRQ(ierr);
56561742edSMatthew G. Knepley       ierr = PetscObjectIncrementTabLevel((PetscObject) subksp, (PetscObject) pc, 1);CHKERRQ(ierr);
57561742edSMatthew G. Knepley       ierr = PetscLogObjectParent((PetscObject) pc, (PetscObject) snes);CHKERRQ(ierr);
58561742edSMatthew G. Knepley       patch->solver[i] = (PetscObject) snes;
59561742edSMatthew G. Knepley     }
60561742edSMatthew G. Knepley   }
61561742edSMatthew G. Knepley   for (i = 0; i < patch->npatch; ++i) {
62561742edSMatthew G. Knepley     SNES snes = (SNES) patch->solver[i];
63561742edSMatthew G. Knepley 
64561742edSMatthew G. Knepley     ierr = SNESSetFunction(snes, patch->patchX[i], SNESPatchComputeResidual_Private, snes);CHKERRQ(ierr);
65561742edSMatthew G. Knepley     ierr = SNESSetJacobian(snes, patch->mat[i], patch->mat[i], SNESPatchComputeJacobian_Private, snes);CHKERRQ(ierr);
66561742edSMatthew G. Knepley   }
67561742edSMatthew G. Knepley   if (!pc->setupcalled && patch->optionsSet) for (i = 0; i < patch->npatch; ++i) {ierr = SNESSetFromOptions((SNES) patch->solver[i]);CHKERRQ(ierr);}
68561742edSMatthew G. Knepley   PetscFunctionReturn(0);
69561742edSMatthew G. Knepley }
70561742edSMatthew G. Knepley 
71561742edSMatthew G. Knepley static PetscErrorCode PCApply_PATCH_Nonlinear(PC pc, PetscInt i, Vec x, Vec y)
72561742edSMatthew G. Knepley {
73561742edSMatthew G. Knepley   PC_PATCH      *patch = (PC_PATCH *) pc->data;
74561742edSMatthew G. Knepley   PetscErrorCode ierr;
75561742edSMatthew G. Knepley 
76561742edSMatthew G. Knepley   PetscFunctionBegin;
77561742edSMatthew G. Knepley   patch->currentPatch = i;
78561742edSMatthew G. Knepley   ierr = PetscLogEventBegin(PC_Patch_Solve, pc, 0, 0, 0);CHKERRQ(ierr);
79561742edSMatthew G. Knepley   ierr = SNESSolve((SNES) patch->solver[i], x, y);CHKERRQ(ierr);
80561742edSMatthew G. Knepley   ierr = PetscLogEventEnd(PC_Patch_Solve, pc, 0, 0, 0);CHKERRQ(ierr);
81561742edSMatthew G. Knepley   PetscFunctionReturn(0);
82561742edSMatthew G. Knepley }
83561742edSMatthew G. Knepley 
84561742edSMatthew G. Knepley static PetscErrorCode PCReset_PATCH_Nonlinear(PC pc)
85561742edSMatthew G. Knepley {
86561742edSMatthew G. Knepley   PC_PATCH      *patch = (PC_PATCH *) pc->data;
87561742edSMatthew G. Knepley   PetscInt       i;
88561742edSMatthew G. Knepley   PetscErrorCode ierr;
89561742edSMatthew G. Knepley 
90561742edSMatthew G. Knepley   PetscFunctionBegin;
91561742edSMatthew G. Knepley   if (patch->solver) {
92561742edSMatthew G. Knepley     for (i = 0; i < patch->npatch; ++i) {ierr = SNESReset((SNES) patch->solver[i]);CHKERRQ(ierr);}
93561742edSMatthew G. Knepley   }
94561742edSMatthew G. Knepley   PetscFunctionReturn(0);
95561742edSMatthew G. Knepley }
96561742edSMatthew G. Knepley 
97561742edSMatthew G. Knepley static PetscErrorCode PCDestroy_PATCH_Nonlinear(PC pc)
98561742edSMatthew G. Knepley {
99561742edSMatthew G. Knepley   PC_PATCH      *patch = (PC_PATCH *) pc->data;
100561742edSMatthew G. Knepley   PetscInt       i;
101561742edSMatthew G. Knepley   PetscErrorCode ierr;
102561742edSMatthew G. Knepley 
103561742edSMatthew G. Knepley   PetscFunctionBegin;
104561742edSMatthew G. Knepley   if (patch->solver) {
105561742edSMatthew G. Knepley     for (i = 0; i < patch->npatch; ++i) {ierr = SNESDestroy((SNES *) &patch->solver[i]);CHKERRQ(ierr);}
106561742edSMatthew G. Knepley     ierr = PetscFree(patch->solver);CHKERRQ(ierr);
107561742edSMatthew G. Knepley   }
108561742edSMatthew G. Knepley   PetscFunctionReturn(0);
109561742edSMatthew G. Knepley }
110561742edSMatthew G. Knepley 
111561742edSMatthew G. Knepley static PetscErrorCode SNESSetUp_Patch(SNES snes)
112561742edSMatthew G. Knepley {
113561742edSMatthew G. Knepley   SNES_Patch    *patch = (SNES_Patch *) snes->data;
114561742edSMatthew G. Knepley   DM             dm;
115561742edSMatthew G. Knepley   Mat            dummy;
116561742edSMatthew G. Knepley   Vec            F;
117561742edSMatthew G. Knepley   PetscInt       n, N;
118561742edSMatthew G. Knepley   PetscErrorCode ierr;
119561742edSMatthew G. Knepley 
120561742edSMatthew G. Knepley   PetscFunctionBegin;
121561742edSMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
122561742edSMatthew G. Knepley   ierr = PCSetDM(patch->pc, dm);CHKERRQ(ierr);
123561742edSMatthew G. Knepley   ierr = SNESGetFunction(snes, &F, NULL, NULL);CHKERRQ(ierr);
124561742edSMatthew G. Knepley   ierr = VecGetLocalSize(F, &n);CHKERRQ(ierr);
125561742edSMatthew G. Knepley   ierr = VecGetSize(F, &N);CHKERRQ(ierr);
126561742edSMatthew G. Knepley   ierr = MatCreateShell(PetscObjectComm((PetscObject) snes), n, n, N, N, (void *) snes, &dummy);CHKERRQ(ierr);
127561742edSMatthew G. Knepley   ierr = PCSetOperators(patch->pc, dummy, dummy);CHKERRQ(ierr);
128561742edSMatthew G. Knepley   ierr = MatDestroy(&dummy);CHKERRQ(ierr);
129561742edSMatthew G. Knepley   ierr = PCSetUp(patch->pc);CHKERRQ(ierr);
130561742edSMatthew G. Knepley   /* allocate workspace */
131561742edSMatthew G. Knepley   PetscFunctionReturn(0);
132561742edSMatthew G. Knepley }
133561742edSMatthew G. Knepley 
134561742edSMatthew G. Knepley static PetscErrorCode SNESReset_Patch(SNES snes)
135561742edSMatthew G. Knepley {
136561742edSMatthew G. Knepley   SNES_Patch    *patch = (SNES_Patch *) snes->data;
137561742edSMatthew G. Knepley   PetscErrorCode ierr;
138561742edSMatthew G. Knepley 
139561742edSMatthew G. Knepley   PetscFunctionBegin;
140561742edSMatthew G. Knepley   ierr = PCReset(patch->pc);CHKERRQ(ierr);
141561742edSMatthew G. Knepley   PetscFunctionReturn(0);
142561742edSMatthew G. Knepley }
143561742edSMatthew G. Knepley 
144561742edSMatthew G. Knepley static PetscErrorCode SNESDestroy_Patch(SNES snes)
145561742edSMatthew G. Knepley {
146561742edSMatthew G. Knepley   SNES_Patch    *patch = (SNES_Patch *) snes->data;
147561742edSMatthew G. Knepley   PetscErrorCode ierr;
148561742edSMatthew G. Knepley 
149561742edSMatthew G. Knepley   PetscFunctionBegin;
150561742edSMatthew G. Knepley   ierr = SNESReset_Patch(snes);CHKERRQ(ierr);
151561742edSMatthew G. Knepley   ierr = PCDestroy(&patch->pc);CHKERRQ(ierr);
152561742edSMatthew G. Knepley   ierr = PetscFree(snes->data);CHKERRQ(ierr);
153561742edSMatthew G. Knepley   PetscFunctionReturn(0);
154561742edSMatthew G. Knepley }
155561742edSMatthew G. Knepley 
156561742edSMatthew G. Knepley static PetscErrorCode SNESSetFromOptions_Patch(PetscOptionItems *PetscOptionsObject, SNES snes)
157561742edSMatthew G. Knepley {
158561742edSMatthew G. Knepley   SNES_Patch     *patch = (SNES_Patch *) snes->data;
159561742edSMatthew G. Knepley   PetscBool      flg;
160561742edSMatthew G. Knepley   PetscErrorCode ierr;
161561742edSMatthew G. Knepley 
162561742edSMatthew G. Knepley   PetscFunctionBegin;
163561742edSMatthew G. Knepley   ierr = PetscOptionsHead(PetscOptionsObject, "Patch nonlinear preconditioner options");CHKERRQ(ierr);
164561742edSMatthew G. Knepley   ierr = PetscOptionsEnum("-snes_patch_type", "Type of composition", "SNESPatchSetType", SNESCompositeTypes, (PetscEnum) patch->type, (PetscEnum *) &patch->type, &flg);CHKERRQ(ierr);
165561742edSMatthew G. Knepley   if (flg) {ierr = SNESPatchSetType(snes, patch->type);CHKERRQ(ierr);}
166561742edSMatthew G. Knepley   ierr = PetscOptionsTail();CHKERRQ(ierr);
167561742edSMatthew G. Knepley 
168561742edSMatthew G. Knepley   ierr = PCSetFromOptions(patch->pc);CHKERRQ(ierr);
169561742edSMatthew G. Knepley   PetscFunctionReturn(0);
170561742edSMatthew G. Knepley }
171561742edSMatthew G. Knepley 
172561742edSMatthew G. Knepley static PetscErrorCode SNESView_Patch(SNES snes,PetscViewer viewer)
173561742edSMatthew G. Knepley {
174561742edSMatthew G. Knepley   SNES_Patch    *patch = (SNES_Patch *) snes->data;
175561742edSMatthew G. Knepley   PetscBool      iascii;
176561742edSMatthew G. Knepley   PetscErrorCode ierr;
177561742edSMatthew G. Knepley 
178561742edSMatthew G. Knepley   PetscFunctionBegin;
179561742edSMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
180561742edSMatthew G. Knepley   if (iascii) {
181561742edSMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer,"  type - %s\n",SNESCompositeTypes[patch->type]);CHKERRQ(ierr);
182561742edSMatthew G. Knepley   }
183561742edSMatthew G. Knepley   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
184561742edSMatthew G. Knepley   ierr = PCView(patch->pc, viewer);CHKERRQ(ierr);
185561742edSMatthew G. Knepley   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
186561742edSMatthew G. Knepley   PetscFunctionReturn(0);
187561742edSMatthew G. Knepley }
188561742edSMatthew G. Knepley 
189561742edSMatthew G. Knepley static PetscErrorCode SNESSolve_Patch(SNES snes)
190561742edSMatthew G. Knepley {
191561742edSMatthew G. Knepley   PetscFunctionBegin;
192561742edSMatthew G. Knepley   PetscFunctionReturn(0);
193561742edSMatthew G. Knepley }
194561742edSMatthew G. Knepley 
195561742edSMatthew G. Knepley static PetscErrorCode SNESPatchSetType_Patch(SNES snes, SNESCompositeType type)
196561742edSMatthew G. Knepley {
197561742edSMatthew G. Knepley   SNES_Patch *patch = (SNES_Patch *) snes->data;
198561742edSMatthew G. Knepley 
199561742edSMatthew G. Knepley   PetscFunctionBegin;
200561742edSMatthew G. Knepley   patch->type = type;
201561742edSMatthew G. Knepley   PetscFunctionReturn(0);
202561742edSMatthew G. Knepley }
203561742edSMatthew G. Knepley 
204561742edSMatthew G. Knepley /*MC
205561742edSMatthew G. Knepley   SNESPATCH - Build a preconditioner by composing together many nonlinear solvers on patches
206561742edSMatthew G. Knepley 
207561742edSMatthew G. Knepley   Options Database Keys:
208561742edSMatthew G. Knepley . -snes_patch_type <type: one of additive, multiplicative, symmetric_multiplicative> - Sets composition type
209561742edSMatthew G. Knepley 
210561742edSMatthew G. Knepley   Level: intermediate
211561742edSMatthew G. Knepley 
212561742edSMatthew G. Knepley   Concepts: composing solvers
213561742edSMatthew G. Knepley 
214561742edSMatthew G. Knepley .seealso:  SNESCreate(), SNESSetType(), SNESType (for list of available types), SNES,
215561742edSMatthew G. Knepley            PCPATCH
216561742edSMatthew G. Knepley 
217561742edSMatthew G. Knepley    References:
218561742edSMatthew G. Knepley .  1. - Peter R. Brune, Matthew G. Knepley, Barry F. Smith, and Xuemin Tu, "Composing Scalable Nonlinear Algebraic Solvers", SIAM Review, 57(4), 2015
219561742edSMatthew G. Knepley 
220561742edSMatthew G. Knepley M*/
221561742edSMatthew G. Knepley PETSC_EXTERN PetscErrorCode SNESCreate_Patch(SNES snes)
222561742edSMatthew G. Knepley {
223561742edSMatthew G. Knepley   PetscErrorCode ierr;
224561742edSMatthew G. Knepley   SNES_Patch    *patch;
225561742edSMatthew G. Knepley 
226561742edSMatthew G. Knepley   PetscFunctionBegin;
227561742edSMatthew G. Knepley   ierr = PetscNewLog(snes, &patch);CHKERRQ(ierr);
228561742edSMatthew G. Knepley 
229561742edSMatthew G. Knepley   snes->ops->solve          = SNESSolve_Patch;
230561742edSMatthew G. Knepley   snes->ops->setup          = SNESSetUp_Patch;
231561742edSMatthew G. Knepley   snes->ops->reset          = SNESReset_Patch;
232561742edSMatthew G. Knepley   snes->ops->destroy        = SNESDestroy_Patch;
233561742edSMatthew G. Knepley   snes->ops->setfromoptions = SNESSetFromOptions_Patch;
234561742edSMatthew G. Knepley   snes->ops->view           = SNESView_Patch;
235561742edSMatthew G. Knepley 
236561742edSMatthew G. Knepley   snes->alwayscomputesfinalresidual = PETSC_FALSE;
237561742edSMatthew G. Knepley 
238561742edSMatthew G. Knepley   snes->data = (void *) patch;
239561742edSMatthew G. Knepley   patch->type = SNES_COMPOSITE_ADDITIVE;
240561742edSMatthew G. Knepley   ierr = PCCreate(PetscObjectComm((PetscObject) snes), &patch->pc);CHKERRQ(ierr);
241561742edSMatthew G. Knepley   ierr = PCSetType(patch->pc, PCPATCH);CHKERRQ(ierr);
242561742edSMatthew G. Knepley 
243561742edSMatthew G. Knepley   ((PC_PATCH *) patch->pc->data)->setupsolver   = PCSetUp_PATCH_Nonlinear;
244561742edSMatthew G. Knepley   ((PC_PATCH *) patch->pc->data)->applysolver   = PCApply_PATCH_Nonlinear;
245561742edSMatthew G. Knepley   ((PC_PATCH *) patch->pc->data)->resetsolver   = PCReset_PATCH_Nonlinear;
246561742edSMatthew G. Knepley   ((PC_PATCH *) patch->pc->data)->destroysolver = PCDestroy_PATCH_Nonlinear;
247561742edSMatthew G. Knepley 
248561742edSMatthew G. Knepley   ierr = PetscObjectComposeFunction((PetscObject) snes, "SNESPatchSetType_C", SNESPatchSetType_Patch);CHKERRQ(ierr);
249561742edSMatthew G. Knepley   PetscFunctionReturn(0);
250561742edSMatthew G. Knepley }
251561742edSMatthew G. Knepley 
252561742edSMatthew G. Knepley /*@
253561742edSMatthew G. Knepley   SNESPatchSetType - Sets the type of composition.
254561742edSMatthew G. Knepley 
255561742edSMatthew G. Knepley   Logically Collective on SNES
256561742edSMatthew G. Knepley 
257561742edSMatthew G. Knepley   Input Parameter:
258561742edSMatthew G. Knepley + snes - the preconditioner context
259561742edSMatthew G. Knepley - type - SNES_COMPOSITE_ADDITIVE (default), SNES_COMPOSITE_MULTIPLICATIVE, etc.
260561742edSMatthew G. Knepley 
261561742edSMatthew G. Knepley   Options Database Key:
262561742edSMatthew G. Knepley . -snes_composite_type <type: one of additive, multiplicative, etc> - Sets composite preconditioner type
263561742edSMatthew G. Knepley 
264561742edSMatthew G. Knepley   Level: Developer
265561742edSMatthew G. Knepley 
266561742edSMatthew G. Knepley .keywords: SNES, set, type, composite preconditioner, additive, multiplicative
267561742edSMatthew G. Knepley @*/
268561742edSMatthew G. Knepley PetscErrorCode SNESPatchSetType(SNES snes, SNESCompositeType type)
269561742edSMatthew G. Knepley {
270561742edSMatthew G. Knepley   PetscErrorCode ierr;
271561742edSMatthew G. Knepley 
272561742edSMatthew G. Knepley   PetscFunctionBegin;
273561742edSMatthew G. Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
274561742edSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(snes,type, 2);
275561742edSMatthew G. Knepley   ierr = PetscTryMethod(snes, "SNESPatchSetType_C", (SNES,SNESCompositeType), (snes,type));CHKERRQ(ierr);
276561742edSMatthew G. Knepley   PetscFunctionReturn(0);
277561742edSMatthew G. Knepley }
278*6c270751SPatrick Farrell 
279*6c270751SPatrick Farrell PetscErrorCode SNESPatchSetDiscretisationInfo(SNES snes, PetscInt nsubspaces, DM *dms, PetscInt *bs, PetscInt *nodesPerCell, const PetscInt **cellNodeMap,
280*6c270751SPatrick Farrell                                             const PetscInt *subspaceOffsets, PetscInt numGhostBcs, const PetscInt *ghostBcNodes, PetscInt numGlobalBcs, const PetscInt *globalBcNodes)
281*6c270751SPatrick Farrell {
282*6c270751SPatrick Farrell   SNES_Patch    *patch = (SNES_Patch *) snes->data;
283*6c270751SPatrick Farrell   PetscErrorCode ierr;
284*6c270751SPatrick Farrell 
285*6c270751SPatrick Farrell   PetscFunctionBegin;
286*6c270751SPatrick Farrell   ierr = PCPatchSetDiscretisationInfo(patch->pc, nsubspaces, dms, bs, nodesPerCell, cellNodeMap, subspaceOffsets, numGhostBcs, ghostBcNodes, numGlobalBcs, globalBcNodes);CHKERRQ(ierr);
287*6c270751SPatrick Farrell   PetscFunctionReturn(0);
288*6c270751SPatrick Farrell }
289*6c270751SPatrick Farrell 
290*6c270751SPatrick Farrell PetscErrorCode SNESPatchSetComputeOperator(SNES snes, PetscErrorCode (*func)(PC, PetscInt, Vec, Mat, IS, PetscInt, const PetscInt *, void *), void *ctx)
291*6c270751SPatrick Farrell {
292*6c270751SPatrick Farrell   SNES_Patch    *patch = (SNES_Patch *) snes->data;
293*6c270751SPatrick Farrell   PetscErrorCode ierr;
294*6c270751SPatrick Farrell 
295*6c270751SPatrick Farrell   PetscFunctionBegin;
296*6c270751SPatrick Farrell   ierr = PCPatchSetComputeOperator(patch->pc, func, ctx);CHKERRQ(ierr);
297*6c270751SPatrick Farrell   PetscFunctionReturn(0);
298*6c270751SPatrick Farrell }
299*6c270751SPatrick Farrell 
300*6c270751SPatrick Farrell PetscErrorCode SNESPatchSetComputeFunction(SNES snes, PetscErrorCode (*func)(PC, PetscInt, Vec, Vec, IS, PetscInt, const PetscInt *, void *), void *ctx)
301*6c270751SPatrick Farrell {
302*6c270751SPatrick Farrell   SNES_Patch    *patch = (SNES_Patch *) snes->data;
303*6c270751SPatrick Farrell   PetscErrorCode ierr;
304*6c270751SPatrick Farrell 
305*6c270751SPatrick Farrell   PetscFunctionBegin;
306*6c270751SPatrick Farrell   ierr = PCPatchSetComputeFunction(patch->pc, func, ctx);CHKERRQ(ierr);
307*6c270751SPatrick Farrell   PetscFunctionReturn(0);
308*6c270751SPatrick Farrell }
309*6c270751SPatrick Farrell 
310*6c270751SPatrick Farrell PetscErrorCode SNESPatchSetConstructType(SNES snes, PCPatchConstructType ctype, PetscErrorCode (*func)(PC, PetscInt *, IS **, IS *, void *), void *ctx)
311*6c270751SPatrick Farrell {
312*6c270751SPatrick Farrell   SNES_Patch    *patch = (SNES_Patch *) snes->data;
313*6c270751SPatrick Farrell   PetscErrorCode ierr;
314*6c270751SPatrick Farrell 
315*6c270751SPatrick Farrell   PetscFunctionBegin;
316*6c270751SPatrick Farrell   ierr = PCPatchSetConstructType(patch->pc, ctype, func, ctx);CHKERRQ(ierr);
317*6c270751SPatrick Farrell   PetscFunctionReturn(0);
318*6c270751SPatrick Farrell }
319*6c270751SPatrick Farrell 
320*6c270751SPatrick Farrell PetscErrorCode SNESPatchSetCellNumbering(SNES snes, PetscSection cellNumbering)
321*6c270751SPatrick Farrell {
322*6c270751SPatrick Farrell   SNES_Patch    *patch = (SNES_Patch *) snes->data;
323*6c270751SPatrick Farrell   PetscErrorCode ierr;
324*6c270751SPatrick Farrell 
325*6c270751SPatrick Farrell   PetscFunctionBegin;
326*6c270751SPatrick Farrell   ierr = PCPatchSetCellNumbering(patch->pc, cellNumbering);CHKERRQ(ierr);
327*6c270751SPatrick Farrell   PetscFunctionReturn(0);
328*6c270751SPatrick Farrell }
329