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