Actual source code: petscda.h

  1: /* $Id: petscda.h,v 1.77 2001/09/11 16:34:35 bsmith Exp $ */

  3: /*
  4:       Regular array object, for easy parallelism of simple grid 
  5:    problems on regular distributed arrays.
  6: */
 9:  #include petscvec.h
 10:  #include petscao.h
 11: PETSC_EXTERN_CXX_BEGIN

 13: /*S
 14:      DA - Abstract PETSc object that manages distributed field data for a single structured grid

 16:    Level: beginner

 18:   Concepts: distributed array

 20: .seealso:  DACreate1d(), DACreate2d(), DACreate3d(), DADestroy(), VecScatter
 21: S*/
 22: typedef struct _p_DA* DA;

 24: /*E
 25:     DAStencilType - Determines if the stencil extends only along the coordinate directions, or also
 26:       to the northeast, northwest etc

 28:    Level: beginner

 30: .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DA
 31: E*/
 32: typedef enum { DA_STENCIL_STAR,DA_STENCIL_BOX } DAStencilType;

 34: /*E
 35:     DAPeriodicType - Is the domain periodic in one or more directions

 37:    Level: beginner

 39: .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DA
 40: E*/
 41: typedef enum { DA_NONPERIODIC,DA_XPERIODIC,DA_YPERIODIC,DA_XYPERIODIC,
 42:                DA_XYZPERIODIC,DA_XZPERIODIC,DA_YZPERIODIC,DA_ZPERIODIC}
 43:                DAPeriodicType;

 45: /*E
 46:     DAInterpolationType - Defines the type of interpolation that will be returned by 
 47:        DAGetInterpolation.

 49:    Level: beginner

 51: .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DA, DAGetInterpolation(), DASetInterpolationType()
 52: E*/
 53: typedef enum { DA_Q0, DA_Q1 } DAInterpolationType;

 55: EXTERN int DASetInterpolationType(DA,DAInterpolationType);

 57: #define DAXPeriodic(pt) ((pt)==DA_XPERIODIC||(pt)==DA_XYPERIODIC||(pt)==DA_XZPERIODIC||(pt)==DA_XYZPERIODIC)
 58: #define DAYPeriodic(pt) ((pt)==DA_YPERIODIC||(pt)==DA_XYPERIODIC||(pt)==DA_YZPERIODIC||(pt)==DA_XYZPERIODIC)
 59: #define DAZPeriodic(pt) ((pt)==DA_ZPERIODIC||(pt)==DA_XZPERIODIC||(pt)==DA_YZPERIODIC||(pt)==DA_XYZPERIODIC)

 61: typedef enum { DA_X,DA_Y,DA_Z } DADirection;

 63: extern int DA_COOKIE;

 65: /* Logging support; why is this done this way? Should be changed to the pattern used by other objects */
 66: enum {DA_GlobalToLocal, DA_LocalToGlobal, DA_LocalADFunction,DA_MAX_EVENTS};
 67: extern int DAEvents[DA_MAX_EVENTS];
 68: #define DALogEventBegin(e,o1,o2,o3,o4) PetscLogEventBegin(DAEvents[e],o1,o2,o3,o4)
 69: #define DALogEventEnd(e,o1,o2,o3,o4)   PetscLogEventEnd(DAEvents[e],o1,o2,o3,o4)

 71: EXTERN int   DACreate1d(MPI_Comm,DAPeriodicType,int,int,int,int*,DA *);
 72: EXTERN int   DACreate2d(MPI_Comm,DAPeriodicType,DAStencilType,int,int,int,int,int,int,int*,int*,DA *);
 73: EXTERN int   DACreate3d(MPI_Comm,DAPeriodicType,DAStencilType,int,int,int,int,int,int,int,int,int *,int *,int *,DA *);
 74: EXTERN int   DADestroy(DA);
 75: EXTERN int   DAView(DA,PetscViewer);

 77: EXTERN int   DAPrintHelp(DA);

 79: EXTERN int   DAGlobalToLocalBegin(DA,Vec,InsertMode,Vec);
 80: EXTERN int   DAGlobalToLocalEnd(DA,Vec,InsertMode,Vec);
 81: EXTERN int   DAGlobalToNaturalBegin(DA,Vec,InsertMode,Vec);
 82: EXTERN int   DAGlobalToNaturalEnd(DA,Vec,InsertMode,Vec);
 83: EXTERN int   DANaturalToGlobalBegin(DA,Vec,InsertMode,Vec);
 84: EXTERN int   DANaturalToGlobalEnd(DA,Vec,InsertMode,Vec);
 85: EXTERN int   DALocalToLocalBegin(DA,Vec,InsertMode,Vec);
 86: EXTERN int   DALocalToLocalEnd(DA,Vec,InsertMode,Vec);
 87: EXTERN int   DALocalToGlobal(DA,Vec,InsertMode,Vec);
 88: EXTERN int   DALocalToGlobalBegin(DA,Vec,Vec);
 89: EXTERN int   DALocalToGlobalEnd(DA,Vec,Vec);
 90: EXTERN int   DAGetOwnershipRange(DA,int **,int **,int **);
 91: EXTERN int   DACreateGlobalVector(DA,Vec *);
 92: EXTERN int   DACreateNaturalVector(DA,Vec *);
 93: EXTERN int   DACreateLocalVector(DA,Vec *);
 94: EXTERN int   DAGetLocalVector(DA,Vec *);
 95: EXTERN int   DARestoreLocalVector(DA,Vec *);
 96: EXTERN int   DAGetGlobalVector(DA,Vec *);
 97: EXTERN int   DARestoreGlobalVector(DA,Vec *);
 98: EXTERN int   DALoad(PetscViewer,int,int,int,DA *);
 99: EXTERN int   DAGetCorners(DA,int*,int*,int*,int*,int*,int*);
100: EXTERN int   DAGetGhostCorners(DA,int*,int*,int*,int*,int*,int*);
101: EXTERN int   DAGetInfo(DA,int*,int*,int*,int*,int*,int*,int*,int*,int*,DAPeriodicType*,DAStencilType*);
102: EXTERN int   DAGetProcessorSubset(DA,DADirection,int,MPI_Comm*);
103: EXTERN int   DARefine(DA,MPI_Comm,DA*);

105: EXTERN int   DAGlobalToNaturalAllCreate(DA,VecScatter*);
106: EXTERN int   DANaturalAllToGlobalCreate(DA,VecScatter*);

108: EXTERN int   DAGetGlobalIndices(DA,int*,int**);
109: EXTERN int   DAGetISLocalToGlobalMapping(DA,ISLocalToGlobalMapping*);
110: EXTERN int   DAGetISLocalToGlobalMappingBlck(DA,ISLocalToGlobalMapping*);

112: EXTERN int   DAGetScatter(DA,VecScatter*,VecScatter*,VecScatter*);

114: EXTERN int   DAGetAO(DA,AO*);
115: EXTERN int   DASetCoordinates(DA,Vec);
116: EXTERN int   DAGetCoordinates(DA,Vec *);
117: EXTERN int   DASetUniformCoordinates(DA,PetscReal,PetscReal,PetscReal,PetscReal,PetscReal,PetscReal);
118: EXTERN int   DASetFieldName(DA,int,const char[]);
119: EXTERN int   DAGetFieldName(DA,int,char **);

121: EXTERN int   DAVecGetArray(DA,Vec,void *);
122: EXTERN int   DAVecRestoreArray(DA,Vec,void *);

124: EXTERN int   DASplitComm2d(MPI_Comm,int,int,int,MPI_Comm*);

126: /*S
127:      SDA - This provides a simplified interface to the DA distributed
128:            array object in PETSc. This is intended for people who are
129:            NOT using PETSc vectors or objects but just want to distribute
130:            simple rectangular arrays amoung a number of procesors and have
131:            PETSc handle moving the ghost-values when needed.

133:           In certain applications this can serve as a replacement for 
134:           BlockComm (which is apparently being phased out?).


137:    Level: beginner

139:   Concepts: simplified distributed array

141: .seealso:  SDACreate1d(), SDACreate2d(), SDACreate3d(), SDADestroy(), DA, SDALocalToLocalBegin(),
142:            SDALocalToLocalEnd(), SDAGetCorners(), SDAGetGhostCorners()
143: S*/
144: typedef struct _SDA* SDA;

146: EXTERN int   SDACreate3d(MPI_Comm,DAPeriodicType,DAStencilType,int,int,int,int,int,int,int,int,int *,int *,int *,SDA *);
147: EXTERN int   SDACreate2d(MPI_Comm,DAPeriodicType,DAStencilType,int,int,int,int,int,int,int *,int *,SDA *);
148: EXTERN int   SDACreate1d(MPI_Comm,DAPeriodicType,int,int,int,int*,SDA *);
149: EXTERN int   SDADestroy(SDA);
150: EXTERN int   SDALocalToLocalBegin(SDA,PetscScalar*,InsertMode,PetscScalar*);
151: EXTERN int   SDALocalToLocalEnd(SDA,PetscScalar*,InsertMode,PetscScalar*);
152: EXTERN int   SDAGetCorners(SDA,int*,int*,int*,int*,int*,int*);
153: EXTERN int   SDAGetGhostCorners(SDA,int*,int*,int*,int*,int*,int*);

155: EXTERN int   MatRegisterDAAD(void);
156: EXTERN int   MatCreateDAAD(DA,Mat*);

158: /*S
159:      DALocalInfo - C struct that contains information about a structured grid and a processors logical
160:               location in it.

162:    Level: beginner

164:   Concepts: distributed array

166: .seealso:  DACreate1d(), DACreate2d(), DACreate3d(), DADestroy(), DA, DAGetLocalInfo(), DAGetInfo()
167: S*/
168: typedef struct {
169:   int            dim,dof,sw;
170:   DAPeriodicType pt;
171:   DAStencilType  st;
172:   int            mx,my,mz;    /* global number of grid points in each direction */
173:   int            xs,ys,zs;    /* starting point of this processor, excluding ghosts */
174:   int            xm,ym,zm;    /* number of grid points on this processor, excluding ghosts */
175:   int            gxs,gys,gzs;    /* starting point of this processor including ghosts */
176:   int            gxm,gym,gzm;    /* number of grid points on this processor including ghosts */
177:   DA             da;
178: } DALocalInfo;

180: #define DAForEachPointBegin2d(info,i,j) {\
181:   int _xints = info->xs,_xinte = info->xs+info->xm,_yints = info->ys,_yinte = info->ys+info->ym;\
182:   for (j=_yints; j<_yinte; j++) {\
183:     for (i=_xints; i<_xinte; i++) {\

185: #define DAForEachPointEnd2d }}}

187: 

189: EXTERN int DAGetLocalInfo(DA,DALocalInfo*);
190: typedef int (*DALocalFunction1)(DALocalInfo*,void*,void*,void*);
191: EXTERN int DAFormFunction1(DA,Vec,Vec,void*);
192: EXTERN int DAFormFunctioni1(DA,int,Vec,PetscScalar*,void*);
193: EXTERN int DAComputeJacobian1WithAdic(DA,Vec,Mat,void*);
194: EXTERN int DAComputeJacobian1WithAdifor(DA,Vec,Mat,void*);
195: EXTERN int DAMultiplyByJacobian1WithAdic(DA,Vec,Vec,Vec,void*);
196: EXTERN int DAMultiplyByJacobian1WithAdifor(DA,Vec,Vec,Vec,void*);
197: EXTERN int DAMultiplyByJacobian1WithAD(DA,Vec,Vec,Vec,void*);
198: EXTERN int DAComputeJacobian1(DA,Vec,Mat,void*);
199: EXTERN int DAGetLocalFunction(DA,DALocalFunction1*);
200: EXTERN int DASetLocalFunction(DA,DALocalFunction1);
201: EXTERN int DASetLocalFunctioni(DA,int (*)(DALocalInfo*,MatStencil*,void*,PetscScalar*,void*));
202: EXTERN int DASetLocalJacobian(DA,DALocalFunction1);
203: EXTERN int DASetLocalAdicFunction_Private(DA,DALocalFunction1);

205: /*MC
206:        DASetLocalAdicFunction - Caches in a DA a local function computed by ADIC/ADIFOR

208:    Collective on DA

210:    Synopsis:
211:    int int DASetLocalAdicFunction(DA da,DALocalFunction1 ad_lf)
212:    
213:    Input Parameter:
214: +  da - initial distributed array
215: -  ad_lf - the local function as computed by ADIC/ADIFOR

217:    Level: intermediate

219: .keywords:  distributed array, refine

221: .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DADestroy(), DAGetLocalFunction(), DASetLocalFunction(),
222:           DASetLocalJacobian()
223: M*/
224: #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
225: #  define DASetLocalAdicFunction(a,d) DASetLocalAdicFunction_Private(a,(DALocalFunction1)d)
226: #else
227: #  define DASetLocalAdicFunction(a,d) DASetLocalAdicFunction_Private(a,0)
228: #endif

230: EXTERN int DASetLocalAdicMFFunction_Private(DA,DALocalFunction1);
231: #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
232: #  define DASetLocalAdicMFFunction(a,d) DASetLocalAdicMFFunction_Private(a,(DALocalFunction1)d)
233: #else
234: #  define DASetLocalAdicMFFunction(a,d) DASetLocalAdicMFFunction_Private(a,0)
235: #endif
236: EXTERN int DASetLocalAdicFunctioni_Private(DA,int (*)(DALocalInfo*,MatStencil*,void*,void*,void*));
237: #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
238: #  define DASetLocalAdicFunctioni(a,d) DASetLocalAdicFunctioni_Private(a,(int (*)(DALocalInfo*,MatStencil*,void*,void*,void*))d)
239: #else
240: #  define DASetLocalAdicFunctioni(a,d) DASetLocalAdicFunctioni_Private(a,0)
241: #endif
242: EXTERN int DASetLocalAdicMFFunctioni_Private(DA,int (*)(DALocalInfo*,MatStencil*,void*,void*,void*));
243: #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
244: #  define DASetLocalAdicMFFunctioni(a,d) DASetLocalAdicMFFunctioni_Private(a,(int (*)(DALocalInfo*,MatStencil*,void*,void*,void*))d)
245: #else
246: #  define DASetLocalAdicMFFunctioni(a,d) DASetLocalAdicMFFunctioni_Private(a,0)
247: #endif
248: EXTERN int DAFormFunctioniTest1(DA,void*);


251:  #include petscmat.h
252: EXTERN int DAGetColoring(DA,ISColoringType,ISColoring *);
253: EXTERN int DAGetMatrix(DA,const MatType,Mat *);
254: EXTERN int DASetGetMatrix(DA,int (*)(DA,const MatType,Mat *));
255: EXTERN int DAGetInterpolation(DA,DA,Mat*,Vec*);
256: EXTERN int DAGetInjection(DA,DA,VecScatter*);
257: EXTERN int DASetBlockFills(DA,int*,int*);

259: EXTERN int DAGetAdicArray(DA,PetscTruth,void**,void**,int*);
260: EXTERN int DARestoreAdicArray(DA,PetscTruth,void**,void**,int*);
261: EXTERN int DAGetAdicMFArray(DA,PetscTruth,void**,void**,int*);
262: EXTERN int DARestoreAdicMFArray(DA,PetscTruth,void**,void**,int*);
263: EXTERN int DAGetArray(DA,PetscTruth,void**);
264: EXTERN int DARestoreArray(DA,PetscTruth,void**);
265: EXTERN int ad_DAGetArray(DA,PetscTruth,void**);
266: EXTERN int ad_DARestoreArray(DA,PetscTruth,void**);
267: EXTERN int admf_DAGetArray(DA,PetscTruth,void**);
268: EXTERN int admf_DARestoreArray(DA,PetscTruth,void**);

270:  #include petscpf.h
271: EXTERN int DACreatePF(DA,PF*);

273: /*S
274:      VecPack - Abstract PETSc object that manages treating several distinct vectors as if they
275:         were one.   The VecPack routines allow one to manage a nonlinear solver that works on a
276:         vector that consists of several distinct parts. This is mostly used for LNKS solvers, 
277:         that is design optimization problems that are written as a nonlinear system

279:    Level: beginner

281:   Concepts: multi-component, LNKS solvers

283: .seealso:  VecPackCreate(), VecPackDestroy()
284: S*/
285: typedef struct _p_VecPack *VecPack;

287: EXTERN int VecPackCreate(MPI_Comm,VecPack*);
288: EXTERN int VecPackDestroy(VecPack);
289: EXTERN int VecPackAddArray(VecPack,int);
290: EXTERN int VecPackAddDA(VecPack,DA);
291: EXTERN int VecPackAddVecScatter(VecPack,VecScatter);
292: EXTERN int VecPackScatter(VecPack,Vec,...);
293: EXTERN int VecPackGather(VecPack,Vec,...);
294: EXTERN int VecPackGetAccess(VecPack,Vec,...);
295: EXTERN int VecPackRestoreAccess(VecPack,Vec,...);
296: EXTERN int VecPackGetLocalVectors(VecPack,...);
297: EXTERN int VecPackGetEntries(VecPack,...);
298: EXTERN int VecPackRestoreLocalVectors(VecPack,...);
299: EXTERN int VecPackCreateGlobalVector(VecPack,Vec*);
300: EXTERN int VecPackGetGlobalIndices(VecPack,...);
301: EXTERN int VecPackRefine(VecPack,MPI_Comm,VecPack*);
302: EXTERN int VecPackGetInterpolation(VecPack,VecPack,Mat*,Vec*);


305:  #include petscsnes.h

307: /*S
308:      DM - Abstract PETSc object that manages an abstract grid object
309:           
310:    Level: intermediate

312:   Concepts: grids, grid refinement

314:    Notes: The DA object and the VecPack object are examples of DMs

316:           Though the DA objects require the petscsnes.h include files the DM library is
317:     NOT dependent on the SNES or KSP library. In fact, the KSP and SNES libraries depend on
318:     DM. (This is not great design, but not trivial to fix).

320: .seealso:  VecPackCreate(), DA, VecPack
321: S*/
322: typedef struct _p_DM* DM;

324: EXTERN int DMView(DM,PetscViewer);
325: EXTERN int DMDestroy(DM);
326: EXTERN int DMCreateGlobalVector(DM,Vec*);
327: EXTERN int DMGetColoring(DM,ISColoringType,ISColoring*);
328: EXTERN int DMGetMatrix(DM,const MatType,Mat*);
329: EXTERN int DMGetInterpolation(DM,DM,Mat*,Vec*);
330: EXTERN int DMGetInjection(DM,DM,VecScatter*);
331: EXTERN int DMRefine(DM,MPI_Comm,DM*);
332: EXTERN int DMGetInterpolationScale(DM,DM,Mat,Vec*);

334: typedef struct NLF_DAAD* NLF;

336: /*S
337:      DMMG -  Data structure to easily manage multi-level non-linear solvers on grids managed by DM
338:           
339:    Level: intermediate

341:   Concepts: multigrid, Newton-multigrid

343: .seealso:  VecPackCreate(), DA, VecPack, DM, DMMGCreate()
344: S*/
345: typedef struct _p_DMMG *DMMG;
346: struct _p_DMMG {
347:   DM         dm;                   /* grid information for this level */
348:   Vec        x,b,r;                /* global vectors used in multigrid preconditioner for this level*/
349:   Mat        J;                    /* matrix on this level */
350:   Mat        R;                    /* restriction to next coarser level (not defined on level 0) */
351:   int        nlevels;              /* number of levels above this one (total number of levels on level 0)*/
352:   MPI_Comm   comm;
353:   int        (*solve)(DMMG*,int);
354:   void       *user;
355:   PetscTruth galerkin;                  /* for A_c = R*A*R^T */

357:   /* KSP only */
358:   KSP       ksp;
359:   int        (*rhs)(DMMG,Vec);
360:   PetscTruth matricesset;               /* User had called DMMGSetKSP() and the matrices have been computed */

362:   /* SNES only */
363:   Mat           B;
364:   Vec           Rscale;                 /* scaling to restriction before computing Jacobian */
365:   int           (*computejacobian)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
366:   int           (*computefunction)(SNES,Vec,Vec,void*);

368:   PetscTruth    updatejacobian;         /* compute new Jacobian when DMMGComputeJacobian_Multigrid() is called */
369:   int           updatejacobianperiod;   /* how often, inside a SNES, the Jacobian is recomputed */

371:   MatFDColoring fdcoloring;             /* only used with FD coloring for Jacobian */
372:   SNES          snes;
373:   int           (*initialguess)(SNES,Vec,void*);
374:   Vec           w,work1,work2;         /* global vectors */
375:   Vec           lwork1;

377:   /* FAS only */
378:   NLF           nlf;                   /* FAS smoother object */
379:   VecScatter    inject;                /* inject from this level to the next coarsest */
380:   PetscTruth    monitor,monitorall;
381:   int           presmooth,postsmooth,coarsesmooth;
382:   PetscReal     rtol,atol,rrtol;       /* convergence tolerance */
383: 
384: };

386: EXTERN int DMMGCreate(MPI_Comm,int,void*,DMMG**);
387: EXTERN int DMMGDestroy(DMMG*);
388: EXTERN int DMMGSetUp(DMMG*);
389: EXTERN int DMMGSetKSP(DMMG*,int (*)(DMMG,Vec),int (*)(DMMG,Mat));
390: EXTERN int DMMGSetSNES(DMMG*,int (*)(SNES,Vec,Vec,void*),int (*)(SNES,Vec,Mat*,Mat*,MatStructure*,void*));
391: EXTERN int DMMGSetInitialGuess(DMMG*,int (*)(SNES,Vec,void*));
392: EXTERN int DMMGView(DMMG*,PetscViewer);
393: EXTERN int DMMGSolve(DMMG*);
394: EXTERN int DMMGSetUseMatrixFree(DMMG*);
395: EXTERN int DMMGSetDM(DMMG*,DM);
396: EXTERN int DMMGSetUpLevel(DMMG*,KSP,int);
397: EXTERN int DMMGSetUseGalerkinCoarse(DMMG*);

399: EXTERN int DMMGSetSNESLocal_Private(DMMG*,DALocalFunction1,DALocalFunction1,DALocalFunction1,DALocalFunction1);
400: #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
401: #  define DMMGSetSNESLocal(dmmg,function,jacobian,ad_function,admf_function) \
402:   DMMGSetSNESLocal_Private(dmmg,(DALocalFunction1)function,(DALocalFunction1)jacobian,(DALocalFunction1)(ad_function),(DALocalFunction1)(admf_function))
403: #else
404: #  define DMMGSetSNESLocal(dmmg,function,jacobian,ad_function,admf_function) DMMGSetSNESLocal_Private(dmmg,(DALocalFunction1)function,(DALocalFunction1)jacobian,(DALocalFunction1)0,(DALocalFunction1)0)
405: #endif

407: EXTERN int DMMGSetSNESLocali_Private(DMMG*,int (*)(DALocalInfo*,MatStencil*,void*,PetscScalar*,void*),int (*)(DALocalInfo*,MatStencil*,void*,void*,void*),int (*)(DALocalInfo*,MatStencil*,void*,void*,void*));
408: #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
409: #  define DMMGSetSNESLocali(dmmg,function,ad_function,admf_function) DMMGSetSNESLocali_Private(dmmg,(int (*)(DALocalInfo*,MatStencil*,void*,PetscScalar*,void*))function,(int (*)(DALocalInfo*,MatStencil*,void*,void*,void*))(ad_function),(int (*)(DALocalInfo*,MatStencil*,void*,void*,void*))(admf_function))
410: #else
411: #  define DMMGSetSNESLocali(dmmg,function,ad_function,admf_function) DMMGSetSNESLocali_Private(dmmg,(int (*)(DALocalInfo*,MatStencil*,void*,PetscScalar*,void*))function,0,0)
412: #endif

414: #define DMMGGetb(ctx)              (ctx)[(ctx)[0]->nlevels-1]->b
415: #define DMMGGetr(ctx)              (ctx)[(ctx)[0]->nlevels-1]->r

417: /*MC
418:    DMMGGetx - Returns the solution vector from a DMMG solve on the finest grid

420:    Synopsis:
421:    Vec DMMGGetx(DMMG *dmmg)

423:    Not Collective, but resulting vector is parallel

425:    Input Parameters:
426: .   dmmg - DMMG solve context

428:    Level: intermediate

430:    Fortran Usage:
431: .     DMMGGetx(DMMG dmmg,Vec x,int ierr)

433: .seealso: DMMGCreate(), DMMGSetSNES(), DMMGSetKSP(), DMMGSetSNESLocal()

435: M*/
436: #define DMMGGetx(ctx)              (ctx)[(ctx)[0]->nlevels-1]->x

438: #define DMMGGetJ(ctx)              (ctx)[(ctx)[0]->nlevels-1]->J
439: #define DMMGGetComm(ctx)           (ctx)[(ctx)[0]->nlevels-1]->comm
440: #define DMMGGetB(ctx)              (ctx)[(ctx)[0]->nlevels-1]->B
441: #define DMMGGetFine(ctx)           (ctx)[(ctx)[0]->nlevels-1]
442: #define DMMGGetKSP(ctx)           (ctx)[(ctx)[0]->nlevels-1]->ksp
443: #define DMMGGetSNES(ctx)           (ctx)[(ctx)[0]->nlevels-1]->snes
444: #define DMMGGetDA(ctx)             (DA)((ctx)[(ctx)[0]->nlevels-1]->dm)
445: #define DMMGGetVecPack(ctx)        (VecPack)((ctx)[(ctx)[0]->nlevels-1]->dm)
446: #define DMMGGetUser(ctx,level)     ((ctx)[levels]->user)
447: #define DMMGSetUser(ctx,level,usr) 0,(ctx)[levels]->user = usr
448: #define DMMGGetLevels(ctx)         (ctx)[0]->nlevels

450: PETSC_EXTERN_CXX_END
451: #endif