Porting continues.
authorilb@NIH.GOV <ilb@NIH.GOV@ba61647d-9d00-f842-95cd-605cb4296b96>
Fri, 9 Mar 2018 23:30:12 +0000 (23:30 +0000)
committerilb@NIH.GOV <ilb@NIH.GOV@ba61647d-9d00-f842-95cd-605cb4296b96>
Fri, 9 Mar 2018 23:30:12 +0000 (23:30 +0000)
git-svn-id: https://citdcbmipav.cit.nih.gov/repos-pub/mipav/trunk@15411 ba61647d-9d00-f842-95cd-605cb4296b96

mipav/src/gov/nih/mipav/model/algorithms/CVODES.java

index a42a086..b728fb9 100644 (file)
@@ -219,6 +219,7 @@ public abstract class CVODES {
        final double FOUR = 4.0;\r
        final double FIVE = 5.0;\r
        final double TWELVE = 12.0;\r
+       final double THIRTY = 30.0;\r
        final double HUNDRED = 100.0;\r
        final double ETAMXF = 0.2;\r
        final double ETAMX1 = 10000.0;\r
@@ -557,9 +558,25 @@ public abstract class CVODES {
     final int cvDlsSetup_select = 1;\r
 \r
     final int cvsRoberts_dns = 1;\r
+    final int cvSDirectDemo_ls_Problem_1 = 2;\r
     int problem = cvsRoberts_dns;\r
     boolean testMode = true;\r
        \r
+    // Linear Solver options for runcvsDirectDemo\r
+       final int FUNC = 1;\r
+       final int DENSE_USER = 2;\r
+       final int DENSE_DQ = 3;\r
+       final int DIAG = 4;\r
+       final int BAND_USER = 5;\r
+       final int BAND_DQ = 6;\r
+       // cvsDirectDemo Problem  1 Constants\r
+       final int P1_NEQ = 2;\r
+       final double P1_ETA = 3.0;\r
+       final int P1_NOUT = 4;\r
+       final double P1_T0 = 0.0;\r
+       final double P1_T1 = 1.39283880203;\r
+       final double P1_DTOUT = 2.214773875;\r
+       final double P1_TOL_FACTOR = 1.0E4;\r
        \r
        public CVODES() {\r
                // eps returns the distance from 1.0 to the next larger double-precision\r
@@ -920,6 +937,264 @@ public abstract class CVODES {
          return(passfail);\r
        }\r
 \r
+       private void runcvsDirectDemo_Problem_1() {\r
+               /* -----------------------------------------------------------------\r
+                * Programmer(s): Scott D. Cohen, Alan C. Hindmarsh and\r
+                *                Radu Serban @ LLNL\r
+                * -----------------------------------------------------------------\r
+                * Demonstration program for CVODE - direct linear solvers.\r
+                * Two separate problems are solved using both the CV_ADAMS and CV_BDF\r
+                * linear multistep methods in combination with CV_FUNCTIONAL and\r
+                * CV_NEWTON iterations:\r
+                *\r
+                * Problem 1: Van der Pol oscillator\r
+                *   xdotdot - 3*(1 - x^2)*xdot + x = 0, x(0) = 2, xdot(0) = 0.\r
+                * This second-order ODE is converted to a first-order system by\r
+                * defining y0 = x and y1 = xdot.\r
+                * The NEWTON iteration cases use the following types of Jacobian\r
+                * approximation: (1) dense, user-supplied, (2) dense, difference\r
+                * quotient approximation, (3) diagonal approximation.\r
+                *\r
+                * Problem 2: ydot = A * y, where A is a banded lower triangular\r
+                * matrix derived from 2-D advection PDE.\r
+                * The NEWTON iteration cases use the following types of Jacobian\r
+                * approximation: (1) band, user-supplied, (2) band, difference\r
+                * quotient approximation, (3) diagonal approximation.\r
+                *\r
+                * For each problem, in the series of eight runs, CVodeInit is\r
+                * called only once, for the first run, whereas CVodeReInit is\r
+                * called for each of the remaining seven runs.\r
+                *\r
+                * Notes: This program demonstrates the usage of the sequential\r
+                * macros NV_Ith_S, SM_ELEMENT_D, SM_COLUMN_B, and\r
+                * SM_COLUMN_ELEMENT_B. The NV_Ith_S macro is used to reference the\r
+                * components of an N_Vector. It works for any size N=NEQ, but\r
+                * due to efficiency concerns it should only by used when the\r
+                * problem size is small. The Problem 1 right hand side and\r
+                * Jacobian functions f1 and Jac1 both use NV_Ith_S. The \r
+                * N_VGetArrayPointer function gives the user access to the \r
+                * memory used for the component storage of an N_Vector. In the \r
+                * sequential case, the user may assume that this is one contiguous \r
+                * array of reals. The N_VGetArrayPointer function\r
+                * gives a more efficient means (than the NV_Ith_S macro) to\r
+                * access the components of an N_Vector and should be used when the\r
+                * problem size is large. The Problem 2 right hand side function f2\r
+                * uses the N_VGetArrayPointer function. The SM_ELEMENT_D macro \r
+                * used in Jac1 gives access to an element of a dense SUNMatrix. It \r
+                * should be used only when the problem size is small (the \r
+                * size of a Dense SUNMatrix is NEQ x NEQ) due to efficiency concerns. For\r
+                * larger problem sizes, the macro SM_COLUMN_D can be used in order\r
+                * to work directly with a column of a Dense SUNMatrix. The SM_COLUMN_B and\r
+                * SM_COLUMN_ELEMENT_B allow efficient columnwise access to the elements\r
+                * of a Banded SUNMatix. These macros are used in the Jac2 function.\r
+                * -----------------------------------------------------------------\r
+                */\r
+               // Shared Problem Constants\r
+               final double ATOL = 1.0E-6;\r
+               final double RTOL = 0.0;\r
+               int miter;\r
+               int f1;\r
+               double ero;\r
+               boolean firstrun;\r
+               int flag;\r
+               double reltol = RTOL;\r
+               double abstol = ATOL;\r
+               double t[] = new double[1];\r
+               int iout;\r
+               double tout;\r
+               int qu;\r
+               double hu;\r
+               int nerr = 0;\r
+               double er;\r
+           NVector y = null;\r
+           double A[][] = null;\r
+           SUNLinearSolver LS = null;\r
+           CVodeMemRec cvode_mem = null;\r
+            \r
+           y = new NVector();\r
+           N_VNew_Serial(y,P1_NEQ);\r
+           System.out.println("Demonstation package for CVODE package - direct linear solvers\n");\r
+               System.out.println("Problem 1: Van der Pol oscillator");\r
+               System.out.println("xdotdot - 3*(1 - x^2)*xdot + x = 0, x(0) = 2, xdot(0) = 0");\r
+               System.out.println("neq = " + P1_NEQ + ", reltol = " + RTOL + ", abstol = " + ATOL);\r
+               \r
+               problem = cvSDirectDemo_ls_Problem_1;\r
+               f1 = cvSDirectDemo_ls_Problem_1;\r
+               cvode_mem = CVodeCreate(CV_ADAMS, CV_FUNCTIONAL);\r
+               if (cvode_mem == null) {\r
+                       return;\r
+               }\r
+               for (miter = FUNC; miter <= DENSE_DQ; miter++) {\r
+                   ero = ZERO;\r
+                   y.data[0] = TWO;\r
+                   y.data[1] = ZERO;\r
+                   \r
+                   firstrun = (miter == FUNC);\r
+                   if (firstrun) {\r
+                       flag = CVodeInit(cvode_mem, f1, P1_T0, y);\r
+                       if (flag < 0) {\r
+                               return;\r
+                       }\r
+                       flag = CVodeSStolerances(cvode_mem, reltol, abstol);\r
+                       if (flag < 0) {\r
+                               return;\r
+                       }\r
+                   } // if (firstrun)\r
+                   else {\r
+                       flag = CVodeSetIterType(cvode_mem, CV_NEWTON);\r
+                       if (flag < 0) {\r
+                               return;\r
+                       }\r
+                       flag = CVodeReInit(cvode_mem, P1_T0, y);\r
+                       if (flag < 0) {\r
+                               return;\r
+                       }\r
+                   } // else\r
+                   \r
+                   flag = PrepareNextRun(cvode_mem, CV_ADAMS, miter, y, A, 0, 0, LS);\r
+                   if (flag < 0) {\r
+                       return;\r
+                   }\r
+                   \r
+                   for (iout = 1, tout = P1_T1; iout <= P1_NOUT; iout++, tout += P1_DTOUT) {\r
+                       flag = CVode(cvode_mem, tout, y, t, CV_NORMAL);\r
+                       if (flag < 0) {\r
+                               return;\r
+                       }\r
+                       // Returns the order on the last successful step\r
+                       qu = cvode_mem.cv_qu;\r
+                       // Return the step size used on the last successful step\r
+                       hu = cvode_mem.cv_hu;\r
+                       System.out.println("time = " + t[0]);\r
+                       System.out.println("y[0] = "+ y.data[0]);\r
+                       System.out.println("y[1] = " + y.data[1]);\r
+                       System.out.println("Step order qu = " + qu);\r
+                       System.out.println("Step size hu = " + hu);\r
+                       if (flag != CV_SUCCESS) {\r
+                               nerr++;\r
+                               break;\r
+                       }\r
+                       if ((iout %2) == 0) {\r
+                           er = Math.abs(y.data[0])/abstol;\r
+                           if (er > ero) ero = er;\r
+                           if (er > P1_TOL_FACTOR) {\r
+                               nerr++;\r
+                               System.out.println("Error exceeds " + P1_TOL_FACTOR + " * tolerance");\r
+                           }\r
+                       } // if ((iout %2) == 0)\r
+                       \r
+                   } // for (iout = 1, tout = P1_T1; iout <= P1_NOUT; iout++, tout += P1_DTOUT)\r
+                   PrintFinalStats(cvode_mem, miter, ero);\r
+               } // for (miter = FUNC; miter <= DENSE_DQ; miter++)\r
+       }\r
+       \r
+       private int PrepareNextRun(CVodeMemRec cvode_mem, int lmm, int miter, NVector y, double A[][],\r
+                       int mu, int ml, SUNLinearSolver LS) {\r
+               int flag = CV_SUCCESS;\r
+               int Jac1;\r
+               if (lmm == CV_ADAMS) {\r
+                   System.out.println("\nLinear MultiStep Method: ADAMS");\r
+               }\r
+           else {\r
+                System.out.println("\nLinear MultiStep Method: BDF");\r
+           }\r
+               \r
+               if (miter == FUNC) {\r
+                   System.out.println("Iteration: FUNCTIONAL");        \r
+               }\r
+               else {\r
+                       System.out.println("Iteration: NEWTON");\r
+               }\r
+               \r
+               switch(miter) {\r
+                   case DENSE_USER:\r
+                       System.out.println("Linear Solver: Dense, User-Supplied Jacobian");\r
+                       // Create dense SUNMatrix for use in linear solver.\r
+                       A = new double[P1_NEQ][P1_NEQ];\r
+                       \r
+                       // Create dense SUNLinearSolver object for use by CVode\r
+                       LS = SUNDenseLinearSolver(y, A);\r
+                       if (LS == null) {\r
+                               return -1;\r
+                       }\r
+                       // Call the CVDlsSetLinearSolver to attach the matrix and linear solver to Cvode\r
+                       flag = CVDlsSetLinearSolver(cvode_mem, LS, A);\r
+                       if (flag < 0) {\r
+                               return flag;\r
+                       }\r
+                       Jac1 = cvSDirectDemo_ls_Problem_1;\r
+                       flag = CVDlsSetJacFn(cvode_mem, Jac1);\r
+                               if (flag != CVDLS_SUCCESS) {\r
+                                       return flag;\r
+                               }\r
+                       break;\r
+                   case DENSE_DQ:\r
+                       System.out.println("Linear Solver: Dense, Difference Quotient Jacobian");\r
+                       // Create dense SUNMatrix for use in linear solver.\r
+                       A = new double[P1_NEQ][P1_NEQ];\r
+                       \r
+                       // Create dense SUNLinearSolver object for use by CVode\r
+                       LS = SUNDenseLinearSolver(y, A);\r
+                       if (LS == null) {\r
+                               return -1;\r
+                       }\r
+                       // Call the CVDlsSetLinearSolver to attach the matrix and linear solver to Cvode\r
+                       flag = CVDlsSetLinearSolver(cvode_mem, LS, A);\r
+                       if (flag < 0) {\r
+                               return flag;\r
+                       }\r
+                       \r
+                       // Use a difference quotient Jacobian\r
+                       flag = CVDlsSetJacFn(cvode_mem, -1);\r
+                       if (flag < 0) {\r
+                               return flag;\r
+                       }\r
+                       break;\r
+               }\r
+               \r
+               return flag;\r
+       }\r
+       \r
+       private void PrintFinalStats(CVodeMemRec cvode_mem, int miter, double ero) {\r
+           long lenrw, leniw;\r
+           long nst, nfe, nsetups, netf, nni, ncfn, nje, nfeLS;\r
+           // Integrator work space requirements\r
+           leniw = cvode_mem.cv_liw;\r
+           lenrw = cvode_mem.cv_lrw;\r
+           // Number of integration steps\r
+           nst = cvode_mem.cv_nst;\r
+           // Number of calls to f\r
+           nfe = cvode_mem.cv_nfe;\r
+           // Number of calls to the linear solver setup routine\r
+           nsetups = cvode_mem.cv_nsetups;\r
+           // Number of error test failures\r
+           netf = cvode_mem.cv_netf[0];\r
+           // Number of iterations in the nonlinear solver\r
+           nni = cvode_mem.cv_nni;\r
+           // Number of convergence failures in the nonlinear solver\r
+           ncfn = cvode_mem.cv_ncfn[0];\r
+           \r
+           System.out.println("Final statistics for this run:");\r
+           System.out.println("CVode double workspace length = " + lenrw);\r
+           System.out.println("CVode integer workspace length = " + leniw);\r
+           System.out.println("Number of integration steps = " + nst);\r
+           System.out.println("Number of f calls = " + nfe);\r
+           System.out.println("Number of linear solver setup calls = " + nsetups);\r
+           System.out.println("Number of nonlinear solver iterations = " + nni);\r
+           System.out.println("Number of nonlinear convergence failures in the nonlinear solver = " + ncfn);\r
+           System.out.println("Number of error test failures = " + netf);\r
+           \r
+           if (miter != FUNC) {\r
+               if (miter != DIAG) {\r
+                   // Number of Jacobian evaluations   \r
+                       nje = cvode_mem.cv_lmem.nje;    \r
+                       // the number of calls to the ODE function needed for the DQ Jacobian approximation\r
+                       nfeLS = cvode_mem.cv_lmem.nfeDQ;\r
+               } // if (miter != DIAG)\r
+               else {\r
+               } // else\r
+           } // if (miter != FUNC)\r
+       }\r
        \r
        private void N_VNew_Serial(NVector y, int length) {\r
            if ((y != null) && (length > 0)) {\r
@@ -929,7 +1204,7 @@ public abstract class CVODES {
        }\r
        \r
        /**\r
-        * f routine.  Compte function f(t,y).\r
+        * f routine.  Compute function f(t,y).\r
         * @param t\r
         * @param yv\r
         * @param ydotv\r
@@ -9305,6 +9580,233 @@ else                return(snrm);
             return(CV_SUCCESS);\r
           }\r
 \r
+          private int CVodeSStolerances(CVodeMemRec cv_mem, double reltol, double abstol)\r
+          {\r
+\r
+            if (cv_mem==null) {\r
+              cvProcessError(null, CV_MEM_NULL, "CVODES", \r
+                             "CVodeSStolerances", MSGCV_NO_MEM);\r
+              return(CV_MEM_NULL);\r
+            }\r
+\r
+            if (cv_mem.cv_MallocDone == false) {\r
+              cvProcessError(cv_mem, CV_NO_MALLOC, "CVODES",\r
+                             "CVodeSStolerances", MSGCV_NO_MALLOC);\r
+              return(CV_NO_MALLOC);\r
+            }\r
+\r
+            /* Check inputs */\r
+\r
+            if (reltol < ZERO) {\r
+              cvProcessError(cv_mem, CV_ILL_INPUT, "CVODES",\r
+                             "CVodeSStolerances", MSGCV_BAD_RELTOL);\r
+              return(CV_ILL_INPUT);\r
+            }\r
+\r
+            if (abstol < ZERO) {\r
+              cvProcessError(cv_mem, CV_ILL_INPUT, "CVODES",\r
+                             "CVodeSStolerances", MSGCV_BAD_ABSTOL);\r
+              return(CV_ILL_INPUT);\r
+            }\r
+\r
+            /* Copy tolerances into memory */\r
+            \r
+            cv_mem.cv_reltol = reltol;\r
+            cv_mem.cv_Sabstol = abstol;\r
+\r
+            cv_mem.cv_itol = CV_SS;\r
+\r
+            cv_mem.cv_user_efun = false;\r
+            //cv_mem.cv_efun = cvEwtSet;\r
+            cv_mem.cv_efun_select = cvEwtSet_select;\r
+            cv_mem.cv_e_data = null; /* will be set to cvode_mem in InitialSetup */\r
+\r
+            return(CV_SUCCESS);\r
+          }\r
+\r
+          /* \r
+           * CVodeSetIterType\r
+           *\r
+           * Specifies the iteration type (CV_FUNCTIONAL or CV_NEWTON)\r
+           */\r
+\r
+          private int CVodeSetIterType(CVodeMemRec cv_mem, int iter)\r
+          {\r
+\r
+            if (cv_mem==null) {\r
+              cvProcessError(null, CV_MEM_NULL, "CVODES", "CVodeSetIterType", MSGCV_NO_MEM);\r
+              return(CV_MEM_NULL);\r
+            }\r
+\r
+            if ((iter != CV_FUNCTIONAL) && (iter != CV_NEWTON)) {\r
+              cvProcessError(cv_mem, CV_ILL_INPUT, "CVODES", "CVodeSetIterType", MSGCV_BAD_ITER);\r
+              return (CV_ILL_INPUT);\r
+            }\r
+\r
+            cv_mem.cv_iter = iter;\r
+\r
+            return(CV_SUCCESS);\r
+          }\r
+          \r
+          /*\r
+           * CVodeReInit\r
+           *\r
+           * CVodeReInit re-initializes CVODES's memory for a problem, assuming\r
+           * it has already been allocated in a prior CVodeInit call.\r
+           * All problem specification inputs are checked for errors.\r
+           * If any error occurs during initialization, it is reported to the\r
+           * file whose file pointer is errfp.\r
+           * The return value is CV_SUCCESS = 0 if no errors occurred, or\r
+           * a negative value otherwise.\r
+           */\r
+\r
+          private int CVodeReInit(CVodeMemRec cv_mem, double t0, NVector y0)\r
+          {\r
+            int i,k;\r
+           \r
+            /* Check cvode_mem */\r
+\r
+            if (cv_mem==null) {\r
+              cvProcessError(null, CV_MEM_NULL, "CVODES", "CVodeReInit",\r
+                             MSGCV_NO_MEM);\r
+              return(CV_MEM_NULL);\r
+            }\r
+\r
+            /* Check if cvode_mem was allocated */\r
+\r
+            if (cv_mem.cv_MallocDone == false) {\r
+              cvProcessError(cv_mem, CV_NO_MALLOC, "CVODES", "CVodeReInit",\r
+                             MSGCV_NO_MALLOC);\r
+              return(CV_NO_MALLOC);\r
+            }\r
+\r
+            /* Check for legal input parameters */\r
+\r
+            if (y0 == null) {\r
+              cvProcessError(cv_mem, CV_ILL_INPUT, "CVODES", "CVodeReInit",\r
+                             MSGCV_NULL_Y0);\r
+              return(CV_ILL_INPUT);\r
+            }\r
+            \r
+            /* Copy the input parameters into CVODES state */\r
+\r
+            cv_mem.cv_tn = t0;\r
+\r
+            /* Set step parameters */\r
+\r
+            cv_mem.cv_q      = 1;\r
+            cv_mem.cv_L      = 2;\r
+            cv_mem.cv_qwait  = cv_mem.cv_L;\r
+            cv_mem.cv_etamax = ETAMX1;\r
+\r
+            cv_mem.cv_qu     = 0;\r
+            cv_mem.cv_hu     = ZERO;\r
+            cv_mem.cv_tolsf  = ONE;\r
+\r
+            /* Set forceSetup to SUNFALSE */\r
+\r
+            cv_mem.cv_forceSetup = false;\r
+\r
+            /* Initialize zn[0] in the history array */\r
+\r
+            N_VScale_Serial(ONE, y0, cv_mem.cv_zn[0]);\r
+           \r
+            /* Initialize all the counters */\r
+\r
+            cv_mem.cv_nst     = 0;\r
+            cv_mem.cv_nfe     = 0;\r
+            cv_mem.cv_ncfn[0]    = 0;\r
+            cv_mem.cv_netf[0]    = 0;\r
+            cv_mem.cv_nni     = 0;\r
+            cv_mem.cv_nsetups = 0;\r
+            cv_mem.cv_nhnil   = 0;\r
+            cv_mem.cv_nstlp   = 0;\r
+            cv_mem.cv_nscon   = 0;\r
+            cv_mem.cv_nge     = 0;\r
+\r
+            cv_mem.cv_irfnd   = 0;\r
+\r
+            /* Initialize other integrator optional outputs */\r
+\r
+            cv_mem.cv_h0u      = ZERO;\r
+            cv_mem.cv_next_h   = ZERO;\r
+            cv_mem.cv_next_q   = 0;\r
+\r
+            /* Initialize Stablilty Limit Detection data */\r
+\r
+            cv_mem.cv_nor = 0;\r
+            for (i = 1; i <= 5; i++)\r
+              for (k = 1; k <= 3; k++) \r
+                cv_mem.cv_ssdat[i-1][k-1] = ZERO;\r
+            \r
+            /* Problem has been successfully re-initialized */\r
+\r
+            return(CV_SUCCESS);\r
+          }\r
+\r
+          /* CVDlsGetWorkSpace returns the length of workspace allocated for the\r
+          CVDLS linear solver. */\r
+       private int CVDlsGetWorkSpace(CVodeMemRec cv_mem, long lenrwLS[],\r
+                             long leniwLS[])\r
+       {\r
+         CVDlsMemRec cvdls_mem;\r
+         int lrw1[] = new int[1];\r
+         int liw1[] = new int[1];\r
+         long lrw, liw;\r
+         int flag;\r
+\r
+         /* Return immediately if cvode_mem or cv_mem->cv_lmem are NULL */\r
+         if (cv_mem == null) {\r
+           cvProcessError(null, CVDLS_MEM_NULL, "CVSDLS",\r
+                          "CVDlsGetWorkSpace", MSGD_CVMEM_NULL);\r
+           return(CVDLS_MEM_NULL);\r
+         }\r
+         \r
+         if (cv_mem.cv_lmem == null) {\r
+           cvProcessError(cv_mem, CVDLS_LMEM_NULL, "CVSDLS",\r
+                          "CVDlsGetWorkSpace", MSGD_LMEM_NULL);\r
+           return(CVDLS_LMEM_NULL);\r
+         }\r
+         cvdls_mem = cv_mem.cv_lmem;\r
+\r
+         /* initialize outputs with requirements from CVDlsMem structure */\r
+         lenrwLS[0] = 0;\r
+         leniwLS[0] = 4;\r
+\r
+         /* add NVector size */\r
+         N_VSpace_Serial(cvdls_mem.x, lrw1, liw1);\r
+         lenrwLS[0] = lrw1[0];\r
+         leniwLS[0] = liw1[0];\r
+         \r
+         /* add SUNMatrix size (only account for the one owned by Dls interface) */\r
+         //*lenrw = SM_LDATA_D(A);\r
+         //*leniw = 3 + SM_COLUMNS_D(A\r
+                 //     The assignment A_ldata = SM_LDATA_D(A) sets A_ldata to be\r
+                 //    the length of the data array for A.\r
+             lenrwLS[0] += cvdls_mem.savedJ.length*cvdls_mem.savedJ[0].length;\r
+          leniwLS[0] += (3 + cvdls_mem.savedJ[0].length);\r
+\r
+         /* add LS sizes */\r
+                // *leniwLS = 2 + DENSE_CONTENT(S)->N;\r
+                // content->N = MatrixRows;\r
+                 //MatrixRows = SUNDenseMatrix_Rows(A);\r
+\r
+                // *lenrwLS = 0;\r
+          SUNLinearSolver LS = cvdls_mem.LS;\r
+        lenrwLS[0] += 0;\r
+        leniwLS[0] += (2 + LS.N);\r
+           \r
+\r
+         return(CVDLS_SUCCESS);\r
+       }\r
+       \r
+       private void N_VSpace_Serial(NVector v, int lrw[], int liw[])\r
+       {\r
+         lrw[0] = v.data.length;\r
+         liw[0] = 1;\r
+\r
+         return;\r
+       }\r
 \r
 \r
 }
\ No newline at end of file