text: /*
   * -----------------------------------------------------------------
   * $Revision: 1.15 $
   * $Date: 2010/12/01 22:35:26 $
   * ----------------------------------------------------------------- 
   * Programmer(s): Alan Hindmarsh, Radu Serban and
   *                Aaron Collier @ LLNL
   * -----------------------------------------------------------------
   * Copyright (c) 2002, The Regents of the University of California  
   * Produced at the Lawrence Livermore National Laboratory
   * All rights reserved
   * For details, see the LICENSE file
   * -----------------------------------------------------------------
   * This is the implementation file for the optional inputs and     
   * outputs for the IDA solver.                                    
   * -----------------------------------------------------------------
   */
  
  #include <stdio.h>
  #include <stdlib.h>
  
  #include "ida_impl.h"
  
  #include <sundials/sundials_math.h>
  
  #define ZERO    RCONST(0.0)
  #define HALF    RCONST(0.5)
  #define ONE     RCONST(1.0)
  #define TWOPT5  RCONST(2.5)
  
  /* 
   * =================================================================
   * IDA optional input functions
   * =================================================================
   */
  
  /* 
   * Readability constants
   */
  
  #define lrw  (IDA_mem->ida_lrw)
  #define liw  (IDA_mem->ida_liw)
  #define lrw1 (IDA_mem->ida_lrw1)
  #define liw1 (IDA_mem->ida_liw1)
  
  int IDASetErrHandlerFn(void *ida_mem, IDAErrHandlerFn ehfun, void *eh_data)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetErrHandlerFn", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    IDA_mem->ida_ehfun = ehfun;
    IDA_mem->ida_eh_data = eh_data;
  
    return(IDA_SUCCESS);
  }
  
  
  int IDASetErrFile(void *ida_mem, FILE *errfp)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetErrFile", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    IDA_mem->ida_errfp = errfp;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetUserData(void *ida_mem, void *user_data)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetUserData", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    IDA_mem->ida_user_data = user_data;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetMaxOrd(void *ida_mem, int maxord)
  {
    IDAMem IDA_mem;
    int maxord_alloc;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetMaxOrd", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    if (maxord <= 0) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetMaxOrd", MSG_NEG_MAXORD);
      return(IDA_ILL_INPUT);
    }
  
    /* Cannot increase maximum order beyond the value that
       was used when allocating memory */
    maxord_alloc = IDA_mem->ida_maxord_alloc;
  
    if (maxord > maxord_alloc) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetMaxOrd", MSG_BAD_MAXORD);
      return(IDA_ILL_INPUT);
    }  
  
    IDA_mem->ida_maxord = MIN(maxord,MAXORD_DEFAULT);
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetMaxNumSteps(void *ida_mem, long int mxsteps)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetMaxNumSteps", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    /* Passing mxsteps=0 sets the default. Passing mxsteps<0 disables the test. */
  
    if (mxsteps == 0)
      IDA_mem->ida_mxstep = MXSTEP_DEFAULT;
    else
      IDA_mem->ida_mxstep = mxsteps;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetInitStep(void *ida_mem, realtype hin)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetInitStep", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    IDA_mem->ida_hin = hin;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetMaxStep(void *ida_mem, realtype hmax)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetMaxStep", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    if (hmax < 0) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetMaxStep", MSG_NEG_HMAX);
      return(IDA_ILL_INPUT);
    }
  
    /* Passing 0 sets hmax = infinity */
    if (hmax == ZERO) {
      IDA_mem->ida_hmax_inv = HMAX_INV_DEFAULT;
      return(IDA_SUCCESS);
    }
  
    IDA_mem->ida_hmax_inv = ONE/hmax;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetStopTime(void *ida_mem, realtype tstop)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetStopTime", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    /* If IDASolve was called at least once, test if tstop is legal
     * (i.e. if it was not already passed).
     * If IDASetStopTime is called before the first call to IDASolve,
     * tstop will be checked in IDASolve. */
    if (IDA_mem->ida_nst > 0) {
  
      if ( (tstop - IDA_mem->ida_tn) * IDA_mem->ida_hh < ZERO ) {
        IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetStopTime", MSG_BAD_TSTOP, IDA_mem->ida_tn);
        return(IDA_ILL_INPUT);
      }
  
    }
  
    IDA_mem->ida_tstop = tstop;
    IDA_mem->ida_tstopset = TRUE;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetNonlinConvCoef(void *ida_mem, realtype epcon)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetNonlinConvCoef", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    if (epcon <= ZERO) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetNonlinConvCoef", MSG_NEG_EPCON);
      return(IDA_ILL_INPUT);
    }
  
    IDA_mem->ida_epcon = epcon;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetMaxErrTestFails(void *ida_mem, int maxnef)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetMaxErrTestFails", MSG_NO_MEM);
      return (IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    IDA_mem->ida_maxnef = maxnef;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetMaxConvFails(void *ida_mem, int maxncf)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetMaxConvFails", MSG_NO_MEM);
      return (IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    IDA_mem->ida_maxncf = maxncf;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetMaxNonlinIters(void *ida_mem, int maxcor)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetMaxNonlinIters", MSG_NO_MEM);
      return (IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    IDA_mem->ida_maxcor = maxcor;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetSuppressAlg(void *ida_mem, booleantype suppressalg)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetSuppressAlg", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    IDA_mem->ida_suppressalg = suppressalg;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetId(void *ida_mem, N_Vector id)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetId", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    if (id == NULL) {
      if (IDA_mem->ida_idMallocDone) {
        N_VDestroy(IDA_mem->ida_id);
        lrw -= lrw1;
        liw -= liw1;
      }
      IDA_mem->ida_idMallocDone = FALSE;    
      return(IDA_SUCCESS);
    }
  
    if ( !(IDA_mem->ida_idMallocDone) ) {
      IDA_mem->ida_id = N_VClone(id);
      lrw += lrw1;
      liw += liw1;
      IDA_mem->ida_idMallocDone = TRUE;
    }
  
    /* Load the id vector */
  
    N_VScale(ONE, id, IDA_mem->ida_id);
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetConstraints(void *ida_mem, N_Vector constraints)
  {
    IDAMem IDA_mem;
    realtype temptest;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetConstraints", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    if (constraints == NULL) {
      if (IDA_mem->ida_constraintsMallocDone) {
        N_VDestroy(IDA_mem->ida_constraints);
        lrw -= lrw1;
        liw -= liw1;
      }
      IDA_mem->ida_constraintsMallocDone = FALSE;
      IDA_mem->ida_constraintsSet = FALSE;
      return(IDA_SUCCESS);
    }
  
    /* Test if required vector ops. are defined */
  
    if (constraints->ops->nvdiv         == NULL ||
        constraints->ops->nvmaxnorm     == NULL ||
        constraints->ops->nvcompare     == NULL ||
        constraints->ops->nvconstrmask  == NULL ||
        constraints->ops->nvminquotient == NULL) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetConstraints", MSG_BAD_NVECTOR);
      return(IDA_ILL_INPUT);
    }
  
    /*  Check the constraints vector */
  
    temptest = N_VMaxNorm(constraints);
    if((temptest > TWOPT5) || (temptest < HALF)){ 
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetConstraints", MSG_BAD_CONSTR);
      return(IDA_ILL_INPUT); 
    }
  
    if ( !(IDA_mem->ida_constraintsMallocDone) ) {
      IDA_mem->ida_constraints = N_VClone(constraints);
      lrw += lrw1;
      liw += liw1;
      IDA_mem->ida_constraintsMallocDone = TRUE;
    }
  
    /* Load the constraints vector */
  
    N_VScale(ONE, constraints, IDA_mem->ida_constraints);
  
    IDA_mem->ida_constraintsSet = TRUE;
  
    return(IDA_SUCCESS);
  }
  
  /* 
   * IDASetRootDirection
   *
   * Specifies the direction of zero-crossings to be monitored.
   * The default is to monitor both crossings.
   */
  
  int IDASetRootDirection(void *ida_mem, int *rootdir)
  {
    IDAMem IDA_mem;
    int i, nrt;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetRootDirection", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    nrt = IDA_mem->ida_nrtfn;
    if (nrt==0) {
      IDAProcessError(NULL, IDA_ILL_INPUT, "IDA", "IDASetRootDirection", MSG_NO_ROOT);
      return(IDA_ILL_INPUT);    
    }
  
    for(i=0; i<nrt; i++) IDA_mem->ida_rootdir[i] = rootdir[i];
  
    return(IDA_SUCCESS);
  }
  
  /*
   * IDASetNoInactiveRootWarn
   *
   * Disables issuing a warning if some root function appears
   * to be identically zero at the beginning of the integration
   */
  
  int IDASetNoInactiveRootWarn(void *ida_mem)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetNoInactiveRootWarn", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    IDA_mem->ida_mxgnull = 0;
    
    return(IDA_SUCCESS);
  }
  
  
  /* 
   * =================================================================
   * IDA IC optional input functions
   * =================================================================
   */
  
  int IDASetNonlinConvCoefIC(void *ida_mem, realtype epiccon)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetNonlinConvCoefIC", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    if (epiccon <= ZERO) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetNonlinConvCoefIC", MSG_BAD_EPICCON);
      return(IDA_ILL_INPUT);
    }
  
    IDA_mem->ida_epiccon = epiccon;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetMaxNumStepsIC(void *ida_mem, int maxnh)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetMaxNumStepsIC", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    if (maxnh <= 0) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetMaxNumStepsIC", MSG_BAD_MAXNH);
      return(IDA_ILL_INPUT);
    }
  
    IDA_mem->ida_maxnh = maxnh;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetMaxNumJacsIC(void *ida_mem, int maxnj)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetMaxNumJacsIC", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
     if (maxnj <= 0) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetMaxNumJacsIC", MSG_BAD_MAXNJ);
      return(IDA_ILL_INPUT);
    } 
  
    IDA_mem->ida_maxnj = maxnj;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetMaxNumItersIC(void *ida_mem, int maxnit)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetMaxNumItersIC", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    if (maxnit <= 0) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetMaxNumItersIC", MSG_BAD_MAXNIT);
      return(IDA_ILL_INPUT);
    }
  
    IDA_mem->ida_maxnit = maxnit;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetLineSearchOffIC(void *ida_mem, booleantype lsoff)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetLineSearchOffIC", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    IDA_mem->ida_lsoff = lsoff;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDASetStepToleranceIC(void *ida_mem, realtype steptol)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetStepToleranceIC", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    if (steptol <= ZERO) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetStepToleranceIC", MSG_BAD_STEPTOL);
      return(IDA_ILL_INPUT);
    }
  
    IDA_mem->ida_steptol = steptol;
  
    return(IDA_SUCCESS);
  }
  
  /* 
   * =================================================================
   * Readability constants
   * =================================================================
   */
  
  #define ewt         (IDA_mem->ida_ewt)
  #define kk          (IDA_mem->ida_kk)
  #define hh          (IDA_mem->ida_hh)
  #define h0u         (IDA_mem->ida_h0u)
  #define tn          (IDA_mem->ida_tn)
  #define nbacktr     (IDA_mem->ida_nbacktr)
  #define nst         (IDA_mem->ida_nst)
  #define nre         (IDA_mem->ida_nre)
  #define ncfn        (IDA_mem->ida_ncfn)
  #define netf        (IDA_mem->ida_netf)
  #define nni         (IDA_mem->ida_nni)
  #define nsetups     (IDA_mem->ida_nsetups)
  #define lrw         (IDA_mem->ida_lrw)
  #define liw         (IDA_mem->ida_liw)
  #define kused       (IDA_mem->ida_kused)          
  #define hused       (IDA_mem->ida_hused)         
  #define tolsf       (IDA_mem->ida_tolsf) 
  #define efun        (IDA_mem->ida_efun)
  #define edata       (IDA_mem->ida_edata)
  #define nge         (IDA_mem->ida_nge)
  #define iroots      (IDA_mem->ida_iroots)
  #define ee          (IDA_mem->ida_ee)
  
  /* 
   * =================================================================
   * IDA optional input functions
   * =================================================================
   */
  
  int IDAGetNumSteps(void *ida_mem, long int *nsteps)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetNumSteps", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *nsteps = nst;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetNumResEvals(void *ida_mem, long int *nrevals)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetNumResEvals", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *nrevals = nre;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetNumLinSolvSetups(void *ida_mem, long int *nlinsetups)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetNumLinSolvSetups", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *nlinsetups = nsetups;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetNumErrTestFails(void *ida_mem, long int *netfails)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetNumErrTestFails", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *netfails = netf;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetNumBacktrackOps(void *ida_mem, long int *nbacktracks)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetNumBacktrackOps", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *nbacktracks = nbacktr;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetConsistentIC(void *ida_mem, N_Vector yy0, N_Vector yp0)
  {
    IDAMem IDA_mem;
    
    if (ida_mem == NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetConsistentIC", MSG_NO_MEM);
      return (IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem; 
  
    if (IDA_mem->ida_kused != 0) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAGetConsistentIC", MSG_TOO_LATE);
      return(IDA_ILL_INPUT);
    }
  
    if(yy0 != NULL) N_VScale(ONE, IDA_mem->ida_phi[0], yy0);
    if(yp0 != NULL) N_VScale(ONE, IDA_mem->ida_phi[1], yp0);
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetLastOrder(void *ida_mem, int *klast)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetLastOrder", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *klast = kused;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetCurrentOrder(void *ida_mem, int *kcur)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetCurrentOrder", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *kcur = kk;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetActualInitStep(void *ida_mem, realtype *hinused)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetActualInitStep", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *hinused = h0u;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetLastStep(void *ida_mem, realtype *hlast)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetLastStep", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *hlast = hused;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetCurrentStep(void *ida_mem, realtype *hcur)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetCurrentStep", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *hcur = hh;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetCurrentTime(void *ida_mem, realtype *tcur)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetCurrentTime", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *tcur = tn;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetTolScaleFactor(void *ida_mem, realtype *tolsfact)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetTolScaleFactor", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *tolsfact = tolsf;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetErrWeights(void *ida_mem, N_Vector eweight)
  {
    IDAMem IDA_mem;
    
    if (ida_mem == NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetErrWeights", MSG_NO_MEM);
      return (IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem; 
  
    N_VScale(ONE, ewt, eweight);
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetEstLocalErrors(void *ida_mem, N_Vector ele)
  {
    IDAMem IDA_mem;
  
    if (ida_mem == NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetEstLocalErrors", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
    IDA_mem = (IDAMem) ida_mem;
  
    N_VScale(ONE, ee, ele);
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetWorkSpace(void *ida_mem, long int *lenrw, long int *leniw)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetWorkSpace", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *leniw = liw;
    *lenrw = lrw;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetIntegratorStats(void *ida_mem, long int *nsteps, long int *nrevals, 
                            long int *nlinsetups, long int *netfails,
                            int *klast, int *kcur, realtype *hinused, realtype *hlast, 
                            realtype *hcur, realtype *tcur)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetIntegratorStats", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *nsteps     = nst;
    *nrevals    = nre;
    *nlinsetups = nsetups;
    *netfails   = netf;
    *klast      = kused;
    *kcur       = kk;
    *hinused    = h0u;
    *hlast      = hused;
    *hcur       = hh;  
    *tcur       = tn;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetNumGEvals(void *ida_mem, long int *ngevals)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetNumGEvals", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *ngevals = nge;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetRootInfo(void *ida_mem, int *rootsfound)
  {
    IDAMem IDA_mem;
    int i, nrt;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetRootInfo", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    nrt = IDA_mem->ida_nrtfn;
  
    for (i=0; i<nrt; i++) rootsfound[i] = iroots[i];
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetNumNonlinSolvIters(void *ida_mem, long int *nniters)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetNumNonlinSolvIters", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *nniters = nni;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetNumNonlinSolvConvFails(void *ida_mem, long int *nncfails)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetNumNonlinSolvConvFails", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *nncfails = ncfn;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  int IDAGetNonlinSolvStats(void *ida_mem, long int *nniters, long int *nncfails)
  {
    IDAMem IDA_mem;
  
    if (ida_mem==NULL) {
      IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDAGetNonlinSolvStats", MSG_NO_MEM);
      return(IDA_MEM_NULL);
    }
  
    IDA_mem = (IDAMem) ida_mem;
  
    *nniters  = nni;
    *nncfails = ncfn;
  
    return(IDA_SUCCESS);
  }
  
  /*-----------------------------------------------------------------*/
  
  char *IDAGetReturnFlagName(long int flag)
  {
    char *name;
  
    name = (char *)malloc(24*sizeof(char));
  
    switch(flag) {
    case IDA_SUCCESS:
      sprintf(name,"IDA_SUCCESS");
      break;
    case IDA_TSTOP_RETURN:
      sprintf(name,"IDA_TSTOP_RETURN");
      break;
    case IDA_ROOT_RETURN:
      sprintf(name,"IDA_ROOT_RETURN");
      break;
    case IDA_TOO_MUCH_WORK:
      sprintf(name,"IDA_TOO_MUCH_WORK");
      break;
    case IDA_TOO_MUCH_ACC:
      sprintf(name,"IDA_TOO_MUCH_ACC");
      break;
    case IDA_ERR_FAIL:
      sprintf(name,"IDA_ERR_FAIL");
      break;
    case IDA_CONV_FAIL:
      sprintf(name,"IDA_CONV_FAIL");
      break;
    case IDA_LINIT_FAIL:
      sprintf(name,"IDA_LINIT_FAIL");
      break;
    case IDA_LSETUP_FAIL:
      sprintf(name,"IDA_LSETUP_FAIL");
      break;
    case IDA_LSOLVE_FAIL:
      sprintf(name,"IDA_LSOLVE_FAIL");
      break;
    case IDA_CONSTR_FAIL:
      sprintf(name,"IDA_CONSTR_FAIL");
      break;
    case IDA_RES_FAIL:
      sprintf(name,"IDA_RES_FAIL");
      break;
    case IDA_FIRST_RES_FAIL:
      sprintf(name,"IDA_FIRST_RES_FAIL");
      break;
    case IDA_REP_RES_ERR:
      sprintf(name,"IDA_REP_RES_ERR");
      break;
    case IDA_RTFUNC_FAIL:
      sprintf(name,"IDA_RTFUNC_FAIL");
      break;
    case IDA_MEM_FAIL:
      sprintf(name,"IDA_MEM_FAIL");
      break;
    case IDA_MEM_NULL:
      sprintf(name,"IDA_MEM_NULL");
      break;
    case IDA_ILL_INPUT:
      sprintf(name,"IDA_ILL_INPUT");
      break;
    case IDA_NO_MALLOC:
      sprintf(name,"IDA_NO_MALLOC");
      break;
    case IDA_BAD_T:
      sprintf(name,"IDA_BAD_T");
      break;
    case IDA_BAD_EWT:
      sprintf(name,"IDA_BAD_EWT");
      break;
    case IDA_NO_RECOVERY:
      sprintf(name,"IDA_NO_RECOVERY");
      break;
    case IDA_LINESEARCH_FAIL:
      sprintf(name,"IDA_LINESEARCH_FAIL");
      break;
  
    default:
      sprintf(name,"NONE");
    }
  
    return(name);
  }
  
  