Actual source code: dmksp.c
petsc-3.10.5 2019-03-28
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: }