Actual source code: dmksp.c
petsc-3.4.5 2014-06-29
1: #include <petsc-private/dmimpl.h>
2: #include <petsc-private/kspimpl.h> /*I "petscksp.h" I*/
3: #include <petscdm.h>
7: static PetscErrorCode DMKSPDestroy(DMKSP *kdm)
8: {
12: if (!*kdm) return(0);
14: if (--((PetscObject)(*kdm))->refct > 0) {*kdm = 0; return(0);}
15: if ((*kdm)->ops->destroy) {((*kdm)->ops->destroy)(kdm);}
16: PetscHeaderDestroy(kdm);
17: return(0);
18: }
22: static PetscErrorCode DMKSPCreate(MPI_Comm comm,DMKSP *kdm)
23: {
27: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
28: KSPInitializePackage();
29: #endif
30: PetscHeaderCreate(*kdm, _p_DMKSP, struct _DMKSPOps, DMKSP_CLASSID, "DMKSP", "DMKSP", "DMKSP", comm, DMKSPDestroy, NULL);
31: PetscMemzero((*kdm)->ops, sizeof(struct _DMKSPOps));
32: return(0);
33: }
38: /* Attaches the DMKSP to the coarse level.
39: * Under what conditions should we copy versus duplicate?
40: */
41: static PetscErrorCode DMCoarsenHook_DMKSP(DM dm,DM dmc,void *ctx)
42: {
46: DMCopyDMKSP(dm,dmc);
47: return(0);
48: }
52: /* Attaches the DMKSP to the coarse level.
53: * Under what conditions should we copy versus duplicate?
54: */
55: static PetscErrorCode DMRefineHook_DMKSP(DM dm,DM dmc,void *ctx)
56: {
60: DMCopyDMKSP(dm,dmc);
61: return(0);
62: }
66: /*@C
67: DMKSPCopy - copies the information in a DMKSP to another DMKSP
69: Not Collective
71: Input Argument:
72: + kdm - Original DMKSP
73: - nkdm - DMKSP to receive the data, should have been created with DMKSPCreate()
75: Level: developer
77: .seealso: DMKSPCreate(), DMKSPDestroy()
78: @*/
79: PetscErrorCode DMKSPCopy(DMKSP kdm,DMKSP nkdm)
80: {
86: nkdm->ops->computeoperators = kdm->ops->computeoperators;
87: nkdm->ops->computerhs = kdm->ops->computerhs;
88: nkdm->ops->computeinitialguess = kdm->ops->computeinitialguess;
89: nkdm->ops->destroy = kdm->ops->destroy;
90: nkdm->ops->duplicate = kdm->ops->duplicate;
92: nkdm->operatorsctx = kdm->operatorsctx;
93: nkdm->rhsctx = kdm->rhsctx;
94: nkdm->initialguessctx = kdm->initialguessctx;
95: nkdm->data = kdm->data;
97: nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
98: nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
99: nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];
101: /* implementation specific copy hooks */
102: if (kdm->ops->duplicate) {(*kdm->ops->duplicate)(kdm,nkdm);}
103: return(0);
104: }
108: /*@C
109: DMGetDMKSP - get read-only private DMKSP context from a DM
111: Not Collective
113: Input Argument:
114: . dm - DM to be used with KSP
116: Output Argument:
117: . snesdm - private DMKSP context
119: Level: developer
121: Notes:
122: Use DMGetDMKSPWrite() if write access is needed. The DMKSPSetXXX API should be used wherever possible.
124: .seealso: DMGetDMKSPWrite()
125: @*/
126: PetscErrorCode DMGetDMKSP(DM dm,DMKSP *kspdm)
127: {
132: *kspdm = (DMKSP) dm->dmksp;
133: if (!*kspdm) {
134: PetscInfo(dm,"Creating new DMKSP\n");
135: DMKSPCreate(PetscObjectComm((PetscObject)dm),kspdm);
136: dm->dmksp = (PetscObject) *kspdm;
137: DMCoarsenHookAdd(dm,DMCoarsenHook_DMKSP,NULL,NULL);
138: DMRefineHookAdd(dm,DMRefineHook_DMKSP,NULL,NULL);
139: }
140: return(0);
141: }
145: /*@C
146: DMGetDMKSPWrite - get write access to private DMKSP context from a DM
148: Not Collective
150: Input Argument:
151: . dm - DM to be used with KSP
153: Output Argument:
154: . kspdm - private DMKSP context
156: Level: developer
158: .seealso: DMGetDMKSP()
159: @*/
160: PetscErrorCode DMGetDMKSPWrite(DM dm,DMKSP *kspdm)
161: {
163: DMKSP kdm;
167: DMGetDMKSP(dm,&kdm);
168: if (!kdm->originaldm) kdm->originaldm = dm;
169: if (kdm->originaldm != dm) { /* Copy on write */
170: DMKSP oldkdm = kdm;
171: PetscInfo(dm,"Copying DMKSP due to write\n");
172: DMKSPCreate(PetscObjectComm((PetscObject)dm),&kdm);
173: DMKSPCopy(oldkdm,kdm);
174: DMKSPDestroy((DMKSP*)&dm->dmksp);
175: dm->dmksp = (PetscObject)kdm;
176: }
177: *kspdm = kdm;
178: return(0);
179: }
183: /*@C
184: DMCopyDMKSP - copies a DM context to a new DM
186: Logically Collective
188: Input Arguments:
189: + dmsrc - DM to obtain context from
190: - dmdest - DM to add context to
192: Level: developer
194: Note:
195: The context is copied by reference. This function does not ensure that a context exists.
197: .seealso: DMGetDMKSP(), KSPSetDM()
198: @*/
199: PetscErrorCode DMCopyDMKSP(DM dmsrc,DM dmdest)
200: {
206: DMKSPDestroy((DMKSP*)&dmdest->dmksp);
207: dmdest->dmksp = dmsrc->dmksp;
208: PetscObjectReference(dmdest->dmksp);
209: DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMKSP,NULL,NULL);
210: DMRefineHookAdd(dmdest,DMRefineHook_DMKSP,NULL,NULL);
211: return(0);
212: }
216: /*@C
217: DMKSPSetComputeOperators - set KSP matrix evaluation function
219: Not Collective
221: Input Argument:
222: + dm - DM to be used with KSP
223: . func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
224: - ctx - context for matrix evaluation
226: Level: advanced
228: Note:
229: KSPSetComputeOperators() is normally used, but it calls this function internally because the user context is actually
230: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
231: not. If DM took a more central role at some later date, this could become the primary method of setting the matrix.
233: .seealso: DMKSPSetContext(), DMKSPGetComputeOperators(), KSPSetOperators()
234: @*/
235: PetscErrorCode DMKSPSetComputeOperators(DM dm,PetscErrorCode (*func)(KSP,Mat,Mat,MatStructure*,void*),void *ctx)
236: {
238: DMKSP kdm;
242: DMGetDMKSPWrite(dm,&kdm);
243: if (func) kdm->ops->computeoperators = func;
244: if (ctx) kdm->operatorsctx = ctx;
245: return(0);
246: }
250: /*@C
251: DMKSPGetComputeOperators - get KSP matrix evaluation function
253: Not Collective
255: Input Argument:
256: . dm - DM to be used with KSP
258: Output Arguments:
259: + func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
260: - ctx - context for matrix evaluation
262: Level: advanced
264: .seealso: DMKSPSetContext(), KSPSetComputeOperators(), DMKSPSetComputeOperators()
265: @*/
266: PetscErrorCode DMKSPGetComputeOperators(DM dm,PetscErrorCode (**func)(KSP,Mat,Mat,MatStructure*,void*),void *ctx)
267: {
269: DMKSP kdm;
273: DMGetDMKSP(dm,&kdm);
274: if (func) *func = kdm->ops->computeoperators;
275: if (ctx) *(void**)ctx = kdm->operatorsctx;
276: return(0);
277: }
281: /*@C
282: DMKSPSetComputeRHS - set KSP right hand side evaluation function
284: Not Collective
286: Input Argument:
287: + dm - DM to be used with KSP
288: . func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
289: - ctx - context for right hand side evaluation
291: Level: advanced
293: Note:
294: KSPSetComputeRHS() is normally used, but it calls this function internally because the user context is actually
295: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
296: not. If DM took a more central role at some later date, this could become the primary method of setting the matrix.
298: .seealso: DMKSPSetContext(), DMKSPGetComputeRHS(), KSPSetRHS()
299: @*/
300: PetscErrorCode DMKSPSetComputeRHS(DM dm,PetscErrorCode (*func)(KSP,Vec,void*),void *ctx)
301: {
303: DMKSP kdm;
307: DMGetDMKSPWrite(dm,&kdm);
308: if (func) kdm->ops->computerhs = func;
309: if (ctx) kdm->rhsctx = ctx;
310: return(0);
311: }
315: /*@C
316: DMKSPSetComputeInitialGuess - set KSP initial guess evaluation function
318: Not Collective
320: Input Argument:
321: + dm - DM to be used with KSP
322: . func - initial guess evaluation function, see KSPSetComputeInitialGuess() for calling sequence
323: - ctx - context for right hand side evaluation
325: Level: advanced
327: Note:
328: KSPSetComputeInitialGuess() is normally used, but it calls this function internally because the user context is actually
329: associated with the DM.
331: .seealso: DMKSPSetContext(), DMKSPGetComputeRHS(), KSPSetRHS()
332: @*/
333: PetscErrorCode DMKSPSetComputeInitialGuess(DM dm,PetscErrorCode (*func)(KSP,Vec,void*),void *ctx)
334: {
336: DMKSP kdm;
340: DMGetDMKSPWrite(dm,&kdm);
341: if (func) kdm->ops->computeinitialguess = func;
342: if (ctx) kdm->initialguessctx = ctx;
343: return(0);
344: }
348: /*@C
349: DMKSPGetComputeRHS - get KSP right hand side evaluation function
351: Not Collective
353: Input Argument:
354: . dm - DM to be used with KSP
356: Output Arguments:
357: + func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
358: - ctx - context for right hand side evaluation
360: Level: advanced
362: .seealso: DMKSPSetContext(), KSPSetComputeRHS(), DMKSPSetComputeRHS()
363: @*/
364: PetscErrorCode DMKSPGetComputeRHS(DM dm,PetscErrorCode (**func)(KSP,Vec,void*),void *ctx)
365: {
367: DMKSP kdm;
371: DMGetDMKSP(dm,&kdm);
372: if (func) *func = kdm->ops->computerhs;
373: if (ctx) *(void**)ctx = kdm->rhsctx;
374: return(0);
375: }
379: /*@C
380: DMKSPGetComputeInitialGuess - get KSP initial guess evaluation function
382: Not Collective
384: Input Argument:
385: . dm - DM to be used with KSP
387: Output Arguments:
388: + func - initial guess evaluation function, see KSPSetComputeInitialGuess() for calling sequence
389: - ctx - context for right hand side evaluation
391: Level: advanced
393: .seealso: DMKSPSetContext(), KSPSetComputeRHS(), DMKSPSetComputeRHS()
394: @*/
395: PetscErrorCode DMKSPGetComputeInitialGuess(DM dm,PetscErrorCode (**func)(KSP,Vec,void*),void *ctx)
396: {
398: DMKSP kdm;
402: DMGetDMKSP(dm,&kdm);
403: if (func) *func = kdm->ops->computeinitialguess;
404: if (ctx) *(void**)ctx = kdm->initialguessctx;
405: return(0);
406: }