Actual source code: dmksp.c
petsc-3.10.3 2018-12-18
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 = 0; 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: }
29: /* Attaches the DMKSP to the coarse level.
30: * Under what conditions should we copy versus duplicate?
31: */
32: static PetscErrorCode DMCoarsenHook_DMKSP(DM dm,DM dmc,void *ctx)
33: {
37: DMCopyDMKSP(dm,dmc);
38: return(0);
39: }
41: /* Attaches the DMKSP to the coarse level.
42: * Under what conditions should we copy versus duplicate?
43: */
44: static PetscErrorCode DMRefineHook_DMKSP(DM dm,DM dmc,void *ctx)
45: {
49: DMCopyDMKSP(dm,dmc);
50: return(0);
51: }
53: /*@C
54: DMKSPCopy - copies the information in a DMKSP to another DMKSP
56: Not Collective
58: Input Argument:
59: + kdm - Original DMKSP
60: - nkdm - DMKSP to receive the data, should have been created with DMKSPCreate()
62: Level: developer
64: .seealso: DMKSPCreate(), DMKSPDestroy()
65: @*/
66: PetscErrorCode DMKSPCopy(DMKSP kdm,DMKSP nkdm)
67: {
73: nkdm->ops->computeoperators = kdm->ops->computeoperators;
74: nkdm->ops->computerhs = kdm->ops->computerhs;
75: nkdm->ops->computeinitialguess = kdm->ops->computeinitialguess;
76: nkdm->ops->destroy = kdm->ops->destroy;
77: nkdm->ops->duplicate = kdm->ops->duplicate;
79: nkdm->operatorsctx = kdm->operatorsctx;
80: nkdm->rhsctx = kdm->rhsctx;
81: nkdm->initialguessctx = kdm->initialguessctx;
82: nkdm->data = kdm->data;
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: Not Collective
98: Input Argument:
99: . dm - DM to be used with KSP
101: Output Argument:
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: DMCoarsenHookAdd(dm,DMCoarsenHook_DMKSP,NULL,NULL);
123: DMRefineHookAdd(dm,DMRefineHook_DMKSP,NULL,NULL);
124: }
125: return(0);
126: }
128: /*@C
129: DMGetDMKSPWrite - get write access to private DMKSP context from a DM
131: Not Collective
133: Input Argument:
134: . dm - DM to be used with KSP
136: Output Argument:
137: . kspdm - private DMKSP context
139: Level: developer
141: .seealso: DMGetDMKSP()
142: @*/
143: PetscErrorCode DMGetDMKSPWrite(DM dm,DMKSP *kspdm)
144: {
146: DMKSP kdm;
150: DMGetDMKSP(dm,&kdm);
151: if (!kdm->originaldm) kdm->originaldm = dm;
152: if (kdm->originaldm != dm) { /* Copy on write */
153: DMKSP oldkdm = kdm;
154: PetscInfo(dm,"Copying DMKSP due to write\n");
155: DMKSPCreate(PetscObjectComm((PetscObject)dm),&kdm);
156: DMKSPCopy(oldkdm,kdm);
157: DMKSPDestroy((DMKSP*)&dm->dmksp);
158: dm->dmksp = (PetscObject)kdm;
159: }
160: *kspdm = kdm;
161: return(0);
162: }
164: /*@C
165: DMCopyDMKSP - copies a DM context to a new DM
167: Logically Collective
169: Input Arguments:
170: + dmsrc - DM to obtain context from
171: - dmdest - DM to add context to
173: Level: developer
175: Note:
176: The context is copied by reference. This function does not ensure that a context exists.
178: .seealso: DMGetDMKSP(), KSPSetDM()
179: @*/
180: PetscErrorCode DMCopyDMKSP(DM dmsrc,DM dmdest)
181: {
187: DMKSPDestroy((DMKSP*)&dmdest->dmksp);
188: dmdest->dmksp = dmsrc->dmksp;
189: PetscObjectReference(dmdest->dmksp);
190: DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMKSP,NULL,NULL);
191: DMRefineHookAdd(dmdest,DMRefineHook_DMKSP,NULL,NULL);
192: return(0);
193: }
195: /*@C
196: DMKSPSetComputeOperators - set KSP matrix evaluation function
198: Not Collective
200: Input Argument:
201: + dm - DM to be used with KSP
202: . func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
203: - ctx - context for matrix evaluation
205: Level: advanced
207: Note:
208: KSPSetComputeOperators() is normally used, but it calls this function internally because the user context is actually
209: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
210: not. If DM took a more central role at some later date, this could become the primary method of setting the matrix.
212: .seealso: DMKSPSetContext(), DMKSPGetComputeOperators(), KSPSetOperators()
213: @*/
214: PetscErrorCode DMKSPSetComputeOperators(DM dm,PetscErrorCode (*func)(KSP,Mat,Mat,void*),void *ctx)
215: {
217: DMKSP kdm;
221: DMGetDMKSPWrite(dm,&kdm);
222: if (func) kdm->ops->computeoperators = func;
223: if (ctx) kdm->operatorsctx = ctx;
224: return(0);
225: }
227: /*@C
228: DMKSPGetComputeOperators - get KSP matrix evaluation function
230: Not Collective
232: Input Argument:
233: . dm - DM to be used with KSP
235: Output Arguments:
236: + func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
237: - ctx - context for matrix evaluation
239: Level: advanced
241: .seealso: DMKSPSetContext(), KSPSetComputeOperators(), DMKSPSetComputeOperators()
242: @*/
243: PetscErrorCode DMKSPGetComputeOperators(DM dm,PetscErrorCode (**func)(KSP,Mat,Mat,void*),void *ctx)
244: {
246: DMKSP kdm;
250: DMGetDMKSP(dm,&kdm);
251: if (func) *func = kdm->ops->computeoperators;
252: if (ctx) *(void**)ctx = kdm->operatorsctx;
253: return(0);
254: }
256: /*@C
257: DMKSPSetComputeRHS - set KSP right hand side evaluation function
259: Not Collective
261: Input Argument:
262: + dm - DM to be used with KSP
263: . func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
264: - ctx - context for right hand side evaluation
266: Level: advanced
268: Note:
269: KSPSetComputeRHS() is normally used, but it calls this function internally because the user context is actually
270: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
271: not. If DM took a more central role at some later date, this could become the primary method of setting the matrix.
273: .seealso: DMKSPSetContext(), DMKSPGetComputeRHS(), KSPSetRHS()
274: @*/
275: PetscErrorCode DMKSPSetComputeRHS(DM dm,PetscErrorCode (*func)(KSP,Vec,void*),void *ctx)
276: {
278: DMKSP kdm;
282: DMGetDMKSPWrite(dm,&kdm);
283: if (func) kdm->ops->computerhs = func;
284: if (ctx) kdm->rhsctx = ctx;
285: return(0);
286: }
288: /*@C
289: DMKSPSetComputeInitialGuess - set KSP initial guess evaluation function
291: Not Collective
293: Input Argument:
294: + dm - DM to be used with KSP
295: . func - initial guess evaluation function, see KSPSetComputeInitialGuess() for calling sequence
296: - ctx - context for right hand side evaluation
298: Level: advanced
300: Note:
301: KSPSetComputeInitialGuess() is normally used, but it calls this function internally because the user context is actually
302: associated with the DM.
304: .seealso: DMKSPSetContext(), DMKSPGetComputeRHS(), KSPSetRHS()
305: @*/
306: PetscErrorCode DMKSPSetComputeInitialGuess(DM dm,PetscErrorCode (*func)(KSP,Vec,void*),void *ctx)
307: {
309: DMKSP kdm;
313: DMGetDMKSPWrite(dm,&kdm);
314: if (func) kdm->ops->computeinitialguess = func;
315: if (ctx) kdm->initialguessctx = ctx;
316: return(0);
317: }
319: /*@C
320: DMKSPGetComputeRHS - get KSP right hand side evaluation function
322: Not Collective
324: Input Argument:
325: . dm - DM to be used with KSP
327: Output Arguments:
328: + func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
329: - ctx - context for right hand side evaluation
331: Level: advanced
333: .seealso: DMKSPSetContext(), KSPSetComputeRHS(), DMKSPSetComputeRHS()
334: @*/
335: PetscErrorCode DMKSPGetComputeRHS(DM dm,PetscErrorCode (**func)(KSP,Vec,void*),void *ctx)
336: {
338: DMKSP kdm;
342: DMGetDMKSP(dm,&kdm);
343: if (func) *func = kdm->ops->computerhs;
344: if (ctx) *(void**)ctx = kdm->rhsctx;
345: return(0);
346: }
348: /*@C
349: DMKSPGetComputeInitialGuess - get KSP initial guess evaluation function
351: Not Collective
353: Input Argument:
354: . dm - DM to be used with KSP
356: Output Arguments:
357: + func - initial guess evaluation function, see KSPSetComputeInitialGuess() for calling sequence
358: - ctx - context for right hand side evaluation
360: Level: advanced
362: .seealso: DMKSPSetContext(), KSPSetComputeRHS(), DMKSPSetComputeRHS()
363: @*/
364: PetscErrorCode DMKSPGetComputeInitialGuess(DM dm,PetscErrorCode (**func)(KSP,Vec,void*),void *ctx)
365: {
367: DMKSP kdm;
371: DMGetDMKSP(dm,&kdm);
372: if (func) *func = kdm->ops->computeinitialguess;
373: if (ctx) *(void**)ctx = kdm->initialguessctx;
374: return(0);
375: }