Actual source code: dmksp.c

petsc-3.9.0 2018-04-07
Report Typos and Errors
  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: }