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