예제 #1
0
파일: idas_ic.c 프로젝트: MaveriQ/AMICI
static int IDAfnorm(IDAMem IDA_mem, realtype *fnorm)
{
  int retval, is;

  /* Get residual vector F, return if failed, and save F in savres. */
  retval = res(t0, ynew, ypnew, delnew, user_data);
  nre++;
  if(retval < 0) return(IDA_RES_FAIL);
  if(retval > 0) return(IC_FAIL_RECOV);

  N_VScale(ONE, delnew, savres);

  /* Call the linear solve function to get J-inverse F; return if failed. */
  retval = lsolve(IDA_mem, delnew, ewt, ynew, ypnew, savres);
  if(retval < 0) return(IDA_LSOLVE_FAIL);
  if(retval > 0) return(IC_FAIL_RECOV);

  /* Compute the WRMS-norm. */
  *fnorm = IDAWrmsNorm(IDA_mem, delnew, ewt, FALSE);


  /* Are we computing SENSITIVITIES with the IDA_SIMULTANEOUS approach? */

  if(sensi && (ism==IDA_SIMULTANEOUS)) {

    /* Evaluate the residual for sensitivities. */
    retval = resS(Ns, t0, 
                  ynew, ypnew, savres,
                  yyS0new, ypS0new, delnewS,
                  user_dataS, tmpS1, tmpS2, tmpS3);
    nrSe++;
    if(retval < 0) return(IDA_RES_FAIL);
    if(retval > 0) return(IC_FAIL_RECOV);

    /* Save delnewS in savresS. */
    for(is=0; is<Ns; is++)
      N_VScale(ONE, delnewS[is], savresS[is]);

    /* Call the linear solve function to get J-inverse deltaS. */
    for(is=0; is<Ns; is++) {

      retval = lsolve(IDA_mem, delnewS[is], ewtS[is], ynew, ypnew, savres);
      if(retval < 0) return(IDA_LSOLVE_FAIL);
      if(retval > 0) return(IC_FAIL_RECOV);
    }
      
    /* Include sensitivities in norm. */
    *fnorm = IDASensWrmsNormUpdate(IDA_mem, *fnorm, delnewS, ewtS, FALSE);
  }

  /* Rescale norm if index = 0. */
  if(sysindex == 0) (*fnorm) *= tscale*SUNRabs(cj);

  return(IDA_SUCCESS);

}
예제 #2
0
파일: ida_ic.c 프로젝트: MaveriQ/AMICI
static int IDAfnorm(IDAMem IDA_mem, realtype *fnorm)
{

  int retval;

  /* Get residual vector F, return if failed, and save F in savres. */
  retval = res(t0, ynew, ypnew, delnew, user_data);
  nre++;
  if(retval < 0) return(IDA_RES_FAIL);
  if(retval > 0) return(IC_FAIL_RECOV);

  N_VScale(ONE, delnew, savres);

  /* Call the linear solve function to get J-inverse F; return if failed. */
  retval = lsolve(IDA_mem, delnew, ewt, ynew, ypnew, savres);
  if(retval < 0) return(IDA_LSOLVE_FAIL);
  if(retval > 0) return(IC_FAIL_RECOV);

  /* Compute the WRMS-norm; rescale if index = 0. */
  *fnorm = IDAWrmsNorm(IDA_mem, delnew, ewt, FALSE);
  if(sysindex == 0) (*fnorm) *= tscale*SUNRabs(cj);

  return(IDA_SUCCESS);

}
예제 #3
0
파일: idas_ic.c 프로젝트: MaveriQ/AMICI
static int IDASensfnorm(IDAMem IDA_mem, realtype *fnorm)
{
  int is, retval;
  
  /* Get sensitivity residual */
  retval = resS(Ns, t0, 
                yy0,  yp0,  delta,
                yyS0new, ypS0new, delnewS,
                user_dataS, tmpS1, tmpS2, tmpS3);
  nrSe++;
  if(retval < 0) return(IDA_RES_FAIL);
  if(retval > 0) return(IC_FAIL_RECOV);
  
  for(is=0; is<Ns; is++) N_VScale(ONE, delnewS[is], savresS[is]);
  
  /* Call linear solve function */
  for(is=0; is<Ns; is++) {
    
    retval = lsolve(IDA_mem, delnewS[is], ewtS[is],  yy0, yp0, delta);
    if(retval < 0) return(IDA_LSOLVE_FAIL);
    if(retval > 0) return(IC_FAIL_RECOV);
  }

  /* Compute the WRMS-norm; rescale if index = 0. */
  *fnorm = IDASensWrmsNorm(IDA_mem, delnewS, ewtS, FALSE);
  if(sysindex == 0) (*fnorm) *= tscale*SUNRabs(cj);

  return(IDA_SUCCESS);
}
예제 #4
0
static int cpNewtonIterationImpl(CPodeMem cp_mem)
{
  int m, retval;
  realtype del, delp, dcon;

  /* Initialize counters */
  mnewt = m = 0;

  /* Initialize delp to avoid compiler warning message */
  del = delp = ZERO;

  /* Looping point for Newton iteration */
  loop {

    /* Evaluate the residual of the nonlinear system*/
    N_VScale(-gamma, ftemp, tempv);

    /* Call the lsolve function (solution in tempv) */
    retval = lsolve(cp_mem, tempv, ewt, y, yp, ftemp);
    nni++;
    if (retval < 0) return(CP_LSOLVE_FAIL);
    if (retval > 0) return(CONV_FAIL);

    /* Get WRMS norm of correction and add correction to acor, y, and yp */
    del = N_VWrmsNorm(tempv, ewt);
    N_VLinearSum(ONE, acor, ONE,       tempv, acor);
    N_VLinearSum(ONE, y,    ONE,       tempv, y);
    N_VLinearSum(ONE, yp,   ONE/gamma, tempv, yp);

    /* Test for convergence.  If m > 0, an estimate of the convergence
       rate constant is stored in crate, and used in the test.        */
    if (m > 0) crate = MAX(NLS_CRDOWN * crate, del/delp);
    dcon = del * MIN(ONE, crate) / tq[4];    
    if (dcon <= ONE) {
      acnrm = (m==0) ? del : N_VWrmsNorm(acor, ewt);
      return(CP_SUCCESS);
    }
    
    mnewt = ++m;
    
    /* Stop at maxcor iterations or if iter. seems to be diverging. */
    if ((m == maxcor) || ((m >= 2) && (del > NLS_RDIV*delp)))  return(CONV_FAIL);
    
    /* Save norm of correction, evaluate f, and loop again */
    delp = del;
    retval = fi(tn, y, yp, ftemp, f_data);
    nfe++;
    if (retval < 0) return(CP_ODEFUNC_FAIL);
    if (retval > 0) return(ODEFUNC_RECVR);

  } /* end loop */
}
예제 #5
0
파일: ida_ic.c 프로젝트: MaveriQ/AMICI
static int IDANewtonIC(IDAMem IDA_mem)
{
  int retval, mnewt;
  realtype delnorm, fnorm, fnorm0, oldfnrm, rate;

  /* Set pointer for vector delnew */
  delnew = phi[2];

  /* Call the linear solve function to get the Newton step, delta. */
  retval = lsolve(IDA_mem, delta, ewt, yy0, yp0, savres);
  if(retval < 0) return(IDA_LSOLVE_FAIL);
  if(retval > 0) return(IC_FAIL_RECOV);

  /* Compute the norm of the step; return now if this is small. */
  fnorm = IDAWrmsNorm(IDA_mem, delta, ewt, FALSE);
  if(sysindex == 0) fnorm *= tscale*SUNRabs(cj);
  if(fnorm <= epsNewt) return(IDA_SUCCESS);
  fnorm0 = fnorm;

  /* Initialize rate to avoid compiler warning message */
  rate = ZERO;

  /* Newton iteration loop */

  for(mnewt = 0; mnewt < maxnit; mnewt++) {

    nni++;
    delnorm = fnorm;
    oldfnrm = fnorm;

    /* Call the Linesearch function and return if it failed. */
    retval = IDALineSrch(IDA_mem, &delnorm, &fnorm);
    if(retval != IDA_SUCCESS) return(retval);

    /* Set the observed convergence rate and test for convergence. */
    rate = fnorm/oldfnrm;
    if(fnorm <= epsNewt) return(IDA_SUCCESS);

    /* If not converged, copy new step vector, and loop. */
    N_VScale(ONE, delnew, delta);

  }   /* End of Newton iteration loop */

  /* Return either IC_SLOW_CONVRG or recoverable fail flag. */
  if(rate <= ICRATEMAX || fnorm < PT1*fnorm0) return(IC_SLOW_CONVRG);
  return(IC_CONV_FAIL);

}
예제 #6
0
파일: idas_ic.c 프로젝트: MaveriQ/AMICI
/*
 * -----------------------------------------------------------------
 * IDASensNewtonIC
 * -----------------------------------------------------------------
 * IDANewtonIC performs the Newton iteration to solve for 
 * sensitivities consistent initial conditions.  It calls 
 * IDASensLineSrch within each iteration.
 * On return, savresS contains the current residual vectors.
 *
 * The return value is IDA_SUCCESS = 0 if no error occurred.
 * The error return values (positive) considered recoverable are:
 *  IC_FAIL_RECOV      if res or lsolve failed recoverably
 *  IC_CONSTR_FAILED   if the constraints could not be met
 *  IC_LINESRCH_FAILED if the linesearch failed (on steptol test)
 *  IC_CONV_FAIL       if the Newton iterations failed to converge
 *  IC_SLOW_CONVRG     if the iterations appear to be converging slowly.
 *                     They failed the convergence test, but showed 
 *                     an overall norm reduction (by a factor of < 0.1)
 *                     or a convergence rate <= ICRATEMAX).
 * The error return values (negative) considered non-recoverable are:
 *  IDA_RES_FAIL   if res had a non-recoverable error
 *  IDA_LSOLVE_FAIL      if lsolve had a non-recoverable error
 * -----------------------------------------------------------------
 */
static int IDASensNewtonIC(IDAMem IDA_mem)
{
  int retval, is, mnewt;
  realtype delnorm, fnorm, fnorm0, oldfnrm, rate;

  for(is=0;is<Ns;is++) {
   
    /* Call the linear solve function to get the Newton step, delta. */
    retval = lsolve(IDA_mem, deltaS[is], ewtS[is],  yy0, yp0, delta);
    if(retval < 0) return(IDA_LSOLVE_FAIL);
    if(retval > 0) return(IC_FAIL_RECOV);

  }
    /* Compute the norm of the step and return if it is small enough */
  fnorm = IDASensWrmsNorm(IDA_mem, deltaS, ewtS, FALSE);
  if(sysindex == 0) fnorm *= tscale*SUNRabs(cj);
  if(fnorm <= epsNewt) return(IDA_SUCCESS);
  fnorm0 = fnorm;

  rate = ZERO;

  /* Newton iteration loop */
  for(mnewt = 0; mnewt < maxnit; mnewt++) {

    nniS++;
    delnorm = fnorm;
    oldfnrm = fnorm;
      
    /* Call the Linesearch function and return if it failed. */
    retval = IDASensLineSrch(IDA_mem, &delnorm, &fnorm);
    if(retval != IDA_SUCCESS) return(retval);
      
    /* Set the observed convergence rate and test for convergence. */
    rate = fnorm/oldfnrm;
    if(fnorm <= epsNewt) return(IDA_SUCCESS);
    
    /* If not converged, copy new step vectors, and loop. */
    for(is=0; is<Ns; is++) N_VScale(ONE, delnewS[is], deltaS[is]);
    
  }   /* End of Newton iteration loop */

  /* Return either IC_SLOW_CONVRG or recoverable fail flag. */
  if(rate <= ICRATEMAX || fnorm < PT1*fnorm0) return(IC_SLOW_CONVRG);
  return(IC_CONV_FAIL);
}
예제 #7
0
파일: kinsol.c 프로젝트: cvoter/Parflow
static int KINLinSolDrv(KINMem kin_mem, N_Vector bb, N_Vector xx)
{
  int ret;

  if (nni - nnilpre >= msbpre)
    pthrsh = TWO;

  loop {
    precondcurrent = FALSE;

    if ((pthrsh > ONEPT5) && setupNonNull)
    {
      /* Call precondset routine  */
      ret = lsetup(kin_mem);
      precondcurrent = TRUE;
      nnilpre = nni;
      if (ret != 0)
        return(KINSOL_PRECONDSET_FAILURE);
    }

    /*  load bb with the current value of fval  */

    N_VScale(-ONE, fval, bb);

    /*  call the generic 'lsolve' routine to solve the system J x = b   */

    ret = lsolve(kin_mem, xx, bb, &res_norm);


    if (ret != 1)
      return(ret);

    if (!precondflag)
      return(KINSOL_KRYLOV_FAILURE);

    if (precondcurrent)
      return(KINSOL_KRYLOV_FAILURE);

    /* loop back only if the preconditioner is in use and is not current */

    pthrsh = TWO;
  }  /*  end of loop  */
}
예제 #8
0
static int IDANewtonIC(IDAMem IDA_mem)
{
  int retval, mnewt;
  realtype delnorm, fnorm, fnorm0, oldfnrm, rate;
//---OPENCOR--- BEGIN
  unsigned char *uc;
//---OPENCOR--- END

  /* Set pointer for vector delnew */
  delnew = phi[2];

  /* Call the linear solve function to get the Newton step, delta. */
  retval = lsolve(IDA_mem, delta, ewt, yy0, yp0, savres);
  if(retval < 0) return(IDA_LSOLVE_FAIL);
  if(retval > 0) return(IC_FAIL_RECOV);

  /* Compute the norm of the step; return now if this is small. */
  fnorm = IDAWrmsNorm(IDA_mem, delta, ewt, FALSE);
  if(sysindex == 0) fnorm *= tscale*ABS(cj);
  if(fnorm <= epsNewt) return(IDA_SUCCESS);
//---OPENCOR--- BEGIN
// Note #1: when trying to retrieve consistent initial conditions, the user may
//          have provided some (very) bad initial conditions, in which case
//          fnorm won't have a finite value. This means that we won't be able to
//          retrieve consistent initial conditions. So, IDA really ought to
//          check that fnorm has a finite value and, if not, then return with
//          some error code...
// Note #2: the code to test whether a value is finite comes from Qt. It's just
//          that using it directly would require a C++ compiler while we would
//          rather stick to a C compiler whenever possible since this will avoid
//          potential warnings because of differences between C and C++...

  uc = (unsigned char *) &fnorm;

#if Q_BYTE_ORDER == Q_BIG_ENDIAN
  if (((uc[0] & 0x7F) == 0x7F) && ((uc[1] & 0xF0) == 0xF0))
    return IC_CONV_FAIL;
#else
  if (((uc[7] & 0x7F) == 0x7F) && ((uc[6] & 0xF0) == 0xF0))
    return IC_CONV_FAIL;
#endif
//---OPENCOR--- END
  fnorm0 = fnorm;

  /* Initialize rate to avoid compiler warning message */
  rate = ZERO;

  /* Newton iteration loop */

  for(mnewt = 0; mnewt < maxnit; mnewt++) {

    nni++;
    delnorm = fnorm;
    oldfnrm = fnorm;

    /* Call the Linesearch function and return if it failed. */
    retval = IDALineSrch(IDA_mem, &delnorm, &fnorm);
    if(retval != IDA_SUCCESS) return(retval);

    /* Set the observed convergence rate and test for convergence. */
    rate = fnorm/oldfnrm;
    if(fnorm <= epsNewt) return(IDA_SUCCESS);

    /* If not converged, copy new step vector, and loop. */
    N_VScale(ONE, delnew, delta);

  }   /* End of Newton iteration loop */

  /* Return either IC_SLOW_CONVRG or recoverable fail flag. */
  if(rate <= ICRATEMAX || fnorm < PT1*fnorm0) return(IC_SLOW_CONVRG);
  return(IC_CONV_FAIL);

}
예제 #9
0
static int cpNewtonIterationExpl(CPodeMem cp_mem)
{
  int m, retval;
  realtype del, delp, dcon;
  N_Vector b;

  mnewt = m = 0;

  /* Initialize delp to avoid compiler warning message */
  del = delp = ZERO;

  /* Looping point for Newton iteration */
  loop {

#ifdef CPODES_DEBUG
    printf("            Iteration # %d\n",m);
#endif
#ifdef CPODES_DEBUG_SERIAL
    printf("                zn[0] = "); N_VPrint_Serial(zn[0]);
    printf("                zn[1] = "); N_VPrint_Serial(zn[1]);
    printf("                ewt   = "); N_VPrint_Serial(ewt);
    printf("                acor  = "); N_VPrint_Serial(acor);
    printf("                ftemp = "); N_VPrint_Serial(ftemp);
#endif

    /* Evaluate the residual of the nonlinear system*/
    N_VLinearSum(rl1, zn[1], ONE, acor, tempv);
    N_VLinearSum(gamma, ftemp, -ONE, tempv, tempv);

    /* Call the lsolve function */
    b = tempv;

#ifdef CPODES_DEBUG
    printf("            Linear solver solve\n");
#endif
#ifdef CPODES_DEBUG_SERIAL
    printf("                rhs   = "); N_VPrint_Serial(b);
#endif

    retval = lsolve(cp_mem, b, ewt, y, NULL, ftemp); 

#ifdef CPODES_DEBUG_SERIAL
    printf("                sol   = "); N_VPrint_Serial(b);
#endif
#ifdef CPODES_DEBUG
    printf("            Linear solver solve return value = %d\n",retval);
#endif

    nni++;    
    if (retval < 0) return(CP_LSOLVE_FAIL);
    if (retval > 0) return(CONV_FAIL);

    /* Get WRMS norm of correction; add correction to acor and y */
    del = N_VWrmsNorm(b, ewt);

#ifdef CPODES_DEBUG
    printf("            Norm of correction:  del = %lg\n", del);
#endif

    N_VLinearSum(ONE, acor, ONE, b, acor);
    N_VLinearSum(ONE, zn[0], ONE, acor, y);
    
    /* Test for convergence.  If m > 0, an estimate of the convergence
       rate constant is stored in crate, and used in the test.        */
    if (m > 0) {
      crate = MAX(NLS_CRDOWN * crate, del/delp);
    }
    dcon = del * MIN(ONE, crate) / tq[4];

#ifdef CPODES_DEBUG
    printf("            Convergence test  dcon = %lg\n", dcon);
#endif

    if (dcon <= ONE) {
      acnrm = (m==0) ? del : N_VWrmsNorm(acor, ewt);

#ifdef CPODES_DEBUG_SERIAL
      printf("            acor = "); N_VPrint_Serial(acor);
#endif
#ifdef CPODES_DEBUG
      printf("            Accumulated correction norm = %lg\n", acnrm);
#endif      

      jcur = FALSE;
      return(CP_SUCCESS); /* Nonlinear system was solved successfully */
    }
    
    mnewt = ++m;
    
    /* Stop at maxcor iterations or if iter. seems to be diverging. */
    if ((m == maxcor) || ((m >= 2) && (del > NLS_RDIV*delp))) return(CONV_FAIL);
    
    /* Save norm of correction, evaluate f, and loop again */
    delp = del;
    retval = fe(tn, y, ftemp, f_data);
    nfe++;
    if (retval < 0) return(CP_ODEFUNC_FAIL);
    if (retval > 0) return(ODEFUNC_RECVR);

  } /* end loop */
}
예제 #10
0
파일: inifcns.cpp 프로젝트: feelpp/feelpp
ex lsolve(const ex &eqns, const ex &symbols, unsigned options)
{
	// solve a system of linear equations
	if (eqns.info(info_flags::relation_equal)) {
		if (!symbols.info(info_flags::symbol))
			throw(std::invalid_argument("lsolve(): 2nd argument must be a symbol"));
		const ex sol = lsolve(lst{eqns}, lst{symbols});
		
		GINAC_ASSERT(sol.nops()==1);
		GINAC_ASSERT(is_exactly_a<relational>(sol.op(0)));
		
		return sol.op(0).op(1); // return rhs of first solution
	}
	
	// syntax checks
	if (!eqns.info(info_flags::list)) {
		throw(std::invalid_argument("lsolve(): 1st argument must be a list or an equation"));
	}
	for (size_t i=0; i<eqns.nops(); i++) {
		if (!eqns.op(i).info(info_flags::relation_equal)) {
			throw(std::invalid_argument("lsolve(): 1st argument must be a list of equations"));
		}
	}
	if (!symbols.info(info_flags::list)) {
		throw(std::invalid_argument("lsolve(): 2nd argument must be a list or a symbol"));
	}
	for (size_t i=0; i<symbols.nops(); i++) {
		if (!symbols.op(i).info(info_flags::symbol)) {
			throw(std::invalid_argument("lsolve(): 2nd argument must be a list of symbols"));
		}
	}
	
	// build matrix from equation system
	matrix sys(eqns.nops(),symbols.nops());
	matrix rhs(eqns.nops(),1);
	matrix vars(symbols.nops(),1);
	
	for (size_t r=0; r<eqns.nops(); r++) {
		const ex eq = eqns.op(r).op(0)-eqns.op(r).op(1); // lhs-rhs==0
		ex linpart = eq;
		for (size_t c=0; c<symbols.nops(); c++) {
			const ex co = eq.coeff(ex_to<symbol>(symbols.op(c)),1);
			linpart -= co*symbols.op(c);
			sys(r,c) = co;
		}
		linpart = linpart.expand();
		rhs(r,0) = -linpart;
	}
	
	// test if system is linear and fill vars matrix
	for (size_t i=0; i<symbols.nops(); i++) {
		vars(i,0) = symbols.op(i);
		if (sys.has(symbols.op(i)))
			throw(std::logic_error("lsolve: system is not linear"));
		if (rhs.has(symbols.op(i)))
			throw(std::logic_error("lsolve: system is not linear"));
	}
	
	matrix solution;
	try {
		solution = sys.solve(vars,rhs,options);
	} catch (const std::runtime_error & e) {
		// Probably singular matrix or otherwise overdetermined system:
		// It is consistent to return an empty list
		return lst{};
	}
	GINAC_ASSERT(solution.cols()==1);
	GINAC_ASSERT(solution.rows()==symbols.nops());
	
	// return list of equations of the form lst{var1==sol1,var2==sol2,...}
	lst sollist;
	for (size_t i=0; i<symbols.nops(); i++)
		sollist.append(symbols.op(i)==solution(i,0));
	
	return sollist;
}
예제 #11
0
파일: idas_ic.c 프로젝트: MaveriQ/AMICI
static int IDANewtonIC(IDAMem IDA_mem)
{
  int retval, mnewt, is;
  realtype delnorm, fnorm, fnorm0, oldfnrm, rate;
  booleantype sensi_sim;

  /* Are we computing sensitivities with the IDA_SIMULTANEOUS approach? */
  sensi_sim = (sensi && (ism==IDA_SIMULTANEOUS));

  /* Set pointer for vector delnew */
  delnew = phi[2];

  /* Call the linear solve function to get the Newton step, delta. */
  retval = lsolve(IDA_mem, delta, ewt, yy0, yp0, savres);
  if(retval < 0) return(IDA_LSOLVE_FAIL);
  if(retval > 0) return(IC_FAIL_RECOV);

  /* Compute the norm of the step. */
  fnorm = IDAWrmsNorm(IDA_mem, delta, ewt, FALSE);

  /* Call the lsolve function to get correction vectors deltaS. */
  if (sensi_sim) {
    for(is=0;is<Ns;is++) {
      retval = lsolve(IDA_mem, deltaS[is], ewtS[is], yy0, yp0, savres);
      if(retval < 0) return(IDA_LSOLVE_FAIL);
      if(retval > 0) return(IC_FAIL_RECOV);
    }
    /* Update the norm of delta. */
    fnorm = IDASensWrmsNormUpdate(IDA_mem, fnorm, deltaS, ewtS, FALSE);
  }

  /* Test for convergence. Return now if the norm is small. */
  if(sysindex == 0) fnorm *= tscale*SUNRabs(cj);
  if(fnorm <= epsNewt) return(IDA_SUCCESS);
  fnorm0 = fnorm;

  /* Initialize rate to avoid compiler warning message */
  rate = ZERO;

  /* Newton iteration loop */

  for(mnewt = 0; mnewt < maxnit; mnewt++) {

    nni++;
    delnorm = fnorm;
    oldfnrm = fnorm;

    /* Call the Linesearch function and return if it failed. */
    retval = IDALineSrch(IDA_mem, &delnorm, &fnorm);
    if(retval != IDA_SUCCESS) return(retval);

    /* Set the observed convergence rate and test for convergence. */
    rate = fnorm/oldfnrm;
    if(fnorm <= epsNewt) return(IDA_SUCCESS);

    /* If not converged, copy new step vector, and loop. */
    N_VScale(ONE, delnew, delta);

    if(sensi_sim) {
      /* Update the iteration's step for sensitivities. */
      for(is=0; is<Ns; is++)
        N_VScale(ONE, delnewS[is], deltaS[is]);
    }

  }   /* End of Newton iteration loop */

  /* Return either IC_SLOW_CONVRG or recoverable fail flag. */
  if(rate <= ICRATEMAX || fnorm < PT1*fnorm0) return(IC_SLOW_CONVRG);
  return(IC_CONV_FAIL);
}