#ifdef PETSC_RCS_HEADER
static char vcid[] = "$Id: schur.h,v 1.3 1999/07/30 02:21:38 knepley Exp $";
#endif
/* 
   Private data structure for Schur complement preconditioner.
*/
#if !defined(__SCHUR_H)
#define __SCHUR_H

#include "petscsles.h"
#include "grid.h"
#include "gvec.h"
#include "gsolver.h"

typedef struct {
  Grid             grid;                /* The problem grid */
  PetscTruth       isConstrained;       /* The flag for constrained problems */
  PetscTruth       explicitConstraints; /* Form the constrained matrix explicitly */
  PetscTruth       useMath;             /* Use Mathematica functions instead */
  PetscViewer      mathViewer;          /* The link to Mathematica */

  /* Division of the problem into fields */
  Vec              u, uNew, uNew2;      /* The velocity variables */
  Vec              p, pNew;             /* The pressure variables */
  VecScatter       uScatter;            /* The scatter from x to the velocity variables u */
  VecScatter       pScatter;            /* The scatter from x to the pressure variables p */
  Vec              projX, projY, projZ; /* The projected vectors for systems with implicit constraints */

  /* Inner solvers */
  SLES             sles;                /* The solver for A^{-1} */
  SLES             schurSles;           /* The solver for B^T A^{-1} B */
  PetscTruth       useLaplacian;        /* Use Laplacian preconditioning of the Schur complement */
  int              iter, schurIter;     /* The number of iterations when solving A and B^T A^{-1} B */

  /* Field variables */
  int              numMomOps;           /* The number of momentum operators */
  int              gradOp;              /* The gradient operator */
  int              divOp;               /* The divergence operator */
  int             *momOps;              /* The momentum operators */
  PetscTruth      *momOpIsALE;          /* The flags for ALE momentum operators */
  PetscScalar     *momOpAlphas;         /* The scalar multipliers for the momentum operators*/
  PetscScalar      gradOpAlpha;         /* The scalar multiplier for the gradient operator */
  int              sField;              /* The shape function field */
  int              tField;              /* The test function field */
  VarOrdering      sOrder;              /* The global variable ordering for the shape function in B */
  LocalVarOrdering sLocOrder;           /* The local  variable ordering for the shape function in B */
  VarOrdering      tOrder;              /* The global variable ordering for the test  function in B */
  LocalVarOrdering tLocOrder;           /* The local  variable ordering for the test  function in B */
  GMat             A;                   /* The momentum matrix */
  GMat             sparseA;             /* The sparsified momentum matrix */
  GMat             B;                   /* The gradient matrix */
  GMat             S;                   /* The Schur complement matrix */
  IS               rowPerm;             /* The bandwidth reducing reordering for the rows of A */
  IS               colPerm;             /* The bandwidth reducing reordering for the cols of A */
  /* THIS IS ONLY A TEST */
  GMat             lap;                 /* The laplacian to precondition the Schur complement */

} PC_Schur;

#endif
