Date: 2013-07-02T14:47:56+00:00

Actual source code: dmksp.c
petsc-3.4.2 2013-07-02

      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: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
     28:   KSPInitializePackage();
     29: #endif
     30:   PetscHeaderCreate(*kdm, _p_DMKSP, struct _DMKSPOps, DMKSP_CLASSID, "DMKSP", "DMKSP", "DMKSP", comm, DMKSPDestroy, NULL);
     31:   PetscMemzero((*kdm)->ops, sizeof(struct _DMKSPOps));
     32:   return(0);
     33: }

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

     46:   DMCopyDMKSP(dm,dmc);
     47:   return(0);
     48: }

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

     60:   DMCopyDMKSP(dm,dmc);
     61:   return(0);
     62: }

     66: /*@C
     67:    DMKSPCopy - copies the information in a DMKSP to another DMKSP

     69:    Not Collective

     71:    Input Argument:
     72: +  kdm - Original DMKSP
     73: -  nkdm - DMKSP to receive the data, should have been created with DMKSPCreate()

     75:    Level: developer

     77: .seealso: DMKSPCreate(), DMKSPDestroy()
     78: @*/
     79: PetscErrorCode DMKSPCopy(DMKSP kdm,DMKSP nkdm)
     80: {

     86:   nkdm->ops->computeoperators    = kdm->ops->computeoperators;
     87:   nkdm->ops->computerhs          = kdm->ops->computerhs;
     88:   nkdm->ops->computeinitialguess = kdm->ops->computeinitialguess;
     89:   nkdm->ops->destroy             = kdm->ops->destroy;
     90:   nkdm->ops->duplicate           = kdm->ops->duplicate;

     92:   nkdm->operatorsctx    = kdm->operatorsctx;
     93:   nkdm->rhsctx          = kdm->rhsctx;
     94:   nkdm->initialguessctx = kdm->initialguessctx;
     95:   nkdm->data            = kdm->data;

     97:   nkdm->fortran_func_pointers[0] = kdm->fortran_func_pointers[0];
     98:   nkdm->fortran_func_pointers[1] = kdm->fortran_func_pointers[1];
     99:   nkdm->fortran_func_pointers[2] = kdm->fortran_func_pointers[2];

    101:   /* implementation specific copy hooks */
    102:   if (kdm->ops->duplicate) {(*kdm->ops->duplicate)(kdm,nkdm);}
    103:   return(0);
    104: }

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

    111:    Not Collective

    113:    Input Argument:
    114: .  dm - DM to be used with KSP

    116:    Output Argument:
    117: .  snesdm - private DMKSP context

    119:    Level: developer

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

    124: .seealso: DMGetDMKSPWrite()
    125: @*/
    126: PetscErrorCode DMGetDMKSP(DM dm,DMKSP *kspdm)
    127: {

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

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

    148:    Not Collective

    150:    Input Argument:
    151: .  dm - DM to be used with KSP

    153:    Output Argument:
    154: .  kspdm - private DMKSP context

    156:    Level: developer

    158: .seealso: DMGetDMKSP()
    159: @*/
    160: PetscErrorCode DMGetDMKSPWrite(DM dm,DMKSP *kspdm)
    161: {
    163:   DMKSP          kdm;

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

    183: /*@C
    184:    DMCopyDMKSP - copies a DM context to a new DM

    186:    Logically Collective

    188:    Input Arguments:
    189: +  dmsrc - DM to obtain context from
    190: -  dmdest - DM to add context to

    192:    Level: developer

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

    197: .seealso: DMGetDMKSP(), KSPSetDM()
    198: @*/
    199: PetscErrorCode DMCopyDMKSP(DM dmsrc,DM dmdest)
    200: {

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

    216: /*@C
    217:    DMKSPSetComputeOperators - set KSP matrix evaluation function

    219:    Not Collective

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

    226:    Level: advanced

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

    233: .seealso: DMKSPSetContext(), DMKSPGetComputeOperators(), KSPSetOperators()
    234: @*/
    235: PetscErrorCode DMKSPSetComputeOperators(DM dm,PetscErrorCode (*func)(KSP,Mat,Mat,MatStructure*,void*),void *ctx)
    236: {
    238:   DMKSP          kdm;

    242:   DMGetDMKSPWrite(dm,&kdm);
    243:   if (func) kdm->ops->computeoperators = func;
    244:   if (ctx) kdm->operatorsctx = ctx;
    245:   return(0);
    246: }

    250: /*@C
    251:    DMKSPGetComputeOperators - get KSP matrix evaluation function

    253:    Not Collective

    255:    Input Argument:
    256: .  dm - DM to be used with KSP

    258:    Output Arguments:
    259: +  func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
    260: -  ctx - context for matrix evaluation

    262:    Level: advanced

    264: .seealso: DMKSPSetContext(), KSPSetComputeOperators(), DMKSPSetComputeOperators()
    265: @*/
    266: PetscErrorCode DMKSPGetComputeOperators(DM dm,PetscErrorCode (**func)(KSP,Mat,Mat,MatStructure*,void*),void *ctx)
    267: {
    269:   DMKSP          kdm;

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

    281: /*@C
    282:    DMKSPSetComputeRHS - set KSP right hand side evaluation function

    284:    Not Collective

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

    291:    Level: advanced

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

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

    307:   DMGetDMKSPWrite(dm,&kdm);
    308:   if (func) kdm->ops->computerhs = func;
    309:   if (ctx) kdm->rhsctx = ctx;
    310:   return(0);
    311: }

    315: /*@C
    316:    DMKSPSetComputeInitialGuess - set KSP initial guess evaluation function

    318:    Not Collective

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

    325:    Level: advanced

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

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

    340:   DMGetDMKSPWrite(dm,&kdm);
    341:   if (func) kdm->ops->computeinitialguess = func;
    342:   if (ctx) kdm->initialguessctx = ctx;
    343:   return(0);
    344: }

    348: /*@C
    349:    DMKSPGetComputeRHS - get KSP right hand side evaluation function

    351:    Not Collective

    353:    Input Argument:
    354: .  dm - DM to be used with KSP

    356:    Output Arguments:
    357: +  func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
    358: -  ctx - context for right hand side evaluation

    360:    Level: advanced

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

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

    379: /*@C
    380:    DMKSPGetComputeInitialGuess - get KSP initial guess evaluation function

    382:    Not Collective

    384:    Input Argument:
    385: .  dm - DM to be used with KSP

    387:    Output Arguments:
    388: +  func - initial guess evaluation function, see KSPSetComputeInitialGuess() for calling sequence
    389: -  ctx - context for right hand side evaluation

    391:    Level: advanced

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

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