Exemplo n.º 1
0
static void CVDenseDQJac(long int N, DenseMat J, realtype t,
                         N_Vector y, N_Vector fy, void *jac_data,
                         N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
{
    realtype fnorm, minInc, inc, inc_inv, yjsaved, srur;
    realtype *tmp2_data, *y_data, *ewt_data;
    N_Vector ftemp, jthCol;
    long int j;

    CVodeMem cv_mem;
    CVDenseMem  cvdense_mem;

    /* jac_data points to cvode_mem */
    cv_mem = (CVodeMem) jac_data;
    cvdense_mem = (CVDenseMem) lmem;

    /* Save pointer to the array in tmp2 */
    tmp2_data = N_VGetArrayPointer(tmp2);

    /* Rename work vectors for readibility */
    ftemp = tmp1;
    jthCol = tmp2;

    /* Obtain pointers to the data for ewt, y */
    ewt_data = N_VGetArrayPointer(ewt);
    y_data   = N_VGetArrayPointer(y);

    /* Set minimum increment based on uround and norm of f */
    srur = RSqrt(uround);
    fnorm = N_VWrmsNorm(fy, ewt);
    minInc = (fnorm != ZERO) ?
             (MIN_INC_MULT * ABS(h) * uround * N * fnorm) : ONE;

    /* This is the only for loop for 0..N-1 in CVODE */

    for (j = 0; j < N; j++) {

        /* Generate the jth col of J(tn,y) */

        N_VSetArrayPointer(DENSE_COL(J,j), jthCol);

        yjsaved = y_data[j];
        inc = MAX(srur*ABS(yjsaved), minInc/ewt_data[j]);
        y_data[j] += inc;
        f(tn, y, ftemp, f_data);
        y_data[j] = yjsaved;

        inc_inv = ONE/inc;
        N_VLinearSum(inc_inv, ftemp, -inc_inv, fy, jthCol);

        DENSE_COL(J,j) = N_VGetArrayPointer(jthCol);
    }

    /* Restore original array pointer in tmp2 */
    N_VSetArrayPointer(tmp2_data, tmp2);

    /* Increment counter nfeD */
    nfeD += N;
}
Exemplo n.º 2
0
int FKINDenseJac(long int N, N_Vector uu, N_Vector fval,
		 DlsMat J, void *user_data, N_Vector vtemp1, N_Vector vtemp2)
{
  realtype *uu_data, *fval_data, *jacdata, *v1_data, *v2_data;
  int ier;

  /* Initialize all pointers to NULL */
  uu_data = fval_data = jacdata = v1_data = v2_data = NULL;

  /* NOTE: The user-supplied routine should set ier to an
     appropriate value, but we preset the value to zero
     (meaning SUCCESS) so the user need only reset the
     value if an error occurred */
  ier = 0;

  /* Get pointers to vector data */
  uu_data   = N_VGetArrayPointer(uu);
  fval_data = N_VGetArrayPointer(fval);
  v1_data   = N_VGetArrayPointer(vtemp1);
  v2_data   = N_VGetArrayPointer(vtemp2);

  jacdata = DENSE_COL(J,0);

  /* Call user-supplied routine */
  FK_DJAC(&N, uu_data, fval_data, jacdata, v1_data, v2_data, &ier);

  return(ier);
}
static int KINDenseDQJac(long int n, DenseMat J,
                         N_Vector u, N_Vector fu, void *jac_data,
                         N_Vector tmp1, N_Vector tmp2)
{
  realtype inc, inc_inv, ujsaved, ujscale, sign;
  realtype *tmp2_data, *u_data, *uscale_data;
  N_Vector ftemp, jthCol;
  long int j;
  int retval;

  KINMem kin_mem;
  KINDenseMem  kindense_mem;

  /* jac_data points to kin_mem */
  kin_mem = (KINMem) jac_data;
  kindense_mem = (KINDenseMem) lmem;

  /* Save pointer to the array in tmp2 */
  tmp2_data = N_VGetArrayPointer(tmp2);

  /* Rename work vectors for readibility */
  ftemp = tmp1; 
  jthCol = tmp2;

  /* Obtain pointers to the data for u and uscale */
  u_data   = N_VGetArrayPointer(u);
  uscale_data = N_VGetArrayPointer(uscale);

  /* This is the only for loop for 0..N-1 in KINSOL */

  for (j = 0; j < n; j++) {

    /* Generate the jth col of J(u) */

    N_VSetArrayPointer(DENSE_COL(J,j), jthCol);

    ujsaved = u_data[j];
    ujscale = ONE/uscale_data[j];
    sign = (ujsaved >= ZERO) ? ONE : -ONE;
    inc = sqrt_relfunc*MAX(ABS(ujsaved), ujscale)*sign;
    u_data[j] += inc;

    retval = func(u, ftemp, f_data);
    if (retval != 0) return(-1); 

    u_data[j] = ujsaved;

    inc_inv = ONE/inc;
    N_VLinearSum(inc_inv, ftemp, -inc_inv, fu, jthCol);

  }

  /* Restore original array pointer in tmp2 */
  N_VSetArrayPointer(tmp2_data, tmp2);

  /* Increment counter nfeD */
  nfeD += n;

  return(0);
}
Exemplo n.º 4
0
int FCVDenseJac(int N, realtype t, 
                N_Vector y, N_Vector fy, 
                DlsMat J, void *user_data,
                N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3)
{
  int ier;
  realtype *ydata, *fydata, *jacdata, *v1data, *v2data, *v3data;
  realtype h;
  FCVUserData CV_userdata;

  CVodeGetLastStep(CV_cvodemem, &h);

  ydata   = N_VGetArrayPointer(y);
  fydata  = N_VGetArrayPointer(fy);
  v1data  = N_VGetArrayPointer(vtemp1);
  v2data  = N_VGetArrayPointer(vtemp2);
  v3data  = N_VGetArrayPointer(vtemp3);

  jacdata = DENSE_COL(J,0);

  CV_userdata = (FCVUserData) user_data;

  FCV_DJAC(&N, &t, ydata, fydata, jacdata, &h, 
           CV_userdata->ipar, CV_userdata->rpar, v1data, v2data, v3data, &ier); 

  return(ier);
}
Exemplo n.º 5
0
void FCVDenseJac(long int N, DenseMat J, realtype t, 
                 N_Vector y, N_Vector fy, void *jac_data,
                 N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3)
{
  N_Vector ewt;
  realtype *ydata, *fydata, *jacdata, *ewtdata, *v1data, *v2data, *v3data;
  realtype h;

  ewt = N_VClone(y);

  CVodeGetErrWeights(CV_cvodemem, ewt);
  CVodeGetLastStep(CV_cvodemem, &h);

  ydata   = N_VGetArrayPointer(y);
  fydata  = N_VGetArrayPointer(fy);
  v1data  = N_VGetArrayPointer(vtemp1);
  v2data  = N_VGetArrayPointer(vtemp2);
  v3data  = N_VGetArrayPointer(vtemp3);
  ewtdata = N_VGetArrayPointer(ewt);

  jacdata = DENSE_COL(J,0);

  FCV_DJAC(&N, &t, ydata, fydata, jacdata, 
           ewtdata, &h, v1data, v2data, v3data);

  N_VDestroy(ewt);

}
int mtlb_IdaDenseJacB(long int NeqB, realtype tt,
                      N_Vector yy, N_Vector yp,
                      N_Vector yyB, N_Vector ypB, N_Vector rrB,
                      realtype c_jB, void *jac_dataB,
                      DenseMat JacB,
                      N_Vector tmp1B, N_Vector tmp2B,
                      N_Vector tmp3B)
{
    double *JB_data;
    long int i;
    mxArray *mx_in[10], *mx_out[3];
    int ret;

    /* Inputs to the Matlab function */
    mx_in[0] = mxCreateScalarDouble(-1.0);        /* type=-1: backward ODE */
    mx_in[1] = mxCreateScalarDouble(tt);          /* current t */
    mx_in[2] = mxCreateDoubleMatrix(N,1,mxREAL);  /* current yy */
    mx_in[3] = mxCreateDoubleMatrix(N,1,mxREAL);  /* current yp */
    mx_in[4] = mxCreateDoubleMatrix(NB,1,mxREAL); /* current yyB */
    mx_in[5] = mxCreateDoubleMatrix(NB,1,mxREAL); /* current ypB */
    mx_in[6] = mxCreateDoubleMatrix(NB,1,mxREAL); /* current rrB */
    mx_in[7] = mxCreateScalarDouble(c_jB);        /* current c_jB */
    mx_in[8] = mx_JACfctB;                        /* matlab function handle */
    mx_in[9] = mx_data;                           /* matlab user data */

    /* Call matlab wrapper */
    GetData(yy, mxGetPr(mx_in[2]), N);
    GetData(yp, mxGetPr(mx_in[3]), N);
    GetData(yyB, mxGetPr(mx_in[4]), NB);
    GetData(ypB, mxGetPr(mx_in[5]), NB);
    GetData(rrB, mxGetPr(mx_in[6]), NB);

    mexCallMATLAB(3,mx_out,10,mx_in,"idm_djac");

    JB_data = mxGetPr(mx_out[0]);
    for (i=0; i<NB; i++)
        memcpy(DENSE_COL(JacB,i), JB_data + i*NB, NB*sizeof(double));

    ret = (int)*mxGetPr(mx_out[1]);

    if (!mxIsEmpty(mx_out[2])) {
        UpdateUserData(mx_out[2]);
    }

    /* Free temporary space */
    mxDestroyArray(mx_in[0]);
    mxDestroyArray(mx_in[1]);
    mxDestroyArray(mx_in[2]);
    mxDestroyArray(mx_in[3]);
    mxDestroyArray(mx_in[4]);
    mxDestroyArray(mx_in[5]);
    mxDestroyArray(mx_in[6]);
    mxDestroyArray(mx_in[7]);
    mxDestroyArray(mx_out[0]);
    mxDestroyArray(mx_out[1]);
    mxDestroyArray(mx_out[2]);

    return(ret);
}
int mtlb_IdaDenseJac(long int Neq, realtype tt,
                     N_Vector yy, N_Vector yp, N_Vector rr,
                     realtype c_j, void *jac_data,
                     DenseMat Jac,
                     N_Vector tmp1, N_Vector tmp2,
                     N_Vector tmp3)
{
    double *J_data;
    long int i;
    int ret;
    mxArray *mx_in[8], *mx_out[3];

    /* Inputs to the Matlab function */
    mx_in[0] = mxCreateScalarDouble(1.0);         /* type=1: forward ODE */
    mx_in[1] = mxCreateScalarDouble(tt);          /* current t */
    mx_in[2] = mxCreateDoubleMatrix(N,1,mxREAL);  /* current yy */
    mx_in[3] = mxCreateDoubleMatrix(N,1,mxREAL);  /* current yp */
    mx_in[4] = mxCreateDoubleMatrix(N,1,mxREAL);  /* current rr */
    mx_in[5] = mxCreateScalarDouble(c_j);         /* current c_j */
    mx_in[6] = mx_JACfct;                         /* matlab function handle */
    mx_in[7] = mx_data;                           /* matlab user data */

    /* Call matlab wrapper */
    GetData(yy, mxGetPr(mx_in[2]), N);
    GetData(yp, mxGetPr(mx_in[3]), N);
    GetData(rr, mxGetPr(mx_in[4]), N);

    mexCallMATLAB(3,mx_out,8,mx_in,"idm_djac");

    /* Extract data */
    J_data = mxGetPr(mx_out[0]);
    for (i=0; i<N; i++)
        memcpy(DENSE_COL(Jac,i), J_data + i*N, N*sizeof(double));

    ret = (int)*mxGetPr(mx_out[1]);

    if (!mxIsEmpty(mx_out[2])) {
        UpdateUserData(mx_out[2]);
    }

    /* Free temporary space */
    mxDestroyArray(mx_in[0]);
    mxDestroyArray(mx_in[1]);
    mxDestroyArray(mx_in[2]);
    mxDestroyArray(mx_in[3]);
    mxDestroyArray(mx_in[4]);
    mxDestroyArray(mx_in[5]);
    mxDestroyArray(mx_out[0]);
    mxDestroyArray(mx_out[1]);
    mxDestroyArray(mx_out[2]);

    return(ret);
}
Exemplo n.º 8
0
int mxW_CVodeDenseJacB(long int NeqB, realtype t,
                       N_Vector y, N_Vector yB, N_Vector fyB,
                       DlsMat JB, void *user_dataB, 
                       N_Vector tmp1B, N_Vector tmp2B, N_Vector tmp3B)
{
  cvmPbData fwdPb, bckPb;
  double *JB_data;
  mxArray *mx_in[6], *mx_out[3];
  int i, ret;

  /* Extract global interface data from user-data */
  bckPb = (cvmPbData) user_dataB;
  fwdPb = bckPb->fwd;

  /* Inputs to the Matlab function */
  mx_in[0] = mxCreateDoubleScalar(t);           /* current t */  
  mx_in[1] = mxCreateDoubleMatrix(N,1,mxREAL);  /* current y */
  mx_in[2] = mxCreateDoubleMatrix(NB,1,mxREAL); /* current yB */
  mx_in[3] = mxCreateDoubleMatrix(NB,1,mxREAL); /* current fyB */
  mx_in[4] = bckPb->JACfct;                     /* matlab function handle */
  mx_in[5] = bckPb->mtlb_data;                  /* matlab user data */
  
  /* Call matlab wrapper */
  GetData(y, mxGetPr(mx_in[1]), N);
  GetData(yB, mxGetPr(mx_in[2]), NB);
  GetData(fyB, mxGetPr(mx_in[3]), NB);

  mexCallMATLAB(3,mx_out,6,mx_in,"cvm_djacB");

  JB_data = mxGetPr(mx_out[0]);
  for (i=0;i<NB;i++)
    memcpy(DENSE_COL(JB,i), JB_data + i*NB, NB*sizeof(double));

  ret = (int)*mxGetPr(mx_out[1]);

  if (!mxIsEmpty(mx_out[2])) {
    UpdateUserData(mx_out[2], bckPb);
  }

  /* Free temporary space */
  mxDestroyArray(mx_in[0]);
  mxDestroyArray(mx_in[1]);
  mxDestroyArray(mx_in[2]);
  mxDestroyArray(mx_in[3]);
  mxDestroyArray(mx_out[0]);
  mxDestroyArray(mx_out[1]);
  mxDestroyArray(mx_out[2]);

  return(ret);
}
Exemplo n.º 9
0
static void
CVDenseDQJac(integertype N, DenseMat J, RhsFn f, void *f_data,
			 realtype tn, N_Vector y, N_Vector fy, N_Vector ewt,
			 realtype h, realtype uround, void *jac_data,
			 long int *nfePtr, N_Vector vtemp1,
			 N_Vector vtemp2, N_Vector vtemp3)
{
	realtype fnorm, minInc, inc, inc_inv, yjsaved, srur;
	realtype *y_data, *ewt_data;
	N_Vector ftemp, jthCol;
	M_Env machEnv;
	integertype j;

	machEnv = y->menv;			/* Get machine environment */

	ftemp = vtemp1;				/* Rename work vector for use as f vector value */

	/* Obtain pointers to the data for ewt, y */
	ewt_data = N_VGetData(ewt);
	y_data = N_VGetData(y);

	/* Set minimum increment based on uround and norm of f */
	srur = RSqrt(uround);
	fnorm = N_VWrmsNorm(fy, ewt);
	minInc = (fnorm != ZERO) ?
		(MIN_INC_MULT * ABS(h) * uround * N * fnorm) : ONE;

	jthCol = N_VMake(N, y_data, machEnv);	/* j loop overwrites this data address */

	/* This is the only for loop for 0..N-1 in CVODE */
	for (j = 0; j < N; j++)
	{

		/* Generate the jth col of J(tn,y) */

		N_VSetData(DENSE_COL(J, j), jthCol);
		yjsaved = y_data[j];
		inc = MAX(srur * ABS(yjsaved), minInc / ewt_data[j]);
		y_data[j] += inc;
		f(N, tn, y, ftemp, f_data);
		inc_inv = ONE / inc;
		N_VLinearSum(inc_inv, ftemp, -inc_inv, fy, jthCol);
		y_data[j] = yjsaved;
	}

	N_VDispose(jthCol);

	/* Increment counter nfe = *nfePtr */
	*nfePtr += N;
}
Exemplo n.º 10
0
int mxW_CVodeDenseJac(long int Neq, realtype t,
                      N_Vector y, N_Vector fy, 
                      DlsMat J, void *user_data,
                      N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
{
  cvmPbData fwdPb;
  double *J_data;
  long int i;
  int ret;
  mxArray *mx_in[5], *mx_out[3];

  /* Extract global interface data from user-data */
  fwdPb = (cvmPbData) user_data;

  /* Inputs to the Matlab function */
  mx_in[0] = mxCreateDoubleScalar(t);           /* current t */  
  mx_in[1] = mxCreateDoubleMatrix(N,1,mxREAL);  /* current y */
  mx_in[2] = mxCreateDoubleMatrix(N,1,mxREAL);  /* current fy */
  mx_in[3] = fwdPb->JACfct;                     /* matlab function handle */
  mx_in[4] = fwdPb->mtlb_data;                  /* matlab user data */
  
  /* Call matlab wrapper */
  GetData(y, mxGetPr(mx_in[1]), N);
  GetData(fy, mxGetPr(mx_in[2]), N);

  mexCallMATLAB(3,mx_out,5,mx_in,"cvm_djac");

  /* Extract data */
  J_data = mxGetPr(mx_out[0]);
  for (i=0;i<N;i++)
    memcpy(DENSE_COL(J,i), J_data + i*N, N*sizeof(double));

  ret = (int)*mxGetPr(mx_out[1]);

  if (!mxIsEmpty(mx_out[2])) {
    UpdateUserData(mx_out[2], fwdPb);
  }

  /* Free temporary space */
  mxDestroyArray(mx_in[0]);
  mxDestroyArray(mx_in[1]);
  mxDestroyArray(mx_in[2]);
  mxDestroyArray(mx_out[0]);
  mxDestroyArray(mx_out[1]);
  mxDestroyArray(mx_out[2]);

  return(ret);
}
Exemplo n.º 11
0
/* C interface to user-supplied Fortran routine FARKDMASS; see 
   farkode.h for additional information  */
int FARKLapackDenseMass(long int N, realtype t, DlsMat M, 
			void *user_data, N_Vector vtemp1, 
			N_Vector vtemp2, N_Vector vtemp3)
{
  int ier;
  realtype *massdata, *v1data, *v2data, *v3data;
  FARKUserData ARK_userdata;

  v1data  = N_VGetArrayPointer(vtemp1);
  v2data  = N_VGetArrayPointer(vtemp2);
  v3data  = N_VGetArrayPointer(vtemp3);
  massdata = DENSE_COL(M,0);
  ARK_userdata = (FARKUserData) user_data;

  FARK_DMASS(&N, &t, massdata, ARK_userdata->ipar, ARK_userdata->rpar, 
	     v1data, v2data, v3data, &ier); 
  return(ier);
}
Exemplo n.º 12
0
int mxW_KINDenseJac(long int Neq,
                    N_Vector y, N_Vector fy, 
                    DlsMat J, void *user_data,
                    N_Vector tmp1, N_Vector tmp2)
{
  kimInterfaceData kimData;
  double *J_data;
  mxArray *mx_in[4], *mx_out[3];
  int i, ret;

  /* Extract global interface data from user-data */
  kimData = (kimInterfaceData) user_data;

  /* Inputs to the Matlab function */
  mx_in[0] = mxCreateDoubleMatrix(N,1,mxREAL);  /* current y */
  mx_in[1] = mxCreateDoubleMatrix(N,1,mxREAL);  /* current fy */
  mx_in[2] = kimData->JACfct;                   /* matlab function handle */
  mx_in[3] = kimData->mtlb_data;                /* matlab user data */
  
  /* Call matlab wrapper */

  GetData(y, mxGetPr(mx_in[0]), N);
  GetData(fy, mxGetPr(mx_in[1]), N);

  mexCallMATLAB(3,mx_out,4,mx_in,"kim_djac");

  J_data = mxGetPr(mx_out[0]);
  for (i=0;i<N;i++)  memcpy(DENSE_COL(J,i), J_data + i*N, N*sizeof(double));
  ret = (int)*mxGetPr(mx_out[1]);
 
  if (!mxIsEmpty(mx_out[2])) {
    UpdateUserData(mx_out[2], kimData);
  }

  /* Free temporary space */
  mxDestroyArray(mx_in[0]);
  mxDestroyArray(mx_in[1]);
  mxDestroyArray(mx_out[0]);
  mxDestroyArray(mx_out[1]);
  mxDestroyArray(mx_out[2]);

  return(ret);
}
Exemplo n.º 13
0
/* The C function FARKLapackDenseJac interfaces between ARKODE
   and a Fortran subroutine FARKDJAC for solution of a linear
   system using Lapack with dense Jacobian approximation.
   Addresses of arguments are passed to FARKDJAC, using the macro
   DENSE_COL and the routine N_VGetArrayPointer from NVECTOR  */
int FARKLapackDenseJac(long int N, realtype t, N_Vector y,
                       N_Vector fy, DlsMat J, void *user_data,
                       N_Vector vtemp1, N_Vector vtemp2,
                       N_Vector vtemp3)
{
    int ier;
    realtype *ydata, *fydata, *jacdata, *v1data, *v2data, *v3data;
    realtype h;
    FARKUserData ARK_userdata;

    ARKodeGetLastStep(ARK_arkodemem, &h);
    ydata   = N_VGetArrayPointer(y);
    fydata  = N_VGetArrayPointer(fy);
    v1data  = N_VGetArrayPointer(vtemp1);
    v2data  = N_VGetArrayPointer(vtemp2);
    v3data  = N_VGetArrayPointer(vtemp3);
    jacdata = DENSE_COL(J,0);
    ARK_userdata = (FARKUserData) user_data;

    FARK_DJAC(&N, &t, ydata, fydata, jacdata, &h, ARK_userdata->ipar,
              ARK_userdata->rpar, v1data, v2data, v3data, &ier);
    return(ier);
}
Exemplo n.º 14
0
int cvDlsDenseDQJac(long int N, realtype t,
                    N_Vector y, N_Vector fy, 
                    DlsMat Jac, void *data,
                    N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
{
  realtype fnorm, minInc, inc, inc_inv, yjsaved, srur;
  realtype *tmp2_data, *y_data, *ewt_data;
  N_Vector ftemp, jthCol;
  long int j;
  int retval = 0;

  CVodeMem cv_mem;
  CVDlsMem cvdls_mem;

  /* data points to cvode_mem */
  cv_mem = (CVodeMem) data;
  cvdls_mem = (CVDlsMem) lmem;

  /* Save pointer to the array in tmp2 */
  tmp2_data = N_VGetArrayPointer(tmp2);

  /* Rename work vectors for readibility */
  ftemp = tmp1; 
  jthCol = tmp2;

  /* Obtain pointers to the data for ewt, y */
  ewt_data = N_VGetArrayPointer(ewt);
  y_data   = N_VGetArrayPointer(y);

  /* Set minimum increment based on uround and norm of f */
  srur = RSqrt(uround);
  fnorm = N_VWrmsNorm(fy, ewt);
  minInc = (fnorm != ZERO) ?
           (MIN_INC_MULT * ABS(h) * uround * N * fnorm) : ONE;

  for (j = 0; j < N; j++) {

    /* Generate the jth col of J(tn,y) */

    N_VSetArrayPointer(DENSE_COL(Jac,j), jthCol);

    yjsaved = y_data[j];
    inc = MAX(srur*ABS(yjsaved), minInc/ewt_data[j]);
    y_data[j] += inc;

    retval = f(t, y, ftemp, user_data);
    nfeDQ++;
    if (retval != 0) break;
    
    y_data[j] = yjsaved;

    inc_inv = ONE/inc;
    N_VLinearSum(inc_inv, ftemp, -inc_inv, fy, jthCol);

    DENSE_COL(Jac,j) = N_VGetArrayPointer(jthCol);
  }

  /* Restore original array pointer in tmp2 */
  N_VSetArrayPointer(tmp2_data, tmp2);

  return(retval);
}
Exemplo n.º 15
0
int kinDlsDenseDQJac(long int N,
                     N_Vector u, N_Vector fu,
                     DlsMat Jac, void *data,
                     N_Vector tmp1, N_Vector tmp2)
{
    realtype inc, inc_inv, ujsaved, ujscale, sign;
    realtype *tmp2_data, *u_data, *uscale_data;
    N_Vector ftemp, jthCol;
    int retval = 0;
    long int j;

    KINMem kin_mem;
    KINDlsMem  kindls_mem;

    /* data points to kin_mem */
    kin_mem = (KINMem) data;
    kindls_mem = (KINDlsMem) lmem;

    /* Save pointer to the array in tmp2 */
    tmp2_data = N_VGetArrayPointer(tmp2);

    /* Rename work vectors for readibility */
    ftemp = tmp1;
    jthCol = tmp2;

    /* Obtain pointers to the data for u and uscale */
    u_data   = N_VGetArrayPointer(u);
    uscale_data = N_VGetArrayPointer(uscale);

    /* This is the only for loop for 0..N-1 in KINSOL */

    for (j = 0; j < N; j++)
    {

        /* Generate the jth col of Jac(u) */

        N_VSetArrayPointer(DENSE_COL(Jac, j), jthCol);

        ujsaved = u_data[j];
        ujscale = ONE / uscale_data[j];
        sign = (ujsaved >= ZERO) ? ONE : -ONE;
        inc = sqrt_relfunc * MAX(ABS(ujsaved), ujscale) * sign;
        u_data[j] += inc;

        retval = func(u, ftemp, user_data);
        nfeDQ++;
        if (retval != 0)
        {
            break;
        }

        u_data[j] = ujsaved;

        inc_inv = ONE / inc;
        N_VLinearSum(inc_inv, ftemp, -inc_inv, fu, jthCol);

    }

    /* Restore original array pointer in tmp2 */
    N_VSetArrayPointer(tmp2_data, tmp2);

    return(retval);
}
Exemplo n.º 16
0
/*
 * -----------------------------------------------------------------
 * idaDlsDenseDQJac
 * -----------------------------------------------------------------
 * This routine generates a dense difference quotient approximation to
 * the Jacobian F_y + c_j*F_y'. It assumes that a dense matrix of type
 * DlsMat is stored column-wise, and that elements within each column
 * are contiguous. The address of the jth column of J is obtained via
 * the macro LAPACK_DENSE_COL and this pointer is associated with an N_Vector
 * using the N_VGetArrayPointer/N_VSetArrayPointer functions.
 * Finally, the actual computation of the jth column of the Jacobian is
 * done with a call to N_VLinearSum.
 * -----------------------------------------------------------------
 */
int idaDlsDenseDQJac(long int N, realtype tt, realtype c_j,
                     N_Vector yy, N_Vector yp, N_Vector rr,
                     DlsMat Jac, void *data,
                     N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
{
    realtype inc, inc_inv, yj, ypj, srur, conj;
    realtype *tmp2_data, *y_data, *yp_data, *ewt_data, *cns_data = NULL;
    N_Vector rtemp, jthCol;
    long int j;
    int retval = 0;

    IDAMem IDA_mem;
    IDADlsMem idadls_mem;

    /* data points to IDA_mem */
    IDA_mem = (IDAMem) data;
    idadls_mem = (IDADlsMem) lmem;

    /* Save pointer to the array in tmp2 */
    tmp2_data = N_VGetArrayPointer(tmp2);

    /* Rename work vectors for readibility */
    rtemp  = tmp1;
    jthCol = tmp2;

    /* Obtain pointers to the data for ewt, yy, yp. */
    ewt_data = N_VGetArrayPointer(ewt);
    y_data   = N_VGetArrayPointer(yy);
    yp_data  = N_VGetArrayPointer(yp);
    if (constraints != NULL)
    {
        cns_data = N_VGetArrayPointer(constraints);
    }

    srur = RSqrt(uround);

    for (j = 0; j < N; j++)
    {

        /* Generate the jth col of J(tt,yy,yp) as delta(F)/delta(y_j). */

        /* Set data address of jthCol, and save y_j and yp_j values. */
        N_VSetArrayPointer(DENSE_COL(Jac, j), jthCol);
        yj = y_data[j];
        ypj = yp_data[j];

        /* Set increment inc to y_j based on sqrt(uround)*abs(y_j), with
        adjustments using yp_j and ewt_j if this is small, and a further
        adjustment to give it the same sign as hh*yp_j. */

        inc = MAX( srur * MAX( ABS(yj), ABS(hh * ypj) ) , ONE / ewt_data[j] );

        if (hh * ypj < ZERO)
        {
            inc = -inc;
        }
        inc = (yj + inc) - yj;

        /* Adjust sign(inc) again if y_j has an inequality constraint. */
        if (constraints != NULL)
        {
            conj = cns_data[j];
            if (ABS(conj) == ONE)
            {
                if ((yj + inc)*conj <  ZERO)
                {
                    inc = -inc;
                }
            }
            else if (ABS(conj) == TWO)
            {
                if ((yj + inc)*conj <= ZERO)
                {
                    inc = -inc;
                }
            }
        }

        /* Increment y_j and yp_j, call res, and break on error return. */
        y_data[j] += inc;
        yp_data[j] += c_j * inc;

        retval = res(tt, yy, yp, rtemp, user_data);
        nreDQ++;
        if (retval != 0)
        {
            break;
        }

        /* Construct difference quotient in jthCol */
        inc_inv = ONE / inc;
        N_VLinearSum(inc_inv, rtemp, -inc_inv, rr, jthCol);

        DENSE_COL(Jac, j) = N_VGetArrayPointer(jthCol);

        /*  reset y_j, yp_j */
        y_data[j] = yj;
        yp_data[j] = ypj;
    }

    /* Restore original array pointer in tmp2 */
    N_VSetArrayPointer(tmp2_data, tmp2);

    return(retval);

}
Exemplo n.º 17
0
/*
 * -----------------------------------------------------------------
 * cpDlsDenseDQJacImpl 
 * -----------------------------------------------------------------
 * This routine generates a dense difference quotient approximation to
 * the Jacobian F_y' + gamma*F_y. It assumes that a dense matrix of type
 * DlsMat is stored column-wise, and that elements within each column
 * are contiguous. The address of the jth column of J is obtained via
 * the macro DENSE_COL and this pointer is associated with an N_Vector
 * using the N_VGetArrayPointer/N_VSetArrayPointer functions. 
 * Finally, the actual computation of the jth column of the Jacobian is 
 * done with a call to N_VLinearSum.
 * -----------------------------------------------------------------
 */ 
int cpDlsDenseDQJacImpl(int N, realtype t, realtype gm,
                        N_Vector y, N_Vector yp, N_Vector r, 
                        DlsMat Jac, void *jac_data,
                        N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
{
  realtype inc, inc_inv, yj, ypj, srur;
  realtype *tmp2_data, *y_data, *yp_data, *ewt_data;
  N_Vector ftemp, jthCol;
  int j;
  int retval = 0;

  CPodeMem cp_mem;
  CPDlsMem  cpdls_mem;

  /* jac_data points to cpode_mem */
  cp_mem = (CPodeMem) jac_data;
  cpdls_mem = (CPDlsMem) lmem;

  /* Save pointer to the array in tmp2 */
  tmp2_data = N_VGetArrayPointer(tmp2);

  /* Rename work vectors for readibility */
  ftemp = tmp1; 
  jthCol = tmp2;

  /* Obtain pointers to the data for ewt, y, and yp */
  ewt_data = N_VGetArrayPointer(ewt);
  y_data   = N_VGetArrayPointer(y);
  yp_data  = N_VGetArrayPointer(yp);

  /* Set minimum increment based on uround and norm of f */
  srur = RSqrt(uround);

  /* Generate each column of the Jacobian M = F_y' + gamma * F_y
     as delta(F)/delta(y_j). */
  for (j = 0; j < N; j++) {

    /* Set data address of jthCol, and save y_j and yp_j values. */
    N_VSetArrayPointer(DENSE_COL(Jac,j), jthCol);
    yj = y_data[j];
    ypj = yp_data[j];

    /* Set increment inc to y_j based on sqrt(uround)*abs(y_j), with
    adjustments using yp_j and ewt_j if this is small, and a further
    adjustment to give it the same sign as h*yp_j. */
    inc = MAX( srur * MAX( ABS(yj), ABS(h*ypj) ) , ONE/ewt_data[j] );
    if (h*ypj < ZERO) inc = -inc;
    inc = (yj + inc) - yj;

    /* Increment y_j and yp_j, call res, and break on error return. */
    y_data[j]  += gamma*inc;
    yp_data[j] += inc;
    retval = fi(t, y, yp, ftemp, f_data);
    nfeDQ++;
    if (retval != 0) break;

    /* Generate the jth col of J(tn,y) */
    inc_inv = ONE/inc;
    N_VLinearSum(inc_inv, ftemp, -inc_inv, r, jthCol);

    DENSE_COL(Jac,j) = N_VGetArrayPointer(jthCol);

    /* Reset y_j, yp_j */     
    y_data[j] = yj;
    yp_data[j] = ypj;
  }

  /* Restore original array pointer in tmp2 */
  N_VSetArrayPointer(tmp2_data, tmp2);

  return(retval);
}