Actual source code: dmksp.c
petsc-3.13.6 2020-09-29
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;
83: /* nkdm->originaldm = kdm->originaldm; */ /* No need since nkdm->originaldm will be immediately updated in caller DMGetDMKSPWrite */
85: nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
86: nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
87: nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];
89: /* implementation specific copy hooks */
90: if (kdm->ops->duplicate) {(*kdm->ops->duplicate)(kdm,nkdm);}
91: return(0);
92: }
94: /*@C
95: DMGetDMKSP - get read-only private DMKSP context from a DM
97: Logically Collective
99: Input Argument:
100: . dm - DM to be used with KSP
102: Output Argument:
103: . snesdm - private DMKSP context
105: Level: developer
107: Notes:
108: Use DMGetDMKSPWrite() if write access is needed. The DMKSPSetXXX API should be used wherever possible.
110: .seealso: DMGetDMKSPWrite()
111: @*/
112: PetscErrorCode DMGetDMKSP(DM dm,DMKSP *kspdm)
113: {
118: *kspdm = (DMKSP) dm->dmksp;
119: if (!*kspdm) {
120: PetscInfo(dm,"Creating new DMKSP\n");
121: DMKSPCreate(PetscObjectComm((PetscObject)dm),kspdm);
122: dm->dmksp = (PetscObject) *kspdm;
123: (*kspdm)->originaldm = dm;
124: DMCoarsenHookAdd(dm,DMCoarsenHook_DMKSP,NULL,NULL);
125: DMRefineHookAdd(dm,DMRefineHook_DMKSP,NULL,NULL);
126: }
127: return(0);
128: }
130: /*@C
131: DMGetDMKSPWrite - get write access to private DMKSP context from a DM
133: Logically Collective
135: Input Argument:
136: . dm - DM to be used with KSP
138: Output Argument:
139: . kspdm - private DMKSP context
141: Level: developer
143: .seealso: DMGetDMKSP()
144: @*/
145: PetscErrorCode DMGetDMKSPWrite(DM dm,DMKSP *kspdm)
146: {
148: DMKSP kdm;
152: DMGetDMKSP(dm,&kdm);
153: if (!kdm->originaldm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DMKSP has a NULL originaldm");
154: if (kdm->originaldm != dm) { /* Copy on write */
155: DMKSP oldkdm = kdm;
156: PetscInfo(dm,"Copying DMKSP due to write\n");
157: DMKSPCreate(PetscObjectComm((PetscObject)dm),&kdm);
158: DMKSPCopy(oldkdm,kdm);
159: DMKSPDestroy((DMKSP*)&dm->dmksp);
160: dm->dmksp = (PetscObject)kdm;
161: kdm->originaldm = dm;
162: }
163: *kspdm = kdm;
164: return(0);
165: }
167: /*@C
168: DMCopyDMKSP - copies a DM context to a new DM
170: Logically Collective
172: Input Arguments:
173: + dmsrc - DM to obtain context from
174: - dmdest - DM to add context to
176: Level: developer
178: Note:
179: The context is copied by reference. This function does not ensure that a context exists.
181: .seealso: DMGetDMKSP(), KSPSetDM()
182: @*/
183: PetscErrorCode DMCopyDMKSP(DM dmsrc,DM dmdest)
184: {
190: DMKSPDestroy((DMKSP*)&dmdest->dmksp);
191: dmdest->dmksp = dmsrc->dmksp;
192: PetscObjectReference(dmdest->dmksp);
193: DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMKSP,NULL,NULL);
194: DMRefineHookAdd(dmdest,DMRefineHook_DMKSP,NULL,NULL);
195: return(0);
196: }
198: /*@C
199: DMKSPSetComputeOperators - set KSP matrix evaluation function
201: Not Collective
203: Input Argument:
204: + dm - DM to be used with KSP
205: . func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
206: - ctx - context for matrix evaluation
208: Level: advanced
210: Note:
211: KSPSetComputeOperators() is normally used, but it calls this function internally because the user context is actually
212: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
213: not. If DM took a more central role at some later date, this could become the primary method of setting the matrix.
215: .seealso: DMKSPSetContext(), DMKSPGetComputeOperators(), KSPSetOperators()
216: @*/
217: PetscErrorCode DMKSPSetComputeOperators(DM dm,PetscErrorCode (*func)(KSP,Mat,Mat,void*),void *ctx)
218: {
220: DMKSP kdm;
224: DMGetDMKSPWrite(dm,&kdm);
225: if (func) kdm->ops->computeoperators = func;
226: if (ctx) kdm->operatorsctx = ctx;
227: return(0);
228: }
230: /*@C
231: DMKSPGetComputeOperators - get KSP matrix evaluation function
233: Not Collective
235: Input Argument:
236: . dm - DM to be used with KSP
238: Output Arguments:
239: + func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
240: - ctx - context for matrix evaluation
242: Level: advanced
244: .seealso: DMKSPSetContext(), KSPSetComputeOperators(), DMKSPSetComputeOperators()
245: @*/
246: PetscErrorCode DMKSPGetComputeOperators(DM dm,PetscErrorCode (**func)(KSP,Mat,Mat,void*),void *ctx)
247: {
249: DMKSP kdm;
253: DMGetDMKSP(dm,&kdm);
254: if (func) *func = kdm->ops->computeoperators;
255: if (ctx) *(void**)ctx = kdm->operatorsctx;
256: return(0);
257: }
259: /*@C
260: DMKSPSetComputeRHS - set KSP right hand side evaluation function
262: Not Collective
264: Input Argument:
265: + dm - DM to be used with KSP
266: . func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
267: - ctx - context for right hand side evaluation
269: Level: advanced
271: Note:
272: KSPSetComputeRHS() is normally used, but it calls this function internally because the user context is actually
273: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
274: not. If DM took a more central role at some later date, this could become the primary method of setting the matrix.
276: .seealso: DMKSPSetContext(), DMKSPGetComputeRHS(), KSPSetRHS()
277: @*/
278: PetscErrorCode DMKSPSetComputeRHS(DM dm,PetscErrorCode (*func)(KSP,Vec,void*),void *ctx)
279: {
281: DMKSP kdm;
285: DMGetDMKSPWrite(dm,&kdm);
286: if (func) kdm->ops->computerhs = func;
287: if (ctx) kdm->rhsctx = ctx;
288: return(0);
289: }
291: /*@C
292: DMKSPSetComputeInitialGuess - set KSP initial guess evaluation function
294: Not Collective
296: Input Argument:
297: + dm - DM to be used with KSP
298: . func - initial guess evaluation function, see KSPSetComputeInitialGuess() for calling sequence
299: - ctx - context for right hand side evaluation
301: Level: advanced
303: Note:
304: KSPSetComputeInitialGuess() is normally used, but it calls this function internally because the user context is actually
305: associated with the DM.
307: .seealso: DMKSPSetContext(), DMKSPGetComputeRHS(), KSPSetRHS()
308: @*/
309: PetscErrorCode DMKSPSetComputeInitialGuess(DM dm,PetscErrorCode (*func)(KSP,Vec,void*),void *ctx)
310: {
312: DMKSP kdm;
316: DMGetDMKSPWrite(dm,&kdm);
317: if (func) kdm->ops->computeinitialguess = func;
318: if (ctx) kdm->initialguessctx = ctx;
319: return(0);
320: }
322: /*@C
323: DMKSPGetComputeRHS - get KSP right hand side evaluation function
325: Not Collective
327: Input Argument:
328: . dm - DM to be used with KSP
330: Output Arguments:
331: + func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
332: - ctx - context for right hand side evaluation
334: Level: advanced
336: .seealso: DMKSPSetContext(), KSPSetComputeRHS(), DMKSPSetComputeRHS()
337: @*/
338: PetscErrorCode DMKSPGetComputeRHS(DM dm,PetscErrorCode (**func)(KSP,Vec,void*),void *ctx)
339: {
341: DMKSP kdm;
345: DMGetDMKSP(dm,&kdm);
346: if (func) *func = kdm->ops->computerhs;
347: if (ctx) *(void**)ctx = kdm->rhsctx;
348: return(0);
349: }
351: /*@C
352: DMKSPGetComputeInitialGuess - get KSP initial guess evaluation function
354: Not Collective
356: Input Argument:
357: . dm - DM to be used with KSP
359: Output Arguments:
360: + func - initial guess evaluation function, see KSPSetComputeInitialGuess() for calling sequence
361: - ctx - context for right hand side evaluation
363: Level: advanced
365: .seealso: DMKSPSetContext(), KSPSetComputeRHS(), DMKSPSetComputeRHS()
366: @*/
367: PetscErrorCode DMKSPGetComputeInitialGuess(DM dm,PetscErrorCode (**func)(KSP,Vec,void*),void *ctx)
368: {
370: DMKSP kdm;
374: DMGetDMKSP(dm,&kdm);
375: if (func) *func = kdm->ops->computeinitialguess;
376: if (ctx) *(void**)ctx = kdm->initialguessctx;
377: return(0);
378: }