Actual source code: dmksp.c
petsc-3.7.1 2016-05-15
Report Typos and Errors

      1: #include <petsc/private/dmimpl.h>
      2: #include <petsc/private/kspimpl.h> /*I "petscksp.h" I*/
      3: #include <petscdm.h>

      7: static PetscErrorCode DMKSPDestroy(DMKSP *kdm)
      8: {

     12:   if (!*kdm) return(0);
     14:   if (--((PetscObject)(*kdm))->refct > 0) {*kdm = 0; return(0);}
     15:   if ((*kdm)->ops->destroy) {((*kdm)->ops->destroy)(kdm);}
     16:   PetscHeaderDestroy(kdm);
     17:   return(0);
     18: }

     22: static PetscErrorCode DMKSPCreate(MPI_Comm comm,DMKSP *kdm)
     23: {

     27:   KSPInitializePackage();
     28:   PetscHeaderCreate(*kdm, DMKSP_CLASSID, "DMKSP", "DMKSP", "DMKSP", comm, DMKSPDestroy, NULL);
     29:   return(0);
     30: }

     35: /* Attaches the DMKSP to the coarse level.
     36:  * Under what conditions should we copy versus duplicate?
     37:  */
     38: static PetscErrorCode DMCoarsenHook_DMKSP(DM dm,DM dmc,void *ctx)
     39: {

     43:   DMCopyDMKSP(dm,dmc);
     44:   return(0);
     45: }

     49: /* Attaches the DMKSP to the coarse level.
     50:  * Under what conditions should we copy versus duplicate?
     51:  */
     52: static PetscErrorCode DMRefineHook_DMKSP(DM dm,DM dmc,void *ctx)
     53: {

     57:   DMCopyDMKSP(dm,dmc);
     58:   return(0);
     59: }

     63: /*@C
     64:    DMKSPCopy - copies the information in a DMKSP to another DMKSP

     66:    Not Collective

     68:    Input Argument:
     69: +  kdm - Original DMKSP
     70: -  nkdm - DMKSP to receive the data, should have been created with DMKSPCreate()

     72:    Level: developer

     74: .seealso: DMKSPCreate(), DMKSPDestroy()
     75: @*/
     76: PetscErrorCode DMKSPCopy(DMKSP kdm,DMKSP nkdm)
     77: {

     83:   nkdm->ops->computeoperators    = kdm->ops->computeoperators;
     84:   nkdm->ops->computerhs          = kdm->ops->computerhs;
     85:   nkdm->ops->computeinitialguess = kdm->ops->computeinitialguess;
     86:   nkdm->ops->destroy             = kdm->ops->destroy;
     87:   nkdm->ops->duplicate           = kdm->ops->duplicate;

     89:   nkdm->operatorsctx    = kdm->operatorsctx;
     90:   nkdm->rhsctx          = kdm->rhsctx;
     91:   nkdm->initialguessctx = kdm->initialguessctx;
     92:   nkdm->data            = kdm->data;

     94:   nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
     95:   nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
     96:   nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];

     98:   /* implementation specific copy hooks */
     99:   if (kdm->ops->duplicate) {(*kdm->ops->duplicate)(kdm,nkdm);}
    100:   return(0);
    101: }

    105: /*@C
    106:    DMGetDMKSP - get read-only private DMKSP context from a DM

    108:    Not Collective

    110:    Input Argument:
    111: .  dm - DM to be used with KSP

    113:    Output Argument:
    114: .  snesdm - private DMKSP context

    116:    Level: developer

    118:    Notes:
    119:    Use DMGetDMKSPWrite() if write access is needed. The DMKSPSetXXX API should be used wherever possible.

    121: .seealso: DMGetDMKSPWrite()
    122: @*/
    123: PetscErrorCode DMGetDMKSP(DM dm,DMKSP *kspdm)
    124: {

    129:   *kspdm = (DMKSP) dm->dmksp;
    130:   if (!*kspdm) {
    131:     PetscInfo(dm,"Creating new DMKSP\n");
    132:     DMKSPCreate(PetscObjectComm((PetscObject)dm),kspdm);
    133:     dm->dmksp = (PetscObject) *kspdm;
    134:     DMCoarsenHookAdd(dm,DMCoarsenHook_DMKSP,NULL,NULL);
    135:     DMRefineHookAdd(dm,DMRefineHook_DMKSP,NULL,NULL);
    136:   }
    137:   return(0);
    138: }

    142: /*@C
    143:    DMGetDMKSPWrite - get write access to private DMKSP context from a DM

    145:    Not Collective

    147:    Input Argument:
    148: .  dm - DM to be used with KSP

    150:    Output Argument:
    151: .  kspdm - private DMKSP context

    153:    Level: developer

    155: .seealso: DMGetDMKSP()
    156: @*/
    157: PetscErrorCode DMGetDMKSPWrite(DM dm,DMKSP *kspdm)
    158: {
    160:   DMKSP          kdm;

    164:   DMGetDMKSP(dm,&kdm);
    165:   if (!kdm->originaldm) kdm->originaldm = dm;
    166:   if (kdm->originaldm != dm) {  /* Copy on write */
    167:     DMKSP oldkdm = kdm;
    168:     PetscInfo(dm,"Copying DMKSP due to write\n");
    169:     DMKSPCreate(PetscObjectComm((PetscObject)dm),&kdm);
    170:     DMKSPCopy(oldkdm,kdm);
    171:     DMKSPDestroy((DMKSP*)&dm->dmksp);
    172:     dm->dmksp = (PetscObject)kdm;
    173:   }
    174:   *kspdm = kdm;
    175:   return(0);
    176: }

    180: /*@C
    181:    DMCopyDMKSP - copies a DM context to a new DM

    183:    Logically Collective

    185:    Input Arguments:
    186: +  dmsrc - DM to obtain context from
    187: -  dmdest - DM to add context to

    189:    Level: developer

    191:    Note:
    192:    The context is copied by reference. This function does not ensure that a context exists.

    194: .seealso: DMGetDMKSP(), KSPSetDM()
    195: @*/
    196: PetscErrorCode DMCopyDMKSP(DM dmsrc,DM dmdest)
    197: {

    203:   DMKSPDestroy((DMKSP*)&dmdest->dmksp);
    204:   dmdest->dmksp = dmsrc->dmksp;
    205:   PetscObjectReference(dmdest->dmksp);
    206:   DMCoarsenHookAdd(dmdest,DMCoarsenHook_DMKSP,NULL,NULL);
    207:   DMRefineHookAdd(dmdest,DMRefineHook_DMKSP,NULL,NULL);
    208:   return(0);
    209: }

    213: /*@C
    214:    DMKSPSetComputeOperators - set KSP matrix evaluation function

    216:    Not Collective

    218:    Input Argument:
    219: +  dm - DM to be used with KSP
    220: .  func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
    221: -  ctx - context for matrix evaluation

    223:    Level: advanced

    225:    Note:
    226:    KSPSetComputeOperators() is normally used, but it calls this function internally because the user context is actually
    227:    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
    228:    not. If DM took a more central role at some later date, this could become the primary method of setting the matrix.

    230: .seealso: DMKSPSetContext(), DMKSPGetComputeOperators(), KSPSetOperators()
    231: @*/
    232: PetscErrorCode DMKSPSetComputeOperators(DM dm,PetscErrorCode (*func)(KSP,Mat,Mat,void*),void *ctx)
    233: {
    235:   DMKSP          kdm;

    239:   DMGetDMKSPWrite(dm,&kdm);
    240:   if (func) kdm->ops->computeoperators = func;
    241:   if (ctx) kdm->operatorsctx = ctx;
    242:   return(0);
    243: }

    247: /*@C
    248:    DMKSPGetComputeOperators - get KSP matrix evaluation function

    250:    Not Collective

    252:    Input Argument:
    253: .  dm - DM to be used with KSP

    255:    Output Arguments:
    256: +  func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
    257: -  ctx - context for matrix evaluation

    259:    Level: advanced

    261: .seealso: DMKSPSetContext(), KSPSetComputeOperators(), DMKSPSetComputeOperators()
    262: @*/
    263: PetscErrorCode DMKSPGetComputeOperators(DM dm,PetscErrorCode (**func)(KSP,Mat,Mat,void*),void *ctx)
    264: {
    266:   DMKSP          kdm;

    270:   DMGetDMKSP(dm,&kdm);
    271:   if (func) *func = kdm->ops->computeoperators;
    272:   if (ctx) *(void**)ctx = kdm->operatorsctx;
    273:   return(0);
    274: }

    278: /*@C
    279:    DMKSPSetComputeRHS - set KSP right hand side evaluation function

    281:    Not Collective

    283:    Input Argument:
    284: +  dm - DM to be used with KSP
    285: .  func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
    286: -  ctx - context for right hand side evaluation

    288:    Level: advanced

    290:    Note:
    291:    KSPSetComputeRHS() is normally used, but it calls this function internally because the user context is actually
    292:    associated with the DM.  This makes the interface consistent regardless of whether the user interacts with a DM or
    293:    not. If DM took a more central role at some later date, this could become the primary method of setting the matrix.

    295: .seealso: DMKSPSetContext(), DMKSPGetComputeRHS(), KSPSetRHS()
    296: @*/
    297: PetscErrorCode DMKSPSetComputeRHS(DM dm,PetscErrorCode (*func)(KSP,Vec,void*),void *ctx)
    298: {
    300:   DMKSP          kdm;

    304:   DMGetDMKSPWrite(dm,&kdm);
    305:   if (func) kdm->ops->computerhs = func;
    306:   if (ctx) kdm->rhsctx = ctx;
    307:   return(0);
    308: }

    312: /*@C
    313:    DMKSPSetComputeInitialGuess - set KSP initial guess evaluation function

    315:    Not Collective

    317:    Input Argument:
    318: +  dm - DM to be used with KSP
    319: .  func - initial guess evaluation function, see KSPSetComputeInitialGuess() for calling sequence
    320: -  ctx - context for right hand side evaluation

    322:    Level: advanced

    324:    Note:
    325:    KSPSetComputeInitialGuess() is normally used, but it calls this function internally because the user context is actually
    326:    associated with the DM.

    328: .seealso: DMKSPSetContext(), DMKSPGetComputeRHS(), KSPSetRHS()
    329: @*/
    330: PetscErrorCode DMKSPSetComputeInitialGuess(DM dm,PetscErrorCode (*func)(KSP,Vec,void*),void *ctx)
    331: {
    333:   DMKSP          kdm;

    337:   DMGetDMKSPWrite(dm,&kdm);
    338:   if (func) kdm->ops->computeinitialguess = func;
    339:   if (ctx) kdm->initialguessctx = ctx;
    340:   return(0);
    341: }

    345: /*@C
    346:    DMKSPGetComputeRHS - get KSP right hand side evaluation function

    348:    Not Collective

    350:    Input Argument:
    351: .  dm - DM to be used with KSP

    353:    Output Arguments:
    354: +  func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
    355: -  ctx - context for right hand side evaluation

    357:    Level: advanced

    359: .seealso: DMKSPSetContext(), KSPSetComputeRHS(), DMKSPSetComputeRHS()
    360: @*/
    361: PetscErrorCode DMKSPGetComputeRHS(DM dm,PetscErrorCode (**func)(KSP,Vec,void*),void *ctx)
    362: {
    364:   DMKSP          kdm;

    368:   DMGetDMKSP(dm,&kdm);
    369:   if (func) *func = kdm->ops->computerhs;
    370:   if (ctx) *(void**)ctx = kdm->rhsctx;
    371:   return(0);
    372: }

    376: /*@C
    377:    DMKSPGetComputeInitialGuess - get KSP initial guess evaluation function

    379:    Not Collective

    381:    Input Argument:
    382: .  dm - DM to be used with KSP

    384:    Output Arguments:
    385: +  func - initial guess evaluation function, see KSPSetComputeInitialGuess() for calling sequence
    386: -  ctx - context for right hand side evaluation

    388:    Level: advanced

    390: .seealso: DMKSPSetContext(), KSPSetComputeRHS(), DMKSPSetComputeRHS()
    391: @*/
    392: PetscErrorCode DMKSPGetComputeInitialGuess(DM dm,PetscErrorCode (**func)(KSP,Vec,void*),void *ctx)
    393: {
    395:   DMKSP          kdm;

    399:   DMGetDMKSP(dm,&kdm);
    400:   if (func) *func = kdm->ops->computeinitialguess;
    401:   if (ctx) *(void**)ctx = kdm->initialguessctx;
    402:   return(0);
    403: }