Actual source code: dmksp.c

petsc-3.13.6 2020-09-29
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;
 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: }