#ifdef PETSC_RCS_HEADER
static char vcid[] = "$Id: gridConst.c,v 1.1 1999/10/17 19:47:46 knepley Exp $";
#endif

#include "src/grid/gridimpl.h"    /*I "grid.h" I*/

/*--------------------------------------------- Constraint Functions ------------------------------------------------*/
#undef  __FUNCT__
#define __FUNCT__ "GridIsConstrained"
/*@C
  GridIsConstrained - This function indicates whether or not constraints are active.

  Not collective

  Input Parameter:
. grid - The grid

  Output Parameter:
. flag - The flag that indicates activate constraints

  Level: intermediate

.keywords constraint
.seealso GridSetConstrained(), GridSetupConstraints()
@*/
int GridIsConstrained(Grid grid, PetscTruth *flag)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  PetscValidPointer(flag);
  *flag = grid->isConstrained;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridSetConstrained"
/*@C
  GridSetConstrained -  This function activates or deactivates constraints.

  Collective on Grid

  Input Parameters:
+ grid - The grid
- flag - The activation flag

  Level: intermediate

.keywords constraint
.seealso GridIsConstrained(), GridSetupConstraints()
@*/
int GridSetConstrained(Grid grid, PetscTruth flag)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  grid->isConstrained = flag;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridGetNumNewFields"
/*@C
  GridGetNumNewFields - This function returns the number of fields introduced by constraints.

  Not collective

  Input Parameter:
. grid         - The grid

  Output Parameter:
. numNewFields - The number of fields introduced by constraints

  Level: intermediate

.keywords constraint
.seealso GridSetNumNewFields(), GridSetupConstraints()
@*/
int GridGetNumNewFields(Grid grid, int *numNewFields)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  PetscValidPointer(numNewFields);
  *numNewFields = grid->numNewFields;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridSetNumNewFields"
/*@C
  GridSetNumNewFields -  This function sets the number of fields introduced by constraints.

  Collective on Grid

  Input Parameters:
+ grid         - The grid
- numNewFields - The number of fields introduced by constraints

  Level: intermediate

.keywords constraint
.seealso GridGetNumNewFields(), GridSetupConstraints()
@*/
int GridSetNumNewFields(Grid grid, int numNewFields)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  grid->numNewFields = numNewFields;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridIsFieldConstrained"
/*@C
  GridIsFieldConstrained - This function indicates whether or not a field is constrained.

  Not collective

  Input Parameters:
+ grid          - The grid
- field         - The field

  Output Parameter:
. isConstrained - The flag that indicates whether the field is constrained

  Level: intermediate

.keywords constraint, field
.seealso GridIsConstrained(), GridSetupConstraints()
@*/
int GridIsFieldConstrained(Grid grid, int field, PetscTruth *isConstrained)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  PetscValidPointer(isConstrained);
  GridValidField(grid, field);
  *isConstrained = grid->fields[field].isConstrained;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridSetFieldConstrained"
/*@C
  GridSetFieldConstrained - This function determines whether or not a field is constrained.

  Not collective

  Input Parameters:
+ grid          - The grid
. field         - The field
- isConstrained - The flag that determines whether the field is constrained

  Level: intermediate

.keywords constraint, field
.seealso GridSetConstrained(), GridSetupConstraints()
@*/
int GridSetFieldConstrained(Grid grid, int field, PetscTruth isConstrained)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  GridValidField(grid, field);
  grid->fields[field].isConstrained = isConstrained;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridGetFieldConstraintCompDiff"
/*@C
  GridGetFieldConstraintCompDiff - This function returns the constraint component difference

  Not collective

  Input Parameter:
+ grid               - The grid
- field              - The field

  Output Parameter:
. constraintCompDiff - The difference between the number of components in the new and constrained field

  Level: intermediate

.keywords constraint, field
.seealso GridIsConstrained(), GridSetupConstraints()
@*/
int GridGetFieldConstraintCompDiff(Grid grid, int field, int *constraintCompDiff)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  PetscValidPointer(constraintCompDiff);
  GridValidField(grid, field);
  *constraintCompDiff = grid->fields[field].constraintCompDiff;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridSetFieldConstraintCompDiff"
/*@C
  GridSetFieldConstraintCompDiff - This function sets the constraint component difference

  Not collective

  Input Parameters:
+ grid               - The grid
. field              - The field
- constraintCompDiff - The difference between the number of components in the new and constrained field

  Level: intermediate

.keywords constraint, field
.seealso GridSetConstrained(), GridSetupConstraints()
@*/
int GridSetFieldConstraintCompDiff(Grid grid, int field, int constraintCompDiff)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  GridValidField(grid, field);
  grid->fields[field].constraintCompDiff = constraintCompDiff;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridGetExplicitConstraints"
/*@C
  GridGetExplicitConstraints - This function indicates whether or not constrained
  objects are formed explicitly or implicitly.

  Not collective

  Input Parameter:
. grid - The grid

  Output Parameter:
. flag - The flag that indicates explicit constraints

  Note:
  Objects formed explicitly are actually vectors and matrices, whereas
  constrained objects formed implicitly are products of projection
  operators and normal objects.

  Level: intermediate

.keywords constraint
.seealso GridSetExplicitConstraints(), GridSetupConstraints()
@*/
int GridGetExplicitConstraints(Grid grid, PetscTruth *flag)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  PetscValidPointer(flag);
  *flag = grid->explicitConstraints;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridSetExplicitConstraints"
/*@C
  GridSetExplicitConstraints - This function determines how to form constrained objects.

  Collective on Grid

  Input Parameters:
+ grid - The grid
- flag - The formation flag

  Note:
  Objects formed explicitly are actually vectors and matrices, whereas
  constrained objects formed implicitly are products of projection
  operators and normal objects.

  Level: intermediate

.keywords constraint
.seealso GridGetExplicitConstraints(), GridSetupConstraints()
@*/
int GridSetExplicitConstraints(Grid grid, PetscTruth flag)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  grid->explicitConstraints = flag;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridGetConstraints"
/*@C
  GridGetConstraints - This function return information about the constrained problem.

  Not collective

  Input Parameter:
. grid            - The grid

  Output Parameters:
+ flag            - The flag that activates constraints
. numInteriorVars - The number of constrained variables unaffected by constraints in this domain
. numLocVars      - The number of constrained variables in this domain
- numVars         - The global number of constrained variables

  Level: advanced

.keywords constraint
.seealso GridSetBoundary
@*/
int GridGetConstraints(Grid grid, PetscTruth *flag, int *numInteriorVars, int *numLocVars, int *numVars)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  if (flag            != PETSC_NULL) {
    PetscValidPointer(flag);
    *flag = grid->isConstrained;
  }
  if (numInteriorVars != PETSC_NULL) {
    PetscValidIntPointer(numInteriorVars);
    *numInteriorVars = grid->constraintOrder->numLocVars - grid->constraintOrder->numLocNewVars;
  }
  if (numLocVars      != PETSC_NULL) {
    PetscValidIntPointer(numLocVars);
    *numLocVars      = grid->constraintOrder->numLocVars;
  }
  if (numVars         != PETSC_NULL) {
    PetscValidIntPointer(numVars);
    *numVars         = grid->constraintOrder->numVars;
  }
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridGetConstraintContext"
/*@C
  GridGetConstraintContext - This function returns the constraint context or PETSC_NULL if no constraints exist.

  Not collective

  Input Parameter:
. grid - The grid

  Output Parameter:
. ctx  - The constraint context

  Level: intermediate

.keywords constraint, context
.seealso GridSetConstraintContext(), GridSetConstraints()
@*/
int GridGetConstraintContext(Grid grid, PetscConstraintObject *ctx)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  PetscValidPointer(ctx);
  *ctx = grid->constraintCtx;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridSetConstraintContext"
/*@C
  GridSetConstraintContext - This function sets the context for the constrained problem.

  Collective on Grid

  Input Parameters:
+ grid - The grid
- ctx  - The constraint context

  Level: intermediate

.keywords constraint, context
.seealso GridGetConstraintContext(), GridSetConstraints()
@*/
int GridSetConstraintContext(Grid grid, PetscConstraintObject ctx)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  grid->constraintCtx = ctx;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridGetConstraintMatrix"
/*@C
  GridGetConstraintMatrix - This function returns the projector from the constrained to the unconstrained variables,
  or PETSC_NULL if no projector exists.

  Collective on Grid

  Input Parameter:
. grid - The grid

  Output Parameters:
. P    - The projector from constrained to the unconstrained variables

  Level: intermediate

.keywords constraint
.seealso GridSetupConstraints()
@*/
int GridGetConstraintMatrix(Grid grid, GMat *P)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  PetscValidPointer(P);
  *P = grid->constraintMatrix;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "GridGetConstraintInverse"
/*@C
  GridGetConstraintInverse - This function returns the psuedo-inverse of the projector from the constrained
  to the unconstrained variables, or PETSC_NULL if no inverse exists.

  Collective on Grid

  Input Parameter:
. grid - The grid

  Output Parameter:
. invP - The pseudo-inverse of the projector from constrained to the unconstrained variables

  Level: intermediate

.keywords constraint
.seealso GridSetupConstraints()
@*/
int GridGetConstraintInverse(Grid grid, GMat *invP)
{
  PetscFunctionBegin;
  PetscValidHeaderSpecific(grid, GRID_COOKIE);
  PetscValidPointer(invP);
  *invP = grid->constraintInverse;
  PetscFunctionReturn(0);
}
