About user defined PC
jiaxun hou
jiaxun_hou at yahoo.com.cn
Wed Aug 9 05:42:35 CDT 2006
Barry,
Thank you very much. Your codes are very useful !
Regards,
Jiaxun
Barry Smith <bsmith at mcs.anl.gov> 写道:
Jiaxun,
I am assuming you are using the PCSHELL? I have added support for this for
you;
* if you are using petsc-dev
(http://www-unix.mcs.anl.gov/petsc/petsc-as/developers/index.html) you need
only do an hg pull to get my additions then run "make" in
src/ksp/pc/impls/shell.
* if you are not using petsc-dev (or use the nightly tar ball) then I attach the
three files that were
changed. include/private/pcimpl.h, include/petscpc.h and
src/ksp/pc/impls/shell/shell.c (again run make in src/ksp/pc/impls/shell)
If you are actually writing a complete PC and not using PCSHELL
http://www-unix.mcs.anl.gov/petsc/petsc-as/snapshots/petsc-current/src/ksp/pc/impls/jacobi/jacobi.c.html
then you just need to provide a routine PCApplyBA_XXXX() with calling sequence:
PC,PCSide,Vec b,Vec x,Vec work
Good luck,
Barry
On Tue, 8 Aug 2006, jiaxun hou wrote:
> Hi,
>
> I met a problem ,when I constructed a user-defined PC. That is I need to defind the process of P^(-1)Mx in each iteration of GMRES by myself for efficient reason, not only define P^(-1)x . But the Petsc seems to separate this process into two parts: the first is y=Mx which is defined in Petsc framework, and the second is P^(-1)y which is defined by the user. So, is there any way to do it without change the code of Petsc framework?
>
> Regards,
> Jiaxun
>
>
> ---------------------------------
> 抢注雅虎免费邮箱-3.5G容量,20M附件!/*
Preconditioner module.
*/
#if !defined(__PETSCPC_H)
#define __PETSCPC_H
#include "petscmat.h"
PETSC_EXTERN_CXX_BEGIN
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCInitializePackage(const char[]);
/*
PCList contains the list of preconditioners currently registered
These are added with the PCRegisterDynamic() macro
*/
extern PetscFList PCList;
#define PCType const char*
/*S
PC - Abstract PETSc object that manages all preconditioners
Level: beginner
Concepts: preconditioners
.seealso: PCCreate(), PCSetType(), PCType (for list of available types)
S*/
typedef struct _p_PC* PC;
/*E
PCType - String with the name of a PETSc preconditioner method or the creation function
with an optional dynamic library name, for example
http://www.mcs.anl.gov/petsc/lib.a:mypccreate()
Level: beginner
Notes: Click on the links below to see details on a particular solver
.seealso: PCSetType(), PC, PCCreate()
E*/
#define PCNONE "none"
#define PCJACOBI "jacobi"
#define PCSOR "sor"
#define PCLU "lu"
#define PCSHELL "shell"
#define PCBJACOBI "bjacobi"
#define PCMG "mg"
#define PCEISENSTAT "eisenstat"
#define PCILU "ilu"
#define PCICC "icc"
#define PCASM "asm"
#define PCKSP "ksp"
#define PCCOMPOSITE "composite"
#define PCREDUNDANT "redundant"
#define PCSPAI "spai"
#define PCNN "nn"
#define PCCHOLESKY "cholesky"
#define PCSAMG "samg"
#define PCPBJACOBI "pbjacobi"
#define PCMAT "mat"
#define PCHYPRE "hypre"
#define PCFIELDSPLIT "fieldsplit"
#define PCTFS "tfs"
#define PCML "ml"
#define PCPROMETHEUS "prometheus"
#define PCGALERKIN "galerkin"
/* Logging support */
extern PetscCookie PETSCKSP_DLLEXPORT PC_COOKIE;
/*E
PCSide - If the preconditioner is to be applied to the left, right
or symmetrically around the operator.
Level: beginner
.seealso:
E*/
typedef enum { PC_LEFT,PC_RIGHT,PC_SYMMETRIC } PCSide;
extern const char *PCSides[];
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCCreate(MPI_Comm,PC*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSetType(PC,PCType);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSetUp(PC);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSetUpOnBlocks(PC);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCApply(PC,Vec,Vec);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCApplySymmetricLeft(PC,Vec,Vec);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCApplySymmetricRight(PC,Vec,Vec);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCApplyBAorAB(PC,PCSide,Vec,Vec,Vec);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCApplyTranspose(PC,Vec,Vec);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCHasApplyTranspose(PC,PetscTruth*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCApplyBAorABTranspose(PC,PCSide,Vec,Vec,Vec);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCApplyRichardson(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCApplyRichardsonExists(PC,PetscTruth*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCRegisterDestroy(void);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCRegisterAll(const char[]);
extern PetscTruth PCRegisterAllCalled;
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCRegister(const char[],const char[],const char[],PetscErrorCode(*)(PC));
/*MC
PCRegisterDynamic - Adds a method to the preconditioner package.
Synopsis:
PetscErrorCode PCRegisterDynamic(char *name_solver,char *path,char *name_create,PetscErrorCode (*routine_create)(PC))
Not collective
Input Parameters:
+ name_solver - name of a new user-defined solver
. path - path (either absolute or relative) the library containing this solver
. name_create - name of routine to create method context
- routine_create - routine to create method context
Notes:
PCRegisterDynamic() may be called multiple times to add several user-defined preconditioners.
If dynamic libraries are used, then the fourth input argument (routine_create)
is ignored.
Sample usage:
.vb
PCRegisterDynamic("my_solver","/home/username/my_lib/lib/libO/solaris/mylib",
"MySolverCreate",MySolverCreate);
.ve
Then, your solver can be chosen with the procedural interface via
$ PCSetType(pc,"my_solver")
or at runtime via the option
$ -pc_type my_solver
Level: advanced
Notes: ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, or ${any environmental variable}
occuring in pathname will be replaced with appropriate values.
If your function is not being put into a shared library then use PCRegister() instead
.keywords: PC, register
.seealso: PCRegisterAll(), PCRegisterDestroy()
M*/
#if defined(PETSC_USE_DYNAMIC_LIBRARIES)
#define PCRegisterDynamic(a,b,c,d) PCRegister(a,b,c,0)
#else
#define PCRegisterDynamic(a,b,c,d) PCRegister(a,b,c,d)
#endif
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCDestroy(PC);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSetFromOptions(PC);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCGetType(PC,PCType*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCGetFactoredMatrix(PC,Mat*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSetModifySubMatrices(PC,PetscErrorCode(*)(PC,PetscInt,const IS[],const IS[],Mat[],void*),void*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCModifySubMatrices(PC,PetscInt,const IS[],const IS[],Mat[],void*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSetOperators(PC,Mat,Mat,MatStructure);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCGetOperators(PC,Mat*,Mat*,MatStructure*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCGetOperatorsSet(PC,PetscTruth*,PetscTruth*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCView(PC,PetscViewer);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSetOptionsPrefix(PC,const char[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCAppendOptionsPrefix(PC,const char[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCGetOptionsPrefix(PC,const char*[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCComputeExplicitOperator(PC,Mat*);
/*
These are used to provide extra scaling of preconditioned
operator for time-stepping schemes like in SUNDIALS
*/
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScale(PC,PetscTruth*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScaleLeft(PC,Vec,Vec);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScaleRight(PC,Vec,Vec);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCDiagonalScaleSet(PC,Vec);
/* ------------- options specific to particular preconditioners --------- */
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCJacobiSetUseRowMax(PC);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCJacobiSetUseAbs(PC);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSORSetSymmetric(PC,MatSORType);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSORSetOmega(PC,PetscReal);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSORSetIterations(PC,PetscInt,PetscInt);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCEisenstatSetOmega(PC,PetscReal);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCEisenstatNoDiagonalScaling(PC);
#define USE_PRECONDITIONER_MATRIX 0
#define USE_TRUE_MATRIX 1
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCBJacobiSetUseTrueLocal(PC);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCBJacobiSetTotalBlocks(PC,PetscInt,const PetscInt[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCBJacobiSetLocalBlocks(PC,PetscInt,const PetscInt[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCKSPSetUseTrue(PC);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApply(PC,PetscErrorCode (*)(void*,Vec,Vec));
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyBA(PC,PetscErrorCode (*)(void*,PCSide,Vec,Vec,Vec));
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyTranspose(PC,PetscErrorCode (*)(void*,Vec,Vec));
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetSetUp(PC,PetscErrorCode (*)(void*));
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyRichardson(PC,PetscErrorCode (*)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt));
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetView(PC,PetscErrorCode (*)(void*,PetscViewer));
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetDestroy(PC,PetscErrorCode (*)(void*));
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetContext(PC,void**);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetContext(PC,void*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetName(PC,const char[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetName(PC,char*[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetZeroPivot(PC,PetscReal);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftNonzero(PC,PetscReal);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetShiftPd(PC,PetscTruth);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetFill(PC,PetscReal);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetPivoting(PC,PetscReal);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorReorderForNonzeroDiagonal(PC,PetscReal);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetMatOrdering(PC,MatOrderingType);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetReuseOrdering(PC,PetscTruth);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetReuseFill(PC,PetscTruth);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetUseInPlace(PC);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetAllowDiagonalFill(PC);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetPivotInBlocks(PC,PetscTruth);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetLevels(PC,PetscInt);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFactorSetUseDropTolerance(PC,PetscReal,PetscReal,PetscInt);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCASMSetLocalSubdomains(PC,PetscInt,IS[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCASMSetTotalSubdomains(PC,PetscInt,IS[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCASMSetOverlap(PC,PetscInt);
/*E
PCASMType - Type of additive Schwarz method to use
$ PC_ASM_BASIC - symmetric version where residuals from the ghost points are used
$ and computed values in ghost regions are added together. Classical
$ standard additive Schwarz
$ PC_ASM_RESTRICT - residuals from ghost points are used but computed values in ghost
$ region are discarded. Default
$ PC_ASM_INTERPOLATE - residuals from ghost points are not used, computed values in ghost
$ region are added back in
$ PC_ASM_NONE - ghost point residuals are not used, computed ghost values are discarded
$ not very good.
Level: beginner
.seealso: PCASMSetType()
E*/
typedef enum {PC_ASM_BASIC = 3,PC_ASM_RESTRICT = 1,PC_ASM_INTERPOLATE = 2,PC_ASM_NONE = 0} PCASMType;
extern const char *PCASMTypes[];
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCASMSetType(PC,PCASMType);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCASMCreateSubdomains2D(PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt *,IS **);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCASMSetUseInPlace(PC);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCASMGetLocalSubdomains(PC,PetscInt*,IS*[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCASMGetLocalSubmatrices(PC,PetscInt*,Mat*[]);
/*E
PCCompositeType - Determines how two or more preconditioner are composed
$ PC_COMPOSITE_ADDITIVE - results from application of all preconditioners are added together
$ PC_COMPOSITE_MULTIPLICATIVE - preconditioners are applied sequentially to the residual freshly
$ computed after the previous preconditioner application
$ PC_COMPOSITE_SPECIAL - This is very special for a matrix of the form alpha I + R + S
$ where first preconditioner is built from alpha I + S and second from
$ alpha I + R
Level: beginner
.seealso: PCCompositeSetType()
E*/
typedef enum {PC_COMPOSITE_ADDITIVE,PC_COMPOSITE_MULTIPLICATIVE,PC_COMPOSITE_SPECIAL} PCCompositeType;
extern const char *PCCompositeTypes[];
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCCompositeSetUseTrue(PC);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCCompositeSetType(PC,PCCompositeType);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCCompositeAddPC(PC,PCType);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCCompositeGetPC(PC pc,PetscInt n,PC *);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCCompositeSpecialSetAlpha(PC,PetscScalar);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCRedundantSetScatter(PC,VecScatter,VecScatter);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCRedundantGetOperators(PC,Mat*,Mat*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCRedundantGetPC(PC,PC*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSPAISetEpsilon(PC,double);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSPAISetNBSteps(PC,PetscInt);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSPAISetMax(PC,PetscInt);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSPAISetMaxNew(PC,PetscInt);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSPAISetBlockSize(PC,PetscInt);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSPAISetCacheSize(PC,PetscInt);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSPAISetVerbose(PC,PetscInt);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSPAISetSp(PC,PetscInt);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCHYPRESetType(PC,const char[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCBJacobiGetLocalBlocks(PC,PetscInt*,const PetscInt*[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCBJacobiGetTotalBlocks(PC,PetscInt*,const PetscInt*[]);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFieldSplitSetFields(PC,PetscInt,PetscInt*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCFieldSplitSetType(PC,PCCompositeType);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCGalerkinSetRestriction(PC,Mat);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCGalerkinSetInterpolation(PC,Mat);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSetCoordinates(PC,PetscInt,PetscReal*);
EXTERN PetscErrorCode PETSCKSP_DLLEXPORT PCSASetVectors(PC,PetscInt,PetscReal *);
PETSC_EXTERN_CXX_END
#endif /* __PETSCPC_H */
#ifndef _PCIMPL
#define _PCIMPL
#include "petscksp.h"
#include "petscpc.h"
typedef struct _PCOps *PCOps;
struct _PCOps {
PetscErrorCode (*setup)(PC);
PetscErrorCode (*apply)(PC,Vec,Vec);
PetscErrorCode (*applyrichardson)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt);
PetscErrorCode (*applyBA)(PC,PCSide,Vec,Vec,Vec);
PetscErrorCode (*applytranspose)(PC,Vec,Vec);
PetscErrorCode (*applyBAtranspose)(PC,PetscInt,Vec,Vec,Vec);
PetscErrorCode (*setfromoptions)(PC);
PetscErrorCode (*presolve)(PC,KSP,Vec,Vec);
PetscErrorCode (*postsolve)(PC,KSP,Vec,Vec);
PetscErrorCode (*getfactoredmatrix)(PC,Mat*);
PetscErrorCode (*applysymmetricleft)(PC,Vec,Vec);
PetscErrorCode (*applysymmetricright)(PC,Vec,Vec);
PetscErrorCode (*setuponblocks)(PC);
PetscErrorCode (*destroy)(PC);
PetscErrorCode (*view)(PC,PetscViewer);
};
/*
Preconditioner context
*/
struct _p_PC {
PETSCHEADER(struct _PCOps);
PetscInt setupcalled;
MatStructure flag;
Mat mat,pmat;
Vec diagonalscaleright,diagonalscaleleft; /* used for time integration scaling */
PetscTruth diagonalscale;
PetscErrorCode (*modifysubmatrices)(PC,PetscInt,const IS[],const IS[],Mat[],void*); /* user provided routine */
void *modifysubmatricesP; /* context for user routine */
void *data;
};
extern PetscEvent PC_SetUp, PC_SetUpOnBlocks, PC_Apply, PC_ApplyCoarse, PC_ApplyMultiple, PC_ApplySymmetricLeft;
extern PetscEvent PC_ApplySymmetricRight, PC_ModifySubMatrices;
#endif
#define PETSCKSP_DLL
/*
This provides a simple shell for Fortran (and C programmers) to
create their own preconditioner without writing much interface code.
*/
#include "private/pcimpl.h" /*I "petscpc.h" I*/
#include "private/vecimpl.h"
EXTERN_C_BEGIN
typedef struct {
void *ctx; /* user provided contexts for preconditioner */
PetscErrorCode (*destroy)(void*);
PetscErrorCode (*setup)(void*);
PetscErrorCode (*apply)(void*,Vec,Vec);
PetscErrorCode (*applyBA)(void*,PCSide,Vec,Vec,Vec);
PetscErrorCode (*presolve)(void*,KSP,Vec,Vec);
PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec);
PetscErrorCode (*view)(void*,PetscViewer);
PetscErrorCode (*applytranspose)(void*,Vec,Vec);
PetscErrorCode (*applyrich)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt);
char *name;
} PC_Shell;
EXTERN_C_END
#undef __FUNCT__
#define __FUNCT__ "PCShellGetContext"
/*@
PCShellGetContext - Returns the user-provided context associated with a shell PC
Not Collective
Input Parameter:
. pc - should have been created with PCCreateShell()
Output Parameter:
. ctx - the user provided context
Level: advanced
Notes:
This routine is intended for use within various shell routines
.keywords: PC, shell, get, context
.seealso: PCCreateShell(), PCShellSetContext()
@*/
PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetContext(PC pc,void **ctx)
{
PetscErrorCode ierr;
PetscTruth flg;
PetscFunctionBegin;
PetscValidHeaderSpecific(pc,PC_COOKIE,1);
PetscValidPointer(ctx,2);
ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);CHKERRQ(ierr);
if (!flg) *ctx = 0;
else *ctx = ((PC_Shell*)(pc->data))->ctx;
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCShellSetContext"
/*@C
PCShellSetContext - sets the context for a shell PC
Collective on PC
Input Parameters:
+ pc - the shell PC
- ctx - the context
Level: advanced
Fortran Notes: The context can only be an integer or a PetscObject
unfortunately it cannot be a Fortran array or derived type.
.seealso: PCCreateShell(), PCShellGetContext()
@*/
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetContext(PC pc,void *ctx)
{
PC_Shell *shell = (PC_Shell*)pc->data;
PetscErrorCode ierr;
PetscTruth flg;
PetscFunctionBegin;
PetscValidHeaderSpecific(pc,PC_COOKIE,1);
ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);CHKERRQ(ierr);
if (flg) {
shell->ctx = ctx;
}
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCSetUp_Shell"
static PetscErrorCode PCSetUp_Shell(PC pc)
{
PC_Shell *shell;
PetscErrorCode ierr;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
if (shell->setup) {
CHKMEMQ;
ierr = (*shell->setup)(shell->ctx);CHKERRQ(ierr);
CHKMEMQ;
}
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCApply_Shell"
static PetscErrorCode PCApply_Shell(PC pc,Vec x,Vec y)
{
PC_Shell *shell;
PetscErrorCode ierr;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
if (!shell->apply) SETERRQ(PETSC_ERR_USER,"No apply() routine provided to Shell PC");
PetscStackPush("PCSHELL user function");
CHKMEMQ;
ierr = (*shell->apply)(shell->ctx,x,y);CHKERRQ(ierr);
CHKMEMQ;
PetscStackPop;
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCApplyBA_Shell"
static PetscErrorCode PCApplyBA_Shell(PC pc,PCSide side,Vec x,Vec y,Vec w)
{
PC_Shell *shell;
PetscErrorCode ierr;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
if (!shell->applyBA) SETERRQ(PETSC_ERR_USER,"No applyBA() routine provided to Shell PC");
PetscStackPush("PCSHELL user function BA");
CHKMEMQ;
ierr = (*shell->applyBA)(shell->ctx,side,x,y,w);CHKERRQ(ierr);
CHKMEMQ;
PetscStackPop;
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCPreSolve_Shell"
static PetscErrorCode PCPreSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
{
PC_Shell *shell;
PetscErrorCode ierr;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
if (!shell->presolve) SETERRQ(PETSC_ERR_USER,"No presolve() routine provided to Shell PC");
ierr = (*shell->presolve)(shell->ctx,ksp,b,x);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCPostSolve_Shell"
static PetscErrorCode PCPostSolve_Shell(PC pc,KSP ksp,Vec b,Vec x)
{
PC_Shell *shell;
PetscErrorCode ierr;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
if (!shell->postsolve) SETERRQ(PETSC_ERR_USER,"No postsolve() routine provided to Shell PC");
ierr = (*shell->postsolve)(shell->ctx,ksp,b,x);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCApplyTranspose_Shell"
static PetscErrorCode PCApplyTranspose_Shell(PC pc,Vec x,Vec y)
{
PC_Shell *shell;
PetscErrorCode ierr;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
if (!shell->applytranspose) SETERRQ(PETSC_ERR_USER,"No applytranspose() routine provided to Shell PC");
ierr = (*shell->applytranspose)(shell->ctx,x,y);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCApplyRichardson_Shell"
static PetscErrorCode PCApplyRichardson_Shell(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt it)
{
PetscErrorCode ierr;
PC_Shell *shell;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
ierr = (*shell->applyrich)(shell->ctx,x,y,w,rtol,abstol,dtol,it);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCDestroy_Shell"
static PetscErrorCode PCDestroy_Shell(PC pc)
{
PC_Shell *shell = (PC_Shell*)pc->data;
PetscErrorCode ierr;
PetscFunctionBegin;
ierr = PetscStrfree(shell->name);CHKERRQ(ierr);
if (shell->destroy) {
ierr = (*shell->destroy)(shell->ctx);CHKERRQ(ierr);
}
ierr = PetscFree(shell);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCView_Shell"
static PetscErrorCode PCView_Shell(PC pc,PetscViewer viewer)
{
PC_Shell *shell = (PC_Shell*)pc->data;
PetscErrorCode ierr;
PetscTruth iascii;
PetscFunctionBegin;
ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
if (iascii) {
if (shell->name) {ierr = PetscViewerASCIIPrintf(viewer," Shell: %s\n",shell->name);CHKERRQ(ierr);}
else {ierr = PetscViewerASCIIPrintf(viewer," Shell: no name\n");CHKERRQ(ierr);}
}
if (shell->view) {
ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
ierr = (*shell->view)(shell->ctx,viewer);CHKERRQ(ierr);
ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
/* ------------------------------------------------------------------------------*/
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "PCShellSetDestroy_Shell"
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetDestroy_Shell(PC pc, PetscErrorCode (*destroy)(void*))
{
PC_Shell *shell;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
shell->destroy = destroy;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "PCShellSetSetUp_Shell"
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetSetUp_Shell(PC pc, PetscErrorCode (*setup)(void*))
{
PC_Shell *shell;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
shell->setup = setup;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "PCShellSetApply_Shell"
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApply_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec))
{
PC_Shell *shell;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
shell->apply = apply;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "PCShellSetApplyBA_Shell"
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyBA_Shell(PC pc,PetscErrorCode (*apply)(void*,PCSide,Vec,Vec,Vec))
{
PC_Shell *shell;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
shell->applyBA = apply;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "PCShellSetPreSolve_Shell"
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPreSolve_Shell(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec))
{
PC_Shell *shell;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
shell->presolve = presolve;
if (presolve) {
pc->ops->presolve = PCPreSolve_Shell;
} else {
pc->ops->presolve = 0;
}
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "PCShellSetPostSolve_Shell"
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPostSolve_Shell(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec))
{
PC_Shell *shell;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
shell->postsolve = postsolve;
if (postsolve) {
pc->ops->postsolve = PCPostSolve_Shell;
} else {
pc->ops->postsolve = 0;
}
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "PCShellSetView_Shell"
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetView_Shell(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
{
PC_Shell *shell;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
shell->view = view;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "PCShellSetApplyTranspose_Shell"
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyTranspose_Shell(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
{
PC_Shell *shell;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
shell->applytranspose = applytranspose;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "PCShellSetName_Shell"
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetName_Shell(PC pc,const char name[])
{
PC_Shell *shell;
PetscErrorCode ierr;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
ierr = PetscStrfree(shell->name);CHKERRQ(ierr);
ierr = PetscStrallocpy(name,&shell->name);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "PCShellGetName_Shell"
PetscErrorCode PETSCKSP_DLLEXPORT PCShellGetName_Shell(PC pc,char *name[])
{
PC_Shell *shell;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
*name = shell->name;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "PCShellSetApplyRichardson_Shell"
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyRichardson_Shell(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,PetscInt))
{
PC_Shell *shell;
PetscFunctionBegin;
shell = (PC_Shell*)pc->data;
pc->ops->applyrichardson = PCApplyRichardson_Shell;
shell->applyrich = apply;
PetscFunctionReturn(0);
}
EXTERN_C_END
/* -------------------------------------------------------------------------------*/
#undef __FUNCT__
#define __FUNCT__ "PCShellSetDestroy"
/*@C
PCShellSetDestroy - Sets routine to use to destroy the user-provided
application context.
Collective on PC
Input Parameters:
+ pc - the preconditioner context
. destroy - the application-provided destroy routine
Calling sequence of destroy:
.vb
PetscErrorCode destroy (void *ptr)
.ve
. ptr - the application context
Level: developer
.keywords: PC, shell, set, destroy, user-provided
.seealso: PCShellSetApply(), PCShellSetContext()
@*/
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetDestroy(PC pc,PetscErrorCode (*destroy)(void*))
{
PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));
PetscFunctionBegin;
PetscValidHeaderSpecific(pc,PC_COOKIE,1);
ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetDestroy_C",(void (**)(void))&f);CHKERRQ(ierr);
if (f) {
ierr = (*f)(pc,destroy);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCShellSetSetUp"
/*@C
PCShellSetSetUp - Sets routine to use to "setup" the preconditioner whenever the
matrix operator is changed.
Collective on PC
Input Parameters:
+ pc - the preconditioner context
. setup - the application-provided setup routine
Calling sequence of setup:
.vb
PetscErrorCode setup (void *ptr)
.ve
. ptr - the application context
Level: developer
.keywords: PC, shell, set, setup, user-provided
.seealso: PCShellSetApplyRichardson(), PCShellSetApply(), PCShellSetContext()
@*/
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetSetUp(PC pc,PetscErrorCode (*setup)(void*))
{
PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*));
PetscFunctionBegin;
PetscValidHeaderSpecific(pc,PC_COOKIE,1);
ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetSetUp_C",(void (**)(void))&f);CHKERRQ(ierr);
if (f) {
ierr = (*f)(pc,setup);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCShellSetView"
/*@C
PCShellSetView - Sets routine to use as viewer of shell preconditioner
Collective on PC
Input Parameters:
+ pc - the preconditioner context
- view - the application-provided view routine
Calling sequence of apply:
.vb
PetscErrorCode view(void *ptr,PetscViewer v)
.ve
+ ptr - the application context
- v - viewer
Level: developer
.keywords: PC, shell, set, apply, user-provided
.seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose()
@*/
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetView(PC pc,PetscErrorCode (*view)(void*,PetscViewer))
{
PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PetscViewer));
PetscFunctionBegin;
PetscValidHeaderSpecific(pc,PC_COOKIE,1);
ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetView_C",(void (**)(void))&f);CHKERRQ(ierr);
if (f) {
ierr = (*f)(pc,view);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCShellSetApply"
/*@C
PCShellSetApply - Sets routine to use as preconditioner.
Collective on PC
Input Parameters:
+ pc - the preconditioner context
- apply - the application-provided preconditioning routine
Calling sequence of apply:
.vb
PetscErrorCode apply (void *ptr,Vec xin,Vec xout)
.ve
+ ptr - the application context
. xin - input vector
- xout - output vector
Level: developer
.keywords: PC, shell, set, apply, user-provided
.seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApplyBA()
@*/
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApply(PC pc,PetscErrorCode (*apply)(void*,Vec,Vec))
{
PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));
PetscFunctionBegin;
PetscValidHeaderSpecific(pc,PC_COOKIE,1);
ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApply_C",(void (**)(void))&f);CHKERRQ(ierr);
if (f) {
ierr = (*f)(pc,apply);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCShellSetApplyBA"
/*@C
PCShellSetApplyBA - Sets routine to use as preconditioner times operator.
Collective on PC
Input Parameters:
+ pc - the preconditioner context
- applyBA - the application-provided BA routine
Calling sequence of apply:
.vb
PetscErrorCode applyBA (void *ptr,Vec xin,Vec xout)
.ve
+ ptr - the application context
. xin - input vector
- xout - output vector
Level: developer
.keywords: PC, shell, set, apply, user-provided
.seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetContext(), PCShellSetApply()
@*/
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyBA(PC pc,PetscErrorCode (*applyBA)(void*,PCSide,Vec,Vec,Vec))
{
PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,PCSide,Vec,Vec,Vec));
PetscFunctionBegin;
PetscValidHeaderSpecific(pc,PC_COOKIE,1);
ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyBA_C",(void (**)(void))&f);CHKERRQ(ierr);
if (f) {
ierr = (*f)(pc,applyBA);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCShellSetApplyTranspose"
/*@C
PCShellSetApplyTranspose - Sets routine to use as preconditioner transpose.
Collective on PC
Input Parameters:
+ pc - the preconditioner context
- apply - the application-provided preconditioning transpose routine
Calling sequence of apply:
.vb
PetscErrorCode applytranspose (void *ptr,Vec xin,Vec xout)
.ve
+ ptr - the application context
. xin - input vector
- xout - output vector
Level: developer
Notes:
Uses the same context variable as PCShellSetApply().
.keywords: PC, shell, set, apply, user-provided
.seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApply(), PCSetContext(), PCShellSetApplyBA()
@*/
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetApplyTranspose(PC pc,PetscErrorCode (*applytranspose)(void*,Vec,Vec))
{
PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,Vec,Vec));
PetscFunctionBegin;
PetscValidHeaderSpecific(pc,PC_COOKIE,1);
ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetApplyTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
if (f) {
ierr = (*f)(pc,applytranspose);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCShellSetPreSolve"
/*@C
PCShellSetPreSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
applied. This usually does something like scale the linear system in some application
specific way.
Collective on PC
Input Parameters:
+ pc - the preconditioner context
- presolve - the application-provided presolve routine
Calling sequence of presolve:
.vb
PetscErrorCode presolve (void *ptr,KSP ksp,Vec b,Vec x)
.ve
+ ptr - the application context
. xin - input vector
- xout - output vector
Level: developer
.keywords: PC, shell, set, apply, user-provided
.seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPostSolve(), PCShellSetContext()
@*/
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPreSolve(PC pc,PetscErrorCode (*presolve)(void*,KSP,Vec,Vec))
{
PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));
PetscFunctionBegin;
PetscValidHeaderSpecific(pc,PC_COOKIE,1);
ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPreSolve_C",(void (**)(void))&f);CHKERRQ(ierr);
if (f) {
ierr = (*f)(pc,presolve);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCShellSetPostSolve"
/*@C
PCShellSetPostSolve - Sets routine to apply to the operators/vectors before a KSPSolve() is
applied. This usually does something like scale the linear system in some application
specific way.
Collective on PC
Input Parameters:
+ pc - the preconditioner context
- postsolve - the application-provided presolve routine
Calling sequence of postsolve:
.vb
PetscErrorCode postsolve(void *ptr,KSP ksp,Vec b,Vec x)
.ve
+ ptr - the application context
. xin - input vector
- xout - output vector
Level: developer
.keywords: PC, shell, set, apply, user-provided
.seealso: PCShellSetApplyRichardson(), PCShellSetSetUp(), PCShellSetApplyTranspose(), PCShellSetPreSolve(), PCShellSetContext()
@*/
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetPostSolve(PC pc,PetscErrorCode (*postsolve)(void*,KSP,Vec,Vec))
{
PetscErrorCode ierr,(*f)(PC,PetscErrorCode (*)(void*,KSP,Vec,Vec));
PetscFunctionBegin;
PetscValidHeaderSpecific(pc,PC_COOKIE,1);
ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetPostSolve_C",(void (**)(void))&f);CHKERRQ(ierr);
if (f) {
ierr = (*f)(pc,postsolve);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCShellSetName"
/*@C
PCShellSetName - Sets an optional name to associate with a shell
preconditioner.
Not Collective
Input Parameters:
+ pc - the preconditioner context
- name - character string describing shell preconditioner
Level: developer
.keywords: PC, shell, set, name, user-provided
.seealso: PCShellGetName()
@*/
PetscErrorCode PETSCKSP_DLLEXPORT PCShellSetName(PC pc,const char name[])
{
PetscErrorCode ierr,(*f)(PC,const char []);
PetscFunctionBegin;
PetscValidHeaderSpecific(pc,PC_COOKIE,1);
ierr = PetscObjectQueryFunction((PetscObject)pc,"PCShellSetName_C",(void (**)(void))&f);CHKERRQ(ierr);
if (f) {
ierr = (*f)(pc,name);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "PCShellGetName"
/*@C
PCShellGetName - Gets an optional name that the user has set for a shell
=== message truncated ===
__________________________________________________
赶快注册雅虎超大容量免费邮箱?
http://cn.mail.yahoo.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20060809/78a20073/attachment.htm>
More information about the petsc-users
mailing list