reorganize scicos_sundials as std lib
Allan CORNET [Thu, 25 Jun 2009 12:04:18 +0000 (14:04 +0200)]
40 files changed:
scilab/modules/scicos/Makefile.am
scilab/modules/scicos/src/c/scicos.c
scilab/modules/scicos/src/c/scicos.vcproj
scilab/modules/scicos/src/scicos_sundials/include/cvode/cvode.h [moved from scilab/modules/scicos/src/scicos_sundials/cvode.h with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/include/cvode/cvode_dense.h [moved from scilab/modules/scicos/src/scicos_sundials/cvode_dense.h with 98% similarity]
scilab/modules/scicos/src/scicos_sundials/include/ida/ida.h [moved from scilab/modules/scicos/src/scicos_sundials/ida.h with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/include/ida/ida_dense.h [moved from scilab/modules/scicos/src/scicos_sundials/ida_dense.h with 98% similarity]
scilab/modules/scicos/src/scicos_sundials/include/kinsol/kinsol.h [moved from scilab/modules/scicos/src/scicos_sundials/kinsol.h with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/include/kinsol/kinsol_dense.h [moved from scilab/modules/scicos/src/scicos_sundials/kinsol_dense.h with 97% similarity]
scilab/modules/scicos/src/scicos_sundials/include/nvector/nvector_serial.h [moved from scilab/modules/scicos/src/scicos_sundials/nvector_serial.h with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/include/sundials/sundials_config.h [moved from scilab/modules/scicos/src/scicos_sundials/sundials_config.h with 97% similarity]
scilab/modules/scicos/src/scicos_sundials/include/sundials/sundials_dense.h [moved from scilab/modules/scicos/src/scicos_sundials/sundials_dense.h with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/include/sundials/sundials_extension.h [new file with mode: 0644]
scilab/modules/scicos/src/scicos_sundials/include/sundials/sundials_math.h [moved from scilab/modules/scicos/src/scicos_sundials/sundials_math.h with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/include/sundials/sundials_nvector.h [moved from scilab/modules/scicos/src/scicos_sundials/sundials_nvector.h with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/include/sundials/sundials_smalldense.h [moved from scilab/modules/scicos/src/scicos_sundials/sundials_smalldense.h with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/include/sundials/sundials_types.h [moved from scilab/modules/scicos/src/scicos_sundials/sundials_types.h with 98% similarity]
scilab/modules/scicos/src/scicos_sundials/scicos_sundials.vcproj
scilab/modules/scicos/src/scicos_sundials/src/cvode/cvode.c [moved from scilab/modules/scicos/src/scicos_sundials/cvode.c with 87% similarity]
scilab/modules/scicos/src/scicos_sundials/src/cvode/cvode_dense.c [moved from scilab/modules/scicos/src/scicos_sundials/cvode_dense.c with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/src/cvode/cvode_dense_impl.h [moved from scilab/modules/scicos/src/scicos_sundials/cvode_dense_impl.h with 98% similarity]
scilab/modules/scicos/src/scicos_sundials/src/cvode/cvode_impl.h [moved from scilab/modules/scicos/src/scicos_sundials/cvode_impl.h with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/src/cvode/cvode_io.c [moved from scilab/modules/scicos/src/scicos_sundials/cvode_io.c with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/src/ida/ida.c [moved from scilab/modules/scicos/src/scicos_sundials/ida.c with 86% similarity]
scilab/modules/scicos/src/scicos_sundials/src/ida/ida_dense.c [moved from scilab/modules/scicos/src/scicos_sundials/ida_dense.c with 97% similarity]
scilab/modules/scicos/src/scicos_sundials/src/ida/ida_dense_impl.h [moved from scilab/modules/scicos/src/scicos_sundials/ida_dense_impl.h with 98% similarity]
scilab/modules/scicos/src/scicos_sundials/src/ida/ida_ic.c [moved from scilab/modules/scicos/src/scicos_sundials/ida_ic.c with 98% similarity]
scilab/modules/scicos/src/scicos_sundials/src/ida/ida_impl.h [moved from scilab/modules/scicos/src/scicos_sundials/ida_impl.h with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/src/ida/ida_io.c [moved from scilab/modules/scicos/src/scicos_sundials/ida_io.c with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/src/kinsol/kinsol.c [moved from scilab/modules/scicos/src/scicos_sundials/kinsol.c with 96% similarity]
scilab/modules/scicos/src/scicos_sundials/src/kinsol/kinsol_dense.c [moved from scilab/modules/scicos/src/scicos_sundials/kinsol_dense.c with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/src/kinsol/kinsol_dense_impl.h [moved from scilab/modules/scicos/src/scicos_sundials/kinsol_dense_impl.h with 96% similarity]
scilab/modules/scicos/src/scicos_sundials/src/kinsol/kinsol_impl.h [moved from scilab/modules/scicos/src/scicos_sundials/kinsol_impl.h with 97% similarity]
scilab/modules/scicos/src/scicos_sundials/src/kinsol/kinsol_io.c [moved from scilab/modules/scicos/src/scicos_sundials/kinsol_io.c with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/src/nvec_ser/nvector_serial.c [moved from scilab/modules/scicos/src/scicos_sundials/nvector_serial.c with 99% similarity]
scilab/modules/scicos/src/scicos_sundials/src/sundials/sundials_dense.c [moved from scilab/modules/scicos/src/scicos_sundials/sundials_dense.c with 96% similarity]
scilab/modules/scicos/src/scicos_sundials/src/sundials/sundials_extension.c [new file with mode: 0644]
scilab/modules/scicos/src/scicos_sundials/src/sundials/sundials_math.c [moved from scilab/modules/scicos/src/scicos_sundials/sundials_math.c with 98% similarity]
scilab/modules/scicos/src/scicos_sundials/src/sundials/sundials_nvector.c [moved from scilab/modules/scicos/src/scicos_sundials/sundials_nvector.c with 100% similarity]
scilab/modules/scicos/src/scicos_sundials/src/sundials/sundials_smalldense.c [moved from scilab/modules/scicos/src/scicos_sundials/sundials_smalldense.c with 98% similarity]

index d8fe016..7f1c911 100644 (file)
@@ -98,7 +98,6 @@ sci_gateway/fortran/sci_vec2var.f
 
 libsciscicos_la_CFLAGS= -I$(srcdir)/includes/ \
                        -I$(srcdir)/src/c/ \
-                       -I$(srcdir)/src/scicos_sundials/ \
                        -I$(top_srcdir)/libs/MALLOC/includes/ \
                        -I$(top_srcdir)/modules/output_stream/includes \
                        -I$(top_srcdir)/libs/doublylinkedlist/includes \
@@ -108,13 +107,17 @@ libsciscicos_la_CFLAGS= -I$(srcdir)/includes/ \
                        -I$(top_srcdir)/modules/intersci/includes \
                        -I$(top_srcdir)/modules/scicos_blocks/includes \
                        -I$(top_srcdir)/modules/action_binding/includes \
-                       -I$(top_srcdir)/modules/time/includes
+                       -I$(top_srcdir)/modules/time/includes \
+                       -I$(top_srcdir)/modules/scicos/src/c/scicos_sundials/include \
+                       -I$(top_srcdir)/modules/scicos/src/c/scicos_sundials/include/sundials \
+                       -I$(top_srcdir)/modules/scicos/src/c/scicos_sundials/src/ida
+                       
 
 libsciscicos_la_SOURCES = $(SCICOS_C_SOURCES) $(SCICOS_FORTRAN_SOURCES) $(GATEWAY_C_SOURCES) $(GATEWAY_FORTRAN_SOURCES)
 
 # For the code check (splint)
 CHECK_SRC= $(SCICOS_C_SOURCES) $(GATEWAY_C_SOURCES)
-INCLUDE_FLAGS = $(libsciscicos_la_CFLAGS)
+INCLUDE_FLAGS = $(libsciscicos_la_CFLAGS) 
 
 libsciscicos_la_LIBADD =  $(top_builddir)/modules/string/libscistring.la $(top_builddir)/modules/mexlib/libmat.la $(top_builddir)/modules/mexlib/libmx.la $(top_builddir)/modules/intersci/libsciintersci.la $(top_builddir)/modules/graphics/libscigraphics.la $(top_builddir)/modules/elementary_functions/libscielementary_functions.la $(top_builddir)/modules/time/libscitime.la $(top_builddir)/modules/dynamic_link/libscidynamic_link.la $(top_builddir)/modules/scicos/libscisundials.la $(top_builddir)/modules/scicos_blocks/libsciscicos_blocks.la $(top_builddir)/modules/mexlib/libmex.la $(top_builddir)/modules/core/libscicore.la $(top_builddir)/libs/MALLOC/libscimalloc.la $(top_builddir)/modules/output_stream/libscioutput_stream.la $(top_builddir)/modules/arnoldi/libsciarnoldi.la 
 
@@ -168,21 +171,31 @@ macros/scicos_utils
 
 
 #### scicos : SUNDIALS STUFF ####
-SUNDIALS_SOURCES = src/scicos_sundials/cvode.c \
-src/scicos_sundials/sundials_dense.c \
-src/scicos_sundials/ida_ic.c \
-src/scicos_sundials/ida_dense.c \
-src/scicos_sundials/cvode_dense.c \
-src/scicos_sundials/nvector_serial.c \
-src/scicos_sundials/sundials_nvector.c \
-src/scicos_sundials/ida_io.c \
-src/scicos_sundials/cvode_io.c \
-src/scicos_sundials/sundials_smalldense.c \
-src/scicos_sundials/sundials_math.c \
-src/scicos_sundials/ida.c \
-src/scicos_sundials/kinsol_io.c \
-src/scicos_sundials/kinsol_dense.c \
-src/scicos_sundials/kinsol.c
+SUNDIALS_SOURCES = src/scicos_sundials/src/cvode/cvode.c \
+src/scicos_sundials/src/cvode/cvode_dense.c \
+src/scicos_sundials/src/cvode/cvode_io.c \
+src/scicos_sundials/src/ida/ida.c \
+src/scicos_sundials/src/ida/ida_dense.c \
+src/scicos_sundials/src/ida/ida_ic.c \
+src/scicos_sundials/src/ida/ida_io.c \
+src/scicos_sundials/src/kinsol/kinsol.c \
+src/scicos_sundials/src/kinsol/kinsol_dense.c \
+src/scicos_sundials/src/kinsol/kinsol_io.c \
+src/scicos_sundials/src/nvec_ser/nvector_serial.c \
+src/scicos_sundials/src/sundials/sundials_dense.c \
+src/scicos_sundials/src/sundials/sundials_math.c \
+src/scicos_sundials/src/sundials/sundials_nvector.c \
+src/scicos_sundials/src/sundials/sundials_smalldense.c \
+src/scicos_sundials/src/sundials/sundials_extension.c
+
+libscisundials_la_CFLAGS = -I$(top_srcdir)/modules/scicos/src/c/scicos_sundials/include \
+-I$(top_srcdir)/modules/scicos/src/c/scicos_sundials/src/cvode \
+-I$(top_srcdir)/modules/scicos/src/c/scicos_sundials/src/ida \
+-I$(top_srcdir)/modules/scicos/src/c/scicos_sundials/src/kinsol \
+-I$(top_srcdir)/modules/scicos/src/c/scicos_sundials/src/nvec_ser \
+-I$(top_srcdir)/modules/scicos/src/c/scicos_sundials/src/nvec_ser \
+-I$(top_srcdir)/modules/scicos/src/c/scicos_sundials/src/sundials
+
 
 libscisundials_la_SOURCES = $(SUNDIALS_SOURCES)
 
index 09a7096..b538d48 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
+
+/* Sundials includes */
+#include <cvode/cvode.h>           /* prototypes for CVODES fcts. and consts. */
+#include <cvode/cvode_dense.h>     /* prototype for CVDense */
+#include <ida/ida.h>
+#include <ida/ida_dense.h>
+#include <nvector/nvector_serial.h>  /* serial N_Vector types, fcts., and macros */
+#include <sundials/sundials_dense.h> /* definitions DenseMat and DENSE_ELEM */
+#include <sundials/sundials_types.h> /* definition of type realtype */
+#include <sundials/sundials_math.h>
+#include <kinsol/kinsol.h>
+#include <kinsol/kinsol_dense.h>
+#include <sundials/sundials_extension.h> /* uses extension for scicos */
+#include "ida_impl.h"
+
 #include "dynamic_link.h"
 #include "scicos-def.h"
 #include "stack-def.h"
 #include "setPrecisionFPU.h"
 #endif
 
-/* Sundials includes */
-#include "cvode.h"           /* prototypes for CVODES fcts. and consts. */
-#include "cvode_dense.h"     /* prototype for CVDense */
-#include "ida.h"
-#include "ida_dense.h"
-#include "nvector_serial.h"  /* serial N_Vector types, fcts., and macros */
-#include "sundials_dense.h" /* definitions DenseMat and DENSE_ELEM */
-#include "sundials_types.h" /* definition of type realtype */
-#include "sundials_math.h"
-#include "ida_impl.h"
-#include "kinsol.h"
-#include "kinsol_dense.h"
 /*--------------------------------------------------------------------------*/
 typedef struct {
        void *ida_mem;
@@ -757,6 +760,8 @@ default :
                        C2F(curblk).kfun = kfun0;
                }
        } else if (*flag__ == 2) { /*run*/
+
+
                /*     integration */
                if (C2F(cmsolver).solver == 0) {      /*  CVODE: Method: BDF,   Nonlinear solver= NEWTON     */
                        cossim(t0);
@@ -1212,6 +1217,10 @@ void cossim(double *told)
                NV_DATA_S(y)=x;
 
                cvode_mem = NULL;
+
+               /* Set extension of Sundials for scicos */
+               set_sundials_with_extension(TRUE);
+
                switch (C2F(cmsolver).solver)
                {
                case 0:   cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);break;
@@ -1637,6 +1646,9 @@ void cossimdaskr(double *told)
        int cnt=0, N_iters;
        maxord = 5;
 
+       /* Set extension of Sundials for scicos */
+       set_sundials_with_extension(TRUE);
+
        CI=1.0;
        if (ng!=0) {
                if((jroot=MALLOC(sizeof(int)*ng))== NULL ){
index 05969ab..c013326 100644 (file)
@@ -45,7 +45,7 @@
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories=".;../../includes;../../../../libs/MALLOC/includes;../../../../libs/doublylinkedlist/includes;../../../core/includes;../../../time/includes;../../../output_stream/includes;../../../scicos_blocks/includes;../../../graphics/includes;../../../string/includes;../../../intersci/src/lib;../../../dynamic_link/includes;../scicos_sundials;../../../action_binding/includes;../../../intersci/includes"
+                               AdditionalIncludeDirectories=".;../../includes;../../../../libs/MALLOC/includes;../../../../libs/doublylinkedlist/includes;../../../core/includes;../../../time/includes;../../../output_stream/includes;../../../scicos_blocks/includes;../../../graphics/includes;../../../string/includes;../../../intersci/src/lib;../../../dynamic_link/includes;../scicos_sundials/include;../scicos_sundials/include/sundials;../scicos_sundials/src/ida;../../../action_binding/includes;../../../intersci/includes"
                                PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;FORDLL;_DEBUG;_WINDOWS;_USRDLL;SCICOS_EXPORTS"
                                MinimalRebuild="true"
                                BasicRuntimeChecks="0"
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories=".;../../includes;../../../../libs/MALLOC/includes;../../../../libs/doublylinkedlist/includes;../../../core/includes;../../../time/includes;../../../output_stream/includes;../../../scicos_blocks/includes;../../../graphics/includes;../../../string/includes;../../../intersci/src/lib;../../../dynamic_link/includes;../scicos_sundials;../../../action_binding/includes;../../../intersci/includes"
+                               AdditionalIncludeDirectories=".;../../includes;../../../../libs/MALLOC/includes;../../../../libs/doublylinkedlist/includes;../../../core/includes;../../../time/includes;../../../output_stream/includes;../../../scicos_blocks/includes;../../../graphics/includes;../../../string/includes;../../../intersci/src/lib;../../../dynamic_link/includes;../scicos_sundials/include;../scicos_sundials/include/sundials;../scicos_sundials/src/ida;../../../action_binding/includes;../../../intersci/includes"
                                PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;FORDLL;_DEBUG;_WINDOWS;_USRDLL;SCICOS_EXPORTS"
                                MinimalRebuild="true"
                                BasicRuntimeChecks="0"
                                InlineFunctionExpansion="1"
                                FavorSizeOrSpeed="1"
                                WholeProgramOptimization="false"
-                               AdditionalIncludeDirectories=".;../../includes;../../../../libs/MALLOC/includes;../../../../libs/doublylinkedlist/includes;../../../core/includes;../../../time/includes;../../../output_stream/includes;../../../scicos_blocks/includes;../../../graphics/includes;../../../string/includes;../../../intersci/src/lib;../../../dynamic_link/includes;../scicos_sundials;../../../action_binding/includes;../../../intersci/includes"
+                               AdditionalIncludeDirectories=".;../../includes;../../../../libs/MALLOC/includes;../../../../libs/doublylinkedlist/includes;../../../core/includes;../../../time/includes;../../../output_stream/includes;../../../scicos_blocks/includes;../../../graphics/includes;../../../string/includes;../../../intersci/src/lib;../../../dynamic_link/includes;../scicos_sundials/include;../scicos_sundials/include/sundials;../scicos_sundials/src/ida;../../../action_binding/includes;../../../intersci/includes"
                                PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;FORDLL;NDEBUG;_WINDOWS;_USRDLL;SCICOS_EXPORTS"
                                StringPooling="true"
                                RuntimeLibrary="2"
                                InlineFunctionExpansion="1"
                                FavorSizeOrSpeed="1"
                                WholeProgramOptimization="false"
-                               AdditionalIncludeDirectories=".;../../includes;../../../../libs/MALLOC/includes;../../../../libs/doublylinkedlist/includes;../../../core/includes;../../../time/includes;../../../output_stream/includes;../../../scicos_blocks/includes;../../../graphics/includes;../../../string/includes;../../../intersci/src/lib;../../../dynamic_link/includes;../scicos_sundials;../../../action_binding/includes;../../../intersci/includes"
+                               AdditionalIncludeDirectories=".;../../includes;../../../../libs/MALLOC/includes;../../../../libs/doublylinkedlist/includes;../../../core/includes;../../../time/includes;../../../output_stream/includes;../../../scicos_blocks/includes;../../../graphics/includes;../../../string/includes;../../../intersci/src/lib;../../../dynamic_link/includes;../scicos_sundials/include;../scicos_sundials/include/sundials;../scicos_sundials/src/ida;../../../action_binding/includes;../../../intersci/includes"
                                PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;FORDLL;NDEBUG;_WINDOWS;_USRDLL;SCICOS_EXPORTS"
                                StringPooling="true"
                                RuntimeLibrary="2"
@@ -34,7 +34,7 @@ extern "C" {
 
 #include <stdio.h>
 
-#include "sundials_nvector.h"
+#include <sundials/sundials_nvector.h>
 
   /*
    * =================================================================
@@ -113,11 +113,12 @@ extern "C" {
    * CVODE return flags
    * ----------------------------------------
    */
+/* SUNDIALS EXTENSION */
+#define CV_ZERO_DETACH_RETURN    3
 
 #define CV_SUCCESS               0
 #define CV_TSTOP_RETURN          1
 #define CV_ROOT_RETURN           2
-#define CV_ZERO_DETACH_RETURN    3
 
 #define CV_WARNING              99
 
@@ -143,7 +144,8 @@ extern "C" {
 #define CV_BAD_T                -25
 #define CV_BAD_DKY              -26
 #define CV_TOO_CLOSE            -27
-  /* added by masoud*/
+
+/* SUNDIALS EXTENSION */
 #define CV_YOUT_NULL            -28
 #define CV_TRET_NULL            -29
 #define CV_BAD_ITASK            -30
@@ -165,6 +167,7 @@ extern "C" {
 #define CV_NULL_G               -46
 #define CV_BAD_TOUT             -47
 #define CV_CLOSE_ROOTS          -48
+
   /*
    * =================================================================
    *              F U N C T I O N   T Y P E S
@@ -687,7 +690,7 @@ extern "C" {
    * The following functions can be called to get optional outputs
    * and statistics related to the main integrator.
    * -----------------------------------------------------------------
-   * CVodeGetWorkSpace returns the CVODE real and int workspaces
+   * CVodeGetWorkSpace returns the CVODE real and integer workspaces
    * CVodeGetNumSteps returns the cumulative number of internal
    *                  steps taken by the solver
    * CVodeGetNumRhsEvals returns the number of calls to the user's
@@ -22,8 +22,8 @@
 extern "C" {
 #endif
 
-#include "sundials_dense.h"
-#include "sundials_nvector.h"
+#include <sundials/sundials_dense.h>
+#include <sundials/sundials_nvector.h>
 
 /*
  * -----------------------------------------------------------------
@@ -156,7 +156,7 @@ int CVDenseSetJacFn(void *cvode_mem, CVDenseJacFn djac, void *jac_data);
  * Optional outputs from the CVDENSE linear solver
  * -----------------------------------------------------------------
  *
- * CVDenseGetWorkSpace returns the real and int workspace used
+ * CVDenseGetWorkSpace returns the real and integer workspace used
  *                     by CVDENSE.
  * CVDenseGetNumJacEvals returns the number of calls made to the
  *                       Jacobian evaluation routine djac.
@@ -33,7 +33,7 @@ extern "C" {
 
 #include <stdio.h>
 
-#include "sundials_nvector.h"
+#include <sundials/sundials_nvector.h>
 
   /*
    * =================================================================
@@ -68,11 +68,14 @@ extern "C" {
    * ----------------------------------------
    */
 
-#define IDA_SUCCESS              0
-#define IDA_TSTOP_RETURN         1
-#define IDA_ROOT_RETURN          2
+/* SUNDIALS EXTENSION */
 #define IDA_ZERO_DETACH_RETURN   3
-#define IDA_WARNING              99
+
+#define IDA_SUCCESS          0
+#define IDA_TSTOP_RETURN     1
+#define IDA_ROOT_RETURN      2
+
+#define IDA_WARNING          99
 
 #define IDA_MEM_NULL        -1
 #define IDA_ILL_INPUT       -2
@@ -99,7 +102,7 @@ extern "C" {
 
 #define IDA_RTFUNC_FAIL     -20
 
-  /* added by masoud*/
+/* SUNDIALS EXTENSION */
 #define IDA_YOUT_NULL            -28
 #define IDA_TRET_NULL            -29
 #define IDA_BAD_ITASK            -30
@@ -838,7 +841,7 @@ extern "C" {
    * and statistics related to the main integrator.                 
    * ---------------------------------------------------------------- 
    *                                                                
-   * IDAGetWorkSpace returns the IDA real and int workspace sizes      
+   * IDAGetWorkSpace returns the IDA real and integer workspace sizes      
    * IDAGetNumSteps returns the cumulative number of internal       
    *       steps taken by the solver                                
    * IDAGetNumRhsEvals returns the number of calls to the user's    
@@ -22,8 +22,8 @@
 extern "C" {
 #endif
 
-#include "sundials_dense.h"
-#include "sundials_nvector.h"
+#include <sundials/sundials_dense.h>
+#include <sundials/sundials_nvector.h>
 
   /*
    * -----------------------------------------------------------------
@@ -174,7 +174,7 @@ extern "C" {
    * -----------------------------------------------------------------
    * Optional outputs from the IDADENSE linear solver
    * -----------------------------------------------------------------
-   * IDADenseGetWorkSpace returns the real and int workspace used 
+   * IDADenseGetWorkSpace returns the real and integer workspace used 
    *     by IDADENSE.                                                  
    * IDADenseGetNumJacEvals returns the number of calls made to the 
    *     Jacobian evaluation routine djac.                          
@@ -1,7 +1,7 @@
 /*
  * -----------------------------------------------------------------
- * Revision: 1.1 $
- * Date: 2008-11-17 16:26:32 $
+ * $Revision: 1.1 $
+ * $Date: 2006/07/05 15:27:52 $
  * -----------------------------------------------------------------
  * Programmer(s): Allan Taylor, Alan Hindmarsh, Radu Serban, and
  *                Aaron Collier @ LLNL
@@ -24,7 +24,7 @@ extern "C" {
 
 #include <stdio.h>
 
-#include "sundials_nvector.h"
+#include <sundials/sundials_nvector.h>
 
   /*
    * =================================================================
@@ -62,9 +62,6 @@ extern "C" {
 #define KIN_REPTD_SYSFUNC_ERR   -15
 #define KIN_NAN_ERR             -16
 
-/* disables fprintf output */
-#define        NO_FPRINTF_OUTPUT 1
-
   /*
    * -----------------------------------------------------------------
    * Enumeration for inputs to KINSetEtaForm (eta choice)
@@ -1,7 +1,7 @@
 /*
  * -----------------------------------------------------------------
- * Revision: 1.1 $
- * Date: 2008-11-17 16:26:32 $
+ * $Revision: 1.1 $
+ * $Date: 2006/07/05 15:27:52 $
  * -----------------------------------------------------------------
  * Programmer(s): Radu Serban @ LLNL
  * -----------------------------------------------------------------
@@ -22,8 +22,8 @@ extern "C" {
 #ifndef _KINDENSE_H
 #define _KINDENSE_H
 
-#include "sundials_dense.h"
-#include "sundials_nvector.h"
+#include <sundials/sundials_dense.h>
+#include <sundials/sundials_nvector.h>
 
 /*
  * -----------------------------------------------------------------
@@ -53,7 +53,7 @@
 extern "C" {
 #endif
 
-#include "sundials_nvector.h"
+#include <sundials/sundials_nvector.h>
 
 /*
  * -----------------------------------------------------------------
@@ -69,3 +69,6 @@
  * ---------------------------------------------------------- */
 
 #define SUNDIALS_MPI_COMM_F2C 1
+
+/* disables fprintf output */
+#define        NO_FPRINTF_OUTPUT 1
\ No newline at end of file
@@ -42,8 +42,8 @@
 extern "C" {
 #endif
 
-#include "sundials_types.h"
-#include "sundials_smalldense.h"
+#include <sundials/sundials_types.h>
+#include <sundials/sundials_smalldense.h>
 
   /*
    * ==================================================================
diff --git a/scilab/modules/scicos/src/scicos_sundials/include/sundials/sundials_extension.h b/scilab/modules/scicos/src/scicos_sundials/include/sundials/sundials_extension.h
new file mode 100644 (file)
index 0000000..f9da9ff
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * -----------------------------------------------------------------
+ * Allan CORNET - 2009 
+ * For details, see sundials/shared/LICENSE.
+ * -----------------------------------------------------------------
+ */
+ #ifndef __SUNDIALS_EXTENSION_H__
+ #define __SUNDIALS_EXTENSION_H__
+ #define BOOL int
+ #define TRUE 1
+ #define FALSE 0
+ /**
+ * checks if sundials extension is enabled
+ * @return TRUE or FALSE
+ */
+ BOOL is_sundials_with_extension(void);
+ /**
+ * set extension mode for sundials
+ * @param[in] _mode TRUE is enabled , FALSE use default mode of sundials
+ * @return new mode
+ */
+ BOOL set_sundials_with_extension(BOOL _mode);
+ #endif /* __SUNDIALS_EXTENSION_H__ */
\ No newline at end of file
@@ -24,7 +24,7 @@
 extern "C" {
 #endif
 
-#include "sundials_types.h"
+#include <sundials/sundials_types.h>
 
 /*
  * -----------------------------------------------------------------
@@ -47,7 +47,7 @@ extern "C" {
 
 #ifndef _SUNDIALS_CONFIG_H
 #define _SUNDIALS_CONFIG_H
-#include "sundials_config.h"
+#include <sundials/sundials_config.h>
 #endif
 
 #include <float.h>
index 5036b2a..3247580 100644 (file)
@@ -45,7 +45,7 @@
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="../../includes;../../../../libs/MALLOC/includes;../../../../libs/doublylinkedlist/includes;../../../core/includes;../../../output_stream/includes;../../../scicos_sundials_blocks/includes;../../../graphics/includes;../../../string/includes;../../../intersci/src/lib"
+                               AdditionalIncludeDirectories="include;include/sundials;src/cvode;src/ida;src/kinsol;src/nvec_ser;src/sundials"
                                PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;FORDLL;_DEBUG;_WINDOWS;_USRDLL;SCICOS_SUNDIALS_EXPORTS"
                                MinimalRebuild="true"
                                BasicRuntimeChecks="0"
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="../../includes;../../../../libs/MALLOC/includes;../../../../libs/doublylinkedlist/includes;../../../core/includes;../../../output_stream/includes;../../../scicos_sundials_blocks/includes;../../../graphics/includes;../../../string/includes;../../../intersci/src/lib"
+                               AdditionalIncludeDirectories="include;include/sundials;src/cvode;src/ida;src/kinsol;src/nvec_ser;src/sundials"
                                PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;FORDLL;_DEBUG;_WINDOWS;_USRDLL;SCICOS_SUNDIALS_EXPORTS"
                                MinimalRebuild="true"
                                BasicRuntimeChecks="0"
                                InlineFunctionExpansion="1"
                                FavorSizeOrSpeed="1"
                                WholeProgramOptimization="false"
-                               AdditionalIncludeDirectories="../../includes;../../../../libs/MALLOC/includes;../../../../libs/doublylinkedlist/includes;../../../core/includes;../../../output_stream/includes;../../../scicos_sundials_blocks/includes;../../../graphics/includes;../../../string/includes;../../../intersci/src/lib"
+                               AdditionalIncludeDirectories="include;include/sundials;src/cvode;src/ida;src/kinsol;src/nvec_ser;src/sundials"
                                PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;FORDLL;NDEBUG;_WINDOWS;_USRDLL;SCICOS_SUNDIALS_EXPORTS"
                                StringPooling="true"
                                RuntimeLibrary="2"
                                InlineFunctionExpansion="1"
                                FavorSizeOrSpeed="1"
                                WholeProgramOptimization="false"
-                               AdditionalIncludeDirectories="../../includes;../../../../libs/MALLOC/includes;../../../../libs/doublylinkedlist/includes;../../../core/includes;../../../output_stream/includes;../../../scicos_sundials_blocks/includes;../../../graphics/includes;../../../string/includes;../../../intersci/src/lib"
+                               AdditionalIncludeDirectories="include;include/sundials;src/cvode;src/ida;src/kinsol;src/nvec_ser;src/sundials"
                                PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;FORDLL;NDEBUG;_WINDOWS;_USRDLL;SCICOS_SUNDIALS_EXPORTS"
                                StringPooling="true"
                                RuntimeLibrary="2"
                        Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
                        >
                        <File
-                               RelativePath=".\cvode.c"
+                               RelativePath=".\src\cvode\cvode.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\cvode_dense.c"
+                               RelativePath=".\src\cvode\cvode_dense.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\cvode_io.c"
+                               RelativePath=".\src\cvode\cvode_io.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\ida.c"
+                               RelativePath=".\src\ida\ida.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\ida_dense.c"
+                               RelativePath=".\src\ida\ida_dense.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\ida_ic.c"
+                               RelativePath=".\src\ida\ida_ic.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\ida_io.c"
+                               RelativePath=".\src\ida\ida_io.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\kinsol.c"
+                               RelativePath=".\src\kinsol\kinsol.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\kinsol_dense.c"
+                               RelativePath=".\src\kinsol\kinsol_dense.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\kinsol_io.c"
+                               RelativePath=".\src\kinsol\kinsol_io.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\nvector_serial.c"
+                               RelativePath=".\src\nvec_ser\nvector_serial.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\sundials_dense.c"
+                               RelativePath=".\src\sundials\sundials_dense.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\sundials_math.c"
+                               RelativePath=".\src\sundials\sundials_extension.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\sundials_nvector.c"
+                               RelativePath=".\src\sundials\sundials_math.c"
                                >
                        </File>
                        <File
-                               RelativePath=".\sundials_smalldense.c"
+                               RelativePath=".\src\sundials\sundials_nvector.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\sundials\sundials_smalldense.c"
                                >
                        </File>
                </Filter>
                        Filter="h;hpp;hxx;hm;inl"
                        >
                        <File
-                               RelativePath=".\cvode.h"
+                               RelativePath=".\include\cvode\cvode.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\include\cvode\cvode_dense.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\cvode_dense.h"
+                               RelativePath=".\src\cvode\cvode_dense_impl.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\cvode_dense_impl.h"
+                               RelativePath=".\src\cvode\cvode_impl.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\cvode_impl.h"
+                               RelativePath=".\include\ida\ida.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\ida.h"
+                               RelativePath=".\include\ida\ida_dense.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\ida_dense.h"
+                               RelativePath=".\src\ida\ida_dense_impl.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\ida_dense_impl.h"
+                               RelativePath=".\src\ida\ida_impl.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\ida_impl.h"
+                               RelativePath=".\include\kinsol\kinsol.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\kinsol.h"
+                               RelativePath=".\include\kinsol\kinsol_dense.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\kinsol_dense.h"
+                               RelativePath=".\src\kinsol\kinsol_dense_impl.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\kinsol_dense_impl.h"
+                               RelativePath=".\src\kinsol\kinsol_impl.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\kinsol_impl.h"
+                               RelativePath=".\include\nvector\nvector_serial.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\nvector_serial.h"
+                               RelativePath=".\include\sundials\sundials_config.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\sundials_config.h"
+                               RelativePath=".\include\sundials\sundials_dense.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\sundials_dense.h"
+                               RelativePath=".\include\sundials\sundials_extension.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\sundials_math.h"
+                               RelativePath=".\include\sundials\sundials_math.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\sundials_nvector.h"
+                               RelativePath=".\include\sundials\sundials_nvector.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\sundials_smalldense.h"
+                               RelativePath=".\include\sundials\sundials_smalldense.h"
                                >
                        </File>
                        <File
-                               RelativePath=".\sundials_types.h"
+                               RelativePath=".\include\sundials\sundials_types.h"
                                >
                        </File>
                </Filter>
 #include <stdarg.h>
 
 #include "cvode_impl.h"
-#include "sundials_math.h"
-#include "sundials_types.h"
+#include <sundials/sundials_math.h>
+#include <sundials/sundials_types.h>
+
+/* SUNDIALS EXTENSION */
+#include "sundials_extension.h"
 
 /*=================================================================*/
 /*             Macros                                              */
 #define RTFOUND          +1
 #define INITROOT         +2
 #define CLOSERT          +3
+
+/* SUNDIALS EXTENSION */
 #define ZERODETACHING    +4
 #define MASKED           55
 
@@ -298,6 +303,18 @@ static int CVRcheck2(CVodeMem cv_mem);
 static int CVRcheck3(CVodeMem cv_mem);
 static int CVRootfind(CVodeMem cv_mem);
 
+static int CVRcheck1Std(CVodeMem cv_mem);
+static int CVRcheck2Std(CVodeMem cv_mem);
+static int CVRcheck3Std(CVodeMem cv_mem);
+static int CVRootfindStd(CVodeMem cv_mem);
+
+/* SUNDIALS EXTENSION */
+static int CVRcheck1Ext(CVodeMem cv_mem);
+static int CVRcheck2Ext(CVodeMem cv_mem);
+static int CVRcheck3Ext(CVodeMem cv_mem);
+static int CVRootfindExt(CVodeMem cv_mem);
+
+
 /* 
  * =================================================================
  * EXPORTED FUNCTIONS IMPLEMENTATION
@@ -436,20 +453,46 @@ int CVodeMalloc(void *cvode_mem, CVRhsFn f, realtype t0, N_Vector y0,
 
   if (y0==NULL) {
     CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeMalloc", MSGCV_NULL_Y0);
-    /* return(CV_ILL_INPUT); Masoud */
-    return(CV_NULL_Y0);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(CV_NULL_Y0);
+       }
+       else
+       {
+               return(CV_ILL_INPUT);
+       }
   }
 
   if ((itol != CV_SS) && (itol != CV_SV) && (itol != CV_WF)) {
     CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeMalloc", MSGCV_BAD_ITOL);
-    /* return(CV_ILL_INPUT); Masoud */
-    return(CV_BAD_ITOL);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(CV_BAD_ITOL);
+       }
+       else
+       {
+               return(CV_ILL_INPUT);
+       }
+
   }
 
   if (f == NULL) {
     CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeMalloc", MSGCV_NULL_F);
-    /* return(CV_ILL_INPUT); Masoud */
-    return(CV_NULL_F);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(CV_NULL_F);
+       }
+       else
+       {
+               return(CV_ILL_INPUT);
+       }
+
   }
 
   /* Test if all required vector operations are implemented */
@@ -457,8 +500,16 @@ int CVodeMalloc(void *cvode_mem, CVRhsFn f, realtype t0, N_Vector y0,
   nvectorOK = CVCheckNvector(y0);
   if(!nvectorOK) {
     CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeMalloc", MSGCV_BAD_NVECTOR);
-    /* return(CV_ILL_INPUT); Masoud */
-    return(CV_BAD_NVECTOR);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(CV_BAD_NVECTOR);
+       }
+       else
+       {
+               return(CV_ILL_INPUT);
+       }
   }
 
   /* Test tolerances */
@@ -467,14 +518,32 @@ int CVodeMalloc(void *cvode_mem, CVRhsFn f, realtype t0, N_Vector y0,
 
     if (abstol == NULL) {
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeMalloc", MSGCV_NULL_ABSTOL);
-    /* return(CV_ILL_INPUT); Masoud */
-      return(CV_NULL_ABSTOL);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(CV_NULL_ABSTOL);
+         }
+         else
+         {
+               return(CV_ILL_INPUT);
+         }
+
     }
 
     if (reltol < ZERO) {
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeMalloc", MSGCV_BAD_RELTOL);
-      /* return(CV_ILL_INPUT); Masoud */
-      return(CV_BAD_RELTOL);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+               return(CV_BAD_RELTOL);
+         }
+         else
+         {
+               return(CV_ILL_INPUT);
+         }
+
     }
 
     if (itol == CV_SS)
@@ -484,8 +553,16 @@ int CVodeMalloc(void *cvode_mem, CVRhsFn f, realtype t0, N_Vector y0,
 
     if (neg_abstol) {
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeMalloc", MSGCV_BAD_ABSTOL);
-      /* return(CV_ILL_INPUT); Masoud */
-      return(CV_BAD_ABSTOL);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(CV_BAD_ABSTOL);
+         }
+         else
+         {
+                 return(CV_ILL_INPUT);
+         }
     }
 
   }
@@ -631,20 +708,44 @@ int CVodeReInit(void *cvode_mem, CVRhsFn f, realtype t0, N_Vector y0,
 
   if (y0 == NULL) {
     CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeReInit", MSGCV_NULL_Y0);
-    /* return(CV_ILL_INPUT); Masoud */
-    return(CV_NULL_Y0);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(CV_NULL_Y0);
+       }
+       else
+       {
+               return(CV_ILL_INPUT);
+       }
   }
   
   if ((itol != CV_SS) && (itol != CV_SV) && (itol != CV_WF)) {
     CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeReInit", MSGCV_BAD_ITOL);
-    /* return(CV_ILL_INPUT); Masoud */
-    return(CV_BAD_ITOL);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(CV_BAD_ITOL);
+       }
+       else
+       {
+               return(CV_ILL_INPUT);
+       }
   }
 
   if (f == NULL) {
     CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeReInit", MSGCV_NULL_F);
-    /* return(CV_ILL_INPUT); Masoud */
-    return(CV_NULL_F);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(CV_NULL_F);
+       }
+       else
+       {
+               return(CV_ILL_INPUT);
+       }
   }
 
   /* Test tolerances */
@@ -653,14 +754,30 @@ int CVodeReInit(void *cvode_mem, CVRhsFn f, realtype t0, N_Vector y0,
 
     if (abstol == NULL) {
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeReInit", MSGCV_NULL_ABSTOL);
-    /* return(CV_ILL_INPUT); Masoud */
-      return(CV_NULL_ABSTOL);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(CV_NULL_ABSTOL);
+         }
+         else
+         {
+                 return(CV_ILL_INPUT);
+         }
     }
 
     if (reltol < ZERO) {
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeReInit", MSGCV_BAD_RELTOL);
-    /* return(CV_ILL_INPUT); Masoud */
-      return(CV_BAD_RELTOL);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(CV_BAD_RELTOL);
+         }
+         else
+         {
+                 return(CV_ILL_INPUT);
+         }
     }
     
     if (itol == CV_SS) {
@@ -671,8 +788,16 @@ int CVodeReInit(void *cvode_mem, CVRhsFn f, realtype t0, N_Vector y0,
     
     if (neg_abstol) {
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeReInit", MSGCV_BAD_ABSTOL);
-    /* return(CV_ILL_INPUT); Masoud */
-      return(CV_BAD_ABSTOL);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+               return(CV_BAD_ABSTOL);
+         }
+         else
+         {
+               return(CV_ILL_INPUT);
+         }
     }
 
   }
@@ -830,8 +955,16 @@ int CVodeRootInit(void *cvode_mem, int nrtfn, CVRootFn g, void *gdata)
         liw -= nrt;
 
         CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeRootInit", MSGCV_NULL_G);
-       /* return(CV_ILL_INPUT); Masoud */
-       return(CV_NULL_G);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(CV_NULL_G);
+               }
+               else
+               {
+                       return(CV_ILL_INPUT);
+               }
       }
       else {
        gfun = g;
@@ -845,8 +978,17 @@ int CVodeRootInit(void *cvode_mem, int nrtfn, CVRootFn g, void *gdata)
   cv_mem->cv_nrtfn = nrt;
   if (g == NULL) {
     CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVodeRootInit", MSGCV_NULL_G);
-    /* return(CV_ILL_INPUT); Masoud */
-    return(CV_NULL_G);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(CV_NULL_G);
+       }
+       else
+       {
+               return(CV_ILL_INPUT);
+       }
+
   }
   else gfun = g;
 
@@ -1042,16 +1184,32 @@ int CVode(void *cvode_mem, realtype tout, N_Vector yout,
   /* Check for yout != NULL */
   if ((y = yout) == NULL) {
     CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_YOUT_NULL);
-    /*    return(CV_ILL_INPUT); Masoud*/
-    return(CV_YOUT_NULL);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(CV_YOUT_NULL);
+       }
+       else
+       {
+               return(CV_ILL_INPUT);
+       }
 
   }
 
   /* Check for tret != NULL */
   if (tret == NULL) {
     CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_TRET_NULL);
-    /*    return(CV_ILL_INPUT); Masoud*/
-    return(CV_TRET_NULL);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(CV_TRET_NULL);
+       }
+       else
+       {
+               return(CV_ILL_INPUT);
+       }
   }
 
   /* Check for valid itask */
@@ -1060,16 +1218,34 @@ int CVode(void *cvode_mem, realtype tout, N_Vector yout,
       (itask != CV_NORMAL_TSTOP) &&
       (itask != CV_ONE_STEP_TSTOP) ) {
     CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_BAD_ITASK);
-    /*    return(CV_ILL_INPUT); Masoud*/
-    return(CV_BAD_ITASK);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(CV_BAD_ITASK);
+       }
+       else
+       {
+               return(CV_ILL_INPUT);
+       }
+
   }
 
   /* Split itask into task and istop */
   if ((itask == CV_NORMAL_TSTOP) || (itask == CV_ONE_STEP_TSTOP)) {
     if ( tstopset == FALSE ) {
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_NO_TSTOP);
-    /*    return(CV_ILL_INPUT); Masoud*/
-      return(CV_NO_TSTOP);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(CV_NO_TSTOP);
+         }
+         else
+         {
+                 return(CV_ILL_INPUT);
+         }
+
     }
     istop = TRUE;
   } else {
@@ -1119,8 +1295,17 @@ int CVode(void *cvode_mem, realtype tout, N_Vector yout,
     h = hin;
     if ( (h != ZERO) && ((tout-tn)*h < ZERO) ) {
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_BAD_H0);
-    /*    return(CV_ILL_INPUT); Masoud*/
-      return(CV_BAD_H0);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(CV_BAD_H0);
+         }
+         else
+         {
+                 return(CV_ILL_INPUT);
+         }
+
     }
     if (h == ZERO) {
       hflag = CVHin(cv_mem, tout);
@@ -1138,8 +1323,17 @@ int CVode(void *cvode_mem, realtype tout, N_Vector yout,
     if (istop) {
       if ( (tstop - tn)*h < ZERO ) {
         CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_BAD_TSTOP, tn);
-       /*    return(CV_ILL_INPUT); Masoud*/
-        return(CV_BAD_TSTOP);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(CV_BAD_TSTOP);
+               }
+               else
+               {
+                       return(CV_ILL_INPUT);
+               }
+
       }
       if ( (tn + h - tstop)*h > ZERO ) 
         h = (tstop - tn)*(ONE-FOUR*uround);
@@ -1161,8 +1355,17 @@ int CVode(void *cvode_mem, realtype tout, N_Vector yout,
 
       if (retval == INITROOT) {
         CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVRcheck1", MSGCV_BAD_INIT_ROOT);
-       /*    return(CV_ILL_INPUT); Masoud*/
-        return(CV_BAD_INIT_ROOT);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(CV_BAD_INIT_ROOT);
+               }
+               else
+               {
+                       return(CV_ILL_INPUT);
+               }
+
       } else if (retval == CV_RTFUNC_FAIL) {
         CVProcessError(cv_mem, CV_RTFUNC_FAIL, "CVODE", "CVRcheck1", MSGCV_RTFUNC_FAILED, tn);
         return(CV_RTFUNC_FAIL);
@@ -1202,8 +1405,17 @@ int CVode(void *cvode_mem, realtype tout, N_Vector yout,
 
       if (retval == CLOSERT) {
         CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVRcheck2", MSGCV_CLOSE_ROOTS, tlo);
-       /*    return(CV_ILL_INPUT); Masoud*/
-        return(CV_CLOSE_ROOTS);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(CV_CLOSE_ROOTS);
+               }
+               else
+               {
+                       return(CV_ILL_INPUT);
+               }
+
       } else if (retval == CV_RTFUNC_FAIL) {
         CVProcessError(cv_mem, CV_RTFUNC_FAIL, "CVODE", "CVRcheck2", MSGCV_RTFUNC_FAILED, tlo);
         return(CV_RTFUNC_FAIL);
@@ -1217,6 +1429,7 @@ int CVode(void *cvode_mem, realtype tout, N_Vector yout,
       if ( ABS(tn - tretlast) > troundoff ) {
 
         retval = CVRcheck3(cv_mem);
+
         if (retval == CV_SUCCESS) {     /* no root found */
           irfnd = 0;
           if ((irfndp == 1) && (task == CV_ONE_STEP)) {
@@ -1231,19 +1444,34 @@ int CVode(void *cvode_mem, realtype tout, N_Vector yout,
         } else if (retval == CV_RTFUNC_FAIL) {  /* g failed */
           CVProcessError(cv_mem, CV_RTFUNC_FAIL, "CVODE", "CVRcheck3", MSGCV_RTFUNC_FAILED, tlo);
           return(CV_RTFUNC_FAIL);
-        } else if (retval == ZERODETACHING) {  /* Zero detaching */
+        }
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension()) 
+               {
+               if (retval == ZERODETACHING) {  /* Zero detaching */
           irfnd = 1;
           tretlast = *tret = tlo;
           return(CV_ZERO_DETACH_RETURN);
        }
+               }
       }
 
     } /* end of root stop check */
     /* Test for tn past tstop */
     if ( istop && ((tstop - tn)*h < ZERO) ) {
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_BAD_TSTOP, tn);
-      /* return(CV_ILL_INPUT); Masoud */
-      return(CV_BAD_TSTOP);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(CV_BAD_TSTOP);
+         }
+         else
+         {
+                 return(CV_ILL_INPUT);
+         }
+
     }
 
     /* In CV_NORMAL mode, test if tout was reached */
@@ -1252,8 +1480,16 @@ int CVode(void *cvode_mem, realtype tout, N_Vector yout,
       ier =  CVodeGetDky(cv_mem, tout, 0, yout);
       if (ier != CV_SUCCESS) {
         CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_BAD_TOUT, tout);
-       /* return(CV_ILL_INPUT); Masoud */
-        return(CV_BAD_TOUT);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(CV_BAD_TOUT);
+               }
+               else
+               {
+                       return(CV_ILL_INPUT);
+               }
       }
       return(CV_SUCCESS);
     }
@@ -1272,8 +1508,17 @@ int CVode(void *cvode_mem, realtype tout, N_Vector yout,
         ier =  CVodeGetDky(cv_mem, tstop, 0, yout);
         if (ier != CV_SUCCESS) {
           CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVode", MSGCV_BAD_TSTOP, tn);
-       /* return(CV_ILL_INPUT); Masoud */
-          return(CV_BAD_TSTOP);
+
+                 /* SUNDIALS EXTENSION */
+                 if (is_sundials_with_extension())
+                 {
+                       return(CV_BAD_TSTOP);
+                 }
+                 else
+                 {
+                       return(CV_ILL_INPUT);
+                 }
+
         }
         tretlast = *tret = tstop;
         return(CV_TSTOP_RETURN);
@@ -1390,12 +1635,18 @@ int CVode(void *cvode_mem, realtype tout, N_Vector yout,
         CVProcessError(cv_mem, CV_RTFUNC_FAIL, "CVODE", "CVRcheck3", MSGCV_RTFUNC_FAILED, tlo);
         istate = CV_RTFUNC_FAIL;
         break;
-      }else if (retval == ZERODETACHING) {  /* Zero detaching */
+      }
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension()) 
+         {
+         if (retval == ZERODETACHING) {  /* Zero detaching */
        irfnd = 1;
         istate = CV_ZERO_DETACH_RETURN;
         tretlast = *tret = tlo;
         break;
       }
+         }
 
     }
 
@@ -1585,7 +1836,7 @@ static booleantype CVCheckNvector(N_Vector tmpl)
  * If all memory allocations are successful, CVAllocVectors returns TRUE. 
  * Otherwise all allocated memory is freed and CVAllocVectors returns FALSE.
  * This routine also sets the optional outputs lrw and liw, which are
- * (respectively) the lengths of the real and int work spaces
+ * (respectively) the lengths of the real and integer work spaces
  * allocated here.
  */
 
@@ -1713,8 +1964,16 @@ static int CVInitialSetup(CVodeMem cv_mem)
   } else {
     if (efun == NULL) {
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVInitialSetup", MSGCV_NO_EFUN);
-      /*return(CV_ILL_INPUT); Masoud */
-      return(CV_NO_EFUN);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(CV_NO_EFUN);
+         }
+         else
+         {
+                 return(CV_ILL_INPUT);
+         }
 
     }
   }
@@ -1724,12 +1983,29 @@ static int CVInitialSetup(CVodeMem cv_mem)
 
     if (itol == CV_WF){ 
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVInitialSetup", MSGCV_EWT_FAIL);
-      /*return(CV_ILL_INPUT); Masoud */
-      return(CV_EWT_FAIL);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+               return(CV_EWT_FAIL);
+         }
+         else
+         {
+               return(CV_ILL_INPUT);
+         }
     }else{ 
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVInitialSetup", MSGCV_BAD_EWT);
-    /*return(CV_ILL_INPUT); Masoud */
-    return(CV_BAD_EWT);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(CV_BAD_EWT);
+         }
+         else
+         {
+                 return(CV_ILL_INPUT);
+         }
+
     }
   }
   
@@ -1739,8 +2015,17 @@ static int CVInitialSetup(CVodeMem cv_mem)
   if (iter == CV_NEWTON) {
     if (lsolve == NULL) {
       CVProcessError(cv_mem, CV_ILL_INPUT, "CVODE", "CVInitialSetup", MSGCV_LSOLVE_NULL);
-      /*return(CV_ILL_INPUT); Masoud */
-      return(CV_LSOLVE_NULL);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+               return(CV_LSOLVE_NULL);
+         }
+         else
+         {
+               return(CV_ILL_INPUT);
+         }
+
     }
     if (linit != NULL) {
       ier = linit(cv_mem);
@@ -3583,7 +3868,22 @@ static int CVsldet(CVodeMem cv_mem)
  * Root finding   
  * =================================================================
  */
-static int CVRcheck1_orig(CVodeMem cv_mem)
+
+/*-----------------------------------------------------------------*/
+
+/* 
+ * CVRcheck1
+ *
+ * This routine completes the initialization of rootfinding memory
+ * information, and checks whether g has a zero both at and very near
+ * the initial point of the IVP.
+ *
+ * This routine returns an int equal to:
+ *  INITROOT = -1 if a close pair of zeros was found, and
+ *  CV_SUCCESS     =  0 otherwise.
+ */
+
+static int CVRcheck1Std(CVodeMem cv_mem)
 {
   int i, retval;
   realtype smallh, hratio;
@@ -3623,7 +3923,7 @@ static int CVRcheck1_orig(CVodeMem cv_mem)
   if (zroot) return(INITROOT);
   return(CV_SUCCESS);
 
-} 
+}
 
 /*
  * CVRcheck2
@@ -3645,7 +3945,7 @@ static int CVRcheck1_orig(CVodeMem cv_mem)
  *      CV_SUCCESS    =  0 otherwise.
  */
 
-static int CVRcheck2_orig(CVodeMem cv_mem)
+static int CVRcheck2Std(CVodeMem cv_mem)
 {
   int i, retval;
   realtype smallh, hratio;
@@ -3707,7 +4007,7 @@ static int CVRcheck2_orig(CVodeMem cv_mem)
  *      CV_SUCCESS    =  0 otherwise.
  */
 
-static int CVRcheck3_orig(CVodeMem cv_mem)
+static int CVRcheck3Std(CVodeMem cv_mem)
 {
   int i, retval, ier;
 
@@ -3804,7 +4104,7 @@ static int CVRcheck3_orig(CVodeMem cv_mem)
  *      CV_SUCCESS    =  0 otherwise.
  */
 
-static int CVRootfind_orig(CVodeMem cv_mem)
+static int CVRootfindStd(CVodeMem cv_mem)
 {
   realtype alpha, tmid, gfrac, maxfrac, fracint, fracsub;
   int i, retval, imax, side, sideprev;
@@ -3822,7 +4122,7 @@ static int CVRootfind_orig(CVodeMem cv_mem)
     } else {
       if (glo[i]*ghi[i] < ZERO) {
         gfrac = ABS(ghi[i]/(ghi[i] - glo[i]));
-        if (gfrac > maxfrac) { /* finding the very first root*/
+        if (gfrac > maxfrac) {
           sgnchg = TRUE;
           maxfrac = gfrac;
           imax = i;
@@ -3946,389 +4246,6 @@ static int CVRootfind_orig(CVodeMem cv_mem)
   return(RTFOUND);
 }
 
-/*-----------------------------------------------------------------*/
-
-/* 
- * CVRcheck1
- *
- * This routine completes the initialization of rootfinding memory
- * information, and checks whether g has a zero both at and very near
- * the initial point of the IVP.
- *
- * This routine returns an int equal to:
- *  INITROOT = -1 if a close pair of zeros was found, and
- *  CV_SUCCESS     =  0 otherwise.
- */
-
-static int CVRcheck1(CVodeMem cv_mem)
-{
-  int i, retval;
-  booleantype zroot;
-
-  for (i = 0; i < nrtfn; i++) iroots[i] = 0;
-  tlo = tn;
-  ttol = (ABS(tn) + ABS(h))*uround*HUN;
-
-  /* Evaluate g at initial t and check for zero values. */
-  retval = gfun(tlo, zn[0], glo, g_data);
-  nge = 1;
-  if (retval != 0) return(CV_RTFUNC_FAIL);
-
-  zroot = FALSE;
-  for (i = 0; i < nrtfn; i++) {
-    if (ABS(glo[i]) == ZERO) 
-      iroots[i] =MASKED; /* arbitrary choice*/
-    else 
-      iroots[i] =0;
-  }
-  return(CV_SUCCESS);
-
-  /* Some g_i is zero at t0; look at g at t0+(small increment). */
-
-} 
-
-/*
- * CVRcheck2
- *
- * This routine checks for exact zeros of g at the last root found,
- * if the last return was a root.  It then checks for a close
- * pair of zeros (an error condition), and for a new root at a
- * nearby point.  The left endpoint (tlo) of the search interval
- * is adjusted if necessary to assure that all g_i are nonzero
- * there, before returning to do a root search in the interval.
- *
- * On entry, tlo = tretlast is the last value of tret returned by
- * CVode.  This may be the previous tn, the previous tout value, or
- * the last root location.
- *
- * This routine returns an int equal to:
- *      CLOSERT = -2 if a close pair of zeros was found,
- *      RTFOUND =  1 if a new zero of g was found near tlo, or
- *      CV_SUCCESS    =  0 otherwise.
- */
-
-static int CVRcheck2(CVodeMem cv_mem)
-{
-  int i, retval;
-
-  if (irfnd == 0) return(CV_SUCCESS);
-
-  (void) CVodeGetDky(cv_mem, tlo, 0, y);
-  retval = gfun(tlo, y, glo, g_data);
-  nge++;
-  if (retval != 0) return(CV_RTFUNC_FAIL);
-
-  for (i = 0; i < nrtfn; i++) {
-    if (ABS(glo[i]) == ZERO) 
-      iroots[i] =MASKED; /* arbitrary choice*/
-    else 
-      iroots[i] =0;
-  }
-  return(CV_SUCCESS);
-
-}
-
-/*
- * CVRcheck3
- *
- * This routine interfaces to CVRootfind to look for a root of g
- * between tlo and either tn or tout, whichever comes first.
- * Only roots beyond tlo in the direction of integration are sought.
- *
- * This routine returns an int equal to:
- *      RTFOUND =  1 if a root of g was found, or
- *      CV_SUCCESS    =  0 otherwise.
- */
-
-static int CVRcheck3(CVodeMem cv_mem)
-{
-  int i, retval, ier;
-  /* Set thi = tn or tout, whichever comes first; set y = y(thi). */
-  if (taskc == CV_ONE_STEP) {
-    thi = tn;
-    N_VScale(ONE, zn[0], y);
-  }
-  if (taskc == CV_NORMAL) {
-    if ( (toutc - tn)*h >= ZERO) {
-      thi = tn; 
-      N_VScale(ONE, zn[0], y);
-    } else {
-      thi = toutc;
-      (void) CVodeGetDky(cv_mem, thi, 0, y);
-    }
-  }
-
-  /* Set ghi = g(thi) and call CVRootfind to search (tlo,thi) for roots. */
-  retval = gfun(thi, y, ghi, g_data);
-  nge++;
-  if (retval != 0) return(CV_RTFUNC_FAIL);
-
-  ttol = (ABS(tn) + ABS(h))*uround*HUN;
-  ier = CVRootfind(cv_mem);
-  tlo = trout;
-  for (i = 0; i < nrtfn; i++) glo[i] = grout[i];
-
-  /* If no root found, return CV_SUCCESS. */  
-  if (ier == CV_SUCCESS) return(CV_SUCCESS);
-
-  /* If a root was found, interpolate to get y(trout) and return.  */
-  (void) CVodeGetDky(cv_mem, trout, 0, y);
-  // return(RTFOUND);
-
-  if (ier == RTFOUND)
-    return(RTFOUND);
-  else
-    return(ZERODETACHING);
-}
-
-/*
- * CVRootFind
- *
- * This routine solves for a root of g(t) between tlo and thi, if
- * one exists.  Only roots of odd multiplicity (i.e. with a change
- * of sign in one of the g_i), or exact zeros, are found.
- * Here the sign of tlo - thi is arbitrary, but if multiple roots
- * are found, the one closest to tlo is returned.
- *
- * The method used is the Illinois algorithm, a modified secant method.
- * Reference: Kathie L. Hiebert and Lawrence F. Shampine, Implicitly
- * Defined Output Points for Solutions of ODEs, Sandia National
- * Laboratory Report SAND80-0180, February 1980.
- *
- * This routine uses the following parameters for communication:
- *
- * nrtfn    = number of functions g_i, or number of components of
- *            the vector-valued function g(t).  Input only.
- *
- * gfun     = user-defined function for g(t).  Its form is
- *            (void) gfun(t, y, gt, g_data)
- *
- * nge      = cumulative counter for gfun calls.
- *
- * ttol     = a convergence tolerance for trout.  Input only.
- *            When a root at trout is found, it is located only to
- *            within a tolerance of ttol.  Typically, ttol should
- *            be set to a value on the order of
- *               100 * UROUND * max (ABS(tlo), ABS(thi))
- *            where UROUND is the unit roundoff of the machine.
- *
- * tlo, thi = endpoints of the interval in which roots are sought.
- *            On input, and must be distinct, but tlo - thi may
- *            be of either sign.  The direction of integration is
- *            assumed to be from tlo to thi.  On return, tlo and thi
- *            are the endpoints of the final relevant interval.
- *
- * glo, ghi = arrays of length nrtfn containing the vectors g(tlo)
- *            and g(thi) respectively.  Input and output.  On input,
- *            none of the glo[i] should be zero.
- *
- * trout    = root location, if a root was found, or thi if not.
- *            Output only.  If a root was found other than an exact
- *            zero of g, trout is the endpoint thi of the final
- *            interval bracketing the root, with size at most ttol.
- *
- * grout    = array of length nrtfn containing g(trout) on return.
- *
- * iroots   = int array of length nrtfn with root information.
- *            Output only.  If a root was found, iroots indicates
- *            which components g_i have a root at trout.  For
- *            i = 0, ..., nrtfn-1, iroots[i] = 1 if g_i has a root
- *            and iroots[i] = 0 otherwise.
- *
- * This routine returns an int equal to:
- *      RTFOUND =  1 if a root of g was found, or
- *      CV_SUCCESS    =  0 otherwise.
- */
-
-static int CVRootfind(CVodeMem cv_mem)
-{
-  realtype alpha, tmid, gfrac, maxfrac, fracint, fracsub;
-  int i, retval, imax, side, sideprev;
-  int istuck,iunstuck,imaxold;
-
-  booleantype zroot, umroot, sgnchg;
-
-  imax = -1;
-  istuck=-1;
-  iunstuck=-1;
-  maxfrac = ZERO;
-
-  /* First check for change in sign in ghi or for a zero in ghi. */
-  zroot = FALSE;
-
-  for (i = 0;  i < nrtfn; i++) {
-    if ((ABS(ghi[i])==ZERO)&& (iroots[i]!=MASKED))  istuck=i;
-    if ((ABS(ghi[i])> ZERO)&& (iroots[i]==MASKED))  iunstuck=i;
-    if ((ABS(ghi[i])> ZERO)&& (glo[i]*ghi[i] <= ZERO)) {
-      gfrac = ABS(ghi[i]/(ghi[i] - glo[i]));
-      if (gfrac > maxfrac) { /* finding the very first root*/
-       maxfrac = gfrac;
-       imax = i;
-      }      
-    }
-  }
-
-  if (imax>=0)
-    sgnchg=TRUE;
-  else if (istuck>=0) {
-    sgnchg=TRUE;
-    imax=istuck;
-  }else  if (iunstuck>=0) {
-    sgnchg=TRUE;
-    imax=iunstuck;
-  }else
-    sgnchg = FALSE;
-  
-  if (!sgnchg) {
-    trout = thi;
-    for (i = 0; i < nrtfn; i++) grout[i] = ghi[i];
-    return(CV_SUCCESS);
-  }
-
-  /* Initialize alpha to avoid compiler warning */
-  alpha = ONE;
-
-  /* A sign change was found.  Loop to locate nearest root. */
-
-  side = 0;  sideprev = -1;
-  loop {                                    /* Looping point */
-    
-    /* Set weight alpha.
-       On the first two passes, set alpha = 1.  Thereafter, reset alpha
-       according to the side (low vs high) of the subinterval in which
-       the sign change was found in the previous two passes.
-       If the sides were opposite, set alpha = 1.
-       If the sides were the same, then double alpha (if high side),
-       or halve alpha (if low side).
-       The next guess tmid is the secant method value if alpha = 1, but
-       is closer to tlo if alpha < 1, and closer to thi if alpha > 1.    */
-
-    if (sideprev == side) {
-      alpha = (side == 2) ? alpha*TWO : alpha*HALF;
-    } else {
-      alpha = ONE;
-    }
-    /* Set next root approximation tmid and get g(tmid).
-       If tmid is too close to tlo or thi, adjust it inward,
-       by a fractional distance that is between 0.1 and 0.5.  */
-    if ((ABS(ghi[imax])==ZERO)||(ABS(glo[imax])==ZERO)){
-      tmid=(tlo+alpha*thi)/(1+alpha);
-    }else{
-      tmid = thi - (thi - tlo)*ghi[imax]/(ghi[imax] - alpha*glo[imax]);
-    }
-
-    if (tmid+1 ==tmid) {printf("tmid is nan\n\r ");exit(0);};
-
-    if (ABS(tmid - tlo) < HALF*ttol) {
-      fracint = ABS(thi - tlo)/ttol;
-      fracsub = (fracint > FIVE) ? TENTH : HALF/fracint;
-      tmid = tlo + fracsub*(thi - tlo);
-    }
-
-    if (ABS(thi - tmid) < HALF*ttol) {
-      fracint = ABS(thi - tlo)/ttol;
-      fracsub = (fracint > FIVE) ? TENTH : HALF/fracint;
-      tmid = thi - fracsub*(thi - tlo);
-    }
-
-    (void) CVodeGetDky(cv_mem, tmid, 0, y);
-    retval = gfun(tmid, y, grout, g_data);
-    nge++;
-    if (retval != 0) return(CV_RTFUNC_FAIL);
-
-    /* Check to see in which subinterval g changes sign, and reset imax.
-       Set side = 1 if sign change is on low side, or 2 if on high side.  */  
-  
-  /* First check for change in sign in ghi or for a zero in ghi. */
-  zroot = FALSE;
-  sideprev = side;
-  imaxold=imax;
-  imax = -1;
-  istuck=-1;iunstuck=-1;
-  maxfrac = ZERO;
-  for (i = 0;  i < nrtfn; i++) {
-    if ((ABS(grout[i])==ZERO)&& (iroots[i]!=MASKED))  istuck=i;
-    if ((ABS(grout[i])> ZERO)&& (iroots[i]==MASKED))  iunstuck=i;
-    if ((ABS(grout[i])> ZERO)&& (glo[i]*grout[i] <= ZERO)) {
-      gfrac = ABS(grout[i]/(grout[i] - glo[i]));
-      if (gfrac > maxfrac) { /* finding the very first root*/
-       maxfrac = gfrac;
-       imax = i;
-      }      
-    }
-  }
-
-  if (imax>=0)
-    sgnchg=TRUE;
-  else if (istuck>=0) {
-    sgnchg=TRUE;
-    imax=istuck;
-  }else  if (iunstuck>=0) {
-    sgnchg=TRUE;
-    imax=iunstuck;
-  }else{
-    sgnchg = FALSE;
-    imax=imaxold;
-  }
-
-    if (sgnchg) {
-      /* Sign change found in (tlo,tmid); replace thi with tmid. */
-      thi = tmid;
-      for (i = 0; i < nrtfn; i++) ghi[i] = grout[i];
-      side = 1;
-      /* Stop at root thi if converged; otherwise loop. */
-      if (ABS(thi - tlo) <= ttol) break;
-      continue;  /* Return to looping point. */
-    }
-
-    /* here, either (ABS(thi - tlo) <= ttol) or NO SIGN CHANGE */
-
-    /* No sign change in (tlo,tmid), and no zero at tmid.
-       Sign change must be in (tmid,thi).  Replace tlo with tmid. */
-    tlo = tmid;
-    for (i = 0; i < nrtfn; i++) glo[i] = grout[i];
-    side = 2;
-    /* Stop at root thi if converged; otherwise loop back. */
-    if (ABS(thi - tlo) <= ttol) break;
-
-  } /* End of root-search loop */
-
-  /* Reset trout and grout, set iroots, and return RTFOUND. */
-  zroot = FALSE;
-  umroot = FALSE;
-  trout = thi;
-  for (i = 0; i < nrtfn; i++) {
-    grout[i] = ghi[i];
-    if (iroots[i]==MASKED){
-      if (ABS(ghi[i]) != ZERO){ 
-       iroots[i] = (ghi[i]> ZERO) ? 2 : -2;
-       umroot=TRUE;
-      }else{
-       iroots[i]=0;
-      }
-    }else{
-      if (ABS(ghi[i])== ZERO){ 
-       iroots[i] = (glo[i]> ZERO) ? -1 : 1;
-       zroot = TRUE;
-      }else{
-       if (glo[i]*ghi[i] < ZERO){
-         iroots[i] = (ghi[i]>glo[i]) ? 1 : -1;
-         zroot = TRUE;
-       }else
-         iroots[i]=0;
-      }
-    }    
-  }
-  if (zroot) {
-    for (i = 0; i < nrtfn; i++) {
-      if ((iroots[i]==2)|| (iroots[i]==-2))  iroots[i]=0;
-    }
-    return(RTFOUND);
-  }
-  if (umroot) return(ZERODETACHING);
-  return(CV_SUCCESS);
-}
-
 /* 
  * =================================================================
  * Internal EWT function
@@ -4443,7 +4360,7 @@ void CVProcessError(CVodeMem cv_mem,
 
 #ifndef NO_FPRINTF_OUTPUT
     fprintf(stderr, "\n[%s ERROR]  %s\n  ", module, fname);
-    fprintf(stderr, "%s", msgfmt);
+    fprintf(stderr, msgfmt);
     fprintf(stderr, "\n\n");
 #endif
 
@@ -4496,3 +4413,443 @@ void CVErrHandler(int error_code, const char *module,
 
   return;
 }
+
+/* SUNDIALS EXTENSION */
+/* ALL NEXT LINES ADDED FOR EXTENSION */
+
+/*-----------------------------------------------------------------*/
+
+/* 
+* CVRcheck1
+*
+* This routine completes the initialization of rootfinding memory
+* information, and checks whether g has a zero both at and very near
+* the initial point of the IVP.
+*
+* This routine returns an int equal to:
+*  INITROOT = -1 if a close pair of zeros was found, and
+*  CV_SUCCESS     =  0 otherwise.
+*/
+
+static int CVRcheck1Ext(CVodeMem cv_mem)
+{
+       int i, retval;
+       booleantype zroot;
+
+       for (i = 0; i < nrtfn; i++) iroots[i] = 0;
+       tlo = tn;
+       ttol = (ABS(tn) + ABS(h))*uround*HUN;
+
+       /* Evaluate g at initial t and check for zero values. */
+       retval = gfun(tlo, zn[0], glo, g_data);
+       nge = 1;
+       if (retval != 0) return(CV_RTFUNC_FAIL);
+
+       zroot = FALSE;
+       for (i = 0; i < nrtfn; i++) {
+               if (ABS(glo[i]) == ZERO) 
+                       iroots[i] =MASKED; /* arbitrary choice*/
+               else 
+                       iroots[i] =0;
+       }
+       return(CV_SUCCESS);
+
+       /* Some g_i is zero at t0; look at g at t0+(small increment). */
+
+} 
+
+/*
+* CVRcheck2
+*
+* This routine checks for exact zeros of g at the last root found,
+* if the last return was a root.  It then checks for a close
+* pair of zeros (an error condition), and for a new root at a
+* nearby point.  The left endpoint (tlo) of the search interval
+* is adjusted if necessary to assure that all g_i are nonzero
+* there, before returning to do a root search in the interval.
+*
+* On entry, tlo = tretlast is the last value of tret returned by
+* CVode.  This may be the previous tn, the previous tout value, or
+* the last root location.
+*
+* This routine returns an int equal to:
+*      CLOSERT = -2 if a close pair of zeros was found,
+*      RTFOUND =  1 if a new zero of g was found near tlo, or
+*      CV_SUCCESS    =  0 otherwise.
+*/
+
+static int CVRcheck2Ext(CVodeMem cv_mem)
+{
+       int i, retval;
+
+       if (irfnd == 0) return(CV_SUCCESS);
+
+       (void) CVodeGetDky(cv_mem, tlo, 0, y);
+       retval = gfun(tlo, y, glo, g_data);
+       nge++;
+       if (retval != 0) return(CV_RTFUNC_FAIL);
+
+       for (i = 0; i < nrtfn; i++) {
+               if (ABS(glo[i]) == ZERO) 
+                       iroots[i] =MASKED; /* arbitrary choice*/
+               else 
+                       iroots[i] =0;
+       }
+       return(CV_SUCCESS);
+
+}
+
+/*
+* CVRcheck3
+*
+* This routine interfaces to CVRootfind to look for a root of g
+* between tlo and either tn or tout, whichever comes first.
+* Only roots beyond tlo in the direction of integration are sought.
+*
+* This routine returns an int equal to:
+*      RTFOUND =  1 if a root of g was found, or
+*      CV_SUCCESS    =  0 otherwise.
+*/
+
+static int CVRcheck3Ext(CVodeMem cv_mem)
+{
+       int i, retval, ier;
+       /* Set thi = tn or tout, whichever comes first; set y = y(thi). */
+       if (taskc == CV_ONE_STEP) {
+               thi = tn;
+               N_VScale(ONE, zn[0], y);
+       }
+       if (taskc == CV_NORMAL) {
+               if ( (toutc - tn)*h >= ZERO) {
+                       thi = tn; 
+                       N_VScale(ONE, zn[0], y);
+               } else {
+                       thi = toutc;
+                       (void) CVodeGetDky(cv_mem, thi, 0, y);
+               }
+       }
+
+       /* Set ghi = g(thi) and call CVRootfind to search (tlo,thi) for roots. */
+       retval = gfun(thi, y, ghi, g_data);
+       nge++;
+       if (retval != 0) return(CV_RTFUNC_FAIL);
+
+       ttol = (ABS(tn) + ABS(h))*uround*HUN;
+       ier = CVRootfind(cv_mem);
+       tlo = trout;
+       for (i = 0; i < nrtfn; i++) glo[i] = grout[i];
+
+       /* If no root found, return CV_SUCCESS. */  
+       if (ier == CV_SUCCESS) return(CV_SUCCESS);
+
+       /* If a root was found, interpolate to get y(trout) and return.  */
+       (void) CVodeGetDky(cv_mem, trout, 0, y);
+       // return(RTFOUND);
+
+       if (ier == RTFOUND)
+               return(RTFOUND);
+       else
+               return(ZERODETACHING);
+}
+
+/*
+* CVRootFind
+*
+* This routine solves for a root of g(t) between tlo and thi, if
+* one exists.  Only roots of odd multiplicity (i.e. with a change
+* of sign in one of the g_i), or exact zeros, are found.
+* Here the sign of tlo - thi is arbitrary, but if multiple roots
+* are found, the one closest to tlo is returned.
+*
+* The method used is the Illinois algorithm, a modified secant method.
+* Reference: Kathie L. Hiebert and Lawrence F. Shampine, Implicitly
+* Defined Output Points for Solutions of ODEs, Sandia National
+* Laboratory Report SAND80-0180, February 1980.
+*
+* This routine uses the following parameters for communication:
+*
+* nrtfn    = number of functions g_i, or number of components of
+*            the vector-valued function g(t).  Input only.
+*
+* gfun     = user-defined function for g(t).  Its form is
+*            (void) gfun(t, y, gt, g_data)
+*
+* nge      = cumulative counter for gfun calls.
+*
+* ttol     = a convergence tolerance for trout.  Input only.
+*            When a root at trout is found, it is located only to
+*            within a tolerance of ttol.  Typically, ttol should
+*            be set to a value on the order of
+*               100 * UROUND * max (ABS(tlo), ABS(thi))
+*            where UROUND is the unit roundoff of the machine.
+*
+* tlo, thi = endpoints of the interval in which roots are sought.
+*            On input, and must be distinct, but tlo - thi may
+*            be of either sign.  The direction of integration is
+*            assumed to be from tlo to thi.  On return, tlo and thi
+*            are the endpoints of the final relevant interval.
+*
+* glo, ghi = arrays of length nrtfn containing the vectors g(tlo)
+*            and g(thi) respectively.  Input and output.  On input,
+*            none of the glo[i] should be zero.
+*
+* trout    = root location, if a root was found, or thi if not.
+*            Output only.  If a root was found other than an exact
+*            zero of g, trout is the endpoint thi of the final
+*            interval bracketing the root, with size at most ttol.
+*
+* grout    = array of length nrtfn containing g(trout) on return.
+*
+* iroots   = int array of length nrtfn with root information.
+*            Output only.  If a root was found, iroots indicates
+*            which components g_i have a root at trout.  For
+*            i = 0, ..., nrtfn-1, iroots[i] = 1 if g_i has a root
+*            and iroots[i] = 0 otherwise.
+*
+* This routine returns an int equal to:
+*      RTFOUND =  1 if a root of g was found, or
+*      CV_SUCCESS    =  0 otherwise.
+*/
+
+static int CVRootfindExt(CVodeMem cv_mem)
+{
+       realtype alpha, tmid, gfrac, maxfrac, fracint, fracsub;
+       int i, retval, imax, side, sideprev;
+       int istuck,iunstuck,imaxold;
+
+       booleantype zroot, umroot, sgnchg;
+
+       imax = -1;
+       istuck=-1;
+       iunstuck=-1;
+       maxfrac = ZERO;
+
+       /* First check for change in sign in ghi or for a zero in ghi. */
+       zroot = FALSE;
+
+       for (i = 0;  i < nrtfn; i++) {
+               if ((ABS(ghi[i])==ZERO)&& (iroots[i]!=MASKED))  istuck=i;
+               if ((ABS(ghi[i])> ZERO)&& (iroots[i]==MASKED))  iunstuck=i;
+               if ((ABS(ghi[i])> ZERO)&& (glo[i]*ghi[i] <= ZERO)) {
+                       gfrac = ABS(ghi[i]/(ghi[i] - glo[i]));
+                       if (gfrac > maxfrac) { /* finding the very first root*/
+                               maxfrac = gfrac;
+                               imax = i;
+                       }      
+               }
+       }
+
+       if (imax>=0)
+               sgnchg=TRUE;
+       else if (istuck>=0) {
+               sgnchg=TRUE;
+               imax=istuck;
+       }else  if (iunstuck>=0) {
+               sgnchg=TRUE;
+               imax=iunstuck;
+       }else
+               sgnchg = FALSE;
+
+       if (!sgnchg) {
+               trout = thi;
+               for (i = 0; i < nrtfn; i++) grout[i] = ghi[i];
+               return(CV_SUCCESS);
+       }
+
+       /* Initialize alpha to avoid compiler warning */
+       alpha = ONE;
+
+       /* A sign change was found.  Loop to locate nearest root. */
+
+       side = 0;  sideprev = -1;
+       loop {                                    /* Looping point */
+
+               /* Set weight alpha.
+               On the first two passes, set alpha = 1.  Thereafter, reset alpha
+               according to the side (low vs high) of the subinterval in which
+               the sign change was found in the previous two passes.
+               If the sides were opposite, set alpha = 1.
+               If the sides were the same, then double alpha (if high side),
+               or halve alpha (if low side).
+               The next guess tmid is the secant method value if alpha = 1, but
+               is closer to tlo if alpha < 1, and closer to thi if alpha > 1.    */
+
+               if (sideprev == side) {
+                       alpha = (side == 2) ? alpha*TWO : alpha*HALF;
+               } else {
+                       alpha = ONE;
+               }
+               /* Set next root approximation tmid and get g(tmid).
+               If tmid is too close to tlo or thi, adjust it inward,
+               by a fractional distance that is between 0.1 and 0.5.  */
+               if ((ABS(ghi[imax])==ZERO)||(ABS(glo[imax])==ZERO)){
+                       tmid=(tlo+alpha*thi)/(1+alpha);
+               }else{
+                       tmid = thi - (thi - tlo)*ghi[imax]/(ghi[imax] - alpha*glo[imax]);
+               }
+
+               if (tmid+1 ==tmid) {printf("tmid is nan\n\r ");exit(0);};
+
+               if (ABS(tmid - tlo) < HALF*ttol) {
+                       fracint = ABS(thi - tlo)/ttol;
+                       fracsub = (fracint > FIVE) ? TENTH : HALF/fracint;
+                       tmid = tlo + fracsub*(thi - tlo);
+               }
+
+               if (ABS(thi - tmid) < HALF*ttol) {
+                       fracint = ABS(thi - tlo)/ttol;
+                       fracsub = (fracint > FIVE) ? TENTH : HALF/fracint;
+                       tmid = thi - fracsub*(thi - tlo);
+               }
+
+               (void) CVodeGetDky(cv_mem, tmid, 0, y);
+               retval = gfun(tmid, y, grout, g_data);
+               nge++;
+               if (retval != 0) return(CV_RTFUNC_FAIL);
+
+               /* Check to see in which subinterval g changes sign, and reset imax.
+               Set side = 1 if sign change is on low side, or 2 if on high side.  */  
+
+               /* First check for change in sign in ghi or for a zero in ghi. */
+               zroot = FALSE;
+               sideprev = side;
+               imaxold=imax;
+               imax = -1;
+               istuck=-1;iunstuck=-1;
+               maxfrac = ZERO;
+               for (i = 0;  i < nrtfn; i++) {
+                       if ((ABS(grout[i])==ZERO)&& (iroots[i]!=MASKED))  istuck=i;
+                       if ((ABS(grout[i])> ZERO)&& (iroots[i]==MASKED))  iunstuck=i;
+                       if ((ABS(grout[i])> ZERO)&& (glo[i]*grout[i] <= ZERO)) {
+                               gfrac = ABS(grout[i]/(grout[i] - glo[i]));
+                               if (gfrac > maxfrac) { /* finding the very first root*/
+                                       maxfrac = gfrac;
+                                       imax = i;
+                               }      
+                       }
+               }
+
+               if (imax>=0)
+                       sgnchg=TRUE;
+               else if (istuck>=0) {
+                       sgnchg=TRUE;
+                       imax=istuck;
+               }else  if (iunstuck>=0) {
+                       sgnchg=TRUE;
+                       imax=iunstuck;
+               }else{
+                       sgnchg = FALSE;
+                       imax=imaxold;
+               }
+
+               if (sgnchg) {
+                       /* Sign change found in (tlo,tmid); replace thi with tmid. */
+                       thi = tmid;
+                       for (i = 0; i < nrtfn; i++) ghi[i] = grout[i];
+                       side = 1;
+                       /* Stop at root thi if converged; otherwise loop. */
+                       if (ABS(thi - tlo) <= ttol) break;
+                       continue;  /* Return to looping point. */
+               }
+
+               /* here, either (ABS(thi - tlo) <= ttol) or NO SIGN CHANGE */
+
+               /* No sign change in (tlo,tmid), and no zero at tmid.
+               Sign change must be in (tmid,thi).  Replace tlo with tmid. */
+               tlo = tmid;
+               for (i = 0; i < nrtfn; i++) glo[i] = grout[i];
+               side = 2;
+               /* Stop at root thi if converged; otherwise loop back. */
+               if (ABS(thi - tlo) <= ttol) break;
+
+       } /* End of root-search loop */
+
+       /* Reset trout and grout, set iroots, and return RTFOUND. */
+       zroot = FALSE;
+       umroot = FALSE;
+       trout = thi;
+       for (i = 0; i < nrtfn; i++) {
+               grout[i] = ghi[i];
+               if (iroots[i]==MASKED){
+                       if (ABS(ghi[i]) != ZERO){ 
+                               iroots[i] = (ghi[i]> ZERO) ? 2 : -2;
+                               umroot=TRUE;
+                       }else{
+                               iroots[i]=0;
+                       }
+               }else{
+                       if (ABS(ghi[i])== ZERO){ 
+                               iroots[i] = (glo[i]> ZERO) ? -1 : 1;
+                               zroot = TRUE;
+                       }else{
+                               if (glo[i]*ghi[i] < ZERO){
+                                       iroots[i] = (ghi[i]>glo[i]) ? 1 : -1;
+                                       zroot = TRUE;
+                               }else
+                                       iroots[i]=0;
+                       }
+               }    
+       }
+       if (zroot) {
+               for (i = 0; i < nrtfn; i++) {
+                       if ((iroots[i]==2)|| (iroots[i]==-2))  iroots[i]=0;
+               }
+               return(RTFOUND);
+       }
+       if (umroot) return(ZERODETACHING);
+       return(CV_SUCCESS);
+}
+
+
+static int CVRcheck1(CVodeMem cv_mem)
+{
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return CVRcheck1Ext(cv_mem);
+       }
+       else
+       {
+               return CVRcheck1Std(cv_mem);
+       }
+}
+
+static int CVRcheck2(CVodeMem cv_mem)
+{
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return CVRcheck2Ext(cv_mem);
+       }
+       else
+       {
+               return CVRcheck2Std(cv_mem);
+       }
+}
+
+static int CVRcheck3(CVodeMem cv_mem)
+{
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return CVRcheck3Ext(cv_mem);
+       }
+       else
+       {
+               return CVRcheck3Std(cv_mem);
+       }
+}
+
+static int CVRootfind(CVodeMem cv_mem)
+{
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return CVRootfindExt(cv_mem);
+       }
+       else
+       {
+               return CVRootfindStd(cv_mem);
+       }
+}
+
@@ -20,7 +20,7 @@
 
 #include "cvode_dense_impl.h"
 #include "cvode_impl.h"
-#include "sundials_math.h"
+#include <sundials/sundials_math.h>
 
 /* Other Constants */
 
@@ -24,7 +24,7 @@ extern "C" {
 
 #include <stdarg.h>
 
-#include "cvode.h"
+#include <cvode/cvode.h>
 
   /*
    * =================================================================
@@ -181,9 +181,9 @@ extern "C" {
       ----------------------------*/
 
     long int cv_lrw1;        /* no. of realtype words in 1 N_Vector         */ 
-    long int cv_liw1;        /* no. of int words in 1 N_Vector          */ 
+    long int cv_liw1;        /* no. of integer words in 1 N_Vector          */ 
     long int cv_lrw;         /* no. of realtype words in CVODE work vectors */
-    long int cv_liw;         /* no. of int words in CVODE work vectors  */
+    long int cv_liw;         /* no. of integer words in CVODE work vectors  */
 
     /*------------------
       Linear Solver Data 
@@ -19,7 +19,7 @@
 #include <stdlib.h>
 
 #include "cvode_impl.h"
-#include "sundials_types.h"
+#include <sundials/sundials_types.h>
 
 #define ZERO RCONST(0.0)
 #define ONE  RCONST(1.0)
 #include <stdarg.h>
 
 #include "ida_impl.h"
-#include "sundials_math.h"
+#include <sundials/sundials_math.h>
+
+/* SUNDIALS EXTENSION */
+#include "sundials_extension.h"
 
 /* 
  * =================================================================
 #define RTFOUND          +1
 #define INITROOT         +2
 #define CLOSERT          +3
+
+/* SUNDIALS EXTENSION */
 #define ZERODETACHING    +4
 #define MASKED           55
 /*
@@ -248,6 +253,17 @@ static int IDARcheck2(IDAMem IDA_mem);
 static int IDARcheck3(IDAMem IDA_mem);
 static int IDARootfind(IDAMem IDA_mem);
 
+static int IDARcheck1Std(IDAMem IDA_mem);
+static int IDARcheck2Std(IDAMem IDA_mem);
+static int IDARcheck3Std(IDAMem IDA_mem);
+static int IDARootfindStd(IDAMem IDA_mem);
+
+static int IDARcheck1Ext(IDAMem IDA_mem);
+static int IDARcheck2Ext(IDAMem IDA_mem);
+static int IDARcheck3Ext(IDAMem IDA_mem);
+static int IDARootfindExt(IDAMem IDA_mem);
+
+
 /* Norm functions */
 
 realtype IDAWrmsNorm(IDAMem IDA_mem, N_Vector x, N_Vector w, booleantype mask);
@@ -371,35 +387,79 @@ int IDAMalloc(void *ida_mem, IDAResFn res,
   
   if (yy0 == NULL) { 
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAMalloc", MSG_Y0_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_NULL_Y0); 
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_NULL_Y0); 
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
 
   }
   
   if (yp0 == NULL) { 
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAMalloc", MSG_YP0_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_YP0_NULL); 
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_YP0_NULL); 
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
 
   if ((itol != IDA_SS) && (itol != IDA_SV) && (itol != IDA_WF)) {
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAMalloc", MSG_BAD_ITOL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_BAD_ITOL);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_BAD_ITOL);
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
 
   if (res == NULL) { 
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAMalloc", MSG_RES_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_RES_NULL); 
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_RES_NULL); 
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
 
   /* Test if all required vector operations are implemented */
   nvectorOK = IDACheckNvector(yy0);
   if (!nvectorOK) {
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAMalloc", MSG_BAD_NVECTOR);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_BAD_NVECTOR);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_BAD_NVECTOR);
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
 
   /* Test tolerances */
@@ -408,14 +468,32 @@ int IDAMalloc(void *ida_mem, IDAResFn res,
 
     if (atol == NULL) { 
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAMalloc", MSG_ATOL_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_NULL_ABSTOL); 
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_NULL_ABSTOL); 
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+
     }
 
     if (rtol < ZERO) { 
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAMalloc", MSG_BAD_RTOL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_BAD_RELTOL); 
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_BAD_RELTOL); 
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+
     }
    
     if (itol == IDA_SS) { 
@@ -426,8 +504,17 @@ int IDAMalloc(void *ida_mem, IDAResFn res,
 
     if (neg_atol) { 
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAMalloc", MSG_BAD_ATOL);
-      /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_BAD_ABSTOL); 
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_BAD_ABSTOL); 
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+
     }
 
   }
@@ -557,26 +644,62 @@ int IDAReInit(void *ida_mem, IDAResFn res,
   
   if (yy0 == NULL) { 
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAReInit", MSG_Y0_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_NULL_Y0); 
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_NULL_Y0); 
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
   
   if (yp0 == NULL) { 
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAReInit", MSG_YP0_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_YP0_NULL); 
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_YP0_NULL); 
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
 
   if ((itol != IDA_SS) && (itol != IDA_SV) && (itol != IDA_WF)) {
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAReInit", MSG_BAD_ITOL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_BAD_ITOL);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_BAD_ITOL);
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
 
   if (res == NULL) { 
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAReInit", MSG_RES_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_RES_NULL); 
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_RES_NULL); 
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
 
   /* Test tolerances */
@@ -585,14 +708,32 @@ int IDAReInit(void *ida_mem, IDAResFn res,
 
     if (atol == NULL) { 
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAReInit", MSG_ATOL_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_NULL_ABSTOL); 
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_NULL_ABSTOL); 
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+    
     }
     
     if (rtol < ZERO) {
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAReInit", MSG_BAD_RTOL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_BAD_RELTOL); 
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_BAD_RELTOL); 
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+
     }
    
     if (itol == IDA_SS) { 
@@ -602,8 +743,17 @@ int IDAReInit(void *ida_mem, IDAResFn res,
     }
     if (neg_atol) { 
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAReInit", MSG_BAD_ATOL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_BAD_ABSTOL); 
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_BAD_ABSTOL); 
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+
     }
 
   }
@@ -740,8 +890,17 @@ int IDARootInit(void *ida_mem, int nrtfn, IDARootFn g, void *gdata)
         liw -= nrt;
 
         IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDARootInit", MSG_ROOT_FUNC_NULL);
-       /*  return(IDA_ILL_INPUT); Masoud */
-       return(IDA_NULL_G);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(IDA_NULL_G);
+               }
+               else
+               {
+                       return(IDA_ILL_INPUT);
+               }
+
       }
       else {
        gfun = g;
@@ -755,8 +914,17 @@ int IDARootInit(void *ida_mem, int nrtfn, IDARootFn g, void *gdata)
   IDA_mem->ida_nrtfn = nrt;
   if (g == NULL) {
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDARootInit", MSG_ROOT_FUNC_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_NULL_G);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_NULL_G);
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
   else gfun = g;
 
@@ -926,7 +1094,7 @@ int IDARootInit(void *ida_mem, int nrtfn, IDARootFn g, void *gdata)
  * and returns.  In the IDA_NORMAL_TSTOP and IDA_ONE_STEP_TSTOP modes, it also
  * takes steps so as to reach tstop exactly and never to go past it.
  *
- * IDASolve returns int values corresponding to success and failure as below:
+ * IDASolve returns integer values corresponding to success and failure as below:
  *
  * successful returns: 
  *
@@ -975,36 +1143,81 @@ int IDASolve(void *ida_mem, realtype tout, realtype *tret,
 
   if (yret == NULL) {
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_YRET_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_YRET_NULL);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_YRET_NULL);
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
   yy = yret;  
 
   if (ypret == NULL) {
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_YPRET_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_YPRET_NULL);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_YPRET_NULL);
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
   yp = ypret;
   
   if (tret == NULL) {
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_TRET_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_TRET_NULL);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_TRET_NULL);
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
 
   if ((itask < IDA_NORMAL) || (itask > IDA_ONE_STEP_TSTOP)) {
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_BAD_ITASK);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_BAD_ITASK);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_BAD_ITASK);
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
   
   /* Split itask into task and istop */
   if ( (itask == IDA_NORMAL_TSTOP) || (itask == IDA_ONE_STEP_TSTOP) ) {
     if ( tstopset == FALSE ) {
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_NO_TSTOP);
-      /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_NO_TSTOP);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_NO_TSTOP);
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+
     }
     istop = TRUE;
   } else {
@@ -1035,15 +1248,33 @@ int IDASolve(void *ida_mem, realtype tout, realtype *tret,
     troundoff = TWO*uround*(ABS(tn) + ABS(tout));    
     if (tdist < troundoff) {
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_TOO_CLOSE);
-      /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_TOO_CLOSE);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_TOO_CLOSE);
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+
     }
 
     hh = hin;
     if ( (hh != ZERO) && ((tout-tn)*hh < ZERO) ) {
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_BAD_HINIT);
-      /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_BAD_HINIT);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_BAD_HINIT);
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+
     }
 
     if (hh == ZERO) {
@@ -1059,8 +1290,17 @@ int IDASolve(void *ida_mem, realtype tout, realtype *tret,
     if (istop) {
       if ( (tstop - tn)*hh < ZERO) {
         IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_BAD_TSTOP, tn);
-       /*  return(IDA_ILL_INPUT); Masoud */
-        return(IDA_BAD_TSTOP);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(IDA_BAD_TSTOP);
+               }
+               else
+               {
+                       return(IDA_ILL_INPUT);
+               }
+
       }
       if ( (tn + hh - tstop)*hh > ZERO) 
         hh = (tstop - tn)*(ONE-FOUR*uround);
@@ -1074,12 +1314,30 @@ int IDASolve(void *ida_mem, realtype tout, realtype *tret,
       ier = IDARcheck1(IDA_mem);
       if (ier == INITROOT) {
         IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDARcheck1", MSG_BAD_INIT_ROOT);
-       /*  return(IDA_ILL_INPUT); Masoud */
-        return(IDA_BAD_INIT_ROOT);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(IDA_BAD_INIT_ROOT);
+               }
+               else
+               {
+                       return(IDA_ILL_INPUT);
+               }
+
       } else if (ier == IDA_RTFUNC_FAIL) {
         IDAProcessError(IDA_mem, IDA_RTFUNC_FAIL, "IDA", "IDARcheck1", MSG_RTFUNC_FAILED, tn);
-       /*  return(IDA_ILL_INPUT); Masoud */
-        return(IDA_RTFUNC_FAIL);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(IDA_RTFUNC_FAIL);
+               }
+               else
+               {
+                       return(IDA_ILL_INPUT);
+               }
+
       }
     }
 
@@ -1112,8 +1370,17 @@ int IDASolve(void *ida_mem, realtype tout, realtype *tret,
 
       if (ier == CLOSERT) {
         IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDARcheck2", MSG_CLOSE_ROOTS, tlo);
-       /*  return(IDA_ILL_INPUT); Masoud */
-        return(IDA_CLOSE_ROOTS);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(IDA_CLOSE_ROOTS);
+               }
+               else
+               {
+                       return(IDA_ILL_INPUT);
+               }
+
       } else if (ier == IDA_RTFUNC_FAIL) {
         IDAProcessError(IDA_mem, IDA_RTFUNC_FAIL, "IDA", "IDARcheck2", MSG_RTFUNC_FAILED, tlo);
         return(IDA_RTFUNC_FAIL);
@@ -1141,11 +1408,16 @@ int IDASolve(void *ida_mem, realtype tout, realtype *tret,
         } else if (ier == IDA_RTFUNC_FAIL) {  /* g failed */
           IDAProcessError(IDA_mem, IDA_RTFUNC_FAIL, "IDA", "IDARcheck3", MSG_RTFUNC_FAILED, tlo);
           return(IDA_RTFUNC_FAIL);
-       } else if (ier == ZERODETACHING) {  /* Zero detaching */
+       } 
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+               if (ier == ZERODETACHING) {  /* Zero detaching */
          irfnd = 1;
          tretlast = *tret = tlo;
           return(IDA_ZERO_DETACH_RETURN);
        }
+               }
       }
 
     } /* end of root stop check */
@@ -1241,12 +1513,18 @@ int IDASolve(void *ida_mem, realtype tout, realtype *tret,
         IDAProcessError(IDA_mem, IDA_RTFUNC_FAIL, "IDA", "IDARcheck3", MSG_RTFUNC_FAILED, tlo);
         istate = IDA_RTFUNC_FAIL;
         break;
-      }else if (ier == ZERODETACHING) {  /* Zero detaching */
+      }
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension()) 
+         {
+          if (ier == ZERODETACHING) {  /* Zero detaching */
        irfnd = 1;
         istate = IDA_ZERO_DETACH_RETURN;
         tretlast = *tret = tlo;
         break;
       }
+         }
 
     }
 
@@ -1412,7 +1690,7 @@ static booleantype IDACheckNvector(N_Vector tmpl)
  * TRUE. Otherwise all allocated memory is freed and IDAAllocVectors 
  * returns FALSE.
  * This routine also sets the optional outputs lrw and liw, which are
- * (respectively) the lengths of the real and int work spaces
+ * (respectively) the lengths of the real and integer work spaces
  * allocated here.
  */
 
@@ -1575,16 +1853,33 @@ int IDAInitialSetup(IDAMem IDA_mem)
   if (suppressalg)
     if (id->ops->nvwrmsnormmask == NULL) {
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAInitialSetup", MSG_BAD_NVECTOR);
-      /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_BAD_NVECTOR);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_BAD_NVECTOR);
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
   }
 
   /* Test id vector for legality */
   
   if (suppressalg && (id==NULL)){ 
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAInitialSetup", MSG_MISSING_ID);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_MISSING_ID); 
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_MISSING_ID); 
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
 
   /* Load ewt */
@@ -1595,8 +1890,17 @@ int IDAInitialSetup(IDAMem IDA_mem)
   } else {
     if (efun == NULL) {
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAInitialSetup", MSG_NO_EFUN);
-    /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_NO_EFUN);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_NO_EFUN);
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+
     }
   }
 
@@ -1605,12 +1909,30 @@ int IDAInitialSetup(IDAMem IDA_mem)
 
     if (itol == IDA_WF){ 
         IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAInitialSetup", MSG_FAIL_EWT);
-    /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_EWT_FAIL);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(IDA_EWT_FAIL);
+               }
+               else
+               {
+                       return(IDA_ILL_INPUT);
+               }
+
     }else{
         IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAInitialSetup", MSG_BAD_EWT);
-    /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_BAD_EWT);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(IDA_BAD_EWT);
+               }
+               else
+               {
+                       return(IDA_ILL_INPUT);
+               }
+
     }
   }
 
@@ -1620,8 +1942,17 @@ int IDAInitialSetup(IDAMem IDA_mem)
     conOK = N_VConstrMask(constraints, phi[0], tempv2);
     if (!conOK) { 
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAInitialSetup", MSG_Y0_FAIL_CONSTR);
-    /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_Y0_FAIL_CONSTR); 
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+               return(IDA_Y0_FAIL_CONSTR); 
+         }
+         else
+         {
+               return(IDA_ILL_INPUT);
+         }
+
     }
   }
 
@@ -1629,16 +1960,34 @@ int IDAInitialSetup(IDAMem IDA_mem)
 
   if (lsolve == NULL) {
     IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAInitialSetup", MSG_LSOLVE_NULL);
-    /*  return(IDA_ILL_INPUT); Masoud */
-    return(IDA_LSOLVE_NULL);
+
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return(IDA_LSOLVE_NULL);
+       }
+       else
+       {
+               return(IDA_ILL_INPUT);
+       }
+
   }
 
   if (linit != NULL) {
     ier = linit(IDA_mem);
     if (ier != 0) {
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDAInitialSetup", MSG_LINIT_FAIL);
-      /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_LINIT_FAIL);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_LINIT_FAIL);
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+
     }
   }
 
@@ -1763,8 +2112,17 @@ static int IDAStopTest1(IDAMem IDA_mem, realtype tout, realtype *tret,
       ier = IDAGetSolution(IDA_mem, tout, yret, ypret);
       if (ier != IDA_SUCCESS) {
         IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_BAD_TOUT, tout);
-       /*  return(IDA_ILL_INPUT); Masoud */
-        return(IDA_BAD_TOUT);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(IDA_BAD_TOUT);
+               }
+               else
+               {
+                       return(IDA_ILL_INPUT);
+               }
+
       }
       *tret = tretlast = tout;
       return(IDA_SUCCESS);
@@ -1784,8 +2142,17 @@ static int IDAStopTest1(IDAMem IDA_mem, realtype tout, realtype *tret,
     /* Test for tn past tstop, tn = tretlast, tn past tout, tn near tstop. */
     if ( (tn - tstop)*hh > ZERO) {
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_BAD_TSTOP, tn);
-      /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_BAD_TSTOP);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_BAD_TSTOP);
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+      
     }
     if (tout == tretlast) {
       *tret = tretlast = tout;
@@ -1795,8 +2162,17 @@ static int IDAStopTest1(IDAMem IDA_mem, realtype tout, realtype *tret,
       ier = IDAGetSolution(IDA_mem, tout, yret, ypret);
       if (ier != IDA_SUCCESS) {
         IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_BAD_TOUT, tout);
-       /*  return(IDA_ILL_INPUT); Masoud */
-        return(IDA_BAD_TOUT);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(IDA_BAD_TOUT);
+               }
+               else
+               {
+                       return(IDA_ILL_INPUT);
+               }
+
       }
       *tret = tretlast = tout;
       return(IDA_SUCCESS);
@@ -1806,8 +2182,17 @@ static int IDAStopTest1(IDAMem IDA_mem, realtype tout, realtype *tret,
       ier = IDAGetSolution(IDA_mem, tstop, yret, ypret);
       if (ier != IDA_SUCCESS) {
         IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_BAD_TSTOP, tn);
-       /*  return(IDA_ILL_INPUT); Masoud */
-        return(IDA_BAD_TSTOP);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(IDA_BAD_TSTOP);
+               }
+               else
+               {
+                       return(IDA_ILL_INPUT);
+               }
+
       }
       *tret = tretlast = tstop;
       return(IDA_TSTOP_RETURN);
@@ -1820,8 +2205,17 @@ static int IDAStopTest1(IDAMem IDA_mem, realtype tout, realtype *tret,
     /* Test for tn past tstop, tn past tretlast, and tn near tstop. */
     if ((tn - tstop)*hh > ZERO) {
       IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_BAD_TSTOP, tn);
-      /*  return(IDA_ILL_INPUT); Masoud */
-      return(IDA_BAD_TSTOP);
+
+         /* SUNDIALS EXTENSION */
+         if (is_sundials_with_extension())
+         {
+                 return(IDA_BAD_TSTOP);
+         }
+         else
+         {
+                 return(IDA_ILL_INPUT);
+         }
+
     }
     if ((tn - tretlast)*hh > ZERO) {
       ier = IDAGetSolution(IDA_mem, tn, yret, ypret);
@@ -1833,8 +2227,16 @@ static int IDAStopTest1(IDAMem IDA_mem, realtype tout, realtype *tret,
       ier = IDAGetSolution(IDA_mem, tstop, yret, ypret);
       if (ier != IDA_SUCCESS) {
         IDAProcessError(IDA_mem, IDA_ILL_INPUT, "IDA", "IDASolve", MSG_BAD_TSTOP, tn);
-       /*  return(IDA_ILL_INPUT); Masoud */
-        return(IDA_BAD_TSTOP);
+
+               /* SUNDIALS EXTENSION */
+               if (is_sundials_with_extension())
+               {
+                       return(IDA_BAD_TSTOP);
+               }
+               else
+               {
+                       return(IDA_ILL_INPUT);
+               }
       }
       *tret = tretlast = tstop;
       return(IDA_TSTOP_RETURN);
@@ -2567,7 +2969,7 @@ static int IDAHandleNFlag(IDAMem IDA_mem, int nflag, realtype err_k, realtype er
 
     (*ncfPtr)++;      /* local counter for convergence failures */
     (*ncfnPtr)++;     /* global counter for convergence failures */
-
+    
     if (nflag < 0) {  /* nonrecoverable failure */
 
       return(nflag);
@@ -2814,7 +3216,8 @@ realtype IDAWrmsNorm(IDAMem IDA_mem, N_Vector x, N_Vector w,
  *   INITROOT    (>0) if a close pair of zeros was found, and
  *   IDA_SUCCESS (=0) otherwise.
  */
-static int IDARcheck1_orig(IDAMem IDA_mem)
+
+static int IDARcheck1Std(IDAMem IDA_mem)
 {
   int i, retval;
   realtype smallh, hratio;
@@ -2856,32 +3259,6 @@ static int IDARcheck1_orig(IDAMem IDA_mem)
 
 }
 
-static int IDARcheck1(IDAMem IDA_mem)
-{
-  int i, retval;
-  booleantype zroot;
-
-  for (i = 0; i < nrtfn; i++) iroots[i] = 0;
-  tlo = tn;
-  ttol = (ABS(tn) + ABS(hh))*uround*HUNDRED;
-
-  /* Evaluate g at initial t and check for zero values. */
-  retval = gfun (tlo, phi[0], phi[1], glo, g_data);
-  nge = 1;
-  if (retval != 0) return(IDA_RTFUNC_FAIL);
-
-  zroot = FALSE;
-
-  for (i = 0; i < nrtfn; i++) {
-    if (ABS(glo[i]) == ZERO) 
-      iroots[i] =MASKED; /* arbitrary choice*/
-    else 
-      iroots[i] =0;
-  }
-  return(IDA_SUCCESS);
-
-}
-
 /*
  * IDARcheck2
  *
@@ -2901,7 +3278,7 @@ static int IDARcheck1(IDAMem IDA_mem)
  *     RTFOUND     (>0) if a new zero of g was found near tlo, or
  *     IDA_SUCCESS (=0) otherwise.
  */
-static int IDARcheck2_orig(IDAMem IDA_mem)
+static int IDARcheck2Std(IDAMem IDA_mem)
 {
   int i, retval;
   realtype smallh, hratio;
@@ -2951,27 +3328,6 @@ static int IDARcheck2_orig(IDAMem IDA_mem)
 
 }
 
-
-static int IDARcheck2(IDAMem IDA_mem)
-{
-  int i, retval;
-
-  if (irfnd == 0) return(IDA_SUCCESS);
-
-  (void) IDAGetSolution(IDA_mem, tlo, yy, yp);
-  retval = gfun (tlo, yy, yp, glo, g_data);  
-  nge++;
-  if (retval != 0) return(IDA_RTFUNC_FAIL);
-
-  for (i = 0; i < nrtfn; i++) {
-    if (ABS(glo[i]) == ZERO) 
-      iroots[i] =MASKED; /* arbitrary choice*/
-    else 
-      iroots[i] =0;
-  }
-  return(IDA_SUCCESS);
-}
-
 /*
  * IDARcheck3
  *
@@ -2984,7 +3340,7 @@ static int IDARcheck2(IDAMem IDA_mem)
  *     IDA_SUCCESS (=0) otherwise.
  */
 
-static int IDARcheck3_origin(IDAMem IDA_mem)
+static int IDARcheck3Std(IDAMem IDA_mem)
 {
   int i, ier, retval;
 
@@ -3017,43 +3373,6 @@ static int IDARcheck3_origin(IDAMem IDA_mem)
 
 }
 
-static int IDARcheck3(IDAMem IDA_mem)
-{
-  int i, ier, retval;
-
-  /* Set thi = tn or tout, whichever comes first. */
-  if (taskc == IDA_ONE_STEP) thi = tn;
-  if (taskc == IDA_NORMAL) {
-    thi = ( (toutc - tn)*hh >= ZERO) ? tn : toutc;
-  }
-
-  /* Get y and y' at thi. */
-  (void) IDAGetSolution(IDA_mem, thi, yy, yp);
-
-
-  /* Set ghi = g(thi) and call IDARootfind to search (tlo,thi) for roots. */
-  retval = gfun (thi, yy, yp, ghi, g_data);  
-  nge++;
-  if (retval != 0) return(IDA_RTFUNC_FAIL);
-
-  ttol = (ABS(tn) + ABS(hh))*uround*HUNDRED;
-  ier = IDARootfind(IDA_mem);
-  tlo = trout;
-  for (i = 0; i < nrtfn; i++) glo[i] = grout[i];
-
-  /* If no root found, return IDA_SUCCESS. */  
-  if (ier == IDA_SUCCESS) return(IDA_SUCCESS);
-
-  /* If a root was found, interpolate to get y(trout) and return.  */
-  (void) IDAGetSolution(IDA_mem, trout, yy, yp);
-  /*  return(RTFOUND);*/
-
-  if (ier == RTFOUND)
-    return(RTFOUND);
-  else
-    return(ZERODETACHING);
-
-}
 /*
  * IDARootfind
  *
@@ -3114,7 +3433,7 @@ static int IDARcheck3(IDAMem IDA_mem)
  *
  */
 
-static int IDARootfind_origin(IDAMem IDA_mem)
+static int IDARootfindStd(IDAMem IDA_mem)
 {
   realtype alph, tmid, gfrac, maxfrac, fracint, fracsub;
   int i, retval, imax, side, sideprev;
@@ -3256,199 +3575,6 @@ static int IDARootfind_origin(IDAMem IDA_mem)
   return(RTFOUND);
 }
 
-/*-------------------*/
-
-static int IDARootfind(IDAMem IDA_mem)
-{
-  realtype alph, tmid, gfrac, maxfrac, fracint, fracsub;
-  int i, retval, imax, side, sideprev;
-  int istuck,iunstuck,imaxold;
-
-  booleantype zroot, umroot, sgnchg;
-
-  imax = -1;
-  istuck=-1;
-  iunstuck=-1;
-  maxfrac = ZERO;
-
-  /* First check for change in sign in ghi or for a zero in ghi. */
-  zroot = FALSE;
-
-  for (i = 0;  i < nrtfn; i++) {
-    if ((ABS(ghi[i])==ZERO)&& (iroots[i]!=MASKED))  istuck=i;
-    if ((ABS(ghi[i])> ZERO)&& (iroots[i]==MASKED))  iunstuck=i;
-    if ((ABS(ghi[i])> ZERO)&& (glo[i]*ghi[i] <= ZERO)) {
-      gfrac = ABS(ghi[i]/(ghi[i] - glo[i]));
-      if (gfrac > maxfrac) { /* finding the very first root*/
-       maxfrac = gfrac;
-       imax = i;
-      }      
-    }
-  }
-
-  if (imax>=0)
-    sgnchg=TRUE;
-  else if (istuck>=0) {
-    sgnchg=TRUE;
-    imax=istuck;
-  }else  if (iunstuck>=0) {
-    sgnchg=TRUE;
-    imax=iunstuck;
-  }else
-    sgnchg = FALSE;
-
-  /* If no sign change was found, reset trout and grout.  Then return
-     IDA_SUCCESS if no zero was found, or set iroots and return RTFOUND.  */ 
-  if (!sgnchg) {
-    trout = thi;
-    for (i = 0; i < nrtfn; i++) grout[i] = ghi[i];
-    return(IDA_SUCCESS);
-  }
-
-
-  /* Initialize alph to avoid compiler warning */
-  alph = ONE;
-
-  /* A sign change was found.  Loop to locate nearest root. */
-
-  side = 0;  sideprev = -1;
-  loop {                                    /* Looping point */
-    
-    /* Set weight alph.
-       On the first two passes, set alph = 1.  Thereafter, reset alph
-       according to the side (low vs high) of the subinterval in which
-       the sign change was found in the previous two passes.
-       If the sides were opposite, set alph = 1.
-       If the sides were the same, then double alph (if high side),
-       or halve alph (if low side).
-       The next guess tmid is the secant method value if alph = 1, but
-       is closer to tlo if alph < 1, and closer to thi if alph > 1.    */
-
-    if (sideprev == side) {
-      alph = (side == 2) ? alph*TWO : alph*HALF;
-    } else {
-      alph = ONE;
-    }
-    /* Set next root approximation tmid and get g(tmid).
-       If tmid is too close to tlo or thi, adjust it inward,
-       by a fractional distance that is between 0.1 and 0.5.  */
-    if ((ABS(ghi[imax])==ZERO)||(ABS(glo[imax])==ZERO)){
-      tmid=(tlo+alph*thi)/(1+alph);
-    }else{
-      tmid = thi - (thi - tlo)*ghi[imax]/(ghi[imax] - alph*glo[imax]);
-    }
-
-    if (tmid+1 ==tmid) {printf("tmid is nan\n\r ");exit(0);};
-
-    if (ABS(tmid - tlo) < HALF*ttol) {
-      fracint = ABS(thi - tlo)/ttol;
-      fracsub = (fracint > FIVE) ? PT1 : HALF/fracint;
-      tmid = tlo + fracsub*(thi - tlo);
-    }
-
-    if (ABS(thi - tmid) < HALF*ttol) {
-      fracint = ABS(thi - tlo)/ttol;
-      fracsub = (fracint > FIVE) ? PT1 : HALF/fracint;
-      tmid = thi - fracsub*(thi - tlo);
-    }
-
-    (void) IDAGetSolution(IDA_mem, tmid, yy, yp);
-    retval = gfun (tmid, yy, yp, grout, g_data); 
-    nge++;
-    if (retval != 0) return(IDA_RTFUNC_FAIL);
-
-    /* Check to see in which subinterval g changes sign, and reset imax.
-       Set side = 1 if sign change is on low side, or 2 if on high side.  */  
-  
-  /* First check for change in sign in ghi or for a zero in ghi. */
-  zroot = FALSE;
-  sideprev = side;
-  imaxold=imax;
-  imax = -1;
-  istuck=-1;iunstuck=-1;
-  maxfrac = ZERO;
-  for (i = 0;  i < nrtfn; i++) {
-    if ((ABS(grout[i])==ZERO)&& (iroots[i]!=MASKED))  istuck=i;
-    if ((ABS(grout[i])> ZERO)&& (iroots[i]==MASKED))  iunstuck=i;
-    if ((ABS(grout[i])> ZERO)&& (glo[i]*grout[i] <= ZERO)) {
-      gfrac = ABS(grout[i]/(grout[i] - glo[i]));
-      if (gfrac > maxfrac) { /* finding the very first root*/
-       maxfrac = gfrac;
-       imax = i;
-      }      
-    }
-  }
-
-  if (imax>=0)
-    sgnchg=TRUE;
-  else if (istuck>=0) {
-    sgnchg=TRUE;
-    imax=istuck;
-  }else  if (iunstuck>=0) {
-    sgnchg=TRUE;
-    imax=iunstuck;
-  }else{
-    sgnchg = FALSE;
-    imax=imaxold;
-  }
-
-    if (sgnchg) {
-      /* Sign change found in (tlo,tmid); replace thi with tmid. */
-      thi = tmid;
-      for (i = 0; i < nrtfn; i++) ghi[i] = grout[i];
-      side = 1;
-      /* Stop at root thi if converged; otherwise loop. */
-      if (ABS(thi - tlo) <= ttol) break;
-      continue;  /* Return to looping point. */
-    }
-
-    /* here, either (ABS(thi - tlo) <= ttol) or NO SIGN CHANGE */
-
-    /* No sign change in (tlo,tmid), and no zero at tmid.
-       Sign change must be in (tmid,thi).  Replace tlo with tmid. */
-    tlo = tmid;
-    for (i = 0; i < nrtfn; i++) glo[i] = grout[i];
-    side = 2;
-    /* Stop at root thi if converged; otherwise loop back. */
-    if (ABS(thi - tlo) <= ttol) break;
-
-  } /* End of root-search loop */
-
-  /* Reset trout and grout, set iroots, and return RTFOUND. */
-  zroot = FALSE;
-  umroot = FALSE;
-  trout = thi;
-  for (i = 0; i < nrtfn; i++) {
-    grout[i] = ghi[i];
-    if (iroots[i]==MASKED){
-      if (ABS(ghi[i]) != ZERO){ 
-       iroots[i] = (ghi[i]> ZERO) ? 2 : -2;
-       umroot=TRUE;
-      }else{
-       iroots[i]=0;
-      }
-    }else{
-      if (ABS(ghi[i])== ZERO){ 
-       iroots[i] = (glo[i]> ZERO) ? -1 : 1;
-       zroot = TRUE;
-      }else{
-       if (glo[i]*ghi[i] < ZERO){
-         iroots[i] = (ghi[i]>glo[i]) ? 1 : -1;
-         zroot = TRUE;
-       }else
-         iroots[i]=0;
-      }
-    }    
-  }
-  if (zroot) {
-    for (i = 0; i < nrtfn; i++) {
-      if ((iroots[i]==2)|| (iroots[i]==-2))  iroots[i]=0;
-    }
-    return(RTFOUND);
-  }
-  if (umroot) return(ZERODETACHING);
-  return(IDA_SUCCESS);
-}
 /* 
  * =================================================================
  * IDA error message handling functions   
@@ -3481,7 +3607,7 @@ void IDAProcessError(IDAMem IDA_mem,
 
 #ifndef NO_FPRINTF_OUTPUT
     fprintf(stderr, "\n[%s ERROR]  %s\n  ", module, fname);
-    fprintf(stderr, "%s", msgfmt);
+    fprintf(stderr, msgfmt);
     fprintf(stderr, "\n\n");
 #endif
 
@@ -3534,3 +3660,339 @@ void IDAErrHandler(int error_code, const char *module,
 
   return;
 }
+
+/* SUNDIALS EXTENSION */
+/* ALL NEXT LINES ADDED FOR EXTENSION */
+
+
+static int IDARcheck1Ext(IDAMem IDA_mem)
+{
+       int i, retval;
+       booleantype zroot;
+
+       for (i = 0; i < nrtfn; i++) iroots[i] = 0;
+       tlo = tn;
+       ttol = (ABS(tn) + ABS(hh))*uround*HUNDRED;
+
+       /* Evaluate g at initial t and check for zero values. */
+       retval = gfun (tlo, phi[0], phi[1], glo, g_data);
+       nge = 1;
+       if (retval != 0) return(IDA_RTFUNC_FAIL);
+
+       zroot = FALSE;
+
+       for (i = 0; i < nrtfn; i++) {
+               if (ABS(glo[i]) == ZERO) 
+                       iroots[i] =MASKED; /* arbitrary choice*/
+               else 
+                       iroots[i] =0;
+       }
+       return(IDA_SUCCESS);
+
+}
+
+static int IDARcheck2Ext(IDAMem IDA_mem)
+{
+       int i, retval;
+
+       if (irfnd == 0) return(IDA_SUCCESS);
+
+       (void) IDAGetSolution(IDA_mem, tlo, yy, yp);
+       retval = gfun (tlo, yy, yp, glo, g_data);  
+       nge++;
+       if (retval != 0) return(IDA_RTFUNC_FAIL);
+
+       for (i = 0; i < nrtfn; i++) {
+               if (ABS(glo[i]) == ZERO) 
+                       iroots[i] =MASKED; /* arbitrary choice*/
+               else 
+                       iroots[i] =0;
+       }
+       return(IDA_SUCCESS);
+}
+
+static int IDARcheck3Ext(IDAMem IDA_mem)
+{
+       int i, ier, retval;
+
+       /* Set thi = tn or tout, whichever comes first. */
+       if (taskc == IDA_ONE_STEP) thi = tn;
+       if (taskc == IDA_NORMAL) {
+               thi = ( (toutc - tn)*hh >= ZERO) ? tn : toutc;
+       }
+
+       /* Get y and y' at thi. */
+       (void) IDAGetSolution(IDA_mem, thi, yy, yp);
+
+
+       /* Set ghi = g(thi) and call IDARootfind to search (tlo,thi) for roots. */
+       retval = gfun (thi, yy, yp, ghi, g_data);  
+       nge++;
+       if (retval != 0) return(IDA_RTFUNC_FAIL);
+
+       ttol = (ABS(tn) + ABS(hh))*uround*HUNDRED;
+       ier = IDARootfind(IDA_mem);
+       tlo = trout;
+       for (i = 0; i < nrtfn; i++) glo[i] = grout[i];
+
+       /* If no root found, return IDA_SUCCESS. */  
+       if (ier == IDA_SUCCESS) return(IDA_SUCCESS);
+
+       /* If a root was found, interpolate to get y(trout) and return.  */
+       (void) IDAGetSolution(IDA_mem, trout, yy, yp);
+       /*  return(RTFOUND);*/
+
+       if (ier == RTFOUND)
+               return(RTFOUND);
+       else
+               return(ZERODETACHING);
+
+}
+
+/*-------------------*/
+
+static int IDARootfindExt(IDAMem IDA_mem)
+{
+       realtype alph, tmid, gfrac, maxfrac, fracint, fracsub;
+       int i, retval, imax, side, sideprev;
+       int istuck,iunstuck,imaxold;
+
+       booleantype zroot, umroot, sgnchg;
+
+       imax = -1;
+       istuck=-1;
+       iunstuck=-1;
+       maxfrac = ZERO;
+
+       /* First check for change in sign in ghi or for a zero in ghi. */
+       zroot = FALSE;
+
+       for (i = 0;  i < nrtfn; i++) {
+               if ((ABS(ghi[i])==ZERO)&& (iroots[i]!=MASKED))  istuck=i;
+               if ((ABS(ghi[i])> ZERO)&& (iroots[i]==MASKED))  iunstuck=i;
+               if ((ABS(ghi[i])> ZERO)&& (glo[i]*ghi[i] <= ZERO)) {
+                       gfrac = ABS(ghi[i]/(ghi[i] - glo[i]));
+                       if (gfrac > maxfrac) { /* finding the very first root*/
+                               maxfrac = gfrac;
+                               imax = i;
+                       }      
+               }
+       }
+
+       if (imax>=0)
+               sgnchg=TRUE;
+       else if (istuck>=0) {
+               sgnchg=TRUE;
+               imax=istuck;
+       }else  if (iunstuck>=0) {
+               sgnchg=TRUE;
+               imax=iunstuck;
+       }else
+               sgnchg = FALSE;
+
+       /* If no sign change was found, reset trout and grout.  Then return
+       IDA_SUCCESS if no zero was found, or set iroots and return RTFOUND.  */ 
+       if (!sgnchg) {
+               trout = thi;
+               for (i = 0; i < nrtfn; i++) grout[i] = ghi[i];
+               return(IDA_SUCCESS);
+       }
+
+
+       /* Initialize alph to avoid compiler warning */
+       alph = ONE;
+
+       /* A sign change was found.  Loop to locate nearest root. */
+
+       side = 0;  sideprev = -1;
+       loop {                                    /* Looping point */
+
+               /* Set weight alph.
+               On the first two passes, set alph = 1.  Thereafter, reset alph
+               according to the side (low vs high) of the subinterval in which
+               the sign change was found in the previous two passes.
+               If the sides were opposite, set alph = 1.
+               If the sides were the same, then double alph (if high side),
+               or halve alph (if low side).
+               The next guess tmid is the secant method value if alph = 1, but
+               is closer to tlo if alph < 1, and closer to thi if alph > 1.    */
+
+               if (sideprev == side) {
+                       alph = (side == 2) ? alph*TWO : alph*HALF;
+               } else {
+                       alph = ONE;
+               }
+               /* Set next root approximation tmid and get g(tmid).
+               If tmid is too close to tlo or thi, adjust it inward,
+               by a fractional distance that is between 0.1 and 0.5.  */
+               if ((ABS(ghi[imax])==ZERO)||(ABS(glo[imax])==ZERO)){
+                       tmid=(tlo+alph*thi)/(1+alph);
+               }else{
+                       tmid = thi - (thi - tlo)*ghi[imax]/(ghi[imax] - alph*glo[imax]);
+               }
+
+               if (tmid+1 ==tmid) {printf("tmid is nan\n\r ");exit(0);};
+
+               if (ABS(tmid - tlo) < HALF*ttol) {
+                       fracint = ABS(thi - tlo)/ttol;
+                       fracsub = (fracint > FIVE) ? PT1 : HALF/fracint;
+                       tmid = tlo + fracsub*(thi - tlo);
+               }
+
+               if (ABS(thi - tmid) < HALF*ttol) {
+                       fracint = ABS(thi - tlo)/ttol;
+                       fracsub = (fracint > FIVE) ? PT1 : HALF/fracint;
+                       tmid = thi - fracsub*(thi - tlo);
+               }
+
+               (void) IDAGetSolution(IDA_mem, tmid, yy, yp);
+               retval = gfun (tmid, yy, yp, grout, g_data); 
+               nge++;
+               if (retval != 0) return(IDA_RTFUNC_FAIL);
+
+               /* Check to see in which subinterval g changes sign, and reset imax.
+               Set side = 1 if sign change is on low side, or 2 if on high side.  */  
+
+               /* First check for change in sign in ghi or for a zero in ghi. */
+               zroot = FALSE;
+               sideprev = side;
+               imaxold=imax;
+               imax = -1;
+               istuck=-1;iunstuck=-1;
+               maxfrac = ZERO;
+               for (i = 0;  i < nrtfn; i++) {
+                       if ((ABS(grout[i])==ZERO)&& (iroots[i]!=MASKED))  istuck=i;
+                       if ((ABS(grout[i])> ZERO)&& (iroots[i]==MASKED))  iunstuck=i;
+                       if ((ABS(grout[i])> ZERO)&& (glo[i]*grout[i] <= ZERO)) {
+                               gfrac = ABS(grout[i]/(grout[i] - glo[i]));
+                               if (gfrac > maxfrac) { /* finding the very first root*/
+                                       maxfrac = gfrac;
+                                       imax = i;
+                               }      
+                       }
+               }
+
+               if (imax>=0)
+                       sgnchg=TRUE;
+               else if (istuck>=0) {
+                       sgnchg=TRUE;
+                       imax=istuck;
+               }else  if (iunstuck>=0) {
+                       sgnchg=TRUE;
+                       imax=iunstuck;
+               }else{
+                       sgnchg = FALSE;
+                       imax=imaxold;
+               }
+
+               if (sgnchg) {
+                       /* Sign change found in (tlo,tmid); replace thi with tmid. */
+                       thi = tmid;
+                       for (i = 0; i < nrtfn; i++) ghi[i] = grout[i];
+                       side = 1;
+                       /* Stop at root thi if converged; otherwise loop. */
+                       if (ABS(thi - tlo) <= ttol) break;
+                       continue;  /* Return to looping point. */
+               }
+
+               /* here, either (ABS(thi - tlo) <= ttol) or NO SIGN CHANGE */
+
+               /* No sign change in (tlo,tmid), and no zero at tmid.
+               Sign change must be in (tmid,thi).  Replace tlo with tmid. */
+               tlo = tmid;
+               for (i = 0; i < nrtfn; i++) glo[i] = grout[i];
+               side = 2;
+               /* Stop at root thi if converged; otherwise loop back. */
+               if (ABS(thi - tlo) <= ttol) break;
+
+       } /* End of root-search loop */
+
+       /* Reset trout and grout, set iroots, and return RTFOUND. */
+       zroot = FALSE;
+       umroot = FALSE;
+       trout = thi;
+       for (i = 0; i < nrtfn; i++) {
+               grout[i] = ghi[i];
+               if (iroots[i]==MASKED){
+                       if (ABS(ghi[i]) != ZERO){ 
+                               iroots[i] = (ghi[i]> ZERO) ? 2 : -2;
+                               umroot=TRUE;
+                       }else{
+                               iroots[i]=0;
+                       }
+               }else{
+                       if (ABS(ghi[i])== ZERO){ 
+                               iroots[i] = (glo[i]> ZERO) ? -1 : 1;
+                               zroot = TRUE;
+                       }else{
+                               if (glo[i]*ghi[i] < ZERO){
+                                       iroots[i] = (ghi[i]>glo[i]) ? 1 : -1;
+                                       zroot = TRUE;
+                               }else
+                                       iroots[i]=0;
+                       }
+               }    
+       }
+       if (zroot) {
+               for (i = 0; i < nrtfn; i++) {
+                       if ((iroots[i]==2)|| (iroots[i]==-2))  iroots[i]=0;
+               }
+               return(RTFOUND);
+       }
+       if (umroot) return(ZERODETACHING);
+       return(IDA_SUCCESS);
+}
+
+
+static int IDARcheck1(IDAMem IDA_mem)
+{
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return IDARcheck1Ext(IDA_mem);
+       }
+       else
+       {
+               return IDARcheck1Std(IDA_mem);
+       }
+}
+
+static int IDARcheck2(IDAMem IDA_mem)
+{
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return IDARcheck2Ext(IDA_mem);
+       }
+       else
+       {
+               return IDARcheck2Std(IDA_mem);
+       }
+}
+
+static int IDARcheck3(IDAMem IDA_mem)
+{
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return IDARcheck3Ext(IDA_mem);
+       }
+       else
+       {
+               return IDARcheck3Std(IDA_mem);
+       }
+}
+
+static int IDARootfind(IDAMem IDA_mem)
+{
+       /* SUNDIALS EXTENSION */
+       if (is_sundials_with_extension())
+       {
+               return IDARootfindExt(IDA_mem);
+       }
+       else
+       {
+               return IDARootfindStd(IDA_mem);
+       }
+}
+
@@ -22,7 +22,7 @@
 #include "ida_impl.h"
 #include "ida_dense_impl.h"
 
-#include "sundials_math.h"
+#include <sundials/sundials_math.h>
 
 /* Constants */
 
@@ -381,7 +381,7 @@ static int IDADenseSetup(IDAMem IDA_mem, N_Vector yyp, N_Vector ypp,
                          N_Vector rrp, N_Vector tmp1, N_Vector tmp2,
                          N_Vector tmp3)
 {
-  int retval;  
+  int retval;
   long int retfac;
   IDADenseMem idadense_mem;
   
@@ -392,9 +392,8 @@ static int IDADenseSetup(IDAMem IDA_mem, N_Vector yyp, N_Vector ypp,
 
   /* Zero out JJ; call Jacobian routine jac; return if it failed. */
   DenseZero(JJ);
-  /*printf(" \n\r XXIDADenseSetup-JAC in ida-dense  ");*/
-  retval = jac(neq, tn, yyp, ypp, rrp, cj, jacdata, JJ, tmp1, tmp2, tmp3);
-
+  retval = jac(neq, tn, yyp, ypp, rrp, cj, jacdata, JJ, 
+               tmp1, tmp2, tmp3);
   if (retval < 0) {
     IDAProcessError(IDA_mem, IDADENSE_JACFUNC_UNRECVR, "IDADENSE", "IDADenseSetup", MSGD_JACFUNC_FAILED);
     last_flag = IDADENSE_JACFUNC_UNRECVR;
@@ -553,13 +552,6 @@ static int IDADenseDQJac(long int Neq, realtype tt, N_Vector yy, N_Vector yp,
     yp_data[j] = ypj;
   }
 
-  /*
-    for (i=0;i<Neq;i++)
-    for (j=0;j<Neq;j++){      
-      printf("J(%d,%d)=%g;",i+1,j+1, DENSE_ELEM(Jac,i,j));
-      if (DENSE_ELEM(Jac,i,j) != DENSE_ELEM(Jac,i,j)) exit(0);
-      }*/
   /* Restore original array pointer in tmp2 */
   N_VSetArrayPointer(tmp2_data, tmp2);
 
@@ -24,7 +24,7 @@ extern "C" {
 
 #include <stdio.h>
 
-#include "ida_dense.h"
+#include <ida/ida_dense.h>
 
 /*
  * -----------------------------------------------------------------
 #include <stdlib.h>
 
 #include "ida_impl.h"
-#include "sundials_math.h"
+#include <sundials/sundials_math.h>
+
+/* SUNDIALS EXTENSION */
+#include "sundials_extension.h"
 
 /* Macro: loop */
 #define loop for(;;)
@@ -205,7 +208,7 @@ int IDACalcIC(void *ida_mem, int icopt, realtype tout1)
   yy0 = N_VClone(ee);
   yp0 = N_VClone(ee);
   t0  = tn;
-  N_VScale(ONE, phi[0], yy0); /* copying phi0-> yy0*/
+  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. */
@@ -222,7 +225,9 @@ int IDACalcIC(void *ida_mem, int icopt, realtype tout1)
   }
 
   /* 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; */
@@ -247,6 +252,7 @@ int IDACalcIC(void *ida_mem, int icopt, realtype tout1)
   }
 
   /* Loop over nwt = number of evaluations of ewt vector. */
+
   for(nwt = 1; nwt <= 2; nwt++) {
  
     /* Loop over nh = number of h values. */
@@ -284,9 +290,13 @@ int IDACalcIC(void *ida_mem, int icopt, realtype tout1)
 
   /* Free temporary space */
 
-  /* Masoud:  in order to return computed new values even if they are not consistent*/ 
-    N_VScale(ONE, yy0, phi[0]); /* addedd by masoud*/
-    N_VScale(ONE, yp0, phi[1]); /* addedd by masoud*/
+  /* SUNDIALS EXTENSION */
+  if (is_sundials_with_extension())
+  {
+         /* in order to return computed new values even if they are not consistent*/ 
+         N_VScale(ONE, yy0, phi[0]);
+         N_VScale(ONE, yp0, phi[1]);
+  }
     
 
   N_VDestroy(yy0);
@@ -302,7 +312,7 @@ int IDACalcIC(void *ida_mem, int icopt, realtype tout1)
     icret = IDAICFailFlag(IDA_mem, retval);
     return(icret);
   }
+
   /* Otherwise return success flag. */
 
   return(IDA_SUCCESS);
@@ -355,8 +365,8 @@ static int IDAnlsIC (IDAMem IDA_mem)
   tv1 = ee;
   tv2 = tempv2;
   tv3 = phi[2];
-  retval = res(t0, yy0, yp0, delta, rdata);
 
+  retval = res(t0, yy0, yp0, delta, rdata);
   nre++;
   if(retval < 0) return(IDA_RES_FAIL);
   if(retval > 0) return(IDA_FIRST_RES_FAIL);
@@ -364,15 +374,16 @@ static int IDAnlsIC (IDAMem IDA_mem)
   N_VScale(ONE, delta, savres);
 
   /* Loop over nj = number of linear solve Jacobian setups. */
+
   for(nj = 1; nj <= maxnj; nj++) {
+
     /* If there is a setup routine, call it. */
-     if(setupNonNull) {
+    if(setupNonNull) {
       nsetups++;
       retval = lsetup(IDA_mem, yy0, yp0, delta, tv1, tv2, tv3);
-
       if(retval < 0) return(IDA_LSETUP_FAIL);
       if(retval > 0) return(IC_FAIL_RECOV);
-      }
+    }
 
     /* Call the Newton iteration routine, and return if successful.  */
     retval = IDANewtonIC(IDA_mem);
@@ -24,7 +24,7 @@ extern "C" {
 
 #include <stdarg.h>
 
-#include "ida.h"
+#include <ida/ida.h>
 
   /* 
    * =================================================================
@@ -172,9 +172,9 @@ extern "C" {
     /* Space requirements for IDA */
 
     long int ida_lrw1;     /* no. of realtype words in 1 N_Vector               */
-    long int ida_liw1;     /* no. of int words in 1 N_Vector                */
+    long int ida_liw1;     /* no. of integer words in 1 N_Vector                */
     long int ida_lrw;      /* number of realtype words in IDA work vectors      */
-    long int ida_liw;      /* no. of int words in IDA work vectors          */
+    long int ida_liw;      /* no. of integer words in IDA work vectors          */
 
     realtype ida_tolsf;    /* tolerance scale factor (saved value)              */
 
@@ -840,6 +840,7 @@ int IDAGetCurrentOrder(void *ida_mem, int *kcur)
   }
 
   IDA_mem = (IDAMem) ida_mem;
+
   *kcur = kk;
 
   return(IDA_SUCCESS);
-/*\r
- * -----------------------------------------------------------------\r
- * Revision: 1.1 $\r
- * Date: 2008-11-17 16:26:32 $\r
- * -----------------------------------------------------------------\r
- * Programmer(s): Allan Taylor, Alan Hindmarsh, Radu Serban, and\r
- *                Aaron Collier @ LLNL\r
- * -----------------------------------------------------------------\r
- * Copyright (c) 2002, The Regents of the University of California.\r
- * Produced at the Lawrence Livermore National Laboratory.\r
- * All rights reserved.\r
- * For details, see the LICENSE file.\r
- * -----------------------------------------------------------------\r
- * This is the implementation file for the main KINSol solver.\r
- * It is independent of the KINSol linear solver in use.\r
- * -----------------------------------------------------------------\r
- *\r
- * EXPORTED FUNCTIONS\r
- * ------------------\r
- *   Creation and allocation functions\r
- *     KINCreate\r
- *     KINMalloc\r
- *   Main solver function\r
- *     KINSol\r
- *   Deallocation function\r
- *     KINFree\r
- *\r
- * PRIVATE FUNCTIONS\r
- * -----------------\r
- *     KINCheckNvector\r
- *   Memory allocation/deallocation\r
- *     KINAllocVectors\r
- *     KINFreeVectors\r
- *   Initial setup\r
- *     KINSolInit\r
- *   Step functions\r
- *     KINLinSolDrv\r
- *     KINFullNewton\r
- *     KINLineSearch\r
- *     KINConstraint\r
- *   Stopping tests\r
- *     KINStop\r
- *     KINForcingTerm\r
- *   Norm functions\r
- *     KINScFNorm\r
- *     KINScSNorm\r
- *   KINSOL Verbose output functions\r
- *     KINPrintInfo\r
- *     KINInfoHandler\r
- *   KINSOL Error Handling functions\r
- *     KINProcessError\r
- *     KINErrHandler\r
- * -----------------------------------------------------------------\r
- */\r
-\r
-/* \r
- * =================================================================\r
- * IMPORTED HEADER FILES\r
- * =================================================================\r
- */\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <stdarg.h>\r
-#include <math.h>\r
-\r
-#include "kinsol_impl.h"\r
-#include "sundials_math.h"\r
-\r
-/* \r
- * =================================================================\r
- * MACRO DEFINITIONS\r
- * =================================================================\r
- */\r
-\r
-/* Macro: loop */\r
-#define loop for(;;)\r
-\r
-/* \r
- * =================================================================\r
- * KINSOL PRIVATE CONSTANTS\r
- * =================================================================\r
- */\r
-\r
-#define HALF      RCONST(0.5)\r
-#define ZERO      RCONST(0.0)\r
-#define ONE       RCONST(1.0)\r
-#define ONEPT5    RCONST(1.5)\r
-#define TWO       RCONST(2.0)\r
-#define THREE     RCONST(3.0)\r
-#define FIVE      RCONST(5.0)\r
-#define POINT1    RCONST(0.1)\r
-#define POINT01   RCONST(0.01)\r
-#define POINT99   RCONST(0.99)\r
-#define THOUSAND  RCONST(1000.0)\r
-#define ONETHIRD  RCONST(0.3333333333333333)\r
-#define TWOTHIRDS RCONST(0.6666666666666667)\r
-#define POINT9    RCONST(0.9)\r
-#define POINT0001 RCONST(0.0001)\r
-\r
-/* \r
- * =================================================================\r
- * KINSOL ROUTINE-SPECIFIC CONSTANTS\r
- * =================================================================\r
- */\r
-\r
-/* \r
- * Control constants for lower-level functions used by KINSol \r
- * ----------------------------------------------------------\r
- *\r
- * KINStop return value requesting more iterations\r
- *    RETRY_ITERATION\r
- *    CONTINUE_ITERATIONS\r
- *\r
- * KINFullNewton and KINLineSearch return values:\r
- *    KIN_SUCCESS\r
- *    KIN_SYSFUNC_FAIL\r
- *    STEP_TOO_SMALL\r
- *\r
- * KINConstraint return values:\r
- *    KIN_SUCCESS\r
- *    CONSTR_VIOLATED\r
- */\r
-\r
-#define RETRY_ITERATION     -998\r
-#define CONTINUE_ITERATIONS -999\r
-#define STEP_TOO_SMALL      -997\r
-#define CONSTR_VIOLATED     -996\r
-\r
-/*\r
- * Algorithmic constants\r
- * ---------------------\r
- *\r
- * MAX_RECVR   max. no. of attempts to correct a recoverable func error\r
- */\r
-\r
-#define MAX_RECVR      5\r
-\r
-/*\r
- * Keys for KINPrintInfo\r
- * ---------------------\r
- */\r
-\r
-#define PRNT_RETVAL     1\r
-#define PRNT_NNI        2\r
-#define PRNT_TOL        3\r
-#define PRNT_FMAX       4\r
-#define PRNT_PNORM      5\r
-#define PRNT_PNORM1     6\r
-#define PRNT_FNORM      7\r
-#define PRNT_LAM        8\r
-#define PRNT_ALPHA      9\r
-#define PRNT_BETA      10\r
-#define PRNT_ALPHABETA 11\r
-#define PRNT_ADJ       12\r
-\r
-/* \r
- * =================================================================\r
- * PRIVATE FUNCTION PROTOTYPES\r
- * =================================================================\r
- */\r
-\r
-static booleantype KINCheckNvector(N_Vector tmpl);\r
-static booleantype KINAllocVectors(KINMem kin_mem, N_Vector tmpl);\r
-static int KINSolInit(KINMem kin_mem, int strategy);\r
-static int KINConstraint(KINMem kin_mem );\r
-static void KINForcingTerm(KINMem kin_mem, realtype fnormp);\r
-static void KINFreeVectors(KINMem kin_mem);\r
-\r
-static int  KINFullNewton(KINMem kin_mem, realtype *fnormp, \r
-                          realtype *f1normp, booleantype *maxStepTaken);\r
-static int  KINLineSearch(KINMem kin_mem, realtype *fnormp, \r
-                          realtype *f1normp, booleantype *maxStepTaken);\r
-\r
-static int  KINLinSolDrv(KINMem kinmem);\r
-static realtype KINScFNorm(KINMem kin_mem, N_Vector v, N_Vector scale);\r
-static realtype KINScSNorm(KINMem kin_mem, N_Vector v, N_Vector u);\r
-static int KINStop(KINMem kin_mem, int strategy, booleantype maxStepTaken, int sflag);\r
-\r
-/* \r
- * =================================================================\r
- * EXPORTED FUNCTIONS IMPLEMENTATION\r
- * =================================================================\r
- */\r
-\r
-/* \r
- * -----------------------------------------------------------------\r
- * Creation and allocation functions\r
- * -----------------------------------------------------------------\r
- */\r
-\r
-/*\r
- * Function : KINCreate\r
- *\r
- * KINCreate creates an internal memory block for a problem to \r
- * be solved by KINSOL. If successful, KINCreate returns a pointer\r
- * to the problem memory. This pointer should be passed to\r
- * KINMalloc. If an initialization error occurs, KINCreate prints\r
- * an error message to standard error and returns NULL. \r
- */\r
-\r
-void *KINCreate(void)\r
-{\r
-  KINMem kin_mem;\r
-  realtype uround;\r
-\r
-  kin_mem = NULL;\r
-  kin_mem = (KINMem) malloc(sizeof(struct KINMemRec));\r
-  if (kin_mem == NULL) {\r
-    KINProcessError(kin_mem, 0, "KINSOL", "KINCreate", MSG_MEM_FAIL);\r
-    return(NULL);\r
-  }\r
-\r
-  /* set uround (unit roundoff) */\r
-\r
-  kin_mem->kin_uround = uround = UNIT_ROUNDOFF;\r
-  \r
-  /* set default values for solver optional inputs */\r
-\r
-  kin_mem->kin_func             = NULL;\r
-  kin_mem->kin_f_data           = NULL;\r
-  kin_mem->kin_constraints      = NULL;\r
-  kin_mem->kin_uscale           = NULL;\r
-  kin_mem->kin_fscale           = NULL;\r
-  kin_mem->kin_constraintsSet   = FALSE;\r
-  kin_mem->kin_ehfun            = KINErrHandler;\r
-  kin_mem->kin_eh_data          = (void *) kin_mem;\r
-  kin_mem->kin_errfp            = stderr;\r
-  kin_mem->kin_ihfun            = KINInfoHandler;\r
-  kin_mem->kin_ih_data          = (void *) kin_mem;\r
-  kin_mem->kin_infofp           = stdout;\r
-  kin_mem->kin_printfl          = PRINTFL_DEFAULT;\r
-  kin_mem->kin_mxiter           = MXITER_DEFAULT;\r
-  kin_mem->kin_noInitSetup      = FALSE;\r
-  kin_mem->kin_msbset           = MSBSET_DEFAULT;\r
-  kin_mem->kin_noResMon         = FALSE;\r
-  kin_mem->kin_msbset_sub       = MSBSET_SUB_DEFAULT;\r
-  kin_mem->kin_update_fnorm_sub = FALSE;\r
-  kin_mem->kin_mxnbcf           = MXNBCF_DEFAULT;\r
-  kin_mem->kin_sthrsh           = TWO;\r
-  kin_mem->kin_noMinEps         = FALSE;\r
-  kin_mem->kin_mxnewtstep       = ZERO;\r
-  kin_mem->kin_sqrt_relfunc     = RSqrt(uround);\r
-  kin_mem->kin_scsteptol        = RPowerR(uround,TWOTHIRDS);\r
-  kin_mem->kin_fnormtol         = RPowerR(uround,ONETHIRD);\r
-  kin_mem->kin_etaflag          = KIN_ETACHOICE1;\r
-  kin_mem->kin_eta              = POINT1;     /* default for KIN_ETACONSTANT */\r
-  kin_mem->kin_eta_alpha        = TWO;        /* default for KIN_ETACHOICE2  */\r
-  kin_mem->kin_eta_gamma        = POINT9;     /* default for KIN_ETACHOICE2  */\r
-  kin_mem->kin_MallocDone       = FALSE;\r
-  kin_mem->kin_setupNonNull     = FALSE;\r
-  kin_mem->kin_omega            = ZERO;       /* default to using min / max  */\r
-  kin_mem->kin_omega_min        = OMEGA_MIN;\r
-  kin_mem->kin_omega_max        = OMEGA_MAX;\r
-\r
-  /* initialize lrw and liw */\r
-\r
-  kin_mem->kin_lrw = 17;\r
-  kin_mem->kin_liw = 22;\r
-\r
-  /* NOTE: needed since KINMalloc could be called after KINSetConstraints */\r
-\r
-  kin_mem->kin_lrw1 = 0;\r
-  kin_mem->kin_liw1 = 0;\r
-\r
-  return((void *) kin_mem);\r
-}\r
-\r
-#define errfp (kin_mem->kin_errfp)\r
-#define liw   (kin_mem->kin_liw)\r
-#define lrw   (kin_mem->kin_lrw)\r
-\r
-/*\r
- * Function : KINMalloc\r
- *\r
- * KINMalloc allocates memory for a problem or execution of KINSol. \r
- * If memory is successfully allocated, KIN_SUCCESS is returned.\r
- * Otherwise, an error message is printed and an error flag\r
- * returned.\r
- */\r
-\r
-int KINMalloc(void *kinmem, KINSysFn func, N_Vector tmpl)\r
-{\r
-  long int liw1, lrw1;\r
-  KINMem kin_mem;\r
-  booleantype allocOK, nvectorOK;\r
-  \r
-  /* check kinmem */\r
-\r
-  if (kinmem == NULL) {\r
-    KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINMalloc", MSG_NO_MEM);\r
-    return(KIN_MEM_NULL);\r
-  }\r
-  kin_mem = (KINMem) kinmem;\r
-\r
-  if (func == NULL) {\r
-    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINMalloc", MSG_FUNC_NULL);\r
-    return(KIN_ILL_INPUT);\r
-  }\r
-\r
-  /* check if all required vector operations are implemented */\r
-\r
-  nvectorOK = KINCheckNvector(tmpl);\r
-  if (!nvectorOK) {\r
-    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINMalloc", MSG_BAD_NVECTOR);\r
-    return(KIN_ILL_INPUT);\r
-  }\r
-\r
-  /* set space requirements for one N_Vector */\r
-\r
-  if (tmpl->ops->nvspace != NULL) {\r
-    N_VSpace(tmpl, &lrw1, &liw1);\r
-    kin_mem->kin_lrw1 = lrw1;\r
-    kin_mem->kin_liw1 = liw1;\r
-  }\r
-  else {\r
-    kin_mem->kin_lrw1 = 0;\r
-    kin_mem->kin_liw1 = 0;\r
-  }\r
-\r
-  /* allocate necessary vectors */\r
-\r
-  allocOK = KINAllocVectors(kin_mem, tmpl);\r
-  if (!allocOK) {\r
-    KINProcessError(kin_mem, KIN_MEM_FAIL, "KINSOL", "KINMalloc", MSG_MEM_FAIL);\r
-    free(kin_mem); kin_mem = NULL;\r
-    return(KIN_MEM_FAIL);\r
-  }\r
-\r
-  /* copy the input parameter into KINSol state */\r
-\r
-  kin_mem->kin_func = func;\r
-\r
-  /* set the linear solver addresses to NULL */\r
-\r
-  kin_mem->kin_linit  = NULL;\r
-  kin_mem->kin_lsetup = NULL;\r
-  kin_mem->kin_lsolve = NULL;\r
-  kin_mem->kin_lfree  = NULL;\r
-  kin_mem->kin_lmem   = NULL;\r
-  \r
-  /* problem memory has been successfully allocated */\r
-\r
-  kin_mem->kin_MallocDone = TRUE;\r
-\r
-  return(KIN_SUCCESS);\r
-}\r
-\r
-/*\r
- * -----------------------------------------------------------------\r
- * Readability constants\r
- * -----------------------------------------------------------------\r
- */\r
-\r
-#define func             (kin_mem->kin_func)\r
-#define f_data           (kin_mem->kin_f_data)\r
-#define printfl          (kin_mem->kin_printfl)\r
-#define mxiter           (kin_mem->kin_mxiter)\r
-#define noInitSetup      (kin_mem->kin_noInitSetup)\r
-#define retry_nni        (kin_mem->kin_retry_nni)\r
-#define msbset           (kin_mem->kin_msbset)\r
-#define etaflag          (kin_mem->kin_etaflag)\r
-#define eta              (kin_mem->kin_eta)\r
-#define ealpha           (kin_mem->kin_eta_alpha)\r
-#define egamma           (kin_mem->kin_eta_gamma)\r
-#define noMinEps         (kin_mem->kin_noMinEps)\r
-#define mxnewtstep       (kin_mem->kin_mxnewtstep)\r
-#define mxnbcf           (kin_mem->kin_mxnbcf)\r
-#define relfunc          (kin_mem->kin_sqrt_relfunc)\r
-#define fnormtol         (kin_mem->kin_fnormtol)\r
-#define scsteptol        (kin_mem->kin_scsteptol)\r
-#define constraints      (kin_mem->kin_constraints)\r
-\r
-#define uround           (kin_mem->kin_uround)\r
-#define nni              (kin_mem->kin_nni)\r
-#define nfe              (kin_mem->kin_nfe)\r
-#define nbcf             (kin_mem->kin_nbcf)  \r
-#define nbktrk           (kin_mem->kin_nbktrk)\r
-#define ncscmx           (kin_mem->kin_ncscmx)\r
-#define stepl            (kin_mem->kin_stepl)\r
-#define stepmul          (kin_mem->kin_stepmul)\r
-#define sthrsh           (kin_mem->kin_sthrsh)\r
-#define linit            (kin_mem->kin_linit)\r
-#define lsetup           (kin_mem->kin_lsetup)\r
-#define lsolve           (kin_mem->kin_lsolve) \r
-#define lfree            (kin_mem->kin_lfree)\r
-#define constraintsSet   (kin_mem->kin_constraintsSet) \r
-#define jacCurrent       (kin_mem->kin_jacCurrent)          \r
-#define nnilset          (kin_mem->kin_nnilset)\r
-#define lmem             (kin_mem->kin_lmem)        \r
-#define inexact_ls       (kin_mem->kin_inexact_ls)\r
-#define setupNonNull     (kin_mem->kin_setupNonNull)\r
-#define fval             (kin_mem->kin_fval)      \r
-#define fnorm            (kin_mem->kin_fnorm)\r
-#define f1norm           (kin_mem->kin_f1norm)\r
-#define etaflag          (kin_mem->kin_etaflag)\r
-#define callForcingTerm  (kin_mem->kin_callForcingTerm)\r
-#define uu               (kin_mem->kin_uu)\r
-#define uscale           (kin_mem->kin_uscale)\r
-#define fscale           (kin_mem->kin_fscale)\r
-#define sJpnorm          (kin_mem->kin_sJpnorm)\r
-#define sfdotJp          (kin_mem->kin_sfdotJp)\r
-#define unew             (kin_mem->kin_unew)\r
-#define pp               (kin_mem->kin_pp)\r
-#define vtemp1           (kin_mem->kin_vtemp1)\r
-#define vtemp2           (kin_mem->kin_vtemp2)\r
-#define eps              (kin_mem->kin_eps)\r
-#define res_norm         (kin_mem->kin_res_norm)\r
-#define liw1             (kin_mem->kin_liw1)\r
-#define lrw1             (kin_mem->kin_lrw1)\r
-\r
-#define noResMon         (kin_mem->kin_noResMon)\r
-#define fnorm_sub        (kin_mem->kin_fnorm_sub)\r
-#define msbset_sub       (kin_mem->kin_msbset_sub)\r
-#define nnilset_sub      (kin_mem->kin_nnilset_sub)\r
-#define update_fnorm_sub (kin_mem->kin_update_fnorm_sub)\r
-#define omega            (kin_mem->kin_omega)\r
-#define omega_min        (kin_mem->kin_omega_min)\r
-#define omega_max        (kin_mem->kin_omega_max)\r
-\r
-/* \r
- * -----------------------------------------------------------------\r
- * Main solver function\r
- * -----------------------------------------------------------------\r
- */\r
-\r
-/*\r
- * Function : KINSol\r
- *\r
- * KINSol (main KINSOL driver routine) manages the computational\r
- * process of computing an approximate solution of the nonlinear\r
- * system F(uu) = 0. The KINSol routine calls the following\r
- * subroutines:\r
- *\r
- *  KINSolInit    checks if initial guess satisfies user-supplied\r
- *                constraints and initializes linear solver\r
- *\r
- *  KINLinSolDrv  interfaces with linear solver to find a\r
- *                solution of the system J(uu)*x = b (calculate\r
- *                Newton step)\r
- *\r
- *  KINFullNewton/KINLineSearch  implement the global strategy\r
- *\r
- *  KINForcingTerm  computes the forcing term (eta)\r
- *\r
- *  KINStop  determines if an approximate solution has been found\r
- */\r
-\r
-int KINSol(void *kinmem, N_Vector u, int strategy,  \r
-           N_Vector u_scale, N_Vector f_scale)\r
-{\r
-  realtype fnormp, f1normp, epsmin;\r
-  KINMem kin_mem;\r
-  int ret, sflag;\r
-  booleantype maxStepTaken;\r
-\r
-  /* intialize to avoid compiler warning messages */\r
-\r
-  maxStepTaken = FALSE;\r
-  f1normp = fnormp = -ONE;\r
-\r
-  /* initialize epsmin to avoid compiler warning message */\r
-\r
-  epsmin = ZERO;\r
-\r
-  /* check for kinmem non-NULL */\r
-\r
-  if (kinmem == NULL) {\r
-    KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSol", MSG_NO_MEM);\r
-    return(KIN_MEM_NULL);\r
-  }\r
-  kin_mem = (KINMem) kinmem;\r
-\r
-  if(kin_mem->kin_MallocDone == FALSE) {\r
-    KINProcessError(NULL, KIN_NO_MALLOC, "KINSOL", "KINSol", MSG_NO_MALLOC);    \r
-    return(KIN_NO_MALLOC);\r
-  }\r
-\r
-  /* load input arguments */\r
-\r
-  uu = u;\r
-  uscale = u_scale;\r
-  fscale = f_scale;\r
-\r
-  /* initialize solver */\r
-\r
-  ret = KINSolInit(kin_mem, strategy);\r
-  if (ret != KIN_SUCCESS) return(ret);\r
-  \r
-  ncscmx = 0;\r
-\r
-  /* Note: The following logic allows the choice of whether or not\r
-     to force a call to the linear solver setup upon a given call to\r
-     KINSol */\r
-\r
-  if (noInitSetup) sthrsh = ONE;\r
-  else             sthrsh = TWO;\r
-\r
-  /* if eps is to be bounded from below, set the bound */\r
-\r
-  if (inexact_ls && !noMinEps) epsmin = POINT01 * fnormtol;\r
-\r
-  loop{\r
-\r
-    retry_nni = FALSE;\r
-\r
-    nni++;\r
-\r
-    /* calculate the epsilon (stopping criteria for iterative linear solver)\r
-       for this iteration based on eta from the routine KINForcingTerm */\r
-\r
-    if (inexact_ls) {\r
-      eps = (eta + uround) * fnorm;\r
-      if(!noMinEps) eps = MAX(epsmin, eps);\r
-    }\r
-\r
-    repeat_nni:\r
-\r
-    /* call KINLinSolDrv to calculate the (approximate) Newton step, pp */ \r
-\r
-    ret = KINLinSolDrv(kin_mem);\r
-    if (ret != KIN_SUCCESS) break;\r
-\r
-    /* call the appropriate routine to calculate an acceptable step pp */\r
-\r
-    sflag = 0;\r
-\r
-    if (strategy == KIN_NONE) {\r
-\r
-      /* Full Newton Step*/\r
-      sflag = KINFullNewton(kin_mem, &fnormp, &f1normp, &maxStepTaken);\r
-\r
-      /* if sysfunc failed unrecoverably, stop */\r
-      if ((sflag == KIN_SYSFUNC_FAIL) || (sflag == KIN_REPTD_SYSFUNC_ERR)) {\r
-        ret = sflag;\r
-        break;\r
-      }\r
-\r
-    } else if (strategy == KIN_LINESEARCH) {\r
-\r
-      /* Line Search */\r
-      sflag = KINLineSearch(kin_mem, &fnormp, &f1normp, &maxStepTaken);\r
-\r
-      /* if sysfunc failed unrecoverably, stop */\r
-      if (sflag == KIN_SYSFUNC_FAIL) {\r
-        ret = sflag;\r
-        break;\r
-      }\r
-\r
-      /* if too many beta condition failures, then stop iteration */\r
-      if (nbcf > mxnbcf) {\r
-        ret = KIN_LINESEARCH_BCFAIL;\r
-        break;\r
-      }\r
-\r
-    }\r
-\r
-    /* evaluate eta by calling the forcing term routine */\r
-\r
-    if (callForcingTerm) KINForcingTerm(kin_mem, fnormp);\r
-\r
-    fnorm = fnormp;\r
-\r
-    /* call KINStop to check if tolerances where met by this iteration */\r
-\r
-    ret = KINStop(kin_mem, strategy, maxStepTaken, sflag); \r
-\r
-    if (ret == RETRY_ITERATION) {\r
-      retry_nni = TRUE;\r
-      goto repeat_nni;\r
-    }\r
-\r
-    /* update uu after the iteration */\r
-\r
-    N_VScale(ONE, unew, uu);\r
-\r
-    f1norm = f1normp;\r
-\r
-    /* print the current nni, fnorm, and nfe values if printfl > 0 */\r
-\r
-    if (printfl>0)\r
-      KINPrintInfo(kin_mem, PRNT_NNI, "KINSOL", "KINSol", INFO_NNI, nni, nfe, fnorm);\r
-\r
-    if (ret != CONTINUE_ITERATIONS) break; \r
-\r
-    fflush(errfp);\r
-    \r
-  }  /* end of loop; return */\r
-\r
-  if (printfl > 0)\r
-    KINPrintInfo(kin_mem, PRNT_RETVAL, "KINSOL", "KINSol", INFO_RETVAL, ret);\r
-\r
-  switch(ret) {\r
-  case KIN_SYSFUNC_FAIL:\r
-    KINProcessError(kin_mem, KIN_SYSFUNC_FAIL, "KINSOL", "KINSol", MSG_SYSFUNC_FAILED);\r
-    break;\r
-  case KIN_REPTD_SYSFUNC_ERR:\r
-    KINProcessError(kin_mem, KIN_REPTD_SYSFUNC_ERR, "KINSOL", "KINSol", MSG_SYSFUNC_REPTD);\r
-    break;\r
-  case KIN_LSETUP_FAIL:\r
-    KINProcessError(kin_mem, KIN_LSETUP_FAIL, "KINSOL", "KINSol", MSG_LSETUP_FAILED);\r
-    break;\r
-  case KIN_LSOLVE_FAIL:\r
-    KINProcessError(kin_mem, KIN_LSOLVE_FAIL, "KINSOL", "KINSol", MSG_LSOLVE_FAILED);\r
-    break;\r
-  case KIN_LINSOLV_NO_RECOVERY:\r
-    KINProcessError(kin_mem, KIN_LINSOLV_NO_RECOVERY, "KINSOL", "KINSol", MSG_LINSOLV_NO_RECOVERY);\r
-    break;\r
-  case KIN_LINESEARCH_NONCONV:\r
-    KINProcessError(kin_mem, KIN_LINESEARCH_NONCONV, "KINSOL", "KINSol", MSG_LINESEARCH_NONCONV);\r
-    break;\r
-  case KIN_LINESEARCH_BCFAIL:\r
-    KINProcessError(kin_mem, KIN_LINESEARCH_BCFAIL, "KINSOL", "KINSol", MSG_LINESEARCH_BCFAIL);\r
-    break;\r
-  case KIN_MAXITER_REACHED:\r
-    KINProcessError(kin_mem, KIN_MAXITER_REACHED, "KINSOL", "KINSol", MSG_MAXITER_REACHED);\r
-    break;\r
-  case KIN_MXNEWT_5X_EXCEEDED:\r
-    KINProcessError(kin_mem, KIN_MXNEWT_5X_EXCEEDED, "KINSOL", "KINSol", MSG_MXNEWT_5X_EXCEEDED);\r
-    break;\r
-  }\r
-  \r
-  return(ret);\r
-}\r
-\r
-/* \r
- * -----------------------------------------------------------------\r
- * Deallocation function\r
- * -----------------------------------------------------------------\r
- */\r
-\r
-/*\r
- * Function : KINFree\r
- *\r
- * This routine frees the problem memory allocated by KINMalloc.\r
- * Such memory includes all the vectors allocated by\r
- * KINAllocVectors, and the memory lmem for the linear solver\r
- * (deallocated by a call to lfree).\r
- */\r
-\r
-void KINFree(void **kinmem)\r
-{\r
-  KINMem kin_mem;\r
-\r
-  if (*kinmem == NULL) return;\r
-\r
-  kin_mem = (KINMem) (*kinmem);\r
-  KINFreeVectors(kin_mem);\r
-\r
-  /* call lfree if non-NULL */\r
-\r
-  if (lfree != NULL) lfree(kin_mem);\r
-\r
-  free(*kinmem);\r
-  *kinmem = NULL;\r
-}\r
-\r
-/* \r
- * =================================================================\r
- * PRIVATE FUNCTIONS\r
- * =================================================================\r
- */\r
-\r
-/*\r
- * Function : KINCheckNvector\r
- *\r
- * This routine checks if all required vector operations are\r
- * implemented (excluding those required by KINConstraint). If all\r
- * necessary operations are present, then KINCheckNvector returns\r
- * TRUE. Otherwise, FALSE is returned.\r
- */\r
-\r
-static booleantype KINCheckNvector(N_Vector tmpl)\r
-{\r
-  if ((tmpl->ops->nvclone     == NULL) ||\r
-      (tmpl->ops->nvdestroy   == NULL) ||\r
-      (tmpl->ops->nvlinearsum == NULL) ||\r
-      (tmpl->ops->nvprod      == NULL) ||\r
-      (tmpl->ops->nvdiv       == NULL) ||\r
-      (tmpl->ops->nvscale     == NULL) ||\r
-      (tmpl->ops->nvabs       == NULL) ||\r
-      (tmpl->ops->nvinv       == NULL) ||\r
-      (tmpl->ops->nvmaxnorm   == NULL) ||\r
-      (tmpl->ops->nvmin       == NULL) ||\r
-      (tmpl->ops->nvwl2norm   == NULL)) return(FALSE);\r
-  else return(TRUE);\r
-}\r
-\r
-/* \r
- * -----------------------------------------------------------------\r
- * Memory allocation/deallocation\r
- * -----------------------------------------------------------------\r
- */\r
-\r
-/*\r
- * Function : KINAllocVectors\r
- *\r
- * This routine allocates the KINSol vectors. If all memory\r
- * allocations are successful, KINAllocVectors returns TRUE.\r
- * Otherwise all allocated memory is freed and KINAllocVectors\r
- * returns FALSE.\r
- */\r
-\r
-static booleantype KINAllocVectors(KINMem kin_mem, N_Vector tmpl)\r
-{\r
-  /* allocate unew, fval, pp, vtemp1 and vtemp2 */\r
-  \r
-  unew = NULL;\r
-  unew = N_VClone(tmpl);\r
-  if (unew == NULL) return(FALSE);\r
-\r
-  fval = NULL;\r
-  fval = N_VClone(tmpl);\r
-  if (fval == NULL) {\r
-    N_VDestroy(unew);\r
-    return(FALSE);\r
-  }\r
-\r
-  pp = NULL;\r
-  pp = N_VClone(tmpl);\r
-  if (pp == NULL) {\r
-    N_VDestroy(unew);\r
-    N_VDestroy(fval);\r
-    return(FALSE);\r
-  }\r
-\r
-  vtemp1 = NULL;\r
-  vtemp1 = N_VClone(tmpl);\r
-  if (vtemp1 == NULL) {\r
-    N_VDestroy(unew);\r
-    N_VDestroy(fval);\r
-    N_VDestroy(pp);\r
-    return(FALSE);\r
-  }\r
-\r
-  vtemp2 = NULL;\r
-  vtemp2 = N_VClone(tmpl);\r
-  if (vtemp2 == NULL) {\r
-    N_VDestroy(unew);\r
-    N_VDestroy(fval);\r
-    N_VDestroy(pp);\r
-    N_VDestroy(vtemp1);\r
-    return(FALSE);\r
-  }\r
-\r
-  /* update solver workspace lengths */\r
-\r
-  liw += 5*liw1;\r
-  lrw += 5*lrw1;\r
-\r
-  return(TRUE);\r
-}\r
-\r
-/*\r
- * KINFreeVectors\r
- *\r
- * This routine frees the KINSol vectors allocated by\r
- * KINAllocVectors.\r
- */\r
-\r
-static void KINFreeVectors(KINMem kin_mem)\r
-{\r
-  if (unew != NULL)   N_VDestroy(unew);\r
-  if (fval != NULL)   N_VDestroy(fval);\r
-  if (pp != NULL)     N_VDestroy(pp);\r
-  if (vtemp1 != NULL) N_VDestroy(vtemp1);\r
-  if (vtemp2 != NULL) N_VDestroy(vtemp2);\r
-\r
-  lrw -= 5*lrw1;\r
-  liw -= 5*liw1;\r
-\r
-  if (kin_mem->kin_constraintsSet) {\r
-    if (constraints != NULL) N_VDestroy(constraints);\r
-    lrw -= lrw1;\r
-    liw -= liw1;\r
-  }\r
-\r
-  return;\r
-}\r
-\r
-/* \r
- * -----------------------------------------------------------------\r
- * Initial setup\r
- * -----------------------------------------------------------------\r
- */\r
-\r
-/*\r
- * KINSolInit\r
- *\r
- * KINSolInit initializes the problem for the specific input\r
- * received in this call to KINSol (which calls KINSolInit). All\r
- * problem specification inputs are checked for errors. If any error\r
- * occurs during initialization, it is reported to the file whose\r
- * file pointer is errfp.\r
- *\r
- * The possible return values for KINSolInit are:\r
- *   KIN_SUCCESS : indicates a normal initialization\r
- *\r
- *   KINS_ILL_INPUT : indicates that an input error has been found\r
- *\r
- *   KIN_INITIAL_GUESS_OK : indicates that the guess uu\r
- *                          satisfied the system func(uu) = 0\r
- *                          within the tolerances specified\r
- */\r
-\r
-static int KINSolInit(KINMem kin_mem, int strategy)\r
-{\r
-  int retval;\r
-  realtype fmax;\r
-  \r
-  /* check for illegal input parameters */\r
-\r
-  if (uu == NULL) {\r
-    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_UU_NULL);\r
-    return(KIN_ILL_INPUT);\r
-  }\r
-\r
-  if ((strategy != KIN_NONE) && (strategy != KIN_LINESEARCH)) {\r
-    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_GLSTRAT);\r
-    return(KIN_ILL_INPUT);\r
-  }\r
-\r
-  if (uscale == NULL)  {\r
-    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_USCALE);\r
-    return(KIN_ILL_INPUT);\r
-  }\r
-\r
-  if (N_VMin(uscale) <= ZERO){\r
-    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_USCALE_NONPOSITIVE);\r
-    return(KIN_ILL_INPUT);\r
-  }\r
-\r
-  if (fscale == NULL)  {\r
-    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_FSCALE);\r
-    return(KIN_ILL_INPUT);\r
-  }\r
-\r
-  if (N_VMin(fscale) <= ZERO){\r
-    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_FSCALE_NONPOSITIVE);\r
-    return(KIN_ILL_INPUT);\r
-  }\r
-\r
-  /* set the constraints flag */\r
-\r
-  if (constraints == NULL) \r
-    constraintsSet = FALSE;\r
-  else {\r
-    constraintsSet = TRUE;\r
-    if ((constraints->ops->nvconstrmask  == NULL) ||\r
-       (constraints->ops->nvminquotient == NULL)) {\r
-      KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_NVECTOR);\r
-      return(KIN_ILL_INPUT);\r
-    }\r
-  }\r
-\r
-  /* check the initial guess uu against the constraints */\r
-\r
-  if (constraintsSet) {\r
-    if (!N_VConstrMask(constraints, uu, vtemp1)) {\r
-      KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_INITIAL_CNSTRNT);\r
-      return(KIN_ILL_INPUT);\r
-    }\r
-  }\r
-  \r
-  /* all error checking is complete at this point */\r
-\r
-  if (printfl > 0)\r
-    KINPrintInfo(kin_mem, PRNT_TOL, "KINSOL", "KINSolInit", INFO_TOL, scsteptol, fnormtol);\r
-\r
-  /* calculate the default value for mxnewtstep (maximum Newton step) */\r
-\r
-  if (mxnewtstep == ZERO)\r
-    mxnewtstep = THOUSAND * N_VWL2Norm(uu, uscale);\r
-  if (mxnewtstep < ONE) mxnewtstep = ONE;\r
-\r
-\r
-  /* additional set-up for inexact linear solvers */\r
-\r
-  if (inexact_ls) {\r
-\r
-    /* set up the coefficients for the eta calculation */\r
-\r
-    callForcingTerm = (etaflag != KIN_ETACONSTANT);\r
-\r
-    /* this value is always used for choice #1 */\r
-\r
-    if (etaflag == KIN_ETACHOICE1) ealpha = (ONE + RSqrt(FIVE)) * HALF;\r
-\r
-    /* initial value for eta set to 0.5 for other than the KIN_ETACONSTANT option */\r
-\r
-    if (etaflag != KIN_ETACONSTANT) eta = HALF;\r
-\r
-    /* disable residual monitoring if using an inexact linear solver */\r
-\r
-    noResMon = TRUE;\r
-\r
-  } else {\r
-\r
-    callForcingTerm = FALSE;\r
-\r
-  }\r
-\r
-  /* initialize counters */\r
-\r
-  nfe = nnilset = nnilset_sub = nni = nbcf = nbktrk = 0;\r
-\r
-  /* see if the system func(uu) = 0 is satisfied by the initial guess uu */\r
-\r
-  retval = func(uu, fval, f_data); nfe++;\r
-  if (retval < 0) {\r
-    KINProcessError(kin_mem, KIN_SYSFUNC_FAIL, "KINSOL", "KINSolInit", MSG_SYSFUNC_FAILED);\r
-    return(KIN_SYSFUNC_FAIL);\r
-  } else if (retval > 0) {\r
-    KINProcessError(kin_mem, KIN_FIRST_SYSFUNC_ERR, "KINSOL", "KINSolInit", MSG_SYSFUNC_FIRST);\r
-    return(KIN_FIRST_SYSFUNC_ERR);\r
-  }\r
-\r
-  fmax = KINScFNorm(kin_mem, fval, fscale);\r
-\r
-  if (printfl > 1)\r
-    KINPrintInfo(kin_mem, PRNT_FMAX, "KINSOL", "KINSolInit", INFO_FMAX, fmax);\r
-\r
-  if (fmax <= (POINT01 * fnormtol)) return(KIN_INITIAL_GUESS_OK);\r
-\r
-  /* initialize the linear solver if linit != NULL */\r
-\r
-  if (linit != NULL) {\r
-    retval = linit(kin_mem);\r
-    if (retval != 0) {\r
-      KINProcessError(kin_mem, KIN_LINIT_FAIL, "KINSOL", "KINSolInit", MSG_LINIT_FAIL);\r
-      return(KIN_LINIT_FAIL);\r
-    }\r
-  }\r
-\r
-  /* initialize the L2 (Euclidean) norms of f for the linear iteration steps */\r
-\r
-  fnorm = N_VWL2Norm(fval, fscale);\r
-  f1norm = HALF * fnorm * fnorm;\r
-\r
-  fnorm_sub = fnorm;\r
-\r
-  if (printfl > 0)\r
-    KINPrintInfo(kin_mem, PRNT_NNI, "KINSOL", "KINSolInit", INFO_NNI, nni, nfe, fnorm);\r
-\r
-  /* problem has now been successfully initialized */\r
-\r
-  return(KIN_SUCCESS);\r
-}\r
-\r
-/* \r
- * -----------------------------------------------------------------\r
- * Step functions\r
- * -----------------------------------------------------------------\r
- */\r
-\r
-/*\r
- * KINLinSolDrv\r
- *\r
- * This routine handles the process of solving for the approximate\r
- * solution of the Newton equations in the Newton iteration.\r
- * Subsequent routines handle the nonlinear aspects of its\r
- * application. \r
- */\r
-\r
-static int KINLinSolDrv(KINMem kin_mem)\r
-{\r
-  N_Vector x, b;\r
-  int retval;\r
-\r
-  if ((nni - nnilset) >= msbset) {\r
-    sthrsh = TWO;\r
-    update_fnorm_sub = TRUE;\r
-  }\r
-\r
-  loop{\r
-\r
-    jacCurrent = FALSE;\r
-\r
-    if ((sthrsh > ONEPT5) && setupNonNull) {\r
-      retval = lsetup(kin_mem);\r
-      jacCurrent = TRUE;\r
-      nnilset = nni;\r
-      nnilset_sub = nni;\r
-      if (retval != 0) return(KIN_LSETUP_FAIL);\r
-    }\r
-\r
-    /* rename vectors for readability */\r
-\r
-    b = unew;\r
-    x = pp;\r
-\r
-    /* load b with the current value of -fval */\r
-\r
-    N_VScale(-ONE, fval, b);\r
-\r
-    /* call the generic 'lsolve' routine to solve the system Jx = b */\r
-\r
-    retval = lsolve(kin_mem, x, b, &res_norm);\r
-\r
-    if (retval == 0)                          return(KIN_SUCCESS);\r
-    else if (retval < 0)                      return(KIN_LSOLVE_FAIL);\r
-    else if ((!setupNonNull) || (jacCurrent)) return(KIN_LINSOLV_NO_RECOVERY);\r
-\r
-    /* loop back only if the linear solver setup is in use and Jacobian information\r
-       is not current */\r
-\r
-    sthrsh = TWO;\r
-\r
-  }\r
-}\r
-\r
-/*\r
- * KINFullNewton\r
- *\r
- * This routine is the main driver for the Full Newton\r
- * algorithm. Its purpose is to compute unew = uu + pp in the\r
- * direction pp from uu, taking the full Newton step. The\r
- * step may be constrained if the constraint conditions are\r
- * violated, or if the norm of pp is greater than mxnewtstep. \r
- */\r
-\r
-static int KINFullNewton(KINMem kin_mem, realtype *fnormp, realtype *f1normp,\r
-                         booleantype *maxStepTaken)\r
-{\r
-  realtype pnorm, ratio;\r
-  booleantype fOK;\r
-  int ircvr, retval;\r
-\r
-  *maxStepTaken = FALSE;\r
-  pnorm = N_VWL2Norm(pp, uscale);\r
-  ratio = ONE;\r
-  if (pnorm > mxnewtstep) {\r
-    ratio = mxnewtstep / pnorm;\r
-    N_VScale(ratio, pp, pp);\r
-    pnorm = mxnewtstep;\r
-  }\r
-\r
-  if (printfl > 0)\r
-    KINPrintInfo(kin_mem, PRNT_PNORM, "KINSOL", "KINFullNewton", INFO_PNORM, pnorm);\r
-\r
-  /* If constraints are active, then constrain the step accordingly */\r
-\r
-  stepl = pnorm;\r
-  stepmul = ONE;\r
-  if (constraintsSet) {\r
-    retval = KINConstraint(kin_mem);\r
-    if (retval == CONSTR_VIOLATED) {\r
-      /* Apply stepmul set in KINConstraint */\r
-      ratio *= stepmul;\r
-      N_VScale(stepmul, pp, pp);\r
-      pnorm *= stepmul;\r
-      stepl = pnorm;\r
-      if (printfl > 0)\r
-        KINPrintInfo(kin_mem, PRNT_PNORM, "KINSOL", "KINFullNewton", INFO_PNORM, pnorm);\r
-      if (pnorm <= scsteptol) return(STEP_TOO_SMALL);\r
-    }\r
-  }\r
\r
-  /* Attempt (at most MAX_RECVR times) to evaluate function at the new iterate */\r
-  \r
-  fOK = FALSE;\r
-\r
-  for (ircvr = 1; ircvr <= MAX_RECVR; ircvr++) {\r
-\r
-    /* compute the iterate unew = uu + pp */\r
-    N_VLinearSum(ONE, uu, ONE, pp, unew);\r
-\r
-    /* evaluate func(unew) and its norm, and return */\r
-    retval = func(unew, fval, f_data); nfe++;\r
-\r
-    /* if func was successful, accept pp */\r
-    if (retval == 0) {fOK = TRUE; break;}\r
-\r
-    /* if func failed unrecoverably, give up */\r
-    else if (retval < 0) return(KIN_SYSFUNC_FAIL);\r
-\r
-    /* func failed recoverably; cut step in half and try again */\r
-    ratio *= HALF;\r
-    N_VScale(HALF, pp, pp);\r
-    pnorm *= HALF;\r
-    stepl = pnorm;\r
-  }\r
-\r
-  /* If func() failed recoverably MAX_RECVR times, give up */\r
-\r
-  if (!fOK) return(KIN_REPTD_SYSFUNC_ERR);\r
-\r
-  /* Evaluate function norms */\r
-\r
-  *fnormp = N_VWL2Norm(fval,fscale);\r
-  *f1normp = HALF * (*fnormp) * (*fnormp);\r
-\r
-  /* scale sfdotJp and sJpnorm by ratio for later use in KINForcingTerm */\r
-\r
-  sfdotJp *= ratio;\r
-  sJpnorm *= ratio;\r
\r
-  if (printfl > 1) \r
-    KINPrintInfo(kin_mem, PRNT_FNORM, "KINSOL", "KINFullNewton", INFO_FNORM, *fnormp);\r
-\r
-  if (pnorm > (POINT99 * mxnewtstep)) *maxStepTaken = TRUE; \r
-\r
-  return(KIN_SUCCESS);\r
-}\r
-\r
-/*\r
- * KINLineSearch\r
- *\r
- * The routine KINLineSearch implements the LineSearch algorithm.\r
- * Its purpose is to find unew = uu + rl * pp in the direction pp\r
- * from uu so that:\r
- *                                    t\r
- *  func(unew) <= func(uu) + alpha * g  (unew - uu) (alpha = 1.e-4)\r
- *\r
- *    and\r
- *                                   t\r
- *  func(unew) >= func(uu) + beta * g  (unew - uu) (beta = 0.9)\r
- *\r
- * where 0 < rlmin <= rl <= rlmax.\r
- *\r
- * Note:\r
- *             mxnewtstep\r
- *  rlmax = ----------------   if uu+pp is feasible\r
- *          ||uscale*pp||_L2\r
- *\r
- *  rlmax = 1   otherwise\r
- *\r
- *    and\r
- *\r
- *                 scsteptol\r
- *  rlmin = --------------------------\r
- *          ||           pp         ||\r
- *          || -------------------- ||_L-infinity\r
- *          || (1/uscale + ABS(uu)) ||\r
- *\r
- *\r
- * If the system function fails unrecoverably at any time, KINLineSearch \r
- * returns KIN_SYSFUNC_FAIL which will halt the solver.\r
- *\r
- * We attempt to corect recoverable system function failures only before \r
- * the alpha-condition loop; i.e. when the solution is updated with the \r
- * full Newton step (possibly reduced due to constraint violations). \r
- * Once we find a feasible pp, we assume that any update up to pp is\r
- * feasible.\r
- * \r
- * If the step size is limited due to constraint violations and/or \r
- * recoverable system function failures, we set rlmax=1 to ensure\r
- * that the update remains feasible during the attempts to enforce \r
- * the beta-condition (this is not an isse while enforcing the alpha\r
- * condition, as rl can only decrease from 1 at that stage)\r
- */\r
-\r
-static int KINLineSearch(KINMem kin_mem, realtype *fnormp, realtype *f1normp,\r
-                         booleantype *maxStepTaken)\r
-{\r
-  realtype pnorm, ratio, slpi, rlmin, rlength, rl, rlmax, rldiff;\r
-  realtype rltmp, rlprev, pt1trl, f1nprv, rllo, rlinc, alpha, beta;\r
-  realtype alpha_cond, beta_cond, rl_a, tmp1, rl_b, tmp2, disc;\r
-  int ircvr, nbktrk_l, retval;\r
-  booleantype firstBacktrack, fOK;\r
-\r
-  /* Initializations */\r
-\r
-  nbktrk_l = 0;          /* local backtracking counter */\r
-  ratio    = ONE;        /* step change ratio          */\r
-  alpha    = POINT0001;\r
-  beta     = POINT9;\r
-\r
-  firstBacktrack = TRUE;\r
-  *maxStepTaken = FALSE;\r
-\r
-  rlprev = f1nprv = ZERO;\r
-\r
-  /* Compute length of Newton step */\r
-\r
-  pnorm = N_VWL2Norm(pp, uscale);\r
-  rlmax = mxnewtstep / pnorm;\r
-  stepl = pnorm;\r
-\r
-  /* If the full Newton step is too large, set it to the maximum allowable value */\r
-\r
-  if(pnorm > mxnewtstep ) {\r
-    ratio = mxnewtstep / pnorm;\r
-    N_VScale(ratio, pp, pp);\r
-    pnorm = mxnewtstep;\r
-    rlmax = ONE;\r
-    stepl = pnorm;\r
-  }\r
-\r
-  /* If constraint checking is activated, check and correct violations */\r
-\r
-  stepmul = ONE;\r
-\r
-  if(constraintsSet){\r
-    retval = KINConstraint(kin_mem);\r
-    if(retval == CONSTR_VIOLATED){\r
-      /* Apply stepmul set in KINConstraint */\r
-      N_VScale(stepmul, pp, pp);\r
-      ratio *= stepmul;\r
-      pnorm *= stepmul;\r
-      rlmax = ONE;\r
-      stepl = pnorm;\r
-      if (printfl > 0) KINPrintInfo(kin_mem, PRNT_PNORM1, "KINSOL", "KINLineSearch", INFO_PNORM1, pnorm);\r
-      if (pnorm <= scsteptol) return(STEP_TOO_SMALL);\r
-    }\r
-  }\r
-\r
-  /* Attempt (at most MAX_RECVR times) to evaluate function at the new iterate */\r
-  \r
-  fOK = FALSE;\r
-\r
-  for (ircvr = 1; ircvr <= MAX_RECVR; ircvr++) {\r
-\r
-    /* compute the iterate unew = uu + pp */\r
-    N_VLinearSum(ONE, uu, ONE, pp, unew);\r
-\r
-    /* evaluate func(unew) and its norm, and return */\r
-    retval = func(unew, fval, f_data); nfe++;\r
-\r
-    /* if func was successful, accept pp */\r
-    if (retval == 0) {fOK = TRUE; break;}\r
-\r
-    /* if func failed unrecoverably, give up */\r
-    else if (retval < 0) return(KIN_SYSFUNC_FAIL);\r
-\r
-    /* func failed recoverably; cut step in half and try again */\r
-    N_VScale(HALF, pp, pp);\r
-    ratio *= HALF;\r
-    pnorm *= HALF;\r
-    rlmax = ONE;\r
-    stepl = pnorm;\r
-\r
-  }\r
-\r
-  /* If func() failed recoverably MAX_RECVR times, give up */\r
-\r
-  if (!fOK) return(KIN_REPTD_SYSFUNC_ERR);\r
-\r
-  /* Evaluate function norms */\r
-\r
-  *fnormp = N_VWL2Norm(fval, fscale);\r
-  *f1normp = HALF * (*fnormp) * (*fnormp) ;\r
-\r
-  /* Estimate the line search value rl (lambda) to satisfy both ALPHA and BETA conditions */\r
-\r
-  slpi = sfdotJp * ratio;\r
-  rlength = KINScSNorm(kin_mem, pp, uu);\r
-  rlmin = scsteptol / rlength;\r
-  rl = ONE;\r
-\r
-  if (printfl > 2)\r
-    KINPrintInfo(kin_mem, PRNT_LAM, "KINSOL", "KINLineSearch", INFO_LAM, rlmin, f1norm, pnorm);\r
-\r
-  /* Loop until the ALPHA condition is satisfied. Terminate if rl becomes too small */\r
-\r
-  loop {\r
-    \r
-    /* Evaluate test quantity */\r
-\r
-    alpha_cond = f1norm + (alpha * slpi * rl);\r
-\r
-    if (printfl > 2)\r
-      KINPrintInfo(kin_mem, PRNT_ALPHA, "KINSOL", "KINLinesearch", \r
-                   INFO_ALPHA, *fnormp, *f1normp, alpha_cond, rl);\r
-\r
-    /* If ALPHA condition is satisfied, break out from loop */\r
-\r
-    if ((*f1normp) <= alpha_cond) break;\r
-\r
-    /* Backtracking. Use quadratic fit the first time and cubic fit afterwards. */\r
-\r
-    if (firstBacktrack) {\r
-\r
-      rltmp = -slpi / (TWO * ((*f1normp) - f1norm - slpi));\r
-      firstBacktrack = FALSE;\r
-\r
-    } else {\r
-\r
-      tmp1 = (*f1normp) - f1norm - (rl * slpi);\r
-      tmp2 = f1nprv - f1norm - (rlprev * slpi);\r
-      rl_a = ((ONE / (rl * rl)) * tmp1) - ((ONE / (rlprev * rlprev)) * tmp2);\r
-      rl_b = ((-rlprev / (rl * rl)) * tmp1) + ((rl / (rlprev * rlprev)) * tmp2);\r
-      tmp1 = ONE / (rl - rlprev);\r
-      rl_a *= tmp1;\r
-      rl_b *= tmp1;\r
-      disc = (rl_b * rl_b) - (THREE * rl_a * slpi);\r
-\r
-      if (ABS(rl_a) < uround) {        /* cubic is actually just a quadratic (rl_a ~ 0) */\r
-        rltmp = -slpi / (TWO * rl_b);\r
-      } else {                         /* real cubic */\r
-        rltmp = (-rl_b + RSqrt(disc)) / (THREE * rl_a);\r
-      }\r
-\r
-      if (rltmp > (HALF * rl)) rltmp = HALF * rl;\r
-\r
-    }\r
-\r
-    /* Set new rl (do not allow a reduction by a factor larger than 10) */\r
-\r
-    rlprev = rl;\r
-    f1nprv = (*f1normp);\r
-    pt1trl = POINT1 * rl;\r
-    rl = MAX(pt1trl, rltmp);\r
-    nbktrk_l++;\r
-\r
-    /* Update unew and re-evaluate function */\r
-\r
-    N_VLinearSum(ONE, uu, rl, pp, unew);\r
-\r
-    retval = func(unew, fval, f_data); nfe++;\r
-    if (retval != 0) return(KIN_SYSFUNC_FAIL);\r
-\r
-    *fnormp = N_VWL2Norm(fval, fscale);\r
-    *f1normp = HALF * (*fnormp) * (*fnormp) ;\r
-\r
-    /* Check if rl (lambda) is too small */\r
-\r
-    if (rl < rlmin) {\r
-      /* unew sufficiently distinct from uu cannot be found.\r
-         copy uu into unew (step remains unchanged) and \r
-         return STEP_TOO_SMALL */\r
-      N_VScale(ONE, uu, unew);\r
-      return(STEP_TOO_SMALL);\r
-    }\r
-\r
-  } /* end ALPHA condition loop */\r
-\r
-\r
-  /* ALPHA condition is satisfied. Now check the BETA condition */\r
-\r
-  beta_cond = f1norm + (beta * slpi * rl);\r
-\r
-  if ((*f1normp) < beta_cond) {\r
-\r
-    /* BETA condition not satisfied */\r
-\r
-    if ((rl == ONE) && (pnorm < mxnewtstep)) {\r
-\r
-      do {\r
-\r
-        rlprev = rl;\r
-        f1nprv = *f1normp;\r
-        rl = MIN((TWO * rl), rlmax);\r
-        nbktrk_l++;\r
-\r
-        N_VLinearSum(ONE, uu, rl, pp, unew);\r
-        retval = func(unew, fval, f_data); nfe++;\r
-        if (retval != 0) return(KIN_SYSFUNC_FAIL);\r
-        *fnormp = N_VWL2Norm(fval, fscale);\r
-        *f1normp = HALF * (*fnormp) * (*fnormp);\r
-\r
-        alpha_cond = f1norm + (alpha * slpi * rl);\r
-        beta_cond = f1norm + (beta * slpi * rl);\r
-\r
-        if (printfl > 2)\r
-          KINPrintInfo(kin_mem, PRNT_BETA, "KINSOL", "KINLineSearch", \r
-                       INFO_BETA, *f1normp, beta_cond, rl);\r
-\r
-      } while (((*f1normp) <= alpha_cond) && \r
-              ((*f1normp) < beta_cond) && (rl < rlmax));\r
-\r
-    } /* enf if (rl == ONE) block */\r
-\r
-    if ((rl < ONE) || ((rl > ONE) && (*f1normp > alpha_cond))) {\r
-\r
-      rllo = MIN(rl, rlprev);\r
-      rldiff = ABS(rlprev - rl);\r
-\r
-      do {\r
-\r
-        rlinc = HALF * rldiff;\r
-        rl = rllo + rlinc;\r
-        nbktrk_l++;\r
-\r
-        N_VLinearSum(ONE, uu, rl, pp, unew);\r
-        retval = func(unew, fval, f_data); nfe++;\r
-        if (retval != 0) return(KIN_SYSFUNC_FAIL);\r
-        *fnormp = N_VWL2Norm(fval, fscale);\r
-        *f1normp = HALF * (*fnormp) * (*fnormp);\r
-\r
-        alpha_cond = f1norm + (alpha * slpi * rl);\r
-        beta_cond = f1norm + (beta * slpi * rl);\r
-\r
-        if (printfl > 2)\r
-          KINPrintInfo(kin_mem, PRNT_ALPHABETA, "KINSOL", "KINLineSearch", \r
-                       INFO_ALPHABETA, *f1normp, alpha_cond, beta_cond, rl);\r
-\r
-        if ((*f1normp) > alpha_cond) rldiff = rlinc;\r
-        else if (*f1normp < beta_cond) {\r
-          rllo = rl;\r
-          rldiff = rldiff - rlinc;\r
-        }\r
-\r
-      } while ((*f1normp > alpha_cond) ||\r
-              ((*f1normp < beta_cond) && (rldiff >= rlmin)));\r
-\r
-      if ((*f1normp) < beta_cond) {\r
-\r
-       /* beta condition could not be satisfied so set unew to last u value\r
-          that satisfied the alpha condition and continue */\r
-\r
-        N_VLinearSum(ONE, uu, rllo, pp, unew);\r
-        retval = func(unew, fval, f_data); nfe++;\r
-        if (retval != 0) return(KIN_SYSFUNC_FAIL);\r
-        *fnormp = N_VWL2Norm(fval, fscale);\r
-        *f1normp = HALF * (*fnormp) * (*fnormp);   \r
-\r
-       /* increment beta-condition failures counter */\r
-\r
-        nbcf++;\r
-\r
-      }\r
-\r
-    }  /* end of if (rl < ONE) block */\r
-\r
-  }  /* end of if (f1normp < beta_cond) block */\r
-\r
-  /* Update number of backtracking operations */\r
-\r
-  nbktrk += nbktrk_l;\r
-\r
-  if (printfl > 1)\r
-    KINPrintInfo(kin_mem, PRNT_ADJ, "KINSOL", "KINLineSearch", INFO_ADJ, nbktrk_l);\r
-\r
-  /* scale sfdotJp and sJpnorm by rl * ratio for later use in KINForcingTerm */\r
-\r
-  sfdotJp = sfdotJp * rl * ratio;\r
-  sJpnorm = sJpnorm * rl * ratio;\r
-\r
-  if ((rl * pnorm) > (POINT99 * mxnewtstep)) *maxStepTaken = TRUE;\r
-\r
-  return(KIN_SUCCESS);\r
-}\r
-\r
-/*\r
- * Function : KINConstraint\r
- *\r
- * This routine checks if the proposed solution vector uu + pp\r
- * violates any constraints. If a constraint is violated, then the\r
- * scalar stepmul is determined such that uu + stepmul * pp does\r
- * not violate any constraints.\r
- *\r
- * Note: This routine is called by the functions\r
- *       KINLineSearch and KINFullNewton.\r
- */\r
-\r
-static int KINConstraint(KINMem kin_mem)\r
-{\r
-  N_VLinearSum(ONE, uu, ONE, pp, vtemp1);\r
-\r
-  /* if vtemp1[i] violates constraint[i] then vtemp2[i] = 1\r
-     else vtemp2[i] = 0 (vtemp2 is the mask vector) */\r
-\r
-  if(N_VConstrMask(constraints, vtemp1, vtemp2)) return(KIN_SUCCESS);\r
-\r
-  /* vtemp1[i] = ABS(pp[i]) */\r
-\r
-  N_VAbs(pp, vtemp1);\r
-\r
-  /* consider vtemp1[i] only if vtemp2[i] = 1 (constraint violated) */\r
-\r
-  N_VProd(vtemp2, vtemp1, vtemp1);\r
-\r
-  N_VAbs(uu, vtemp2);\r
-  stepmul = POINT9 * N_VMinQuotient(vtemp2, vtemp1);\r
-\r
-  return(CONSTR_VIOLATED);\r
-}\r
-\r
-/*\r
- * -----------------------------------------------------------------\r
- * Stopping tests\r
- * -----------------------------------------------------------------\r
- */\r
-\r
-/*\r
- * KINStop\r
- *\r
- * This routine checks the current iterate unew to see if the\r
- * system func(unew) = 0 is satisfied by a variety of tests.\r
- *\r
- * strategy is one of KIN_NONE or KIN_LINESEARCH\r
- * sflag    is one of KIN_SUCCESS, STEP_TOO_SMALL\r
- */\r
-\r
-static int KINStop(KINMem kin_mem, int strategy, booleantype maxStepTaken, int sflag)\r
-{\r
-  realtype fmax, rlength;\r
-  N_Vector delta;\r
-\r
-  /* Check for too small a step */\r
-\r
-  if (sflag == STEP_TOO_SMALL) {\r
-\r
-    if (setupNonNull && !jacCurrent) {\r
-      /* If the Jacobian is out of date, update it and retry */\r
-      sthrsh = TWO;\r
-      return(CONTINUE_ITERATIONS);\r
-    } else {\r
-      /* Give up */\r
-      if (strategy == KIN_NONE)  return(KIN_STEP_LT_STPTOL);\r
-      else                       return(KIN_LINESEARCH_NONCONV);\r
-    }\r
-\r
-  }\r
-\r
-  /* Check tolerance on scaled function norm at the current iterate */\r
-\r
-  fmax = KINScFNorm(kin_mem, fval, fscale);\r
-\r
-  if (printfl > 1) \r
-    KINPrintInfo(kin_mem, PRNT_FMAX, "KINSOL", "KINStop", INFO_FMAX, fmax);\r
-\r
-  if (fmax <= fnormtol) return(KIN_SUCCESS);\r
-\r
-  /* Check if the scaled distance between the last two steps is too small */\r
-  /* NOTE: pp used as work space to store this distance */\r
-\r
-  delta = pp;\r
-  N_VLinearSum(ONE, unew, -ONE, uu, delta);\r
-  rlength = KINScSNorm(kin_mem, delta, unew);\r
-\r
-  if (rlength <= scsteptol) {\r
-\r
-    if (setupNonNull && !jacCurrent) {\r
-      /* If the Jacobian is out of date, update it and retry */\r
-      sthrsh = TWO;\r
-      return(CONTINUE_ITERATIONS);\r
-    } else {\r
-      /* give up */\r
-      return(KIN_STEP_LT_STPTOL);\r
-    }\r
-\r
-  }\r
-\r
-  /* Check if the maximum number of iterations is reached */\r
-\r
-  if (nni >= mxiter) return(KIN_MAXITER_REACHED);\r
-\r
-  /* Check for consecutive number of steps taken of size mxnewtstep\r
-     and if not maxStepTaken, then set ncscmx to 0 */\r
\r
-  if (maxStepTaken) ncscmx++;\r
-  else              ncscmx = 0;\r
\r
-  if (ncscmx == 5) return(KIN_MXNEWT_5X_EXCEEDED);\r
-\r
-  /* Proceed according to the type of linear solver used */\r
-\r
-  if (inexact_ls) {\r
-\r
-    /* We're doing inexact Newton.\r
-       Load threshold for reevaluating the Jacobian. */\r
-\r
-    sthrsh = rlength;\r
-\r
-  } else if (!noResMon) {\r
-\r
-    /* We're doing modified Newton and the user did not disable residual monitoring.\r
-       Check if it is time to monitor residual. */\r
-\r
-    if ((nni - nnilset_sub) >= msbset_sub) {\r
-\r
-      /* Residual monitoring needed */\r
-\r
-      nnilset_sub = nni;\r
-\r
-      /* If OMEGA is still zero at this point, estimate it */\r
-      if (omega == ZERO)\r
-        omega = MIN(omega_min*EXP(MAX(ZERO,(fnorm/fnormtol)-ONE)), omega_max);\r
-\r
-      /* Check if making satisfactory progress */\r
-\r
-      if (fnorm > omega*fnorm_sub) {\r
-        /* Insuficient progress */\r
-       if (setupNonNull && !jacCurrent) {\r
-          /* If the Jacobian is out of date, update it and retry */\r
-         sthrsh = TWO;\r
-         return(RETRY_ITERATION);\r
-       } else {\r
-          /* Otherwise, we cannot do anything, so just return. */\r
-        }\r
-      } else {\r
-        /* Sufficient progress */\r
-       fnorm_sub = fnorm;\r
-       sthrsh = ONE;\r
-      }\r
-\r
-    } else {\r
-\r
-      /* Residual monitoring not needed */\r
-\r
-      /* Reset sthrsh */\r
-      if (retry_nni || update_fnorm_sub) fnorm_sub = fnorm;\r
-      if (update_fnorm_sub) update_fnorm_sub = FALSE;\r
-      sthrsh = ONE;\r
-\r
-    }\r
-\r
-  }\r
-\r
-  /* if made it to here, then the iteration process is not finished\r
-     so return CONTINUE_ITERATIONS flag */\r
-\r
-  return(CONTINUE_ITERATIONS);\r
-}\r
-\r
-/*\r
- * KINForcingTerm\r
- *\r
- * This routine computes eta, the scaling factor in the linear\r
- * convergence stopping tolerance eps when choice #1 or choice #2\r
- * forcing terms are used. Eta is computed here for all but the\r
- * first iterative step, which is set to the default in routine\r
- * KINSolInit.\r
- *\r
- * This routine was written by Homer Walker of Utah State\r
- * University with subsequent modifications by Allan Taylor @ LLNL.\r
- *\r
- * It is based on the concepts of the paper 'Choosing the forcing\r
- * terms in an inexact Newton method', SIAM J Sci Comput, 17\r
- * (1996), pp 16 - 32, or Utah State University Research Report\r
- * 6/94/75 of the same title.\r
- */\r
-\r
-static void KINForcingTerm(KINMem kin_mem, realtype fnormp)\r
-{\r
-  realtype eta_max, eta_min, eta_safe, linmodel_norm;\r
-\r
-  eta_max  = POINT9;\r
-  eta_min  = POINT0001;\r
-  eta_safe = HALF;\r
-\r
-  /* choice #1 forcing term */\r
-\r
-  if (etaflag == KIN_ETACHOICE1) {\r
-\r
-    /* compute the norm of f + Jp , scaled L2 norm */\r
-\r
-    linmodel_norm = RSqrt((fnorm * fnorm) + (TWO * sfdotJp) + (sJpnorm * sJpnorm));\r
-\r
-    /* form the safeguarded for choice #1 */ \r
-\r
-    eta_safe = RPowerR(eta, ealpha); \r
-    eta = ABS(fnormp - linmodel_norm) / fnorm; \r
-  }\r
-\r
-  /* choice #2 forcing term */\r
-\r
-  if (etaflag == KIN_ETACHOICE2) {\r
-    eta_safe = egamma * RPowerR(eta, ealpha); \r
-    eta = egamma * RPowerR((fnormp / fnorm), ealpha); \r
-  }\r
-\r
-  /* apply safeguards */\r
\r
-  if(eta_safe < POINT1) eta_safe = ZERO;\r
-  eta = MAX(eta, eta_safe); \r
-  eta = MAX(eta, eta_min); \r
-  eta = MIN(eta, eta_max); \r
-\r
-  return; \r
-}\r
-\r
-\r
-/*\r
- * -----------------------------------------------------------------\r
- * Norm functions\r
- * -----------------------------------------------------------------\r
- */\r
-\r
-/*\r
- * Function : KINScFNorm\r
- *\r
- * This routine computes the max norm for scaled vectors. The\r
- * scaling vector is scale, and the vector of which the norm is to\r
- * be determined is vv. The returned value, fnormval, is the\r
- * resulting scaled vector norm. This routine uses N_Vector\r
- * functions from the vector module.\r
- */\r
-\r
-static realtype KINScFNorm(KINMem kin_mem, N_Vector v, N_Vector scale)\r
-{\r
-  N_VProd(scale, v, vtemp1);\r
-  return(N_VMaxNorm(vtemp1));\r
-}\r
-\r
-/*\r
- * Function : KINScSNorm\r
- *\r
- * This routine computes the max norm of the scaled steplength, ss.\r
- * Here ucur is the current step and usc is the u scale factor.\r
- */\r
-\r
-static realtype KINScSNorm(KINMem kin_mem, N_Vector v, N_Vector u)\r
-{\r
-  realtype length;\r
-\r
-  N_VInv(uscale, vtemp1);\r
-  N_VAbs(u, vtemp2);\r
-  N_VLinearSum(ONE, vtemp1, ONE, vtemp2, vtemp1);\r
-  N_VDiv(v, vtemp1, vtemp1);\r
-\r
-  length = N_VMaxNorm(vtemp1);\r
-\r
-  return(length);\r
-}\r
-\r
-/* \r
- * =================================================================\r
- * KINSOL Verbose output functions\r
- * =================================================================\r
- */\r
-\r
-/* \r
- * KINPrintInfo\r
- *\r
- * KINPrintInfo is a high level error handling function\r
- * Based on the value info_code, it composes the info message and\r
- * passes it to the info handler function.\r
- */\r
-\r
-#define ihfun    (kin_mem->kin_ihfun)\r
-#define ih_data  (kin_mem->kin_ih_data)\r
-\r
-void KINPrintInfo(KINMem kin_mem, \r
-                  int info_code, const char *module, const char *fname, \r
-                  const char *msgfmt, ...)\r
-{\r
-  va_list ap;\r
-  char msg[256], msg1[40];\r
-  char retstr[30];\r
-  int ret;\r
-\r
-  /* Initialize argument processing \r
-   (msgfrmt is the last required argument) */\r
-\r
-  va_start(ap, msgfmt); \r
-\r
-  if (info_code == PRNT_RETVAL) {\r
-\r
-    /* If info_code = PRNT_RETVAL, decode the numeric value */\r
-\r
-    ret = va_arg(ap, int);\r
-\r
-    switch(ret) {\r
-    case KIN_SUCCESS:\r
-      sprintf(retstr, "KIN_SUCCESS");\r
-      break;\r
-    case KIN_STEP_LT_STPTOL:\r
-      sprintf(retstr, "KIN_STEP_LT_STPTOL");\r
-      break;\r
-    case KIN_LINESEARCH_NONCONV:\r
-      sprintf(retstr, "KIN_LINESEARCH_NONCONV");\r
-      break;\r
-    case KIN_LINESEARCH_BCFAIL:\r
-      sprintf(retstr, "KIN_LINESEARCH_BCFAIL");\r
-      break;\r
-    case KIN_MAXITER_REACHED:\r
-      sprintf(retstr, "KIN_MAXITER_REACHED");\r
-      break;\r
-    case KIN_MXNEWT_5X_EXCEEDED:\r
-      sprintf(retstr, "KIN_MXNEWT_5X_EXCEEDED");\r
-      break;\r
-    case KIN_LINSOLV_NO_RECOVERY:\r
-      sprintf(retstr, "KIN_LINSOLV_NO_RECOVERY");\r
-      break;\r
-    case KIN_LSETUP_FAIL:\r
-      sprintf(retstr, "KIN_PRECONDSET_FAILURE");\r
-      break;\r
-    case KIN_LSOLVE_FAIL:\r
-      sprintf(retstr, "KIN_PRECONDSOLVE_FAILURE");\r
-      break;\r
-    }\r
-\r
-    /* Compose the message */\r
-\r
-    sprintf(msg1, msgfmt, ret);\r
-    sprintf(msg,"%s (%s)",msg1,retstr);\r
-\r
-\r
-  } else {\r
-  \r
-    /* Compose the message */\r
-\r
-    vsprintf(msg, msgfmt, ap);\r
-\r
-  }\r
-\r
-  /* call the info message handler */\r
-\r
-  ihfun(module, fname, msg, ih_data);\r
-\r
-  /* finalize argument processing */\r
-\r
-  va_end(ap);\r
-\r
-  return;\r
-}\r
-\r
-\r
-/*\r
- * KINInfoHandler \r
- *\r
- * This is the default KINSOL info handling function.\r
- * It sends the info message to the stream pointed to by kin_infofp \r
- */\r
-\r
-#define infofp (kin_mem->kin_infofp)\r
-\r
-void KINInfoHandler(const char *module, const char *function, \r
-                    char *msg, void *data)\r
-{\r
-  KINMem kin_mem;\r
-\r
-  /* data points to kin_mem here */\r
-\r
-  kin_mem = (KINMem) data;\r
-\r
-\r
-#ifndef NO_FPRINTF_OUTPUT\r
-  fprintf(infofp,"\n[%s] %s\n",module, function);\r
-  fprintf(infofp,"   %s\n",msg);\r
-#endif  \r
-\r
-}\r
-\r
-/* \r
- * =================================================================\r
- * KINSOL Error Handling functions\r
- * =================================================================\r
- */\r
-\r
-/* \r
- * KINProcessError \r
- *\r
- * Thi is a high level error handling function\r
- * - if cv_mem==NULL it prints the error message to stderr\r
- * - otherwise, it sets-up and calls the error hadling function \r
- *   pointed to by cv_ehfun\r
- */\r
-\r
-#define ehfun    (kin_mem->kin_ehfun)\r
-#define eh_data  (kin_mem->kin_eh_data)\r
-\r
-void KINProcessError(KINMem kin_mem, \r
-                    int error_code, const char *module, const char *fname, \r
-                    const char *msgfmt, ...)\r
-{\r
-  va_list ap;\r
-  char msg[256];\r
-\r
-  /* Initialize the argument pointer variable \r
-     (msgfmt is the last required argument to KINProcessError) */\r
-\r
-  va_start(ap, msgfmt);\r
-\r
-  if (kin_mem == NULL) {    /* We write to stderr */\r
-\r
-#ifndef NO_FPRINTF_OUTPUT\r
-    fprintf(stderr, "\n[%s ERROR]  %s\n  ", module, fname);\r
-    fprintf(stderr, msgfmt);\r
-    fprintf(stderr, "\n\n");\r
-#endif\r
-\r
-  } else {                 /* We can call ehfun */\r
-\r
-    /* Compose the message */\r
-\r
-    vsprintf(msg, msgfmt, ap);\r
-\r
-    /* Call ehfun */\r
-\r
-    ehfun(error_code, module, fname, msg, eh_data);\r
-\r
-  }\r
-\r
-  /* Finalize argument processing */\r
-  \r
-  va_end(ap);\r
-\r
-  return;\r
-\r
-}\r
-\r
-/* \r
- * KINErrHandler \r
- *\r
- * This is the default error handling function.\r
- * It sends the error message to the stream pointed to by kin_errfp \r
- */\r
-\r
-#define errfp    (kin_mem->kin_errfp)\r
-\r
-void KINErrHandler(int error_code, const char *module,\r
-                   const char *function, char *msg, void *data)\r
-{\r
-  KINMem kin_mem;\r
-  char err_type[10];\r
-\r
-  /* data points to kin_mem here */\r
-\r
-  kin_mem = (KINMem) data;\r
-\r
-  if (error_code == KIN_WARNING)\r
-    sprintf(err_type,"WARNING");\r
-  else\r
-    sprintf(err_type,"ERROR");\r
-\r
-#ifndef NO_FPRINTF_OUTPUT\r
-  if (errfp!=NULL) {\r
-    fprintf(errfp,"\n[%s %s]  %s\n",module,err_type,function);\r
-    fprintf(errfp,"  %s\n\n",msg);\r
-  }\r
-#endif\r
-\r
-  return;\r
-}\r
-\r
-\r
-\0\r
-\0
\ No newline at end of file
+/*
+ * -----------------------------------------------------------------
+ * $Revision: 1.1 $
+ * $Date: 2006/07/05 15:32:36 $
+ * -----------------------------------------------------------------
+ * Programmer(s): Allan Taylor, 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 main KINSol solver.
+ * It is independent of the KINSol linear solver in use.
+ * -----------------------------------------------------------------
+ *
+ * EXPORTED FUNCTIONS
+ * ------------------
+ *   Creation and allocation functions
+ *     KINCreate
+ *     KINMalloc
+ *   Main solver function
+ *     KINSol
+ *   Deallocation function
+ *     KINFree
+ *
+ * PRIVATE FUNCTIONS
+ * -----------------
+ *     KINCheckNvector
+ *   Memory allocation/deallocation
+ *     KINAllocVectors
+ *     KINFreeVectors
+ *   Initial setup
+ *     KINSolInit
+ *   Step functions
+ *     KINLinSolDrv
+ *     KINFullNewton
+ *     KINLineSearch
+ *     KINConstraint
+ *   Stopping tests
+ *     KINStop
+ *     KINForcingTerm
+ *   Norm functions
+ *     KINScFNorm
+ *     KINScSNorm
+ *   KINSOL Verbose output functions
+ *     KINPrintInfo
+ *     KINInfoHandler
+ *   KINSOL Error Handling functions
+ *     KINProcessError
+ *     KINErrHandler
+ * -----------------------------------------------------------------
+ */
+
+/* 
+ * =================================================================
+ * IMPORTED HEADER FILES
+ * =================================================================
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <math.h>
+
+#include "kinsol_impl.h"
+#include <sundials/sundials_math.h>
+
+/* 
+ * =================================================================
+ * MACRO DEFINITIONS
+ * =================================================================
+ */
+
+/* Macro: loop */
+#define loop for(;;)
+
+/* 
+ * =================================================================
+ * KINSOL PRIVATE CONSTANTS
+ * =================================================================
+ */
+
+#define HALF      RCONST(0.5)
+#define ZERO      RCONST(0.0)
+#define ONE       RCONST(1.0)
+#define ONEPT5    RCONST(1.5)
+#define TWO       RCONST(2.0)
+#define THREE     RCONST(3.0)
+#define FIVE      RCONST(5.0)
+#define POINT1    RCONST(0.1)
+#define POINT01   RCONST(0.01)
+#define POINT99   RCONST(0.99)
+#define THOUSAND  RCONST(1000.0)
+#define ONETHIRD  RCONST(0.3333333333333333)
+#define TWOTHIRDS RCONST(0.6666666666666667)
+#define POINT9    RCONST(0.9)
+#define POINT0001 RCONST(0.0001)
+
+/* 
+ * =================================================================
+ * KINSOL ROUTINE-SPECIFIC CONSTANTS
+ * =================================================================
+ */
+
+/* 
+ * Control constants for lower-level functions used by KINSol 
+ * ----------------------------------------------------------
+ *
+ * KINStop return value requesting more iterations
+ *    RETRY_ITERATION
+ *    CONTINUE_ITERATIONS
+ *
+ * KINFullNewton and KINLineSearch return values:
+ *    KIN_SUCCESS
+ *    KIN_SYSFUNC_FAIL
+ *    STEP_TOO_SMALL
+ *
+ * KINConstraint return values:
+ *    KIN_SUCCESS
+ *    CONSTR_VIOLATED
+ */
+
+#define RETRY_ITERATION     -998
+#define CONTINUE_ITERATIONS -999
+#define STEP_TOO_SMALL      -997
+#define CONSTR_VIOLATED     -996
+
+/*
+ * Algorithmic constants
+ * ---------------------
+ *
+ * MAX_RECVR   max. no. of attempts to correct a recoverable func error
+ */
+
+#define MAX_RECVR      5
+
+/*
+ * Keys for KINPrintInfo
+ * ---------------------
+ */
+
+#define PRNT_RETVAL     1
+#define PRNT_NNI        2
+#define PRNT_TOL        3
+#define PRNT_FMAX       4
+#define PRNT_PNORM      5
+#define PRNT_PNORM1     6
+#define PRNT_FNORM      7
+#define PRNT_LAM        8
+#define PRNT_ALPHA      9
+#define PRNT_BETA      10
+#define PRNT_ALPHABETA 11
+#define PRNT_ADJ       12
+
+/* 
+ * =================================================================
+ * PRIVATE FUNCTION PROTOTYPES
+ * =================================================================
+ */
+
+static booleantype KINCheckNvector(N_Vector tmpl);
+static booleantype KINAllocVectors(KINMem kin_mem, N_Vector tmpl);
+static int KINSolInit(KINMem kin_mem, int strategy);
+static int KINConstraint(KINMem kin_mem );
+static void KINForcingTerm(KINMem kin_mem, realtype fnormp);
+static void KINFreeVectors(KINMem kin_mem);
+
+static int  KINFullNewton(KINMem kin_mem, realtype *fnormp, 
+                          realtype *f1normp, booleantype *maxStepTaken);
+static int  KINLineSearch(KINMem kin_mem, realtype *fnormp, 
+                          realtype *f1normp, booleantype *maxStepTaken);
+
+static int  KINLinSolDrv(KINMem kinmem);
+static realtype KINScFNorm(KINMem kin_mem, N_Vector v, N_Vector scale);
+static realtype KINScSNorm(KINMem kin_mem, N_Vector v, N_Vector u);
+static int KINStop(KINMem kin_mem, int strategy, booleantype maxStepTaken, int sflag);
+
+/* 
+ * =================================================================
+ * EXPORTED FUNCTIONS IMPLEMENTATION
+ * =================================================================
+ */
+
+/* 
+ * -----------------------------------------------------------------
+ * Creation and allocation functions
+ * -----------------------------------------------------------------
+ */
+
+/*
+ * Function : KINCreate
+ *
+ * KINCreate creates an internal memory block for a problem to 
+ * be solved by KINSOL. If successful, KINCreate returns a pointer
+ * to the problem memory. This pointer should be passed to
+ * KINMalloc. If an initialization error occurs, KINCreate prints
+ * an error message to standard error and returns NULL. 
+ */
+
+void *KINCreate(void)
+{
+  KINMem kin_mem;
+  realtype uround;
+
+  kin_mem = NULL;
+  kin_mem = (KINMem) malloc(sizeof(struct KINMemRec));
+  if (kin_mem == NULL) {
+    KINProcessError(kin_mem, 0, "KINSOL", "KINCreate", MSG_MEM_FAIL);
+    return(NULL);
+  }
+
+  /* set uround (unit roundoff) */
+
+  kin_mem->kin_uround = uround = UNIT_ROUNDOFF;
+  
+  /* set default values for solver optional inputs */
+
+  kin_mem->kin_func             = NULL;
+  kin_mem->kin_f_data           = NULL;
+  kin_mem->kin_constraints      = NULL;
+  kin_mem->kin_uscale           = NULL;
+  kin_mem->kin_fscale           = NULL;
+  kin_mem->kin_constraintsSet   = FALSE;
+  kin_mem->kin_ehfun            = KINErrHandler;
+  kin_mem->kin_eh_data          = (void *) kin_mem;
+  kin_mem->kin_errfp            = stderr;
+  kin_mem->kin_ihfun            = KINInfoHandler;
+  kin_mem->kin_ih_data          = (void *) kin_mem;
+  kin_mem->kin_infofp           = stdout;
+  kin_mem->kin_printfl          = PRINTFL_DEFAULT;
+  kin_mem->kin_mxiter           = MXITER_DEFAULT;
+  kin_mem->kin_noInitSetup      = FALSE;
+  kin_mem->kin_msbset           = MSBSET_DEFAULT;
+  kin_mem->kin_noResMon         = FALSE;
+  kin_mem->kin_msbset_sub       = MSBSET_SUB_DEFAULT;
+  kin_mem->kin_update_fnorm_sub = FALSE;
+  kin_mem->kin_mxnbcf           = MXNBCF_DEFAULT;
+  kin_mem->kin_sthrsh           = TWO;
+  kin_mem->kin_noMinEps         = FALSE;
+  kin_mem->kin_mxnewtstep       = ZERO;
+  kin_mem->kin_sqrt_relfunc     = RSqrt(uround);
+  kin_mem->kin_scsteptol        = RPowerR(uround,TWOTHIRDS);
+  kin_mem->kin_fnormtol         = RPowerR(uround,ONETHIRD);
+  kin_mem->kin_etaflag          = KIN_ETACHOICE1;
+  kin_mem->kin_eta              = POINT1;     /* default for KIN_ETACONSTANT */
+  kin_mem->kin_eta_alpha        = TWO;        /* default for KIN_ETACHOICE2  */
+  kin_mem->kin_eta_gamma        = POINT9;     /* default for KIN_ETACHOICE2  */
+  kin_mem->kin_MallocDone       = FALSE;
+  kin_mem->kin_setupNonNull     = FALSE;
+  kin_mem->kin_omega            = ZERO;       /* default to using min / max  */
+  kin_mem->kin_omega_min        = OMEGA_MIN;
+  kin_mem->kin_omega_max        = OMEGA_MAX;
+
+  /* initialize lrw and liw */
+
+  kin_mem->kin_lrw = 17;
+  kin_mem->kin_liw = 22;
+
+  /* NOTE: needed since KINMalloc could be called after KINSetConstraints */
+
+  kin_mem->kin_lrw1 = 0;
+  kin_mem->kin_liw1 = 0;
+
+  return((void *) kin_mem);
+}
+
+#define errfp (kin_mem->kin_errfp)
+#define liw   (kin_mem->kin_liw)
+#define lrw   (kin_mem->kin_lrw)
+
+/*
+ * Function : KINMalloc
+ *
+ * KINMalloc allocates memory for a problem or execution of KINSol. 
+ * If memory is successfully allocated, KIN_SUCCESS is returned.
+ * Otherwise, an error message is printed and an error flag
+ * returned.
+ */
+
+int KINMalloc(void *kinmem, KINSysFn func, N_Vector tmpl)
+{
+  long int liw1, lrw1;
+  KINMem kin_mem;
+  booleantype allocOK, nvectorOK;
+  
+  /* check kinmem */
+
+  if (kinmem == NULL) {
+    KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINMalloc", MSG_NO_MEM);
+    return(KIN_MEM_NULL);
+  }
+  kin_mem = (KINMem) kinmem;
+
+  if (func == NULL) {
+    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINMalloc", MSG_FUNC_NULL);
+    return(KIN_ILL_INPUT);
+  }
+
+  /* check if all required vector operations are implemented */
+
+  nvectorOK = KINCheckNvector(tmpl);
+  if (!nvectorOK) {
+    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINMalloc", MSG_BAD_NVECTOR);
+    return(KIN_ILL_INPUT);
+  }
+
+  /* set space requirements for one N_Vector */
+
+  if (tmpl->ops->nvspace != NULL) {
+    N_VSpace(tmpl, &lrw1, &liw1);
+    kin_mem->kin_lrw1 = lrw1;
+    kin_mem->kin_liw1 = liw1;
+  }
+  else {
+    kin_mem->kin_lrw1 = 0;
+    kin_mem->kin_liw1 = 0;
+  }
+
+  /* allocate necessary vectors */
+
+  allocOK = KINAllocVectors(kin_mem, tmpl);
+  if (!allocOK) {
+    KINProcessError(kin_mem, KIN_MEM_FAIL, "KINSOL", "KINMalloc", MSG_MEM_FAIL);
+    free(kin_mem); kin_mem = NULL;
+    return(KIN_MEM_FAIL);
+  }
+
+  /* copy the input parameter into KINSol state */
+
+  kin_mem->kin_func = func;
+
+  /* set the linear solver addresses to NULL */
+
+  kin_mem->kin_linit  = NULL;
+  kin_mem->kin_lsetup = NULL;
+  kin_mem->kin_lsolve = NULL;
+  kin_mem->kin_lfree  = NULL;
+  kin_mem->kin_lmem   = NULL;
+  
+  /* problem memory has been successfully allocated */
+
+  kin_mem->kin_MallocDone = TRUE;
+
+  return(KIN_SUCCESS);
+}
+
+/*
+ * -----------------------------------------------------------------
+ * Readability constants
+ * -----------------------------------------------------------------
+ */
+
+#define func             (kin_mem->kin_func)
+#define f_data           (kin_mem->kin_f_data)
+#define printfl          (kin_mem->kin_printfl)
+#define mxiter           (kin_mem->kin_mxiter)
+#define noInitSetup      (kin_mem->kin_noInitSetup)
+#define retry_nni        (kin_mem->kin_retry_nni)
+#define msbset           (kin_mem->kin_msbset)
+#define etaflag          (kin_mem->kin_etaflag)
+#define eta              (kin_mem->kin_eta)
+#define ealpha           (kin_mem->kin_eta_alpha)
+#define egamma           (kin_mem->kin_eta_gamma)
+#define noMinEps         (kin_mem->kin_noMinEps)
+#define mxnewtstep       (kin_mem->kin_mxnewtstep)
+#define mxnbcf           (kin_mem->kin_mxnbcf)
+#define relfunc          (kin_mem->kin_sqrt_relfunc)
+#define fnormtol         (kin_mem->kin_fnormtol)
+#define scsteptol        (kin_mem->kin_scsteptol)
+#define constraints      (kin_mem->kin_constraints)
+
+#define uround           (kin_mem->kin_uround)
+#define nni              (kin_mem->kin_nni)
+#define nfe              (kin_mem->kin_nfe)
+#define nbcf             (kin_mem->kin_nbcf)  
+#define nbktrk           (kin_mem->kin_nbktrk)
+#define ncscmx           (kin_mem->kin_ncscmx)
+#define stepl            (kin_mem->kin_stepl)
+#define stepmul          (kin_mem->kin_stepmul)
+#define sthrsh           (kin_mem->kin_sthrsh)
+#define linit            (kin_mem->kin_linit)
+#define lsetup           (kin_mem->kin_lsetup)
+#define lsolve           (kin_mem->kin_lsolve) 
+#define lfree            (kin_mem->kin_lfree)
+#define constraintsSet   (kin_mem->kin_constraintsSet) 
+#define jacCurrent       (kin_mem->kin_jacCurrent)          
+#define nnilset          (kin_mem->kin_nnilset)
+#define lmem             (kin_mem->kin_lmem)        
+#define inexact_ls       (kin_mem->kin_inexact_ls)
+#define setupNonNull     (kin_mem->kin_setupNonNull)
+#define fval             (kin_mem->kin_fval)      
+#define fnorm            (kin_mem->kin_fnorm)
+#define f1norm           (kin_mem->kin_f1norm)
+#define etaflag          (kin_mem->kin_etaflag)
+#define callForcingTerm  (kin_mem->kin_callForcingTerm)
+#define uu               (kin_mem->kin_uu)
+#define uscale           (kin_mem->kin_uscale)
+#define fscale           (kin_mem->kin_fscale)
+#define sJpnorm          (kin_mem->kin_sJpnorm)
+#define sfdotJp          (kin_mem->kin_sfdotJp)
+#define unew             (kin_mem->kin_unew)
+#define pp               (kin_mem->kin_pp)
+#define vtemp1           (kin_mem->kin_vtemp1)
+#define vtemp2           (kin_mem->kin_vtemp2)
+#define eps              (kin_mem->kin_eps)
+#define res_norm         (kin_mem->kin_res_norm)
+#define liw1             (kin_mem->kin_liw1)
+#define lrw1             (kin_mem->kin_lrw1)
+
+#define noResMon         (kin_mem->kin_noResMon)
+#define fnorm_sub        (kin_mem->kin_fnorm_sub)
+#define msbset_sub       (kin_mem->kin_msbset_sub)
+#define nnilset_sub      (kin_mem->kin_nnilset_sub)
+#define update_fnorm_sub (kin_mem->kin_update_fnorm_sub)
+#define omega            (kin_mem->kin_omega)
+#define omega_min        (kin_mem->kin_omega_min)
+#define omega_max        (kin_mem->kin_omega_max)
+
+/* 
+ * -----------------------------------------------------------------
+ * Main solver function
+ * -----------------------------------------------------------------
+ */
+
+/*
+ * Function : KINSol
+ *
+ * KINSol (main KINSOL driver routine) manages the computational
+ * process of computing an approximate solution of the nonlinear
+ * system F(uu) = 0. The KINSol routine calls the following
+ * subroutines:
+ *
+ *  KINSolInit    checks if initial guess satisfies user-supplied
+ *                constraints and initializes linear solver
+ *
+ *  KINLinSolDrv  interfaces with linear solver to find a
+ *                solution of the system J(uu)*x = b (calculate
+ *                Newton step)
+ *
+ *  KINFullNewton/KINLineSearch  implement the global strategy
+ *
+ *  KINForcingTerm  computes the forcing term (eta)
+ *
+ *  KINStop  determines if an approximate solution has been found
+ */
+
+int KINSol(void *kinmem, N_Vector u, int strategy,  
+           N_Vector u_scale, N_Vector f_scale)
+{
+  realtype fnormp, f1normp, epsmin;
+  KINMem kin_mem;
+  int ret, sflag;
+  booleantype maxStepTaken;
+
+  /* intialize to avoid compiler warning messages */
+
+  maxStepTaken = FALSE;
+  f1normp = fnormp = -ONE;
+
+  /* initialize epsmin to avoid compiler warning message */
+
+  epsmin = ZERO;
+
+  /* check for kinmem non-NULL */
+
+  if (kinmem == NULL) {
+    KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSol", MSG_NO_MEM);
+    return(KIN_MEM_NULL);
+  }
+  kin_mem = (KINMem) kinmem;
+
+  if(kin_mem->kin_MallocDone == FALSE) {
+    KINProcessError(NULL, KIN_NO_MALLOC, "KINSOL", "KINSol", MSG_NO_MALLOC);    
+    return(KIN_NO_MALLOC);
+  }
+
+  /* load input arguments */
+
+  uu = u;
+  uscale = u_scale;
+  fscale = f_scale;
+
+  /* initialize solver */
+
+  ret = KINSolInit(kin_mem, strategy);
+  if (ret != KIN_SUCCESS) return(ret);
+  
+  ncscmx = 0;
+
+  /* Note: The following logic allows the choice of whether or not
+     to force a call to the linear solver setup upon a given call to
+     KINSol */
+
+  if (noInitSetup) sthrsh = ONE;
+  else             sthrsh = TWO;
+
+  /* if eps is to be bounded from below, set the bound */
+
+  if (inexact_ls && !noMinEps) epsmin = POINT01 * fnormtol;
+
+  loop{
+
+    retry_nni = FALSE;
+
+    nni++;
+
+    /* calculate the epsilon (stopping criteria for iterative linear solver)
+       for this iteration based on eta from the routine KINForcingTerm */
+
+    if (inexact_ls) {
+      eps = (eta + uround) * fnorm;
+      if(!noMinEps) eps = MAX(epsmin, eps);
+    }
+
+    repeat_nni:
+
+    /* call KINLinSolDrv to calculate the (approximate) Newton step, pp */ 
+
+    ret = KINLinSolDrv(kin_mem);
+    if (ret != KIN_SUCCESS) break;
+
+    /* call the appropriate routine to calculate an acceptable step pp */
+
+    sflag = 0;
+
+    if (strategy == KIN_NONE) {
+
+      /* Full Newton Step*/
+      sflag = KINFullNewton(kin_mem, &fnormp, &f1normp, &maxStepTaken);
+
+      /* if sysfunc failed unrecoverably, stop */
+      if ((sflag == KIN_SYSFUNC_FAIL) || (sflag == KIN_REPTD_SYSFUNC_ERR)) {
+        ret = sflag;
+        break;
+      }
+
+    } else if (strategy == KIN_LINESEARCH) {
+
+      /* Line Search */
+      sflag = KINLineSearch(kin_mem, &fnormp, &f1normp, &maxStepTaken);
+
+      /* if sysfunc failed unrecoverably, stop */
+      if (sflag == KIN_SYSFUNC_FAIL) {
+        ret = sflag;
+        break;
+      }
+
+      /* if too many beta condition failures, then stop iteration */
+      if (nbcf > mxnbcf) {
+        ret = KIN_LINESEARCH_BCFAIL;
+        break;
+      }
+
+    }
+
+    /* evaluate eta by calling the forcing term routine */
+
+    if (callForcingTerm) KINForcingTerm(kin_mem, fnormp);
+
+    fnorm = fnormp;
+
+    /* call KINStop to check if tolerances where met by this iteration */
+
+    ret = KINStop(kin_mem, strategy, maxStepTaken, sflag); 
+
+    if (ret == RETRY_ITERATION) {
+      retry_nni = TRUE;
+      goto repeat_nni;
+    }
+
+    /* update uu after the iteration */
+
+    N_VScale(ONE, unew, uu);
+
+    f1norm = f1normp;
+
+    /* print the current nni, fnorm, and nfe values if printfl > 0 */
+
+    if (printfl>0)
+      KINPrintInfo(kin_mem, PRNT_NNI, "KINSOL", "KINSol", INFO_NNI, nni, nfe, fnorm);
+
+    if (ret != CONTINUE_ITERATIONS) break; 
+
+    fflush(errfp);
+    
+  }  /* end of loop; return */
+
+  if (printfl > 0)
+    KINPrintInfo(kin_mem, PRNT_RETVAL, "KINSOL", "KINSol", INFO_RETVAL, ret);
+
+  switch(ret) {
+  case KIN_SYSFUNC_FAIL:
+    KINProcessError(kin_mem, KIN_SYSFUNC_FAIL, "KINSOL", "KINSol", MSG_SYSFUNC_FAILED);
+    break;
+  case KIN_REPTD_SYSFUNC_ERR:
+    KINProcessError(kin_mem, KIN_REPTD_SYSFUNC_ERR, "KINSOL", "KINSol", MSG_SYSFUNC_REPTD);
+    break;
+  case KIN_LSETUP_FAIL:
+    KINProcessError(kin_mem, KIN_LSETUP_FAIL, "KINSOL", "KINSol", MSG_LSETUP_FAILED);
+    break;
+  case KIN_LSOLVE_FAIL:
+    KINProcessError(kin_mem, KIN_LSOLVE_FAIL, "KINSOL", "KINSol", MSG_LSOLVE_FAILED);
+    break;
+  case KIN_LINSOLV_NO_RECOVERY:
+    KINProcessError(kin_mem, KIN_LINSOLV_NO_RECOVERY, "KINSOL", "KINSol", MSG_LINSOLV_NO_RECOVERY);
+    break;
+  case KIN_LINESEARCH_NONCONV:
+    KINProcessError(kin_mem, KIN_LINESEARCH_NONCONV, "KINSOL", "KINSol", MSG_LINESEARCH_NONCONV);
+    break;
+  case KIN_LINESEARCH_BCFAIL:
+    KINProcessError(kin_mem, KIN_LINESEARCH_BCFAIL, "KINSOL", "KINSol", MSG_LINESEARCH_BCFAIL);
+    break;
+  case KIN_MAXITER_REACHED:
+    KINProcessError(kin_mem, KIN_MAXITER_REACHED, "KINSOL", "KINSol", MSG_MAXITER_REACHED);
+    break;
+  case KIN_MXNEWT_5X_EXCEEDED:
+    KINProcessError(kin_mem, KIN_MXNEWT_5X_EXCEEDED, "KINSOL", "KINSol", MSG_MXNEWT_5X_EXCEEDED);
+    break;
+  }
+  
+  return(ret);
+}
+
+/* 
+ * -----------------------------------------------------------------
+ * Deallocation function
+ * -----------------------------------------------------------------
+ */
+
+/*
+ * Function : KINFree
+ *
+ * This routine frees the problem memory allocated by KINMalloc.
+ * Such memory includes all the vectors allocated by
+ * KINAllocVectors, and the memory lmem for the linear solver
+ * (deallocated by a call to lfree).
+ */
+
+void KINFree(void **kinmem)
+{
+  KINMem kin_mem;
+
+  if (*kinmem == NULL) return;
+
+  kin_mem = (KINMem) (*kinmem);
+  KINFreeVectors(kin_mem);
+
+  /* call lfree if non-NULL */
+
+  if (lfree != NULL) lfree(kin_mem);
+
+  free(*kinmem);
+  *kinmem = NULL;
+}
+
+/* 
+ * =================================================================
+ * PRIVATE FUNCTIONS
+ * =================================================================
+ */
+
+/*
+ * Function : KINCheckNvector
+ *
+ * This routine checks if all required vector operations are
+ * implemented (excluding those required by KINConstraint). If all
+ * necessary operations are present, then KINCheckNvector returns
+ * TRUE. Otherwise, FALSE is returned.
+ */
+
+static booleantype KINCheckNvector(N_Vector tmpl)
+{
+  if ((tmpl->ops->nvclone     == NULL) ||
+      (tmpl->ops->nvdestroy   == NULL) ||
+      (tmpl->ops->nvlinearsum == NULL) ||
+      (tmpl->ops->nvprod      == NULL) ||
+      (tmpl->ops->nvdiv       == NULL) ||
+      (tmpl->ops->nvscale     == NULL) ||
+      (tmpl->ops->nvabs       == NULL) ||
+      (tmpl->ops->nvinv       == NULL) ||
+      (tmpl->ops->nvmaxnorm   == NULL) ||
+      (tmpl->ops->nvmin       == NULL) ||
+      (tmpl->ops->nvwl2norm   == NULL)) return(FALSE);
+  else return(TRUE);
+}
+
+/* 
+ * -----------------------------------------------------------------
+ * Memory allocation/deallocation
+ * -----------------------------------------------------------------
+ */
+
+/*
+ * Function : KINAllocVectors
+ *
+ * This routine allocates the KINSol vectors. If all memory
+ * allocations are successful, KINAllocVectors returns TRUE.
+ * Otherwise all allocated memory is freed and KINAllocVectors
+ * returns FALSE.
+ */
+
+static booleantype KINAllocVectors(KINMem kin_mem, N_Vector tmpl)
+{
+  /* allocate unew, fval, pp, vtemp1 and vtemp2 */
+  
+  unew = NULL;
+  unew = N_VClone(tmpl);
+  if (unew == NULL) return(FALSE);
+
+  fval = NULL;
+  fval = N_VClone(tmpl);
+  if (fval == NULL) {
+    N_VDestroy(unew);
+    return(FALSE);
+  }
+
+  pp = NULL;
+  pp = N_VClone(tmpl);
+  if (pp == NULL) {
+    N_VDestroy(unew);
+    N_VDestroy(fval);
+    return(FALSE);
+  }
+
+  vtemp1 = NULL;
+  vtemp1 = N_VClone(tmpl);
+  if (vtemp1 == NULL) {
+    N_VDestroy(unew);
+    N_VDestroy(fval);
+    N_VDestroy(pp);
+    return(FALSE);
+  }
+
+  vtemp2 = NULL;
+  vtemp2 = N_VClone(tmpl);
+  if (vtemp2 == NULL) {
+    N_VDestroy(unew);
+    N_VDestroy(fval);
+    N_VDestroy(pp);
+    N_VDestroy(vtemp1);
+    return(FALSE);
+  }
+
+  /* update solver workspace lengths */
+
+  liw += 5*liw1;
+  lrw += 5*lrw1;
+
+  return(TRUE);
+}
+
+/*
+ * KINFreeVectors
+ *
+ * This routine frees the KINSol vectors allocated by
+ * KINAllocVectors.
+ */
+
+static void KINFreeVectors(KINMem kin_mem)
+{
+  if (unew != NULL)   N_VDestroy(unew);
+  if (fval != NULL)   N_VDestroy(fval);
+  if (pp != NULL)     N_VDestroy(pp);
+  if (vtemp1 != NULL) N_VDestroy(vtemp1);
+  if (vtemp2 != NULL) N_VDestroy(vtemp2);
+
+  lrw -= 5*lrw1;
+  liw -= 5*liw1;
+
+  if (kin_mem->kin_constraintsSet) {
+    if (constraints != NULL) N_VDestroy(constraints);
+    lrw -= lrw1;
+    liw -= liw1;
+  }
+
+  return;
+}
+
+/* 
+ * -----------------------------------------------------------------
+ * Initial setup
+ * -----------------------------------------------------------------
+ */
+
+/*
+ * KINSolInit
+ *
+ * KINSolInit initializes the problem for the specific input
+ * received in this call to KINSol (which calls KINSolInit). All
+ * problem specification inputs are checked for errors. If any error
+ * occurs during initialization, it is reported to the file whose
+ * file pointer is errfp.
+ *
+ * The possible return values for KINSolInit are:
+ *   KIN_SUCCESS : indicates a normal initialization
+ *
+ *   KINS_ILL_INPUT : indicates that an input error has been found
+ *
+ *   KIN_INITIAL_GUESS_OK : indicates that the guess uu
+ *                          satisfied the system func(uu) = 0
+ *                          within the tolerances specified
+ */
+
+static int KINSolInit(KINMem kin_mem, int strategy)
+{
+  int retval;
+  realtype fmax;
+  
+  /* check for illegal input parameters */
+
+  if (uu == NULL) {
+    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_UU_NULL);
+    return(KIN_ILL_INPUT);
+  }
+
+  if ((strategy != KIN_NONE) && (strategy != KIN_LINESEARCH)) {
+    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_GLSTRAT);
+    return(KIN_ILL_INPUT);
+  }
+
+  if (uscale == NULL)  {
+    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_USCALE);
+    return(KIN_ILL_INPUT);
+  }
+
+  if (N_VMin(uscale) <= ZERO){
+    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_USCALE_NONPOSITIVE);
+    return(KIN_ILL_INPUT);
+  }
+
+  if (fscale == NULL)  {
+    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_FSCALE);
+    return(KIN_ILL_INPUT);
+  }
+
+  if (N_VMin(fscale) <= ZERO){
+    KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_FSCALE_NONPOSITIVE);
+    return(KIN_ILL_INPUT);
+  }
+
+  /* set the constraints flag */
+
+  if (constraints == NULL) 
+    constraintsSet = FALSE;
+  else {
+    constraintsSet = TRUE;
+    if ((constraints->ops->nvconstrmask  == NULL) ||
+       (constraints->ops->nvminquotient == NULL)) {
+      KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_NVECTOR);
+      return(KIN_ILL_INPUT);
+    }
+  }
+
+  /* check the initial guess uu against the constraints */
+
+  if (constraintsSet) {
+    if (!N_VConstrMask(constraints, uu, vtemp1)) {
+      KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_INITIAL_CNSTRNT);
+      return(KIN_ILL_INPUT);
+    }
+  }
+  
+  /* all error checking is complete at this point */
+
+  if (printfl > 0)
+    KINPrintInfo(kin_mem, PRNT_TOL, "KINSOL", "KINSolInit", INFO_TOL, scsteptol, fnormtol);
+
+  /* calculate the default value for mxnewtstep (maximum Newton step) */
+
+  if (mxnewtstep == ZERO)
+    mxnewtstep = THOUSAND * N_VWL2Norm(uu, uscale);
+  if (mxnewtstep < ONE) mxnewtstep = ONE;
+
+
+  /* additional set-up for inexact linear solvers */
+
+  if (inexact_ls) {
+
+    /* set up the coefficients for the eta calculation */
+
+    callForcingTerm = (etaflag != KIN_ETACONSTANT);
+
+    /* this value is always used for choice #1 */
+
+    if (etaflag == KIN_ETACHOICE1) ealpha = (ONE + RSqrt(FIVE)) * HALF;
+
+    /* initial value for eta set to 0.5 for other than the KIN_ETACONSTANT option */
+
+    if (etaflag != KIN_ETACONSTANT) eta = HALF;
+
+    /* disable residual monitoring if using an inexact linear solver */
+
+    noResMon = TRUE;
+
+  } else {
+
+    callForcingTerm = FALSE;
+
+  }
+
+  /* initialize counters */
+
+  nfe = nnilset = nnilset_sub = nni = nbcf = nbktrk = 0;
+
+  /* see if the system func(uu) = 0 is satisfied by the initial guess uu */
+
+  retval = func(uu, fval, f_data); nfe++;
+  if (retval < 0) {
+    KINProcessError(kin_mem, KIN_SYSFUNC_FAIL, "KINSOL", "KINSolInit", MSG_SYSFUNC_FAILED);
+    return(KIN_SYSFUNC_FAIL);
+  } else if (retval > 0) {
+    KINProcessError(kin_mem, KIN_FIRST_SYSFUNC_ERR, "KINSOL", "KINSolInit", MSG_SYSFUNC_FIRST);
+    return(KIN_FIRST_SYSFUNC_ERR);
+  }
+
+  fmax = KINScFNorm(kin_mem, fval, fscale);
+
+  if (printfl > 1)
+    KINPrintInfo(kin_mem, PRNT_FMAX, "KINSOL", "KINSolInit", INFO_FMAX, fmax);
+
+  if (fmax <= (POINT01 * fnormtol)) return(KIN_INITIAL_GUESS_OK);
+
+  /* initialize the linear solver if linit != NULL */
+
+  if (linit != NULL) {
+    retval = linit(kin_mem);
+    if (retval != 0) {
+      KINProcessError(kin_mem, KIN_LINIT_FAIL, "KINSOL", "KINSolInit", MSG_LINIT_FAIL);
+      return(KIN_LINIT_FAIL);
+    }
+  }
+
+  /* initialize the L2 (Euclidean) norms of f for the linear iteration steps */
+
+  fnorm = N_VWL2Norm(fval, fscale);
+  f1norm = HALF * fnorm * fnorm;
+
+  fnorm_sub = fnorm;
+
+  if (printfl > 0)
+    KINPrintInfo(kin_mem, PRNT_NNI, "KINSOL", "KINSolInit", INFO_NNI, nni, nfe, fnorm);
+
+  /* problem has now been successfully initialized */
+
+  return(KIN_SUCCESS);
+}
+
+/* 
+ * -----------------------------------------------------------------
+ * Step functions
+ * -----------------------------------------------------------------
+ */
+
+/*
+ * KINLinSolDrv
+ *
+ * This routine handles the process of solving for the approximate
+ * solution of the Newton equations in the Newton iteration.
+ * Subsequent routines handle the nonlinear aspects of its
+ * application. 
+ */
+
+static int KINLinSolDrv(KINMem kin_mem)
+{
+  N_Vector x, b;
+  int retval;
+
+  if ((nni - nnilset) >= msbset) {
+    sthrsh = TWO;
+    update_fnorm_sub = TRUE;
+  }
+
+  loop{
+
+    jacCurrent = FALSE;
+
+    if ((sthrsh > ONEPT5) && setupNonNull) {
+      retval = lsetup(kin_mem);
+      jacCurrent = TRUE;
+      nnilset = nni;
+      nnilset_sub = nni;
+      if (retval != 0) return(KIN_LSETUP_FAIL);
+    }
+
+    /* rename vectors for readability */
+
+    b = unew;
+    x = pp;
+
+    /* load b with the current value of -fval */
+
+    N_VScale(-ONE, fval, b);
+
+    /* call the generic 'lsolve' routine to solve the system Jx = b */
+
+    retval = lsolve(kin_mem, x, b, &res_norm);
+
+    if (retval == 0)                          return(KIN_SUCCESS);
+    else if (retval < 0)                      return(KIN_LSOLVE_FAIL);
+    else if ((!setupNonNull) || (jacCurrent)) return(KIN_LINSOLV_NO_RECOVERY);
+
+    /* loop back only if the linear solver setup is in use and Jacobian information
+       is not current */
+
+    sthrsh = TWO;
+
+  }
+}
+
+/*
+ * KINFullNewton
+ *
+ * This routine is the main driver for the Full Newton
+ * algorithm. Its purpose is to compute unew = uu + pp in the
+ * direction pp from uu, taking the full Newton step. The
+ * step may be constrained if the constraint conditions are
+ * violated, or if the norm of pp is greater than mxnewtstep. 
+ */
+
+static int KINFullNewton(KINMem kin_mem, realtype *fnormp, realtype *f1normp,
+                         booleantype *maxStepTaken)
+{
+  realtype pnorm, ratio;
+  booleantype fOK;
+  int ircvr, retval;
+
+  *maxStepTaken = FALSE;
+  pnorm = N_VWL2Norm(pp, uscale);
+  ratio = ONE;
+  if (pnorm > mxnewtstep) {
+    ratio = mxnewtstep / pnorm;
+    N_VScale(ratio, pp, pp);
+    pnorm = mxnewtstep;
+  }
+
+  if (printfl > 0)
+    KINPrintInfo(kin_mem, PRNT_PNORM, "KINSOL", "KINFullNewton", INFO_PNORM, pnorm);
+
+  /* If constraints are active, then constrain the step accordingly */
+
+  stepl = pnorm;
+  stepmul = ONE;
+  if (constraintsSet) {
+    retval = KINConstraint(kin_mem);
+    if (retval == CONSTR_VIOLATED) {
+      /* Apply stepmul set in KINConstraint */
+      ratio *= stepmul;
+      N_VScale(stepmul, pp, pp);
+      pnorm *= stepmul;
+      stepl = pnorm;
+      if (printfl > 0)
+        KINPrintInfo(kin_mem, PRNT_PNORM, "KINSOL", "KINFullNewton", INFO_PNORM, pnorm);
+      if (pnorm <= scsteptol) return(STEP_TOO_SMALL);
+    }
+  }
+  /* Attempt (at most MAX_RECVR times) to evaluate function at the new iterate */
+  
+  fOK = FALSE;
+
+  for (ircvr = 1; ircvr <= MAX_RECVR; ircvr++) {
+
+    /* compute the iterate unew = uu + pp */
+    N_VLinearSum(ONE, uu, ONE, pp, unew);
+
+    /* evaluate func(unew) and its norm, and return */
+    retval = func(unew, fval, f_data); nfe++;
+
+    /* if func was successful, accept pp */
+    if (retval == 0) {fOK = TRUE; break;}
+
+    /* if func failed unrecoverably, give up */
+    else if (retval < 0) return(KIN_SYSFUNC_FAIL);
+
+    /* func failed recoverably; cut step in half and try again */
+    ratio *= HALF;
+    N_VScale(HALF, pp, pp);
+    pnorm *= HALF;
+    stepl = pnorm;
+  }
+
+  /* If func() failed recoverably MAX_RECVR times, give up */
+
+  if (!fOK) return(KIN_REPTD_SYSFUNC_ERR);
+
+  /* Evaluate function norms */
+
+  *fnormp = N_VWL2Norm(fval,fscale);
+  *f1normp = HALF * (*fnormp) * (*fnormp);
+
+  /* scale sfdotJp and sJpnorm by ratio for later use in KINForcingTerm */
+
+  sfdotJp *= ratio;
+  sJpnorm *= ratio;
+  if (printfl > 1) 
+    KINPrintInfo(kin_mem, PRNT_FNORM, "KINSOL", "KINFullNewton", INFO_FNORM, *fnormp);
+
+  if (pnorm > (POINT99 * mxnewtstep)) *maxStepTaken = TRUE; 
+
+  return(KIN_SUCCESS);
+}
+
+/*
+ * KINLineSearch
+ *
+ * The routine KINLineSearch implements the LineSearch algorithm.
+ * Its purpose is to find unew = uu + rl * pp in the direction pp
+ * from uu so that:
+ *                                    t
+ *  func(unew) <= func(uu) + alpha * g  (unew - uu) (alpha = 1.e-4)
+ *
+ *    and
+ *                                   t
+ *  func(unew) >= func(uu) + beta * g  (unew - uu) (beta = 0.9)
+ *
+ * where 0 < rlmin <= rl <= rlmax.
+ *
+ * Note:
+ *             mxnewtstep
+ *  rlmax = ----------------   if uu+pp is feasible
+ *          ||uscale*pp||_L2
+ *
+ *  rlmax = 1   otherwise
+ *
+ *    and
+ *
+ *                 scsteptol
+ *  rlmin = --------------------------
+ *          ||           pp         ||
+ *          || -------------------- ||_L-infinity
+ *          || (1/uscale + ABS(uu)) ||
+ *
+ *
+ * If the system function fails unrecoverably at any time, KINLineSearch 
+ * returns KIN_SYSFUNC_FAIL which will halt the solver.
+ *
+ * We attempt to corect recoverable system function failures only before 
+ * the alpha-condition loop; i.e. when the solution is updated with the 
+ * full Newton step (possibly reduced due to constraint violations). 
+ * Once we find a feasible pp, we assume that any update up to pp is
+ * feasible.
+ * 
+ * If the step size is limited due to constraint violations and/or 
+ * recoverable system function failures, we set rlmax=1 to ensure
+ * that the update remains feasible during the attempts to enforce 
+ * the beta-condition (this is not an isse while enforcing the alpha
+ * condition, as rl can only decrease from 1 at that stage)
+ */
+
+static int KINLineSearch(KINMem kin_mem, realtype *fnormp, realtype *f1normp,
+                         booleantype *maxStepTaken)
+{
+  realtype pnorm, ratio, slpi, rlmin, rlength, rl, rlmax, rldiff;
+  realtype rltmp, rlprev, pt1trl, f1nprv, rllo, rlinc, alpha, beta;
+  realtype alpha_cond, beta_cond, rl_a, tmp1, rl_b, tmp2, disc;
+  int ircvr, nbktrk_l, retval;
+  booleantype firstBacktrack, fOK;
+
+  /* Initializations */
+
+  nbktrk_l = 0;          /* local backtracking counter */
+  ratio    = ONE;        /* step change ratio          */
+  alpha    = POINT0001;
+  beta     = POINT9;
+
+  firstBacktrack = TRUE;
+  *maxStepTaken = FALSE;
+
+  rlprev = f1nprv = ZERO;
+
+  /* Compute length of Newton step */
+
+  pnorm = N_VWL2Norm(pp, uscale);
+  rlmax = mxnewtstep / pnorm;
+  stepl = pnorm;
+
+  /* If the full Newton step is too large, set it to the maximum allowable value */
+
+  if(pnorm > mxnewtstep ) {
+    ratio = mxnewtstep / pnorm;
+    N_VScale(ratio, pp, pp);
+    pnorm = mxnewtstep;
+    rlmax = ONE;
+    stepl = pnorm;
+  }
+
+  /* If constraint checking is activated, check and correct violations */
+
+  stepmul = ONE;
+
+  if(constraintsSet){
+    retval = KINConstraint(kin_mem);
+    if(retval == CONSTR_VIOLATED){
+      /* Apply stepmul set in KINConstraint */
+      N_VScale(stepmul, pp, pp);
+      ratio *= stepmul;
+      pnorm *= stepmul;
+      rlmax = ONE;
+      stepl = pnorm;
+      if (printfl > 0) KINPrintInfo(kin_mem, PRNT_PNORM1, "KINSOL", "KINLineSearch", INFO_PNORM1, pnorm);
+      if (pnorm <= scsteptol) return(STEP_TOO_SMALL);
+    }
+  }
+
+  /* Attempt (at most MAX_RECVR times) to evaluate function at the new iterate */
+  
+  fOK = FALSE;
+
+  for (ircvr = 1; ircvr <= MAX_RECVR; ircvr++) {
+
+    /* compute the iterate unew = uu + pp */
+    N_VLinearSum(ONE, uu, ONE, pp, unew);
+
+    /* evaluate func(unew) and its norm, and return */
+    retval = func(unew, fval, f_data); nfe++;
+
+    /* if func was successful, accept pp */
+    if (retval == 0) {fOK = TRUE; break;}
+
+    /* if func failed unrecoverably, give up */
+    else if (retval < 0) return(KIN_SYSFUNC_FAIL);
+
+    /* func failed recoverably; cut step in half and try again */
+    N_VScale(HALF, pp, pp);
+    ratio *= HALF;
+    pnorm *= HALF;
+    rlmax = ONE;
+    stepl = pnorm;
+
+  }
+
+  /* If func() failed recoverably MAX_RECVR times, give up */
+
+  if (!fOK) return(KIN_REPTD_SYSFUNC_ERR);
+
+  /* Evaluate function norms */
+
+  *fnormp = N_VWL2Norm(fval, fscale);
+  *f1normp = HALF * (*fnormp) * (*fnormp) ;
+
+  /* Estimate the line search value rl (lambda) to satisfy both ALPHA and BETA conditions */
+
+  slpi = sfdotJp * ratio;
+  rlength = KINScSNorm(kin_mem, pp, uu);
+  rlmin = scsteptol / rlength;
+  rl = ONE;
+
+  if (printfl > 2)
+    KINPrintInfo(kin_mem, PRNT_LAM, "KINSOL", "KINLineSearch", INFO_LAM, rlmin, f1norm, pnorm);
+
+  /* Loop until the ALPHA condition is satisfied. Terminate if rl becomes too small */
+
+  loop {
+    
+    /* Evaluate test quantity */
+
+    alpha_cond = f1norm + (alpha * slpi * rl);
+
+    if (printfl > 2)
+      KINPrintInfo(kin_mem, PRNT_ALPHA, "KINSOL", "KINLinesearch", 
+                   INFO_ALPHA, *fnormp, *f1normp, alpha_cond, rl);
+
+    /* If ALPHA condition is satisfied, break out from loop */
+
+    if ((*f1normp) <= alpha_cond) break;
+
+    /* Backtracking. Use quadratic fit the first time and cubic fit afterwards. */
+
+    if (firstBacktrack) {
+
+      rltmp = -slpi / (TWO * ((*f1normp) - f1norm - slpi));
+      firstBacktrack = FALSE;
+
+    } else {
+
+      tmp1 = (*f1normp) - f1norm - (rl * slpi);
+      tmp2 = f1nprv - f1norm - (rlprev * slpi);
+      rl_a = ((ONE / (rl * rl)) * tmp1) - ((ONE / (rlprev * rlprev)) * tmp2);
+      rl_b = ((-rlprev / (rl * rl)) * tmp1) + ((rl / (rlprev * rlprev)) * tmp2);
+      tmp1 = ONE / (rl - rlprev);
+      rl_a *= tmp1;
+      rl_b *= tmp1;
+      disc = (rl_b * rl_b) - (THREE * rl_a * slpi);
+
+      if (ABS(rl_a) < uround) {        /* cubic is actually just a quadratic (rl_a ~ 0) */
+        rltmp = -slpi / (TWO * rl_b);
+      } else {                         /* real cubic */
+        rltmp = (-rl_b + RSqrt(disc)) / (THREE * rl_a);
+      }
+
+      if (rltmp > (HALF * rl)) rltmp = HALF * rl;
+
+    }
+
+    /* Set new rl (do not allow a reduction by a factor larger than 10) */
+
+    rlprev = rl;
+    f1nprv = (*f1normp);
+    pt1trl = POINT1 * rl;
+    rl = MAX(pt1trl, rltmp);
+    nbktrk_l++;
+
+    /* Update unew and re-evaluate function */
+
+    N_VLinearSum(ONE, uu, rl, pp, unew);
+
+    retval = func(unew, fval, f_data); nfe++;
+    if (retval != 0) return(KIN_SYSFUNC_FAIL);
+
+    *fnormp = N_VWL2Norm(fval, fscale);
+    *f1normp = HALF * (*fnormp) * (*fnormp) ;
+
+    /* Check if rl (lambda) is too small */
+
+    if (rl < rlmin) {
+      /* unew sufficiently distinct from uu cannot be found.
+         copy uu into unew (step remains unchanged) and 
+         return STEP_TOO_SMALL */
+      N_VScale(ONE, uu, unew);
+      return(STEP_TOO_SMALL);
+    }
+
+  } /* end ALPHA condition loop */
+
+
+  /* ALPHA condition is satisfied. Now check the BETA condition */
+
+  beta_cond = f1norm + (beta * slpi * rl);
+
+  if ((*f1normp) < beta_cond) {
+
+    /* BETA condition not satisfied */
+
+    if ((rl == ONE) && (pnorm < mxnewtstep)) {
+
+      do {
+
+        rlprev = rl;
+        f1nprv = *f1normp;
+        rl = MIN((TWO * rl), rlmax);
+        nbktrk_l++;
+
+        N_VLinearSum(ONE, uu, rl, pp, unew);
+        retval = func(unew, fval, f_data); nfe++;
+        if (retval != 0) return(KIN_SYSFUNC_FAIL);
+        *fnormp = N_VWL2Norm(fval, fscale);
+        *f1normp = HALF * (*fnormp) * (*fnormp);
+
+        alpha_cond = f1norm + (alpha * slpi * rl);
+        beta_cond = f1norm + (beta * slpi * rl);
+
+        if (printfl > 2)
+          KINPrintInfo(kin_mem, PRNT_BETA, "KINSOL", "KINLineSearch", 
+                       INFO_BETA, *f1normp, beta_cond, rl);
+
+      } while (((*f1normp) <= alpha_cond) && 
+              ((*f1normp) < beta_cond) && (rl < rlmax));
+
+    } /* enf if (rl == ONE) block */
+
+    if ((rl < ONE) || ((rl > ONE) && (*f1normp > alpha_cond))) {
+
+      rllo = MIN(rl, rlprev);
+      rldiff = ABS(rlprev - rl);
+
+      do {
+
+        rlinc = HALF * rldiff;
+        rl = rllo + rlinc;
+        nbktrk_l++;
+
+        N_VLinearSum(ONE, uu, rl, pp, unew);
+        retval = func(unew, fval, f_data); nfe++;
+        if (retval != 0) return(KIN_SYSFUNC_FAIL);
+        *fnormp = N_VWL2Norm(fval, fscale);
+        *f1normp = HALF * (*fnormp) * (*fnormp);
+
+        alpha_cond = f1norm + (alpha * slpi * rl);
+        beta_cond = f1norm + (beta * slpi * rl);
+
+        if (printfl > 2)
+          KINPrintInfo(kin_mem, PRNT_ALPHABETA, "KINSOL", "KINLineSearch", 
+                       INFO_ALPHABETA, *f1normp, alpha_cond, beta_cond, rl);
+
+        if ((*f1normp) > alpha_cond) rldiff = rlinc;
+        else if (*f1normp < beta_cond) {
+          rllo = rl;
+          rldiff = rldiff - rlinc;
+        }
+
+      } while ((*f1normp > alpha_cond) ||
+              ((*f1normp < beta_cond) && (rldiff >= rlmin)));
+
+      if ((*f1normp) < beta_cond) {
+
+       /* beta condition could not be satisfied so set unew to last u value
+          that satisfied the alpha condition and continue */
+
+        N_VLinearSum(ONE, uu, rllo, pp, unew);
+        retval = func(unew, fval, f_data); nfe++;
+        if (retval != 0) return(KIN_SYSFUNC_FAIL);
+        *fnormp = N_VWL2Norm(fval, fscale);
+        *f1normp = HALF * (*fnormp) * (*fnormp);   
+
+       /* increment beta-condition failures counter */
+
+        nbcf++;
+
+      }
+
+    }  /* end of if (rl < ONE) block */
+
+  }  /* end of if (f1normp < beta_cond) block */
+
+  /* Update number of backtracking operations */
+
+  nbktrk += nbktrk_l;
+
+  if (printfl > 1)
+    KINPrintInfo(kin_mem, PRNT_ADJ, "KINSOL", "KINLineSearch", INFO_ADJ, nbktrk_l);
+
+  /* scale sfdotJp and sJpnorm by rl * ratio for later use in KINForcingTerm */
+
+  sfdotJp = sfdotJp * rl * ratio;
+  sJpnorm = sJpnorm * rl * ratio;
+
+  if ((rl * pnorm) > (POINT99 * mxnewtstep)) *maxStepTaken = TRUE;
+
+  return(KIN_SUCCESS);
+}
+
+/*
+ * Function : KINConstraint
+ *
+ * This routine checks if the proposed solution vector uu + pp
+ * violates any constraints. If a constraint is violated, then the
+ * scalar stepmul is determined such that uu + stepmul * pp does
+ * not violate any constraints.
+ *
+ * Note: This routine is called by the functions
+ *       KINLineSearch and KINFullNewton.
+ */
+
+static int KINConstraint(KINMem kin_mem)
+{
+  N_VLinearSum(ONE, uu, ONE, pp, vtemp1);
+
+  /* if vtemp1[i] violates constraint[i] then vtemp2[i] = 1
+     else vtemp2[i] = 0 (vtemp2 is the mask vector) */
+
+  if(N_VConstrMask(constraints, vtemp1, vtemp2)) return(KIN_SUCCESS);
+
+  /* vtemp1[i] = ABS(pp[i]) */
+
+  N_VAbs(pp, vtemp1);
+
+  /* consider vtemp1[i] only if vtemp2[i] = 1 (constraint violated) */
+
+  N_VProd(vtemp2, vtemp1, vtemp1);
+
+  N_VAbs(uu, vtemp2);
+  stepmul = POINT9 * N_VMinQuotient(vtemp2, vtemp1);
+
+  return(CONSTR_VIOLATED);
+}
+
+/*
+ * -----------------------------------------------------------------
+ * Stopping tests
+ * -----------------------------------------------------------------
+ */
+
+/*
+ * KINStop
+ *
+ * This routine checks the current iterate unew to see if the
+ * system func(unew) = 0 is satisfied by a variety of tests.
+ *
+ * strategy is one of KIN_NONE or KIN_LINESEARCH
+ * sflag    is one of KIN_SUCCESS, STEP_TOO_SMALL
+ */
+
+static int KINStop(KINMem kin_mem, int strategy, booleantype maxStepTaken, int sflag)
+{
+  realtype fmax, rlength;
+  N_Vector delta;
+
+  /* Check for too small a step */
+
+  if (sflag == STEP_TOO_SMALL) {
+
+    if (setupNonNull && !jacCurrent) {
+      /* If the Jacobian is out of date, update it and retry */
+      sthrsh = TWO;
+      return(CONTINUE_ITERATIONS);
+    } else {
+      /* Give up */
+      if (strategy == KIN_NONE)  return(KIN_STEP_LT_STPTOL);
+      else                       return(KIN_LINESEARCH_NONCONV);
+    }
+
+  }
+
+  /* Check tolerance on scaled function norm at the current iterate */
+
+  fmax = KINScFNorm(kin_mem, fval, fscale);
+
+  if (printfl > 1) 
+    KINPrintInfo(kin_mem, PRNT_FMAX, "KINSOL", "KINStop", INFO_FMAX, fmax);
+
+  if (fmax <= fnormtol) return(KIN_SUCCESS);
+
+  /* Check if the scaled distance between the last two steps is too small */
+  /* NOTE: pp used as work space to store this distance */
+
+  delta = pp;
+  N_VLinearSum(ONE, unew, -ONE, uu, delta);
+  rlength = KINScSNorm(kin_mem, delta, unew);
+
+  if (rlength <= scsteptol) {
+
+    if (setupNonNull && !jacCurrent) {
+      /* If the Jacobian is out of date, update it and retry */
+      sthrsh = TWO;
+      return(CONTINUE_ITERATIONS);
+    } else {
+      /* give up */
+      return(KIN_STEP_LT_STPTOL);
+    }
+
+  }
+
+  /* Check if the maximum number of iterations is reached */
+
+  if (nni >= mxiter) return(KIN_MAXITER_REACHED);
+
+  /* Check for consecutive number of steps taken of size mxnewtstep
+     and if not maxStepTaken, then set ncscmx to 0 */
+  if (maxStepTaken) ncscmx++;
+  else              ncscmx = 0;
+  if (ncscmx == 5) return(KIN_MXNEWT_5X_EXCEEDED);
+
+  /* Proceed according to the type of linear solver used */
+
+  if (inexact_ls) {
+
+    /* We're doing inexact Newton.
+       Load threshold for reevaluating the Jacobian. */
+
+    sthrsh = rlength;
+
+  } else if (!noResMon) {
+
+    /* We're doing modified Newton and the user did not disable residual monitoring.
+       Check if it is time to monitor residual. */
+
+    if ((nni - nnilset_sub) >= msbset_sub) {
+
+      /* Residual monitoring needed */
+
+      nnilset_sub = nni;
+
+      /* If OMEGA is still zero at this point, estimate it */
+      if (omega == ZERO)
+        omega = MIN(omega_min*EXP(MAX(ZERO,(fnorm/fnormtol)-ONE)), omega_max);
+
+      /* Check if making satisfactory progress */
+
+      if (fnorm > omega*fnorm_sub) {
+        /* Insuficient progress */
+       if (setupNonNull && !jacCurrent) {
+          /* If the Jacobian is out of date, update it and retry */
+         sthrsh = TWO;
+         return(RETRY_ITERATION);
+       } else {
+          /* Otherwise, we cannot do anything, so just return. */
+        }
+      } else {
+        /* Sufficient progress */
+       fnorm_sub = fnorm;
+       sthrsh = ONE;
+      }
+
+    } else {
+
+      /* Residual monitoring not needed */
+
+      /* Reset sthrsh */
+      if (retry_nni || update_fnorm_sub) fnorm_sub = fnorm;
+      if (update_fnorm_sub) update_fnorm_sub = FALSE;
+      sthrsh = ONE;
+
+    }
+
+  }
+
+  /* if made it to here, then the iteration process is not finished
+     so return CONTINUE_ITERATIONS flag */
+
+  return(CONTINUE_ITERATIONS);
+}
+
+/*
+ * KINForcingTerm
+ *
+ * This routine computes eta, the scaling factor in the linear
+ * convergence stopping tolerance eps when choice #1 or choice #2
+ * forcing terms are used. Eta is computed here for all but the
+ * first iterative step, which is set to the default in routine
+ * KINSolInit.
+ *
+ * This routine was written by Homer Walker of Utah State
+ * University with subsequent modifications by Allan Taylor @ LLNL.
+ *
+ * It is based on the concepts of the paper 'Choosing the forcing
+ * terms in an inexact Newton method', SIAM J Sci Comput, 17
+ * (1996), pp 16 - 32, or Utah State University Research Report
+ * 6/94/75 of the same title.
+ */
+
+static void KINForcingTerm(KINMem kin_mem, realtype fnormp)
+{
+  realtype eta_max, eta_min, eta_safe, linmodel_norm;
+
+  eta_max  = POINT9;
+  eta_min  = POINT0001;
+  eta_safe = HALF;
+
+  /* choice #1 forcing term */
+
+  if (etaflag == KIN_ETACHOICE1) {
+
+    /* compute the norm of f + Jp , scaled L2 norm */
+
+    linmodel_norm = RSqrt((fnorm * fnorm) + (TWO * sfdotJp) + (sJpnorm * sJpnorm));
+
+    /* form the safeguarded for choice #1 */ 
+
+    eta_safe = RPowerR(eta, ealpha); 
+    eta = ABS(fnormp - linmodel_norm) / fnorm; 
+  }
+
+  /* choice #2 forcing term */
+
+  if (etaflag == KIN_ETACHOICE2) {
+    eta_safe = egamma * RPowerR(eta, ealpha); 
+    eta = egamma * RPowerR((fnormp / fnorm), ealpha); 
+  }
+
+  /* apply safeguards */
+  if(eta_safe < POINT1) eta_safe = ZERO;
+  eta = MAX(eta, eta_safe); 
+  eta = MAX(eta, eta_min); 
+  eta = MIN(eta, eta_max); 
+
+  return; 
+}
+
+
+/*
+ * -----------------------------------------------------------------
+ * Norm functions
+ * -----------------------------------------------------------------
+ */
+
+/*
+ * Function : KINScFNorm
+ *
+ * This routine computes the max norm for scaled vectors. The
+ * scaling vector is scale, and the vector of which the norm is to
+ * be determined is vv. The returned value, fnormval, is the
+ * resulting scaled vector norm. This routine uses N_Vector
+ * functions from the vector module.
+ */
+
+static realtype KINScFNorm(KINMem kin_mem, N_Vector v, N_Vector scale)
+{
+  N_VProd(scale, v, vtemp1);
+  return(N_VMaxNorm(vtemp1));
+}
+
+/*
+ * Function : KINScSNorm
+ *
+ * This routine computes the max norm of the scaled steplength, ss.
+ * Here ucur is the current step and usc is the u scale factor.
+ */
+
+static realtype KINScSNorm(KINMem kin_mem, N_Vector v, N_Vector u)
+{
+  realtype length;
+
+  N_VInv(uscale, vtemp1);
+  N_VAbs(u, vtemp2);
+  N_VLinearSum(ONE, vtemp1, ONE, vtemp2, vtemp1);
+  N_VDiv(v, vtemp1, vtemp1);
+
+  length = N_VMaxNorm(vtemp1);
+
+  return(length);
+}
+
+/* 
+ * =================================================================
+ * KINSOL Verbose output functions
+ * =================================================================
+ */
+
+/* 
+ * KINPrintInfo
+ *
+ * KINPrintInfo is a high level error handling function
+ * Based on the value info_code, it composes the info message and
+ * passes it to the info handler function.
+ */
+
+#define ihfun    (kin_mem->kin_ihfun)
+#define ih_data  (kin_mem->kin_ih_data)
+
+void KINPrintInfo(KINMem kin_mem, 
+                  int info_code, const char *module, const char *fname, 
+                  const char *msgfmt, ...)
+{
+  va_list ap;
+  char msg[256], msg1[40];
+  char retstr[30];
+  int ret;
+
+  /* Initialize argument processing 
+   (msgfrmt is the last required argument) */
+
+  va_start(ap, msgfmt); 
+
+  if (info_code == PRNT_RETVAL) {
+
+    /* If info_code = PRNT_RETVAL, decode the numeric value */
+
+    ret = va_arg(ap, int);
+
+    switch(ret) {
+    case KIN_SUCCESS:
+      sprintf(retstr, "KIN_SUCCESS");
+      break;
+    case KIN_STEP_LT_STPTOL:
+      sprintf(retstr, "KIN_STEP_LT_STPTOL");
+      break;
+    case KIN_LINESEARCH_NONCONV:
+      sprintf(retstr, "KIN_LINESEARCH_NONCONV");
+      break;
+    case KIN_LINESEARCH_BCFAIL:
+      sprintf(retstr, "KIN_LINESEARCH_BCFAIL");
+      break;
+    case KIN_MAXITER_REACHED:
+      sprintf(retstr, "KIN_MAXITER_REACHED");
+      break;
+    case KIN_MXNEWT_5X_EXCEEDED:
+      sprintf(retstr, "KIN_MXNEWT_5X_EXCEEDED");
+      break;
+    case KIN_LINSOLV_NO_RECOVERY:
+      sprintf(retstr, "KIN_LINSOLV_NO_RECOVERY");
+      break;
+    case KIN_LSETUP_FAIL:
+      sprintf(retstr, "KIN_PRECONDSET_FAILURE");
+      break;
+    case KIN_LSOLVE_FAIL:
+      sprintf(retstr, "KIN_PRECONDSOLVE_FAILURE");
+      break;
+    }
+
+    /* Compose the message */
+
+    sprintf(msg1, msgfmt, ret);
+    sprintf(msg,"%s (%s)",msg1,retstr);
+
+
+  } else {
+  
+    /* Compose the message */
+
+    vsprintf(msg, msgfmt, ap);
+
+  }
+
+  /* call the info message handler */
+
+  ihfun(module, fname, msg, ih_data);
+
+  /* finalize argument processing */
+
+  va_end(ap);
+
+  return;
+}
+
+
+/*
+ * KINInfoHandler 
+ *
+ * This is the default KINSOL info handling function.
+ * It sends the info message to the stream pointed to by kin_infofp 
+ */
+
+#define infofp (kin_mem->kin_infofp)
+
+void KINInfoHandler(const char *module, const char *function, 
+                    char *msg, void *data)
+{
+  KINMem kin_mem;
+
+  /* data points to kin_mem here */
+
+  kin_mem = (KINMem) data;
+  
+#ifndef NO_FPRINTF_OUTPUT
+  fprintf(infofp,"\n[%s] %s\n",module, function);
+  fprintf(infofp,"   %s\n",msg);
+#endif  
+
+}
+
+/* 
+ * =================================================================
+ * KINSOL Error Handling functions
+ * =================================================================
+ */
+
+/* 
+ * KINProcessError 
+ *
+ * Thi is a high level error handling function
+ * - if cv_mem==NULL it prints the error message to stderr
+ * - otherwise, it sets-up and calls the error hadling function 
+ *   pointed to by cv_ehfun
+ */
+
+#define ehfun    (kin_mem->kin_ehfun)
+#define eh_data  (kin_mem->kin_eh_data)
+
+void KINProcessError(KINMem kin_mem, 
+                    int error_code, const char *module, const char *fname, 
+                    const char *msgfmt, ...)
+{
+  va_list ap;
+  char msg[256];
+
+  /* Initialize the argument pointer variable 
+     (msgfmt is the last required argument to KINProcessError) */
+
+  va_start(ap, msgfmt);
+
+  if (kin_mem == NULL) {    /* We write to stderr */
+
+#ifndef NO_FPRINTF_OUTPUT
+    fprintf(stderr, "\n[%s ERROR]  %s\n  ", module, fname);
+    fprintf(stderr, msgfmt);
+    fprintf(stderr, "\n\n");
+#endif
+
+  } else {                 /* We can call ehfun */
+
+    /* Compose the message */
+
+    vsprintf(msg, msgfmt, ap);
+
+    /* Call ehfun */
+
+    ehfun(error_code, module, fname, msg, eh_data);
+
+  }
+
+  /* Finalize argument processing */
+  
+  va_end(ap);
+
+  return;
+
+}
+
+/* 
+ * KINErrHandler 
+ *
+ * This is the default error handling function.
+ * It sends the error message to the stream pointed to by kin_errfp 
+ */
+
+#define errfp    (kin_mem->kin_errfp)
+
+void KINErrHandler(int error_code, const char *module,
+                   const char *function, char *msg, void *data)
+{
+  KINMem kin_mem;
+  char err_type[10];
+
+  /* data points to kin_mem here */
+
+  kin_mem = (KINMem) data;
+
+  if (error_code == KIN_WARNING)
+    sprintf(err_type,"WARNING");
+  else
+    sprintf(err_type,"ERROR");
+
+#ifndef NO_FPRINTF_OUTPUT
+  if (errfp!=NULL) {
+    fprintf(errfp,"\n[%s %s]  %s\n",module,err_type,function);
+    fprintf(errfp,"  %s\n\n",msg);
+  }
+#endif
+
+  return;
+}
+
@@ -1,7 +1,7 @@
 /*
  * -----------------------------------------------------------------
- * Revision: 1.1 $
- * Date: 2008-11-17 16:26:32 $
+ * $Revision: 1.2 $
+ * $Date: 2006/10/11 16:34:19 $
  * ----------------------------------------------------------------- 
  * Programmer(s): Radu Serban @ LLNL
  * -----------------------------------------------------------------
@@ -20,7 +20,7 @@
 #include "kinsol_dense_impl.h"
 #include "kinsol_impl.h"
 
-#include "sundials_math.h"
+#include <sundials/sundials_math.h>
 
 /* Other Constants */
 
@@ -1,7 +1,7 @@
 /*
  * -----------------------------------------------------------------
- * Revision: 1.1 $
- * Date: 2008-11-17 16:26:32 $
+ * $Revision: 1.1 $
+ * $Date: 2006/07/05 15:32:36 $
  * -----------------------------------------------------------------
  * Programmer(s): Radu Serban @ LLNL
  * -----------------------------------------------------------------
@@ -21,7 +21,7 @@ extern "C" {
 #ifndef _KINDENSE_IMPL_H
 #define _KINDENSE_IMPL_H
 
-#include "kinsol_dense.h"
+#include <kinsol/kinsol_dense.h>
 
 /*
  * -----------------------------------------------------------------
-/*\r
- * -----------------------------------------------------------------\r
- * Revision: 1.1 $\r
- * Date: 2008-11-17 16:26:32 $\r
- * -----------------------------------------------------------------\r
- * Programmer(s): Allan Taylor, Alan Hindmarsh, Radu Serban, and\r
- *                Aaron Collier @ LLNL\r
- * -----------------------------------------------------------------\r
- * Copyright (c) 2002, The Regents of the University of California.\r
- * Produced at the Lawrence Livermore National Laboratory.\r
- * All rights reserved.\r
- * For details, see the LICENSE file.\r
- * -----------------------------------------------------------------\r
- * KINSOL solver module header file (private version)\r
- * -----------------------------------------------------------------\r
- */\r
-\r
-#ifndef _KINSOL_IMPL_H\r
-#define _KINSOL_IMPL_H\r
-\r
-#ifdef __cplusplus  /* wrapper to enable C++ usage */\r
-extern "C" {\r
-#endif\r
-\r
-#include <stdarg.h>\r
-\r
-#include "kinsol.h"\r
-\r
-  /*\r
-   * =================================================================\r
-   *   M A I N    S O L V E R    M E M O R Y    B L O C K\r
-   * =================================================================\r
-   */\r
-\r
-  /* KINSOL default constants */\r
\r
-#define PRINTFL_DEFAULT    0\r
-#define MXITER_DEFAULT     200\r
-#define MXNBCF_DEFAULT     10\r
-#define MSBSET_DEFAULT     10\r
-#define MSBSET_SUB_DEFAULT 5\r
-\r
-#define OMEGA_MIN RCONST(0.00001)\r
-#define OMEGA_MAX RCONST(0.9)\r
-\r
-  /*\r
-   * -----------------------------------------------------------------\r
-   * Types : struct KINMemRec and struct *KINMem\r
-   * -----------------------------------------------------------------\r
-   * A variable declaration of type struct *KINMem denotes a\r
-   * pointer to a data structure of type struct KINMemRec. The\r
-   * KINMemRec structure contains numerous fields that must be\r
-   * accessible by KINSOL solver module routines.\r
-   * -----------------------------------------------------------------\r
-   */\r
-\r
-  typedef struct KINMemRec {\r
-\r
-    realtype kin_uround;        /* machine epsilon (or unit roundoff error) \r
-                                   (defined in sundials_types.h)                */\r
-\r
-    /* problem specification data */\r
-\r
-    KINSysFn kin_func;           /* nonlinear system function implementation     */\r
-    void *kin_f_data;            /* work space available to func routine         */\r
-    realtype kin_fnormtol;       /* stopping tolerance on L2-norm of function\r
-                                    value                                        */\r
-    realtype kin_scsteptol;      /* scaled step length tolerance                 */\r
-    int kin_globalstrategy;      /* choices are KIN_NONE and KIN_LINESEARCH      */\r
-    int kin_printfl;             /* level of verbosity of output                 */\r
-    long int kin_mxiter;         /* maximum number of nonlinear iterations       */\r
-    long int kin_msbset;         /* maximum number of nonlinear iterations that\r
-                                    may be performed between calls to the\r
-                                    linear solver setup routine (lsetup)         */\r
-    long int kin_msbset_sub;     /* subinterval length for residual monitoring   */\r
-    long int kin_mxnbcf;         /* maximum number of beta condition failures    */\r
-    int kin_etaflag;             /* choices are KIN_ETACONSTANT, KIN_ETACHOICE1\r
-                                    and KIN_ETACHOICE2                           */\r
-    booleantype kin_noMinEps;    /* flag controlling whether or not the value\r
-                                    of eps is bounded below                      */\r
-    booleantype kin_setupNonNull;   /* flag indicating if linear solver setup\r
-                                       routine is non-null and if setup is used  */\r
-    booleantype kin_constraintsSet; /* flag indicating if constraints are being\r
-                                       used                                      */\r
-    booleantype kin_jacCurrent;     /* flag indicating if the Jacobian info. \r
-                                       used by the linear solver is current      */\r
-    booleantype kin_callForcingTerm; /* flag set if using either KIN_ETACHOICE1\r
-                                        or KIN_ETACHOICE2                        */\r
-    booleantype kin_noResMon;         /* flag indicating if the nonlinear\r
-                                         residual monitoring scheme should be\r
-                                         used                                    */\r
-    booleantype kin_retry_nni;        /* flag indicating if nonlinear iteration\r
-                                         should be retried (set by residual\r
-                                         monitoring algorithm)                   */\r
-    booleantype kin_update_fnorm_sub; /* flag indicating if the fnorm associated\r
-                                         with the subinterval needs to be\r
-                                         updated (set by residual monitoring\r
-                                         algorithm)                              */\r
-\r
-    realtype kin_mxnewtstep;     /* maximum allowable scaled step length         */\r
-    realtype kin_sqrt_relfunc;   /* relative error bound for func(u)             */\r
-    realtype kin_stepl;          /* scaled length of current step                */\r
-    realtype kin_stepmul;        /* step scaling factor                          */\r
-    realtype kin_eps;            /* current value of eps                         */\r
-    realtype kin_eta;            /* current value of eta                         */\r
-    realtype kin_eta_gamma;      /* gamma value used in eta calculation\r
-                                    (choice #2)                                  */\r
-    realtype kin_eta_alpha;      /* alpha value used in eta calculation\r
-                                    (choice #2)                                  */\r
-    booleantype kin_noInitSetup; /* flag controlling whether or not the KINSol\r
-                                    routine makes an initial call to the\r
-                                    linear solver setup routine (lsetup)         */\r
-    realtype kin_sthrsh;         /* threshold value for calling the linear   \r
-                                    solver setup routine                         */\r
-\r
-    /* counters */\r
-\r
-    long int kin_nni;            /* number of nonlinear iterations               */\r
-    long int kin_nfe;            /* number of calls made to func routine         */\r
-    long int kin_nnilset;        /* value of nni counter when the linear solver\r
-                                    setup was last called                        */\r
-    long int kin_nnilset_sub;    /* value of nni counter when the linear solver\r
-                                    setup was last called (subinterval)          */\r
-    long int kin_nbcf;           /* number of times the beta-condition could not \r
-                                    be met in KINLineSearch                      */\r
-    long int kin_nbktrk;         /* number of backtracks performed by\r
-                                    KINLineSearch                                */\r
-    long int kin_ncscmx;         /* number of consecutive steps of size\r
-                                    mxnewtstep taken                             */\r
-\r
-    /* vectors */\r
-\r
-    N_Vector kin_uu;          /* solution vector/current iterate (initially\r
-                                 contains initial guess, but holds approximate\r
-                                 solution upon completion if no errors occurred) */\r
-    N_Vector kin_unew;        /* next iterate (unew = uu+pp)                     */\r
-    N_Vector kin_fval;        /* vector containing result of nonlinear system\r
-                                 function evaluated at a given iterate\r
-                                 (fval = func(uu))                               */\r
-    N_Vector kin_uscale;      /* iterate scaling vector                          */\r
-    N_Vector kin_fscale;      /* fval scaling vector                             */\r
-    N_Vector kin_pp;          /* incremental change vector (pp = unew-uu)        */\r
-    N_Vector kin_constraints; /* constraints vector                              */ \r
-    N_Vector kin_vtemp1;      /* scratch vector #1                               */\r
-    N_Vector kin_vtemp2;      /* scratch vector #2                               */\r
-\r
-    /* space requirements for vector storage */ \r
-\r
-    long int kin_lrw1;        /* number of realtype-sized memory blocks needed\r
-                                 for a single N_Vector                           */ \r
-    long int kin_liw1;        /* number of int-sized memory blocks needed for\r
-                                 a single N_Vecotr                               */ \r
-    long int kin_lrw;         /* total number of realtype-sized memory blocks\r
-                                 needed for all KINSOL work vectors              */\r
-    long int kin_liw;         /* total number of int-sized memory blocks needed\r
-                                 for all KINSOL work vectors                     */\r
-\r
-    /* linear solver data */\r
\r
-    /* function prototypes (pointers) */\r
-\r
-    int (*kin_linit)(struct KINMemRec *kin_mem);\r
-\r
-    int (*kin_lsetup)(struct KINMemRec *kin_mem);\r
-\r
-    int (*kin_lsolve)(struct KINMemRec *kin_mem, N_Vector xx, N_Vector bb, \r
-                      realtype *res_norm );\r
-\r
-    void (*kin_lfree)(struct KINMemRec *kin_mem);\r
-\r
-    booleantype kin_inexact_ls; /* flag set by the linear solver module\r
-                                   (in linit) indicating whether this is an\r
-                                   iterative linear solver (TRUE), or a direct\r
-                                   linear solver (FALSE)                         */\r
-\r
-    void *kin_lmem;         /* pointer to linear solver memory block             */\r
-\r
-    realtype kin_fnorm;     /* value of L2-norm of fscale*fval                   */\r
-    realtype kin_f1norm;    /* f1norm = 0.5*(fnorm)^2                            */\r
-    realtype kin_res_norm;  /* value of L2-norm of residual (set by the linear\r
-                               solver)                                           */\r
-    realtype kin_sfdotJp;   /* value of scaled func(u) vector (fscale*fval)\r
-                               dotted with scaled J(u)*pp vector                 */\r
-    realtype kin_sJpnorm;   /* value of L2-norm of fscale*(J(u)*pp)              */\r
-\r
-    realtype kin_fnorm_sub; /* value of L2-norm of fscale*fval (subinterval)     */\r
-    realtype kin_omega;     /* constant value for real scalar used in test to\r
-                               determine if reduction of norm of nonlinear\r
-                               residual is sufficient. a value of zero indicates\r
-                &nb