#define PETSCTS_DLL

#include "src/ts/tsimpl.h"      /*I "petscts.h"  I*/

#undef __FUNCT__  
#define __FUNCT__ "TSPublish_Petsc"
static PetscErrorCode TSPublish_Petsc(PetscObject obj)
{
  PetscFunctionBegin;
  PetscFunctionReturn(0);
}

#undef  __FUNCT__
#define __FUNCT__ "TSCreate"
/*@C
  TSCreate - This function creates an empty timestepper. The problem type can then be set with TSSetProblemType() and the 
       type of solver can then be set with TSSetType().

  Collective on MPI_Comm

  Input Parameter:
. comm - The communicator

  Output Parameter:
. ts   - The TS

  Level: beginner

.keywords: TS, create
.seealso: TSSetType(), TSSetUp(), TSDestroy(), MeshCreate(), TSSetProblemType()
@*/
PetscErrorCode PETSCTS_DLLEXPORT TSCreate(MPI_Comm comm, TS *ts) {
  TS             t;
  PetscErrorCode ierr;

  PetscFunctionBegin;
  PetscValidPointer(ts,1);
  *ts = PETSC_NULL;
#ifndef PETSC_USE_DYNAMIC_LIBRARIES
  ierr = TSInitializePackage(PETSC_NULL);CHKERRQ(ierr);
#endif

  ierr = PetscHeaderCreate(t, _p_TS, struct _TSOps, TS_COOKIE, -1, "TS", comm, TSDestroy, TSView);CHKERRQ(ierr);
  ierr = PetscLogObjectMemory(t, sizeof(struct _p_TS));CHKERRQ(ierr);
  ierr = PetscMemzero(t->ops, sizeof(struct _TSOps));CHKERRQ(ierr);
  t->bops->publish    = TSPublish_Petsc;
  t->type_name        = PETSC_NULL;

  t->ops->applymatrixbc = TSDefaultSystemMatrixBC;
  t->ops->applyrhsbc    = TSDefaultRhsBC;
  t->ops->applysolbc    = TSDefaultSolutionBC;
  t->ops->prestep       = TSDefaultPreStep;
  t->ops->update        = TSDefaultUpdate;
  t->ops->poststep      = TSDefaultPostStep;

  /* General TS description */
  t->problem_type       = TS_LINEAR;
  t->vec_sol            = PETSC_NULL;
  t->vec_sol_always     = PETSC_NULL;
  t->numbermonitors     = 0;
  t->isGTS              = PETSC_FALSE;
  t->isExplicit         = PETSC_NULL;
  t->Iindex             = PETSC_NULL;
  t->ksp               = PETSC_NULL;
  t->A                  = PETSC_NULL;
  t->B                  = PETSC_NULL;
  t->snes               = PETSC_NULL;
  t->funP               = PETSC_NULL;
  t->jacP               = PETSC_NULL;
  t->setupcalled        = 0;
  t->data               = PETSC_NULL;
  t->user               = PETSC_NULL;
  t->max_steps          = 5000;
  t->max_time           = 5.0;
  t->time_step          = .1;
  t->time_step_old      = t->time_step;
  t->initial_time_step  = t->time_step;
  t->steps              = 0;
  t->ptime              = 0.0;
  t->linear_its         = 0;
  t->nonlinear_its      = 0;
  t->work               = PETSC_NULL;
  t->nwork              = 0;

  *ts = t;
  PetscFunctionReturn(0);
}

#undef __FUNCT__  
#define __FUNCT__ "TSScaleShiftMatrices"
PetscErrorCode TSScaleShiftMatrices(TS ts,Mat A,Mat B,MatStructure str)
{
  PetscTruth     flg;
  PetscErrorCode ierr;
  PetscScalar    mone = -1,mdt = 1.0/ts->time_step;

  PetscFunctionBegin;
  ierr = PetscTypeCompare((PetscObject)ts->A,MATMFFD,&flg);CHKERRQ(ierr);
  if (!flg) {
    ierr = MatScale(ts->A,mone);CHKERRQ(ierr);
    ierr = MatShift(ts->A,mdt);CHKERRQ(ierr);
  }
  if (ts->B != ts->A && str != SAME_PRECONDITIONER) {
    ierr = MatScale(ts->B,mone);CHKERRQ(ierr);
    ierr = MatShift(ts->B,mdt);CHKERRQ(ierr);
  }
  PetscFunctionReturn(0);
}
