#include /*I "petscsnes.h" I*/ #include #undef __FUNCT__ #define __FUNCT__ "MatMultASPIN" PetscErrorCode MatMultASPIN(Mat m,Vec X,Vec Y) { PetscErrorCode ierr; void *ctx; SNES snes; PetscInt n,i; VecScatter *oscatter; SNES *subsnes; PetscBool match; MPI_Comm comm; KSP ksp; Vec *x,*b; Vec W; SNES npc; Mat subJ,subpJ; PetscFunctionBegin; ierr = MatShellGetContext(m,&ctx);CHKERRQ(ierr); snes = (SNES)ctx; ierr = SNESGetNPC(snes,&npc);CHKERRQ(ierr); ierr = SNESGetFunction(npc,&W,NULL,NULL);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)npc,SNESNASM,&match);CHKERRQ(ierr); if (!match) { ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"MatMultASPIN requires that the nonlinear preconditioner be Nonlinear additive Schwarz"); } ierr = SNESNASMGetSubdomains(npc,&n,&subsnes,NULL,&oscatter,NULL);CHKERRQ(ierr); ierr = SNESNASMGetSubdomainVecs(npc,&n,&x,&b,NULL,NULL);CHKERRQ(ierr); ierr = VecSet(Y,0);CHKERRQ(ierr); ierr = MatMult(npc->jacobian_pre,X,W);CHKERRQ(ierr); for (i=0;i