Actual source code: dmksp.c
1: #include <petsc/private/dmimpl.h>
2: #include <petsc/private/kspimpl.h>
3: #include <petscdm.h>
5: static PetscErrorCode DMKSPDestroy(DMKSP *kdm)
6: {
10: if (!*kdm) return(0);
12: if (--((PetscObject)(*kdm))->refct > 0) {*kdm = NULL; return(0);}
13: if ((*kdm)->ops->destroy) {((*kdm)->ops->destroy)(kdm);}
14: PetscHeaderDestroy(kdm);
15: return(0);
16: }
18: static PetscErrorCode DMKSPCreate(MPI_Comm comm,DMKSP *kdm)
19: {
23: KSPInitializePackage();
24: PetscHeaderCreate(*kdm, DMKSP_CLASSID, "DMKSP", "DMKSP", "DMKSP", comm, DMKSPDestroy, NULL);
25: return(0);
26: }
28: /* Attaches the DMKSP to the coarse level.
29: * Under what conditions should we copy versus duplicate?
30: */
31: static PetscErrorCode DMCoarsenHook_DMKSP(DM dm,DM dmc,void *ctx)
32: {
36: DMCopyDMKSP(dm,dmc);
37: return(0);
38: }
40: /* Attaches the DMKSP to the coarse level.
41: * Under what conditions should we copy versus duplicate?
42: */
43: static PetscErrorCode DMRefineHook_DMKSP(DM dm,DM dmc,void *ctx)
44: {
48: DMCopyDMKSP(dm,dmc);
49: return(0);
50: }
52: /*@C
53: DMKSPCopy - copies the information in a DMKSP to another DMKSP
55: Not Collective
57: Input Parameters:
58: + kdm - Original DMKSP
59: - nkdm - DMKSP to receive the data, should have been created with DMKSPCreate()
61: Level: developer
63: .seealso: DMKSPCreate(), DMKSPDestroy()
64: @*/
65: PetscErrorCode DMKSPCopy(DMKSP kdm,DMKSP nkdm)
66: {
72: nkdm->ops->computeoperators = kdm->ops->computeoperators;
73: nkdm->ops->computerhs = kdm->ops->computerhs;
74: nkdm->ops->computeinitialguess = kdm->ops->computeinitialguess;
75: nkdm->ops->destroy = kdm->ops->destroy;
76: nkdm->ops->duplicate = kdm->ops->duplicate;
78: nkdm->operatorsctx = kdm->operatorsctx;
79: nkdm->rhsctx = kdm->rhsctx;
80: nkdm->initialguessctx = kdm->initialguessctx;
81: nkdm->data = kdm->data;
82: /* nkdm->originaldm = kdm->originaldm; */ /* No need since nkdm->originaldm will be immediately updated in caller DMGetDMKSPWrite */
84: nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
85: nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
86: nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];
88: /* implementation specific copy hooks */
89: if (kdm->ops->duplicate) {(*kdm->ops->duplicate)(kdm,nkdm);}
90: return(0);
91: }
93: /*@C
94: DMGetDMKSP - get read-only private DMKSP context from a DM
96: Logically Collective
98: Input Parameter:
99: . dm - DM to be used with KSP
101: Output Parameter:
102: . snesdm - private DMKSP context
104: Level: developer
106: Notes:
107: Use DMGetDMKSPWrite() if write access is needed. The DMKSPSetXXX API should be used wherever possible.
109: .seealso: DMGetDMKSPWrite()
110: @*/
111: PetscErrorCode DMGetDMKSP(DM dm,DMKSP *kspdm)
112: {
117: *kspdm = (DMKSP) dm->dmksp;
118: if (!*kspdm) {
119: PetscInfo(dm,"Creating new DMKSP\n");
120: DMKSPCreate(PetscObjectComm((PetscObject)dm),kspdm);
121: dm->dmksp = (PetscObject) *kspdm;
122: (*kspdm)->originaldm = dm;
123: DMCoarsenHookAdd(dm,DMCoarsenHook_DMKSP,NULL,NULL);
124: DMRefineHookAdd(dm,DMRefineHook_DMKSP,NULL,NULL);
125: }
126: return(0);
127: }
129: /*@C
130: DMGetDMKSPWrite - get write access to private DMKSP context from a DM
132: Logically Collective
134: Input Parameter:
135: . dm - DM to be used with KSP
137: Output Parameter:
138: . kspdm - private DMKSP context
140: Level: developer
142: .seealso: DMGetDMKSP()
143: @*/
144: PetscErrorCode DMGetDMKSPWrite(DM dm,DMKSP *kspdm)
145: {
147: DMKSP kdm;
151: DMGetDMKSP(dm,&kdm);
152: if (!kdm->originaldm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DMKSP has a NULL originaldm");
153: if (kdm->originaldm != dm) { /* Copy on write */
154: DMKSP oldkdm = kdm;
155: PetscInfo(dm,"Copying DMKSP due to write\n");
156: DMKSPCreate(PetscObjectComm((PetscObject)dm),&kdm);
157: DMKSPCopy(oldkdm,kdm);
158: DMKSPDestroy((DMKSP*)&dm->dmksp);
159: dm->dmksp = (PetscObject)kdm;
160: kdm->originaldm = dm;
161: }
162: *kspdm = kdm;
163: return(0);
164: }
166: /*@C
167: DMCopyDMKSP - copies a DM context to a new DM
169: Logically Collective
171: Input Parameters:
172: + dmsrc - DM to obtain context from
173: - dmdest - DM to add context to
175: Level: developer
177: Note:
178: The context is copied by reference. This function does not ensure that a context exists.
180: .seealso: DMGetDMKSP(), KSPSetDM()
181: @*/
182: PetscErrorCode DMCopyDMKSP(DM dmsrc,DM dmdest)
183: {
189: DMKSPDestroy((DMKSP*)&dmdest->dmksp);
190: dmdest->dmksp = dmsrc->dmksp;
191: PetscObjectReference(dmdest->dmksp);
192: DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMKSP,NULL,NULL);
193: DMRefineHookAdd(dmdest,DMRefineHook_DMKSP,NULL,NULL);
194: return(0);
195: }
197: /*@C
198: DMKSPSetComputeOperators - set KSP matrix evaluation function
200: Not Collective
202: Input Parameters:
203: + dm - DM to be used with KSP
204: . func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
205: - ctx - context for matrix evaluation
207: Level: advanced
209: Note:
210: KSPSetComputeOperators() is normally used, but it calls this function internally because the user context is actually
211: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
212: not. If DM took a more central role at some later date, this could become the primary method of setting the matrix.
214: .seealso: DMKSPSetContext(), DMKSPGetComputeOperators(), KSPSetOperators()
215: @*/
216: PetscErrorCode DMKSPSetComputeOperators(DM dm,PetscErrorCode (*func)(KSP,Mat,Mat,void*),void *ctx)
217: {
219: DMKSP kdm;
223: DMGetDMKSPWrite(dm,&kdm);
224: if (func) kdm->ops->computeoperators = func;
225: if (ctx) kdm->operatorsctx = ctx;
226: return(0);
227: }
229: /*@C
230: DMKSPGetComputeOperators - get KSP matrix evaluation function
232: Not Collective
234: Input Parameter:
235: . dm - DM to be used with KSP
237: Output Parameters:
238: + func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
239: - ctx - context for matrix evaluation
241: Level: advanced
243: .seealso: DMKSPSetContext(), KSPSetComputeOperators(), DMKSPSetComputeOperators()
244: @*/
245: PetscErrorCode DMKSPGetComputeOperators(DM dm,PetscErrorCode (**func)(KSP,Mat,Mat,void*),void *ctx)
246: {
248: DMKSP kdm;
252: DMGetDMKSP(dm,&kdm);
253: if (func) *func = kdm->ops->computeoperators;
254: if (ctx) *(void**)ctx = kdm->operatorsctx;
255: return(0);
256: }
258: /*@C
259: DMKSPSetComputeRHS - set KSP right hand side evaluation function
261: Not Collective
263: Input Parameters:
264: + dm - DM to be used with KSP
265: . func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
266: - ctx - context for right hand side evaluation
268: Level: advanced
270: Note:
271: KSPSetComputeRHS() is normally used, but it calls this function internally because the user context is actually
272: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
273: not. If DM took a more central role at some later date, this could become the primary method of setting the matrix.
275: .seealso: DMKSPSetContext(), DMKSPGetComputeRHS(), KSPSetRHS()
276: @*/
277: PetscErrorCode DMKSPSetComputeRHS(DM dm,PetscErrorCode (*func)(KSP,Vec,void*),void *ctx)
278: {
280: DMKSP kdm;
284: DMGetDMKSPWrite(dm,&kdm);
285: if (func) kdm->ops->computerhs = func;
286: if (ctx) kdm->rhsctx = ctx;
287: return(0);
288: }
290: /*@C
291: DMKSPSetComputeInitialGuess - set KSP initial guess evaluation function
293: Not Collective
295: Input Parameters:
296: + dm - DM to be used with KSP
297: . func - initial guess evaluation function, see KSPSetComputeInitialGuess() for calling sequence
298: - ctx - context for right hand side evaluation
300: Level: advanced
302: Note:
303: KSPSetComputeInitialGuess() is normally used, but it calls this function internally because the user context is actually
304: associated with the DM.
306: .seealso: DMKSPSetContext(), DMKSPGetComputeRHS(), KSPSetRHS()
307: @*/
308: PetscErrorCode DMKSPSetComputeInitialGuess(DM dm,PetscErrorCode (*func)(KSP,Vec,void*),void *ctx)
309: {
311: DMKSP kdm;
315: DMGetDMKSPWrite(dm,&kdm);
316: if (func) kdm->ops->computeinitialguess = func;
317: if (ctx) kdm->initialguessctx = ctx;
318: return(0);
319: }
321: /*@C
322: DMKSPGetComputeRHS - get KSP right hand side evaluation function
324: Not Collective
326: Input Parameter:
327: . dm - DM to be used with KSP
329: Output Parameters:
330: + func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
331: - ctx - context for right hand side evaluation
333: Level: advanced
335: .seealso: DMKSPSetContext(), KSPSetComputeRHS(), DMKSPSetComputeRHS()
336: @*/
337: PetscErrorCode DMKSPGetComputeRHS(DM dm,PetscErrorCode (**func)(KSP,Vec,void*),void *ctx)
338: {
340: DMKSP kdm;
344: DMGetDMKSP(dm,&kdm);
345: if (func) *func = kdm->ops->computerhs;
346: if (ctx) *(void**)ctx = kdm->rhsctx;
347: return(0);
348: }
350: /*@C
351: DMKSPGetComputeInitialGuess - get KSP initial guess evaluation function
353: Not Collective
355: Input Parameter:
356: . dm - DM to be used with KSP
358: Output Parameters:
359: + func - initial guess evaluation function, see KSPSetComputeInitialGuess() for calling sequence
360: - ctx - context for right hand side evaluation
362: Level: advanced
364: .seealso: DMKSPSetContext(), KSPSetComputeRHS(), DMKSPSetComputeRHS()
365: @*/
366: PetscErrorCode DMKSPGetComputeInitialGuess(DM dm,PetscErrorCode (**func)(KSP,Vec,void*),void *ctx)
367: {
369: DMKSP kdm;
373: DMGetDMKSP(dm,&kdm);
374: if (func) *func = kdm->ops->computeinitialguess;
375: if (ctx) *(void**)ctx = kdm->initialguessctx;
376: return(0);
377: }