/* 
 * file:   ssman1d_init.c 
 * author: Hinke Osinga and Reza Rokni --- University of Exeter
 * date:   April 2001
 */

/*
 * release_ssman1d(struct Fixpt_DataS*)
 * ssman1d_load(struct Fixpt_DataS*, int )
 * ssman1d_compute_init(void)
 * suman1d_compute_init(void)
 */

#include <stdio.h>
#include <math.h>

#include "math_utils.h"
#include "constants.h"
#include "prop.h"
#include "modellib.h"
#include "defaults.h"
#include "pm.h"
#include "fixed.h"
#include "flow.h"
#include "utilities.h"
#include "ssman1d.h"

/*
 * release_ssman1d(fp)
 *         fp is a pointer to the fixed point data structure
 * 
 * procedure to free up the memory allocated with the fixed point data 
 * structure 
 * identical to release_fp(fp, 1) defined in $DSTOOL/src/fixed/fp_init.c
 */
void release_ssman1d(struct Fixpt_DataS* fp)
{
  int traj_length;
  int var_dim = fp->prop_cntl.ph_space_dim - 1;

  traj_length = (fp->stab_steps*fp->stab_pts > 
		 fp->unstab_steps*fp->unstab_pts) ?
    (fp->stab_steps*fp->stab_pts) : (fp->unstab_steps*fp->unstab_pts);

  comp_free(&(fp->prop_cntl));
  release_integ(&(fp->prop_cntl),traj_length);

  free_ivector(fp->indx,0,var_dim);
  free_dvector(fp->x1,0,var_dim);
  free_dvector(fp->x2,0,var_dim);
  free_dvector(fp->x3,0,var_dim);
  free_dvector(fp->fx,0,var_dim);
  free_dmatrix(fp->jacobian,0,var_dim, 0, var_dim);
  free_dmatrix(fp->jact,0,var_dim, 0, var_dim);
  free_dmatrix(fp->eval,0,1,0,var_dim);
  free_dmatrix(fp->evectors,0,var_dim,0,var_dim);

  fp->indx = (int *) NULL;
  fp->x1 = fp->x2 = fp->x3 = fp->fx = (double *) NULL;
  fp->jacobian = fp->jact = fp->eval = fp->evectors = (double **) NULL;
}

/*
 * ssman1d_load(fp, us)
 *       fp is a pointer to the fixed point data structure
 *       us is an integer telling whether we prepare to computed
 *       strong stable or strong unstable manifolds 
 *
 * us: 0 for strong stable manifold
 *     1 for strong unstable manifold
 * 
 * procedure to allocate memory and load the fixed point data structure
 * similar to load_fp(fp, 1) defined in $DSTOOL/src/fixed/fp_init.c
 *   the only difference is the option for stable or unstable manifold.
 */
int ssman1d_load(struct Fixpt_DataS* fp, int us)
{
  int traj_length;
  int var_dim, status=0;

  if ((us != 0) && (us != 1)){
    system_mess_proc(1,"ssman1d_load: flag should be 0 for strong stable or 1 for strong unstable manifold \n");
    return(-1);
  }

  /* load info from fixed panel via the postmaster */
  /* Some of this info is needed in computing the Jacobian!!!! */
  fp->fd_step = *((double *) pm(GET, "Fixed.FD_Step", NULL));
  fp->dup = *((double *) pm(GET, "Fixed.Dups", NULL));
  fp->varb_conv = *((double *) pm(GET, "Fixed.Var_Conv", NULL));
  fp->funct_conv = *((double *) pm(GET, "Fixed.Funct_Conv", NULL));

  /* load other info from ssman1d panel via the postmaster */
  fp->eigen_dist = *((double *) pm(GET, "SSMan1D.Ini_Step", NULL));

  if (us == 0){
    fp->stab_pts = 1;
    fp->stab_steps = *((int *) pm(GET, "SSMan1D.Tot_Steps", NULL));
    fp->unstab_pts = 0;
    fp->unstab_steps = 0;
    traj_length = fp->stab_steps * fp->stab_pts;
  }

  if (us == 1){
    fp->stab_pts = 0;
    fp->stab_steps = 0;
    fp->unstab_pts = 1;
    fp->unstab_steps = *((int *) pm(GET, "SSMan1D.Tot_Steps", NULL));
    traj_length = fp->unstab_steps * fp->unstab_pts;
  }

  fp->memory = (memory) pm(GET, "Memory.Fixed", NULL);

  /* setup propagation structure */
  fp->prop_cntl.direction = FORWARD;
  fp->prop_cntl.iterations = traj_length;
  fp->prop_cntl.start_to_save = 0;
  fp->prop_cntl.time_step = *((double *) pm( GET, "Flow.Stepsize", NULL));
  fp->prop_cntl.prop_mode = PROP_NSTEP;
  fp->prop_cntl.f_iter = fp->prop_cntl.f_skip =
    *((int *) pm(GET, "Flow.Skip_Size", NULL));
  fp->prop_cntl.table_color = -1; /* system color */

  /* do memory allocations */
  if (allocate_integ(&(fp->prop_cntl),traj_length)) status = -1;
  var_dim = fp->prop_cntl.ph_space_dim -1;
  if (!(fp->indx = ivector(0,var_dim))) status= -1;
  if (!(fp->x1 = dvector(0,var_dim))) status= -1;
  if (!(fp->x2 = dvector(0,var_dim))) status= -1;
  if (!(fp->x3 = dvector(0,var_dim))) status= -1;
  if (!(fp->fx = dvector(0,var_dim))) status= -1;
  if (!(fp->jacobian = dmatrix(0,var_dim, 0 , var_dim))) status= -1;
  if (!(fp->jact = dmatrix(0,var_dim, 0 , var_dim))) status= -1;
  if (!(fp->eval = dmatrix(0,1,0,var_dim))) status= -1;
  if (!(fp->evectors = dmatrix(0,var_dim,0,var_dim))) status= -1;

  if (comp_alloc(&(fp->prop_cntl))) status = -1;
  else comp_def_setup(&(fp->prop_cntl));

  if (status == -1){
    system_mess_proc(1,"ssman1d_load: Memory Allocation Failure \n");
    release_ssman1d(fp);
  }

  return(status);
}

/* 
 * ssman1d_compute_init()
 * 
 * prodcedure called to compute the strong stable manifold.
 * results are stored in the fixed point memory object and displayed.
 * 
 * NOTE: currently only manifolds of vector fields are implemented.
 *
 * identical to fp_1dman_init() defined in $DSTOOL/src/fixed/fp_init.c
 */
void ssman1d_compute_init()
{
  struct Fixpt_DataS fixpt_cntl;
	
  if (ssman1d_load(&fixpt_cntl,0) == -1){
    system_mess_proc(1,"ssman1d_init: Memory alloc error.");
    return;
  }

  s1dman_compute(&fixpt_cntl,0);
  release_ssman1d(&fixpt_cntl);
  pm(EXEC, "Memory.Count", NULL);
  return;
}

/* 
 * suman1d_compute_init()
 * 
 * prodcedure called to compute the strong unstable manifold.
 * results are stored in the fixed point memory object and displayed.
 * 
 * NOTE: currently only manifolds of vector fields are implemented.
 *
 * identical to fp_1dman_init() defined in $DSTOOL/src/fixed/fp_init.c
 */
void suman1d_compute_init()
{
  struct Fixpt_DataS fixpt_cntl;
	
  if (ssman1d_load(&fixpt_cntl,1) == -1){
    system_mess_proc(1,"usman_init: Memory alloc error.");
    return;
  }
	
  s1dman_compute(&fixpt_cntl,1);
  release_ssman1d(&fixpt_cntl);
  pm(EXEC, "Memory.Count", NULL);
  return;
}











