realtype N_VMin_SensWrapper(N_Vector x)
{
  int i;
  realtype min, tmp;

  min = N_VMin(NV_VEC_SW(x,0));

  for (i=1; i < NV_NVECS_SW(x); i++) {
    tmp = N_VMin(NV_VEC_SW(x,i));
    if (tmp < min) min = tmp;
  }

  return(min);
}
Example #2
0
/* Fortran interface routine to set residual tolerance 
   scalar/array; functions as an all-in-one interface to the C 
   routines ARKodeResStolerance and ARKodeResVtolerance; 
   see farkode.h for further details */
void FARK_SETRESTOLERANCE(int *itol, realtype *atol, int *ier) {

  N_Vector Vatol;
  realtype abstol;

  *ier = 0;

  /* Set tolerance, based on itol argument */
  abstol=1.e-9;
  switch (*itol) {
  case 1:
    if (*atol > 0.0)  abstol = *atol;
    *ier = ARKodeResStolerance(ARK_arkodemem, abstol); 
    break;
  case 2:
    Vatol = NULL;
    Vatol = N_VCloneEmpty(F2C_ARKODE_vec);
    if (Vatol == NULL) {
      *ier = -1;
      return;
    }
    N_VSetArrayPointer(atol, Vatol);
    if (N_VMin(Vatol) <= 0.0)  N_VConst(abstol, Vatol);
    *ier = ARKodeResVtolerance(ARK_arkodemem, Vatol);
    N_VDestroy(Vatol);
    break;
  }

  return;
}
Example #3
0
int CVodeSetQuadTolerances(void *cvode_mem, int itolQ, 
                           realtype *reltolQ, void *abstolQ)
{
  CVodeMem cv_mem;
  booleantype neg_abstol;

  if (cvode_mem==NULL) {
    fprintf(stderr, MSGCVS_SET_NO_MEM);
    return(CV_MEM_NULL);
  }
  
  cv_mem = (CVodeMem) cvode_mem;

  if ((itolQ != CV_SS) && (itolQ != CV_SV)) {
    if(errfp!=NULL) fprintf(errfp, MSGCVS_BAD_ITOLQ);
    return(CV_ILL_INPUT);
  }

  if (reltolQ == NULL) {
    if(errfp!=NULL) fprintf(errfp, MSGCVS_RELTOLQ_NULL);
    return(CV_ILL_INPUT);
  }
  
  if (*reltolQ < ZERO) {
    if(errfp!=NULL) fprintf(errfp, MSGCVS_BAD_RELTOLQ);
    return(CV_ILL_INPUT);
  }

  if (abstolQ == NULL) {
    if(errfp!=NULL) fprintf(errfp, MSGCVS_ABSTOLQ_NULL);
    return(CV_ILL_INPUT);
  }

  if (itolQ == CV_SS) {
    neg_abstol = (*((realtype *)abstolQ) < ZERO);
  } else {
    neg_abstol = (N_VMin((N_Vector)abstolQ) < ZERO);
  }
  if (neg_abstol) {
    if(errfp!=NULL) fprintf(errfp, MSGCVS_BAD_ABSTOLQ);
    return(CV_ILL_INPUT);
  }

  cv_mem->cv_itolQ    = itolQ;
  cv_mem->cv_reltolQ  = reltolQ;
  cv_mem->cv_abstolQ  = abstolQ;
  
  return(CV_SUCCESS);
}
Example #4
0
int IDACalcIC(void *ida_mem, int icopt, realtype tout1)
{
  int ewtsetOK;
  int ier, nwt, nh, mxnh, icret, retval=0;
  realtype tdist, troundoff, minid, hic, ypnorm;
  IDAMem IDA_mem;

  /* Check if IDA memory exists */

  if(ida_mem == NULL) {
    IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDACalcIC", MSG_NO_MEM);
    return(IDA_MEM_NULL);
  }
  IDA_mem = (IDAMem) ida_mem;

  /* Check if problem was malloc'ed */
  
  if(IDA_mem->ida_MallocDone == FALSE) {
    IDAProcessError(IDA_mem, IDA_NO_MALLOC, "IDA", "IDACalcIC", MSG_NO_MALLOC);
    return(IDA_NO_MALLOC);
  }

  /* Check inputs to IDA for correctness and consistency */

  ier = IDAInitialSetup(IDA_mem);
  if(ier != IDA_SUCCESS) return(IDA_ILL_INPUT);
  IDA_mem->ida_SetupDone = TRUE;

  /* Check legality of input arguments, and set IDA memory copies. */

  if(icopt != IDA_YA_YDP_INIT && icopt != IDA_Y_INIT) {
    IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDACalcIC", MSG_IC_BAD_ICOPT);
    return(IDA_ILL_INPUT);
  }
  IDA_mem->ida_icopt = icopt;

  if(icopt == IDA_YA_YDP_INIT && (id == NULL)) {
    IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDACalcIC", MSG_IC_MISSING_ID);
    return(IDA_ILL_INPUT);
  }

  tdist = SUNRabs(tout1 - tn);
  troundoff = TWO*uround*(SUNRabs(tn) + SUNRabs(tout1));
  if(tdist < troundoff) {
    IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDACalcIC", MSG_IC_TOO_CLOSE);
    return(IDA_ILL_INPUT);
  }

  /* Allocate space and initialize temporary vectors */

  yy0 = N_VClone(ee);
  yp0 = N_VClone(ee);
  t0  = tn;
  N_VScale(ONE, phi[0], yy0);
  N_VScale(ONE, phi[1], yp0);

  /* For use in the IDA_YA_YP_INIT case, set sysindex and tscale. */

  IDA_mem->ida_sysindex = 1;
  IDA_mem->ida_tscale   = tdist;
  if(icopt == IDA_YA_YDP_INIT) {
    minid = N_VMin(id);
    if(minid < ZERO) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDACalcIC", MSG_IC_BAD_ID);
      return(IDA_ILL_INPUT);
    }
    if(minid > HALF) IDA_mem->ida_sysindex = 0;
  }

  /* Set the test constant in the Newton convergence test */

  IDA_mem->ida_epsNewt = epiccon;

  /* Initializations: 
     cjratio = 1 (for use in direct linear solvers); 
     set nbacktr = 0; */

  cjratio = ONE;
  nbacktr = 0;

  /* Set hic, hh, cj, and mxnh. */

  hic = PT001*tdist;
  ypnorm = IDAWrmsNorm(IDA_mem, yp0, ewt, suppressalg);
  if(ypnorm > HALF/hic) hic = HALF/ypnorm;
  if(tout1 < tn) hic = -hic;
  hh = hic;
  if(icopt == IDA_YA_YDP_INIT) {
    cj = ONE/hic;
    mxnh = maxnh;
  }
  else {
    cj = ZERO;
    mxnh = 1;
  }

  /* Loop over nwt = number of evaluations of ewt vector. */

  for(nwt = 1; nwt <= 2; nwt++) {
 
    /* Loop over nh = number of h values. */
    for(nh = 1; nh <= mxnh; nh++) {

      /* Call the IC nonlinear solver function. */
      retval = IDAnlsIC(IDA_mem);

      /* Cut h and loop on recoverable IDA_YA_YDP_INIT failure; else break. */
      if(retval == IDA_SUCCESS) break;
      ncfn++;
      if(retval < 0) break;
      if(nh == mxnh) break;
      /* If looping to try again, reset yy0 and yp0 if not converging. */
      if(retval != IC_SLOW_CONVRG) {
        N_VScale(ONE, phi[0], yy0);
        N_VScale(ONE, phi[1], yp0);
      }
      hic *= PT1;
      cj = ONE/hic;
      hh = hic;
    }   /* End of nh loop */

    /* Break on failure; else reset ewt, save yy0, yp0 in phi, and loop. */
    if(retval != IDA_SUCCESS) break;
    ewtsetOK = efun(yy0, ewt, edata);
    if(ewtsetOK != 0) { 
      retval = IDA_BAD_EWT; 
      break; 
    }
    N_VScale(ONE, yy0, phi[0]);
    N_VScale(ONE, yp0, phi[1]);

  }   /* End of nwt loop */

  /* Free temporary space */

  N_VDestroy(yy0);
  N_VDestroy(yp0);

  /* Load the optional outputs. */

  if(icopt == IDA_YA_YDP_INIT)   hused = hic;

  /* On any failure, print message and return proper flag. */

  if(retval != IDA_SUCCESS) {
    icret = IDAICFailFlag(IDA_mem, retval);
    return(icret);
  }

  /* Otherwise return success flag. */

  return(IDA_SUCCESS);

}
int IDASetTolerances(void *ida_mem, 
                     int itol, realtype rtol, void *atol)
{
  IDAMem IDA_mem;
  booleantype neg_atol;

  if (ida_mem==NULL) {
    IDAProcessError(NULL, IDA_MEM_NULL, "IDA", "IDASetTolerances", MSG_NO_MEM);
    return(IDA_MEM_NULL);
  }

  IDA_mem = (IDAMem) ida_mem;

  /* Check if ida_mem was allocated */

  if (IDA_mem->ida_MallocDone == FALSE) {
    IDAProcessError(IDA_mem, IDA_NO_MALLOC, "IDA", "IDASetTolerances", MSG_NO_MALLOC);
    return(IDA_NO_MALLOC);
  }

  /* Check inputs */

  if ((itol != IDA_SS) && (itol != IDA_SV)) {
    IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetTolerances", MSG_BAD_ITOL);
    return(IDA_ILL_INPUT);
  }

  if (atol == NULL) { 
    IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetTolerances", MSG_ATOL_NULL);
    return(IDA_ILL_INPUT); 
  }

  if (rtol < ZERO) { 
    IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetTolerances", MSG_BAD_RTOL);
    return(IDA_ILL_INPUT); 
  }

    
  if (itol == IDA_SS) { 
    neg_atol = (*((realtype *)atol) < ZERO); 
  } else { 
    neg_atol = (N_VMin((N_Vector)atol) < ZERO); 
  }

  if (neg_atol) { 
    IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASetTolerances", MSG_BAD_ATOL);
    return(IDA_ILL_INPUT); 
  }

  /* Copy tolerances into memory */

  if ( (itol != IDA_SV) && (IDA_mem->ida_VatolMallocDone) ) {
    N_VDestroy(IDA_mem->ida_Vatol);
    lrw -= lrw1;
    liw -= liw1;
    IDA_mem->ida_VatolMallocDone = FALSE;
  }

  if ( (itol == IDA_SV) && !(IDA_mem->ida_VatolMallocDone) ) {
    IDA_mem->ida_Vatol = NULL;
    IDA_mem->ida_Vatol = N_VClone(IDA_mem->ida_ewt);
    lrw += lrw1;
    liw += liw1;
    IDA_mem->ida_VatolMallocDone = TRUE;
  }

  IDA_mem->ida_itol = itol;
  IDA_mem->ida_rtol = rtol;      
  if (itol == IDA_SS)
    IDA_mem->ida_Satol = *((realtype *)atol);
  else 
    N_VScale(ONE, (N_Vector)atol, IDA_mem->ida_Vatol);

  IDA_mem->ida_efun = IDAEwtSet;
  IDA_mem->ida_edata = ida_mem;

  return(IDA_SUCCESS);
}
Example #6
0
static int KINSolInit(void *kinmem, integer Neq,
                      N_Vector uu, SysFn func, int globalstrategy,
                      N_Vector uscale, N_Vector fscale,
                      real fnormtol, real scsteptol, N_Vector constraints,
                      boole optIn, long int iopt[], real ropt[], void *f_data)

{
  boole ioptExists, roptExists, ioptBad, roptNeg;
  KINMem kin_mem;
  FILE *fp;

  /* Check for legal input parameters */

  kin_mem = (KINMem)kinmem;

  fp = kin_mem->kin_msgfp;

  if (Neq <= 0)
  {
    fprintf(fp, MSG_BAD_NEQ, Neq);
    return(-1);
  }

  if (uu == NULL)
  {
    fprintf(fp, MSG_UU_NULL);
    return(-1);
  }

  if (func == NULL)
  {
    fprintf(fp, MSG_FUNC_NULL);
    return(-1);
  }

  if ((globalstrategy != INEXACT_NEWTON) && (globalstrategy != LINESEARCH))
  {
    fprintf(fp, MSG_BAD_GLSTRAT, globalstrategy, INEXACT_NEWTON, LINESEARCH);
    return(-1);
  }

  if (uscale == NULL)
  {
    fprintf(fp, MSG_BAD_USCALE);
    return(-1);
  }

  if (N_VMin(uscale) <= ZERO)
  {
    fprintf(fp, MSG_USCALE_NONPOSITIVE);
    return(-1);
  }

  if (fscale == NULL)
  {
    fprintf(fp, MSG_BAD_FSCALE);
    return(-1);
  }

  if (N_VMin(fscale) <= ZERO)
  {
    fprintf(fp, MSG_FSCALE_NONPOSITIVE);
    return(-1);
  }

  if (fnormtol < ZERO)
  {
    fprintf(fp, MSG_BAD_FNORMTOL, fnormtol);
    return(-1);
  }

  if (scsteptol < ZERO)
  {
    fprintf(fp, MSG_BAD_SCSTEPTOL, scsteptol);
    return(-1);
  }

  if ((optIn != FALSE) && (optIn != TRUE))
  {
    fprintf(fp, MSG_BAD_OPTIN, optIn, FALSE, TRUE);
    return(-1);
  }

  if ((optIn) && (iopt == NULL) && (ropt == NULL))
  {
    fprintf(fp, MSG_BAD_OPT);
    return(-1);
  }
  kin_mem->kin_ioptExists = ioptExists = (iopt != NULL);
  kin_mem->kin_roptExists = roptExists = (ropt != NULL);


  /*  Set the constraints flag */
  if (constraints == NULL)
    constraintsSet = FALSE;
  else
    constraintsSet = TRUE;


  /* All error checking is complete at this point */


  /* Copy the input parameters into KINSol state */

  kin_mem->kin_uu = uu;
  kin_mem->kin_func = func;
  kin_mem->kin_f_data = f_data;
  kin_mem->kin_globalstrategy = globalstrategy;
  kin_mem->kin_fnormtol = fnormtol;
  kin_mem->kin_scsteptol = scsteptol;
  kin_mem->kin_iopt = iopt;
  kin_mem->kin_ropt = ropt;
  kin_mem->kin_constraints = constraints;
  kin_mem->kin_uscale = uscale;
  kin_mem->kin_fscale = fscale;
  kin_mem->kin_precondflag = FALSE;  /* set to the correct state in KINSpgmr */


/* (additional readability constants are defined below/after KINMalloc) */

  /*  check the value of the two tolerances  */

  if (scsteptol <= ZERO)
    scsteptol = RPowerR(uround, TWOTHIRDS);

  if (fnormtol <= ZERO)
    fnormtol = RPowerR(uround, ONETHIRD);

  /* Handle the remaining optional inputs */

  printfl = PRINTFL_DEFAULT;
  mxiter = MXITER_DEFAULT;

  if (ioptExists && optIn)
  {
    if (iopt[PRINTFL] > 0 && iopt[PRINTFL] < 4)
      printfl = iopt[PRINTFL];
    if (iopt[MXITER] > 0)
      mxiter = iopt[MXITER];
    ioptBad = (iopt[PRINTFL] < 0 || iopt[MXITER] < 0 || iopt[PRINTFL] > 3);
    if (ioptBad)
    {
      fprintf(fp, MSG_IOPT_OUT);
      free(kin_mem);
      return(-1);
    }
  }

  if (printfl > 0)
    fprintf(fp, "scsteptol used: %12.3g \n", scsteptol);
  if (printfl > 0)
    fprintf(fp, "fnormtol  used: %12.3g \n", fnormtol);

  sqrt_relfunc = RSqrt(uround);

  /*  calculate the default value for mxnewtstep (max Newton step) */

  mxnewtstep = THOUSAND * N_VWL2Norm(uu, uscale);
  if (mxnewtstep < ONE)
    mxnewtstep = ONE;
  relu = RELU_DEFAULT;

  if (roptExists && optIn)
  {
    if (ropt[MXNEWTSTEP] > ZERO)
      mxnewtstep = ropt[MXNEWTSTEP];
    if (ropt[RELFUNC] > ZERO)
      sqrt_relfunc = RSqrt(ropt[RELFUNC]);
    if (ropt[RELU] > ZERO)
      relu = ropt[RELU];
    roptNeg = (ropt[MXNEWTSTEP] < ZERO || ropt[RELFUNC] < ZERO || ropt[RELU] < ZERO);
    if (roptNeg)
    {
      fprintf(fp, MSG_ROPT_OUT);
      free(kin_mem);
      return(-1);
    }
  }

  /* set up the coefficients for the eta calculation */

  etaflag = ETACHOICE1; /* default choice */

  if (ioptExists && optIn)
  {
    etaflag = iopt[ETACHOICE];
    if (etaflag < ETACHOICE1 || etaflag > ETACONSTANT)
    {
      fprintf(fp, MSG_BAD_ETACHOICE);
      etaflag = ETACHOICE1;
    }
  }
  callForcingTerm = (etaflag != ETACONSTANT);


  if (etaflag == ETACHOICE1)
    /* this value ALWAYS used for Choice 1 */
    ealpha = ONE + HALF * RSqrt(FIVE);

  if (etaflag == ETACHOICE2)
  {
    /* default values: */
    ealpha = TWO;
    egamma = POINT9;
  }

  if (etaflag == ETACONSTANT)
    eta = POINT1;
  /* default value used --constant case */
  else
    eta = HALF;
  /* Initial value for eta set to 0.5 for other than the ETACONSTANT option */


  if (roptExists && optIn)
  {
    if (etaflag == ETACHOICE2)
    {
      ealpha = ropt[ETAALPHA];
      egamma = ropt[ETAGAMMA];
      if (ealpha <= ONE || ealpha > TWO)
      {
        /* alpha value out of range */
        if (ealpha != ZERO)
          fprintf(fp, MSG_ALPHA_BAD);
        ealpha = 2.;
      }
      if (egamma <= ZERO || egamma > ONE)
      {
        /* gamma value out of range */
        if (egamma != ZERO)
          fprintf(fp, MSG_GAMMA_BAD);
        egamma = POINT9;
      }
    }
    else if (etaflag == ETACONSTANT)
      eta = ropt[ETACONST];
    if (eta <= ZERO || eta > ONE)
    {
      if (eta != ZERO)
        fprintf(fp, MSG_ETACONST_BAD);
      eta = POINT1;
    }
  }

  /* Initialize all the counters */

  nfe = nnilpre = nni = nbcf = nbktrk = 0;

  /* Initialize optional output locations in iopt, ropt */

  if (ioptExists)
  {
    iopt[NFE] = iopt[NNI] = 0;
    iopt[NBKTRK] = 0;
  }

  if (roptExists)
  {
    ropt[FNORM] = ZERO;
    ropt[STEPL] = ZERO;
  }

  /*  check the initial guess uu against the constraints, if any, and
   * also see if the system func(uu) = 0 is satisfied by the initial guess uu */

  if (constraintsSet)
  {
    if (!KINInitialConstraint(kin_mem))
    {
      fprintf(fp, MSG_INITIAL_CNSTRNT);
      KINFreeVectors(kin_mem);
      free(kin_mem);
      return(-1);
    }
  }

  if (KINInitialStop(kin_mem))
    return(+1);

  /* initialize the L2 norms of f for the linear  iteration steps  */
  fnorm = N_VWL2Norm(fval, fscale);
  f1norm = HALF * fnorm * fnorm;
  if (printfl > 0)
    fprintf(fp,
            "KINSolInit nni= %4ld  fnorm= %26.16g  nfe=%6ld \n", nni, fnorm, nfe);

  /* Problem has been successfully initialized */

  return(0);
}
Example #7
0
/* Fortran interface routine to initialize ARKode memory 
   structure; functions as an all-in-one interface to the C 
   routines ARKodeCreate, ARKodeSetUserData, ARKodeInit, and 
   ARKodeSStolerances (or ARKodeSVtolerances); see farkode.h 
   for further details */
void FARK_MALLOC(realtype *t0, realtype *y0, int *imex, 
		 int *iatol, realtype *rtol, realtype *atol, 
		 long int *iout, realtype *rout, 
		 long int *ipar, realtype *rpar, int *ier) {

  N_Vector Vatol;
  FARKUserData ARK_userdata;
  realtype reltol, abstol;

  *ier = 0;

  /* Check for required vector operations */
  if(F2C_ARKODE_vec->ops->nvgetarraypointer == NULL) {
    *ier = -1;
    printf("Error: getarraypointer vector operation is not implemented.\n\n");
    return;
  }
  if(F2C_ARKODE_vec->ops->nvsetarraypointer == NULL) {
    *ier = -1;
    printf("Error: setarraypointer vector operation is not implemented.\n\n");
    return;
  }
  if(F2C_ARKODE_vec->ops->nvcloneempty == NULL) {
    *ier = -1;
    printf("Error: cloneempty vector operation is not implemented.\n\n");
    return;
  }

  /* Initialize all pointers to NULL */
  ARK_arkodemem = NULL;
  Vatol = NULL;

  /* initialize global constants to zero */
  ARK_nrtfn = 0;
  ARK_ls = 0;
  ARK_mass_ls = 0;

  /* Create ARKODE object */
  ARK_arkodemem = ARKodeCreate();
  if (ARK_arkodemem == NULL) {
    *ier = -1;
    return;
  }

  /* Set and attach user data */
  ARK_userdata = NULL;
  ARK_userdata = (FARKUserData) malloc(sizeof *ARK_userdata);
  if (ARK_userdata == NULL) {
    *ier = -1;
    return;
  }
  ARK_userdata->rpar = rpar;
  ARK_userdata->ipar = ipar;
  *ier = ARKodeSetUserData(ARK_arkodemem, ARK_userdata);
  if(*ier != ARK_SUCCESS) {
    free(ARK_userdata); ARK_userdata = NULL;
    *ier = -1;
    return;
  }

  /* Set data in F2C_ARKODE_vec to y0 */
  N_VSetArrayPointer(y0, F2C_ARKODE_vec);

  /* Call ARKodeInit based on imex argument */
  switch (*imex) {
  case 0:  /* purely implicit */
    *ier = ARKodeInit(ARK_arkodemem, NULL, FARKfi, 
		      *t0, F2C_ARKODE_vec);
    break;
  case 1:  /* purely explicit */
    *ier = ARKodeInit(ARK_arkodemem, FARKfe, NULL, 
		      *t0, F2C_ARKODE_vec);
    break;
  case 2:  /* imex */
    *ier = ARKodeInit(ARK_arkodemem, FARKfe, FARKfi, 
		      *t0, F2C_ARKODE_vec);
    break;
  }
    
  /* Reset data pointers */
  N_VSetArrayPointer(NULL, F2C_ARKODE_vec);

  /* On failure, exit */
  if(*ier != ARK_SUCCESS) {
    free(ARK_userdata);
    ARK_userdata = NULL;
    *ier = -1;
    return;
  }

  /* Set tolerances -- if <= 0, keep as defaults */
  reltol=1.e-4;
  abstol=1.e-9;
  if (*rtol > 0.0)  reltol = *rtol;
  switch (*iatol) {
  case 1:
    if (*atol > 0.0)  abstol = *atol;
    *ier = ARKodeSStolerances(ARK_arkodemem, reltol, abstol); 
    break;
  case 2:
    Vatol = N_VCloneEmpty(F2C_ARKODE_vec);
    if (Vatol == NULL) {
      free(ARK_userdata);
      ARK_userdata = NULL;
      *ier = -1;
      return;
    }
    N_VSetArrayPointer(atol, Vatol);
    if (N_VMin(Vatol) <= 0.0)  N_VConst(abstol, Vatol);
    *ier = ARKodeSVtolerances(ARK_arkodemem, reltol, Vatol);
    N_VDestroy(Vatol);
    break;
  }

  /* On failure, exit */
  if(*ier != ARK_SUCCESS) {
    free(ARK_userdata); 
    ARK_userdata = NULL;
    *ier = -1;
    return;
  }

  /* store pointers to optional output arrays in global vars */
  ARK_iout = iout;
  ARK_rout = rout;

  /* Store the unit roundoff in rout for user access */
  ARK_rout[5] = UNIT_ROUNDOFF;

  return;
}
Example #8
0
/* Fortran interface routine to re-initialize ARKode memory 
   structure; functions as an all-in-one interface to the C 
   routines ARKodeReInit and ARKodeSStolerances (or 
   ARKodeSVtolerances); see farkode.h for further details */
void FARK_REINIT(realtype *t0, realtype *y0, int *imex, int *iatol, 
		 realtype *rtol, realtype *atol, int *ier) {

  N_Vector Vatol;
  realtype reltol, abstol;
  *ier = 0;

  /* Initialize all pointers to NULL */
  Vatol = NULL;

  /* Set data in F2C_ARKODE_vec to y0 */
  N_VSetArrayPointer(y0, F2C_ARKODE_vec);

  /* Call ARKodeReInit based on imex argument */
  switch (*imex) {
  case 0:  /* purely implicit */
    *ier = ARKodeReInit(ARK_arkodemem, NULL, FARKfi, 
			*t0, F2C_ARKODE_vec);
    break;
  case 1:  /* purely explicit */
    *ier = ARKodeReInit(ARK_arkodemem, FARKfe, NULL, 
			*t0, F2C_ARKODE_vec);
    break;
  case 2:  /* imex */
    *ier = ARKodeReInit(ARK_arkodemem, FARKfe, FARKfi, 
			*t0, F2C_ARKODE_vec);
    break;
  }

  /* Reset data pointers */
  N_VSetArrayPointer(NULL, F2C_ARKODE_vec);

  /* On failure, exit */
  if (*ier != ARK_SUCCESS) {
    *ier = -1;
    return;
  }

  /* Set tolerances */
  reltol=1.e-4;
  abstol=1.e-9;
  if (*rtol > 0.0)  reltol = *rtol;
  switch (*iatol) {
  case 1:
    if (*atol > 0.0)  abstol = *atol;
    *ier = ARKodeSStolerances(ARK_arkodemem, reltol, abstol); 
    break;
  case 2:
    Vatol = N_VCloneEmpty(F2C_ARKODE_vec);
    if (Vatol == NULL) {
      *ier = -1;
      return;
    }
    N_VSetArrayPointer(atol, Vatol);
    if (N_VMin(Vatol) <= 0.0)  N_VConst(abstol, Vatol);
    *ier = ARKodeSVtolerances(ARK_arkodemem, reltol, Vatol);
    N_VDestroy(Vatol);
    break;
  }

  /* On failure, exit */
  if (*ier != ARK_SUCCESS) {
    *ier = -1;
    return;
  }

  return;
}
Example #9
0
int CPodeSetQuadErrCon(void *cpode_mem, booleantype errconQ, 
                       int tol_typeQ, realtype reltolQ, void *abstolQ)
{
  CPodeMem cp_mem;
  booleantype neg_abstol;

  if (cpode_mem==NULL) {
    cpProcessError(NULL, CP_MEM_NULL, "CPODES", "CPodeSetQuadErrCon", MSGCP_NO_MEM);    
    return(CP_MEM_NULL);
  }
  
  cp_mem = (CPodeMem) cpode_mem;

  cp_mem->cp_errconQ = errconQ;

  /* Ckeck if quadrature was initialized? */

  if (cp_mem->cp_quadMallocDone == FALSE) {
    cpProcessError(cp_mem, CP_NO_QUAD, "CPODES", "CPodeSetQuadErrCon", MSGCP_NO_QUAD); 
    return(CP_NO_QUAD);
  }

  /* Check inputs */

  if(errconQ == FALSE) {
    if (cp_mem->cp_VabstolQMallocDone) {
      N_VDestroy(cp_mem->cp_VabstolQ);
      lrw -= lrw1Q;
      liw -= liw1Q;
      cp_mem->cp_VabstolQMallocDone = FALSE;
    }
    return(CP_SUCCESS);
  }
  
  if ((tol_typeQ != CP_SS) && (tol_typeQ != CP_SV)) {
    cpProcessError(cp_mem, CP_ILL_INPUT, "CPODES", "CPodeSetQuadErrCon", MSGCP_BAD_ITOLQ);
    return(CP_ILL_INPUT);
  }

  if (abstolQ == NULL) {
    cpProcessError(cp_mem, CP_ILL_INPUT, "CPODES", "CPodeSetQuadErrCon", MSGCP_NULL_ABSTOLQ);
    return(CP_ILL_INPUT);
  }

  if (reltolQ < ZERO) {
    cpProcessError(cp_mem, CP_ILL_INPUT, "CPODES", "CPodeSetQuadErrCon", MSGCP_BAD_RELTOLQ);
    return(CP_ILL_INPUT);
  }

  if (tol_typeQ == CP_SS)
    neg_abstol = (*((realtype *)abstolQ) < ZERO);
  else
    neg_abstol = (N_VMin((N_Vector)abstolQ) < ZERO);

  if (neg_abstol) {
    cpProcessError(cp_mem, CP_ILL_INPUT, "CPODES", "CPodeSetQuadErrCon", MSGCP_BAD_ABSTOLQ);
    return(CP_ILL_INPUT);
  }

  /* See if we need to free or allocate memory */

  if ( (tol_typeQ != CP_SV) && (cp_mem->cp_VabstolQMallocDone) ) {
    N_VDestroy(cp_mem->cp_VabstolQ);
    lrw -= lrw1Q;
    liw -= liw1Q;
    cp_mem->cp_VabstolQMallocDone = FALSE;
  }

  if ( (tol_typeQ == CP_SV) && !(cp_mem->cp_VabstolQMallocDone) ) {
    cp_mem->cp_VabstolQ = N_VClone(cp_mem->cp_tempvQ);
    lrw += lrw1Q;
    liw += liw1Q;
    cp_mem->cp_VabstolQMallocDone = TRUE;
  }

  /* Copy tolerances into memory */

  cp_mem->cp_tol_typeQ = tol_typeQ;
  cp_mem->cp_reltolQ   = reltolQ;

  if (tol_typeQ == CP_SS)
    cp_mem->cp_SabstolQ = *((realtype *)abstolQ);
  else
    N_VScale(ONE, (N_Vector)abstolQ, cp_mem->cp_VabstolQ);
  
  return(CP_SUCCESS);
}
Example #10
0
int CPodeSetTolerances(void *cpode_mem, 
                       int tol_type, realtype reltol, void *abstol)
{
  CPodeMem cp_mem;
  booleantype neg_abstol;

  /* Check CPODES memory */
  if (cpode_mem==NULL) {
    cpProcessError(NULL, CP_MEM_NULL, "CPODES", "CPodeSetTolerances", MSGCP_NO_MEM);
    return(CP_MEM_NULL);
  }
  cp_mem = (CPodeMem) cpode_mem;

  /* Check if cpode_mem was allocated */
  if (cp_mem->cp_MallocDone == FALSE) {
    cpProcessError(cp_mem, CP_NO_MALLOC, "CPODES", "CPodeSetTolerances", MSGCP_NO_MALLOC);
    return(CP_NO_MALLOC);
  }

  /* Check inputs for legal values */
  if ( (tol_type != CP_SS) && (tol_type != CP_SV) ) {
    cpProcessError(cp_mem, CP_ILL_INPUT, "CPODES", "CPodeSetTolerances", MSGCP_BAD_ITOL);
    return(CP_ILL_INPUT);
  }
  if (abstol == NULL) {
    cpProcessError(cp_mem, CP_ILL_INPUT, "CPODES", "CPodeSetTolerances", MSGCP_NULL_ABSTOL);
    return(CP_ILL_INPUT);
  }

  /* Check positivity of tolerances */
  if (reltol < ZERO) {
    cpProcessError(cp_mem, CP_ILL_INPUT, "CPODES", "CPodeSetTolerances", MSGCP_BAD_RELTOL);
    return(CP_ILL_INPUT);
  }

  if (tol_type == CP_SS)
    neg_abstol = (*((realtype *)abstol) < ZERO);
  else
    neg_abstol = (N_VMin((N_Vector)abstol) < ZERO);
 
  if (neg_abstol) {
    cpProcessError(cp_mem, CP_ILL_INPUT, "CPODES", "CPodeSetTolerances", MSGCP_BAD_ABSTOL);
    return(CP_ILL_INPUT);
  }

  /* Copy tolerances into memory */
  cp_mem->cp_tol_type = tol_type;
  cp_mem->cp_reltol   = reltol;

  if (tol_type == CP_SS) {
    cp_mem->cp_Sabstol = *((realtype *)abstol);
  } else {
    if ( !(cp_mem->cp_VabstolMallocDone) ) {
      cp_mem->cp_Vabstol = N_VClone(cp_mem->cp_ewt);
      lrw += lrw1;
      liw += liw1;
      cp_mem->cp_VabstolMallocDone = TRUE;
    }
    N_VScale(ONE, (N_Vector)abstol, cp_mem->cp_Vabstol);
  }

  return(CP_SUCCESS);
}
Example #11
0
int IDACalcIC(void *ida_mem, int icopt, realtype tout1)
{
  int ewtsetOK;
  int ier, nwt, nh, mxnh, icret, retval=0;
  int is;
  realtype tdist, troundoff, minid, hic, ypnorm;
  IDAMem IDA_mem;
  booleantype sensi_stg, sensi_sim;

  /* Check if IDA memory exists */

  if(ida_mem == NULL) {
    IDAProcessError(NULL, IDA_MEM_NULL, "IDAS", "IDACalcIC", MSG_NO_MEM);
    return(IDA_MEM_NULL);
  }
  IDA_mem = (IDAMem) ida_mem;

  /* Check if problem was malloc'ed */
  
  if(IDA_mem->ida_MallocDone == FALSE) {
    IDAProcessError(IDA_mem, IDA_NO_MALLOC, "IDAS", "IDACalcIC", MSG_NO_MALLOC);
    return(IDA_NO_MALLOC);
  }

  /* Check inputs to IDA for correctness and consistency */

  ier = IDAInitialSetup(IDA_mem);
  if(ier != IDA_SUCCESS) return(IDA_ILL_INPUT);
  IDA_mem->ida_SetupDone = TRUE;

  /* Check legality of input arguments, and set IDA memory copies. */

  if(icopt != IDA_YA_YDP_INIT && icopt != IDA_Y_INIT) {
    IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDAS", "IDACalcIC", MSG_IC_BAD_ICOPT);
    return(IDA_ILL_INPUT);
  }
  IDA_mem->ida_icopt = icopt;

  if(icopt == IDA_YA_YDP_INIT && (id == NULL)) {
    IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDAS", "IDACalcIC", MSG_IC_MISSING_ID);
    return(IDA_ILL_INPUT);
  }

  tdist = SUNRabs(tout1 - tn);
  troundoff = TWO*uround*(SUNRabs(tn) + SUNRabs(tout1));
  if(tdist < troundoff) {
    IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDAS", "IDACalcIC", MSG_IC_TOO_CLOSE);
    return(IDA_ILL_INPUT);
  }

  /* Are we computing sensitivities? */
  sensi_stg  = (sensi && (ism==IDA_STAGGERED));
  sensi_sim  = (sensi && (ism==IDA_SIMULTANEOUS));

  /* Allocate space and initialize temporary vectors */

  yy0 = N_VClone(ee);
  yp0 = N_VClone(ee);
  t0  = tn;
  N_VScale(ONE, phi[0], yy0);
  N_VScale(ONE, phi[1], yp0);

  if (sensi) {

    /* Allocate temporary space required for sensitivity IC: yyS0 and ypS0. */      
    yyS0 = N_VCloneVectorArray(Ns, ee);
    ypS0 = N_VCloneVectorArray(Ns, ee);
    
    /* Initialize sensitivity vector. */
    for (is=0; is<Ns; is++) {
      N_VScale(ONE, phiS[0][is], yyS0[is]);  
      N_VScale(ONE, phiS[1][is], ypS0[is]);  
    }
    
    /* Initialize work space vectors needed for sensitivities. */
    savresS = phiS[2];
    delnewS = phiS[3];
    yyS0new = phiS[4];
    ypS0new = eeS;
  }

  /* For use in the IDA_YA_YP_INIT case, set sysindex and tscale. */

  IDA_mem->ida_sysindex = 1;
  IDA_mem->ida_tscale   = tdist;
  if(icopt == IDA_YA_YDP_INIT) {
    minid = N_VMin(id);
    if(minid < ZERO) {
      IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDAS", "IDACalcIC", MSG_IC_BAD_ID);
      return(IDA_ILL_INPUT);
    }
    if(minid > HALF) IDA_mem->ida_sysindex = 0;
  }

  /* Set the test constant in the Newton convergence test */

  IDA_mem->ida_epsNewt = epiccon;

  /* Initializations: 
     cjratio = 1 (for use in direct linear solvers); 
     set nbacktr = 0; */

  cjratio = ONE;
  nbacktr = 0;

  /* Set hic, hh, cj, and mxnh. */

  hic = PT001*tdist;
  ypnorm = IDAWrmsNorm(IDA_mem, yp0, ewt, suppressalg);

  if (sensi_sim) 
    ypnorm = IDASensWrmsNormUpdate(IDA_mem, ypnorm, ypS0, ewtS, FALSE);

  if(ypnorm > HALF/hic) hic = HALF/ypnorm;
  if(tout1 < tn) hic = -hic;
  hh = hic;
  if(icopt == IDA_YA_YDP_INIT) {
    cj = ONE/hic;
    mxnh = maxnh;
  }
  else {
    cj = ZERO;
    mxnh = 1;
  }

  /* Loop over nwt = number of evaluations of ewt vector. */

  for(nwt = 1; nwt <= 2; nwt++) {
 
    /* Loop over nh = number of h values. */
    for(nh = 1; nh <= mxnh; nh++) {

      /* Call the IC nonlinear solver function. */
      retval = IDANlsIC(IDA_mem);

      /* Cut h and loop on recoverable IDA_YA_YDP_INIT failure; else break. */
      if(retval == IDA_SUCCESS) break;
      ncfn++;
      if(retval < 0) break;
      if(nh == mxnh) break;

      /* If looping to try again, reset yy0 and yp0 if not converging. */
      if(retval != IC_SLOW_CONVRG) {
        N_VScale(ONE, phi[0], yy0);
        N_VScale(ONE, phi[1], yp0);
        if (sensi_sim) {

          /* Reset yyS0 and ypS0. */
          /* Copy phiS[0] and phiS[1] into yyS0 and ypS0. */
          for (is=0; is<Ns; is++) {
            N_VScale(ONE, phiS[0][is], yyS0[is]);         
            N_VScale(ONE, phiS[1][is], ypS0[is]);         
          }
        }
      }
      hic *= PT1;
      cj = ONE/hic;
      hh = hic;
    }   /* End of nh loop */

    /* Break on failure */
    if(retval != IDA_SUCCESS) break;
    
    /* Reset ewt, save yy0, yp0 in phi, and loop. */
    ewtsetOK = efun(yy0, ewt, edata);
    if(ewtsetOK != 0) { 
      retval = IDA_BAD_EWT; 
      break; 
    }
    N_VScale(ONE, yy0, phi[0]);
    N_VScale(ONE, yp0, phi[1]);
    
    if (sensi_sim) {
      
      /* Reevaluate ewtS. */
      ewtsetOK = IDASensEwtSet(IDA_mem, yyS0, ewtS);
      if(ewtsetOK != 0) { 
        retval = IDA_BAD_EWT; 
        break; 
      }
      
      /* Save yyS0 and ypS0. */
      for (is=0; is<Ns; is++) {
            N_VScale(ONE, yyS0[is], phiS[0][is]);         
            N_VScale(ONE, ypS0[is], phiS[1][is]);        
      }
    }

  }   /* End of nwt loop */

  /* Load the optional outputs. */

  if(icopt == IDA_YA_YDP_INIT)   hused = hic;

  /* On any failure, free memory, print error message and return */

  if(retval != IDA_SUCCESS) {
    N_VDestroy(yy0);
    N_VDestroy(yp0);

    if(sensi) {
      N_VDestroyVectorArray(yyS0, Ns);
      N_VDestroyVectorArray(ypS0, Ns);
    }

    icret = IDAICFailFlag(IDA_mem, retval);
    return(icret);
  }

  /* Unless using the STAGGERED approach for sensitivities, return now */

  if (!sensi_stg) {

    N_VDestroy(yy0);
    N_VDestroy(yp0);

    if(sensi) {
      N_VDestroyVectorArray(yyS0, Ns);
      N_VDestroyVectorArray(ypS0, Ns);
    }

    return(IDA_SUCCESS);
  }

  /* Find consistent I.C. for sensitivities using a staggered approach */
 
  
  /* Evaluate res at converged y, needed for future evaluations of sens. RHS 
     If res() fails recoverably, treat it as a convergence failure and 
     attempt the step again */
        
  retval = res(t0, yy0, yp0, delta, user_data);
  nre++;
  if(retval < 0) 
    /* res function failed unrecoverably. */
    return(IDA_RES_FAIL);

  if(retval > 0) 
    /* res function failed recoverably but no recovery possible. */
    return(IDA_FIRST_RES_FAIL);
  
  /* Loop over nwt = number of evaluations of ewt vector. */
  for(nwt = 1; nwt <= 2; nwt++) {
 
    /* Loop over nh = number of h values. */
    for(nh = 1; nh <= mxnh; nh++) {

      retval = IDASensNlsIC(IDA_mem);
      if(retval == IDA_SUCCESS) break;

      /* Increment the number of the sensitivity related corrector convergence failures. */
      ncfnS++;

      if(retval < 0) break;
      if(nh == mxnh) break;

      /* If looping to try again, reset yyS0 and ypS0 if not converging. */
      if(retval != IC_SLOW_CONVRG) {
        for (is=0; is<Ns; is++) {
          N_VScale(ONE, phiS[0][is], yyS0[is]);  
          N_VScale(ONE, phiS[1][is], ypS0[is]);  
        }
      }
      hic *= PT1;
      cj = ONE/hic;
      hh = hic;
        
    }   /* End of nh loop */

    /* Break on failure */
    if(retval != IDA_SUCCESS) break;

    /* Since it was successful, reevaluate ewtS with the new values of yyS0, save 
       yyS0 and ypS0 in phiS[0] and phiS[1] and loop one more time to check and 
       maybe correct the  new sensitivities IC with respect to the new weights. */
    
    /* Reevaluate ewtS. */
    ewtsetOK = IDASensEwtSet(IDA_mem, yyS0, ewtS);
    if(ewtsetOK != 0) { 
      retval = IDA_BAD_EWT; 
      break; 
    }

    /* Save yyS0 and ypS0. */
    for (is=0; is<Ns; is++) {
      N_VScale(ONE, yyS0[is], phiS[0][is]);         
      N_VScale(ONE, ypS0[is], phiS[1][is]);        
    }

  }   /* End of nwt loop */


  /* Load the optional outputs. */
  if(icopt == IDA_YA_YDP_INIT)   hused = hic;

  /* Free temporary space */
  N_VDestroy(yy0);
  N_VDestroy(yp0);

  /* Here sensi is TRUE, so deallocate sensitivity temporary vectors. */
  N_VDestroyVectorArray(yyS0, Ns);
  N_VDestroyVectorArray(ypS0, Ns);


  /* On any failure, print message and return proper flag. */
  if(retval != IDA_SUCCESS) {
    icret = IDAICFailFlag(IDA_mem, retval);
    return(icret);
  }

  /* Otherwise return success flag. */

  return(IDA_SUCCESS);

}