#ifdef PETSC_RCS_HEADER
static char vcid[] = "$Id: fieldClassMapReg.c,v 1.2 2000/01/10 03:54:17 knepley Exp $";
#endif

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

PetscFList FieldClassMapList                       = 0;
int        FieldClassMapRegisterAllCalled          = 0;
PetscFList FieldClassMapSerializeList              = 0;
int        FieldClassMapSerializeRegisterAllCalled = 0;
PetscFList FieldClassMapOrderingList               = 0;
int        FieldClassMapOrderingRegisterAllCalled  = 0;

#undef __FUNCT__  
#define __FUNCT__ "FieldClassMapSetType"
/*@C
  FieldClassMapSetType - Sets the creation method for the map.

  Collective on FieldClassMap

  Input Parameters:
+ map    - The FieldClassMap context
- method - A known method

  Options Database Command:
. -class_map_type <method> - Sets the method; use -help for a list
                             of available methods (for instance, tri2d)

  Notes:
  See "petsc/include/grid.h" for available methods (for instance)
. CLASS_MAP_TRIANGULAR_2D - Triangular 2D map

  Normally, it is best to use the FieldClassMapSetFromOptions() command and
  then set the FieldClassMap type from the options database rather than by using
  this routine.  Using the options database provides the user with
  maximum flexibility in evaluating the many different solvers.
  The FieldClassMapSetType() routine is provided for those situations
  where it is necessary to set the application ordering independently of the
  command line or options database.  This might be the case, for example,
  when the choice of solver changes during the execution of the
  program, and the user's application is taking responsibility for
  choosing the appropriate method.  In other words, this routine is
  not for beginners.

  Level: intermediate

.keywords: class, field class, class map, set, type
.seealso FieldClassMapSetSerializeType()
@*/
int FieldClassMapSetType(FieldClassMap map, FieldClassMapType method)
{
  int      (*r)(FieldClassMap);
  PetscTruth match;
  int        ierr;

  PetscFunctionBegin;
  PetscValidHeaderSpecific(map, CLASS_MAP_COOKIE);
  ierr = PetscTypeCompare((PetscObject) map, method, &match);                                             CHKERRQ(ierr);
  if (match == PETSC_TRUE) PetscFunctionReturn(0);

  /* Get the function pointers for the method requested */
  if (!FieldClassMapRegisterAllCalled) {
    ierr = FieldClassMapRegisterAll(PETSC_NULL);                                                          CHKERRQ(ierr);
  }
  ierr = PetscFListFind(map->comm, FieldClassMapList, method, (void (**)(void)) &r);                      CHKERRQ(ierr);
  if (!r) {
    SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Unknown method: %s", method);
  }

  if (map->ops->destroy) {
    ierr = (*map->ops->destroy)(map);                                                                     CHKERRQ(ierr);
  }
  ierr = (*r)(map);                                                                                       CHKERRQ(ierr);

  ierr = PetscObjectChangeTypeName((PetscObject) map, method);                                            CHKERRQ(ierr);
  PetscFunctionReturn(0);
}

#undef __FUNCT__
#define __FUNCT__ "FieldClassMapGetType"
/*@C
  FieldClassMapGetType - Gets the FieldClassMap method type and name (as a string).

  Not collective

  Input Parameter:
. map  - The map

  Output Parameter:
. type - The name of FieldClassMap method

  Level: intermediate

.keywords: class, field class, class map, get, type
.seealso FieldClassMapSetType()
@*/
int FieldClassMapGetType(FieldClassMap map, FieldClassMapType *type)
{
  int ierr;

  PetscFunctionBegin;
  PetscValidHeaderSpecific(map, CLASS_MAP_COOKIE);
  PetscValidPointer(type);
  if (!FieldClassMapRegisterAllCalled) {
    ierr = FieldClassMapRegisterAll(PETSC_NULL);                                                         CHKERRQ(ierr);
  }
  *type = map->type_name;
  PetscFunctionReturn(0);
}

#undef __FUNCT__  
#define __FUNCT__ "FieldClassMapSetSerializeType"
/*@C
  FieldClassMapSetSerializeType - Sets the serialization method for the map.

  Collective on FieldClassMap

  Input Parameters:
+ map    - The FieldClassMap context
- method - A known method

  Options Database Command:
. -class_map_serialize_type <method> - Sets the method; use -help for a list
            8                          of available methods (for instance, tri2d_binary)

  Notes:
  See "petsc/include/grid.h" for available methods (for instance)
. CLASS_MAP_SER_TRIANGULAR_2D_BINARY - Triangular 2D map to binary file

  Normally, it is best to use the FieldClassMapSetFromOptions() command and
  then set the FieldClassMap type from the options database rather than by using
  this routine.  Using the options database provides the user with
  maximum flexibility in evaluating the many different solvers.
  The FieldClassMapSetSerializeType() routine is provided for those situations
  where it is necessary to set the application ordering independently of the
  command line or options database.  This might be the case, for example,
  when the choice of solver changes during the execution of the
  program, and the user's application is taking responsibility for
  choosing the appropriate method.  In other words, this routine is
  not for beginners.

  Level: intermediate

.keywords: class, field class, class map, set, type, serialization
.seealso FieldClassMapSetType()
@*/
int FieldClassMapSetSerializeType(FieldClassMap map, FieldClassMapSerializeType method)
{
  int      (*r)(MPI_Comm, FieldClassMap *, PetscViewer, PetscTruth);
  PetscTruth match;
  int        ierr;

  PetscFunctionBegin;
  PetscValidHeaderSpecific(map, CLASS_MAP_COOKIE);
  ierr = PetscSerializeCompare((PetscObject) map, method, &match);                                        CHKERRQ(ierr);
  if (match == PETSC_TRUE) PetscFunctionReturn(0);

  /* Get the function pointers for the method requested but do not call */
  if (!FieldClassMapSerializeRegisterAllCalled) {
    ierr = FieldClassMapSerializeRegisterAll(PETSC_NULL);                                                 CHKERRQ(ierr);
  }
  ierr = PetscFListFind(map->comm, FieldClassMapSerializeList, method, (void (**)(void)) &r);             CHKERRQ(ierr);
  if (!r) {
    SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Unknown method: %s", method);
  }

  ierr = PetscObjectChangeSerializeName((PetscObject) map, method);                                       CHKERRQ(ierr);
  PetscFunctionReturn(0);
}

/*-------------------------------------------------------------------------------------------------------------------*/
#undef __FUNCT__  
#define __FUNCT__ "FieldClassMapRegisterDestroy"
/*@C
  FieldClassMapRegisterDestroy - Frees the list of creation routines for
  maps that were registered by PetscFListAdd().

  Not collective

  Level: advanced

.keywords: class, field class, class map, register, destroy
.seealso: FieldClassMapRegisterAll(), FieldClassMapSerializeRegisterDestroy()
@*/
int FieldClassMapRegisterDestroy()
{
  int ierr;

  PetscFunctionBegin;
  if (FieldClassMapList) {
    ierr = PetscFListDestroy(&FieldClassMapList);                                                         CHKERRQ(ierr);
    FieldClassMapList = PETSC_NULL;
  }
  FieldClassMapRegisterAllCalled = 0;
  PetscFunctionReturn(0);
}

#undef __FUNCT__  
#define __FUNCT__ "FieldClassMapSerializeRegisterDestroy"
/*@C
  FieldClassMapSerializeRegisterDestroy - Frees the list of serialization routines for
  maps that were registered by PetscFListAdd().

  Not collective

  Level: advanced

.keywords: class, field class, class map, serialization, register, destroy
.seealso: FieldClassMapSerializeRegisterAll(), FieldClassMapRegisterDestroy()
@*/
int FieldClassMapSerializeRegisterDestroy()
{
  int ierr;

  PetscFunctionBegin;
  if (FieldClassMapSerializeList) {
    ierr = PetscFListDestroy(&FieldClassMapSerializeList);                                                CHKERRQ(ierr);
    FieldClassMapSerializeList = PETSC_NULL;
  }
  FieldClassMapSerializeRegisterAllCalled = 0;
  PetscFunctionReturn(0);
}
