/* Jacobian routine to compute J(t,y) = df/dy. */
static int Jac(long int N, realtype t,
               N_Vector y, N_Vector fy, DlsMat J, void *user_data,
               N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
{
  realtype *rdata = (realtype *) user_data;   /* cast user_data to realtype */
  realtype ep = rdata[2];                     /* access data entries */
  realtype u = NV_Ith_S(y,0);                 /* access solution values */
  realtype v = NV_Ith_S(y,1);
  realtype w = NV_Ith_S(y,2);

  /* fill in the Jacobian */
  DENSE_ELEM(J,0,0) = -(w+1.0) + 2.0*u*v;
  DENSE_ELEM(J,0,1) = u*u;
  DENSE_ELEM(J,0,2) = -u;

  DENSE_ELEM(J,1,0) = w - 2.0*u*v;
  DENSE_ELEM(J,1,1) = -u*u;
  DENSE_ELEM(J,1,2) = u;

  DENSE_ELEM(J,2,0) = -w;
  DENSE_ELEM(J,2,1) = 0.0;
  DENSE_ELEM(J,2,2) = -1.0/ep - u;

  return 0;                                  /* Return with success */
}
Exemple #2
0
void PrintMat(DlsMat A)
{
  long int i, j, start, finish;
  realtype **a;

  switch (A->type) {

  case SUNDIALS_DENSE:

    printf("\n");
    for (i=0; i < A->M; i++) {
      for (j=0; j < A->N; j++) {
#if defined(SUNDIALS_EXTENDED_PRECISION)
        printf("%12Lg  ", DENSE_ELEM(A,i,j));
#elif defined(SUNDIALS_DOUBLE_PRECISION)
        printf("%12g  ", DENSE_ELEM(A,i,j));
#else
        printf("%12g  ", DENSE_ELEM(A,i,j));
#endif
      }
      printf("\n");
    }
    printf("\n");

    break;

  case SUNDIALS_BAND:

    a = A->cols;
    printf("\n");
    for (i=0; i < A->N; i++) {
      start = SUNMAX(0,i-A->ml);
      finish = SUNMIN(A->N-1,i+A->mu);
      for (j=0; j < start; j++) printf("%12s  ","");
      for (j=start; j <= finish; j++) {
#if defined(SUNDIALS_EXTENDED_PRECISION)
        printf("%12Lg  ", a[j][i-j+A->s_mu]);
#elif defined(SUNDIALS_DOUBLE_PRECISION)
        printf("%12g  ", a[j][i-j+A->s_mu]);
#else
        printf("%12g  ", a[j][i-j+A->s_mu]);
#endif
      }
      printf("\n");
    }
    printf("\n");

    break;

  }

}
Exemple #3
0
static void Jac1(long int N, DenseMat J, realtype tn,
                 N_Vector y, N_Vector fy, void *jac_data,
                 N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
{
  realtype y0, y1;

  y0 = NV_Ith_S(y,0);
  y1 = NV_Ith_S(y,1);

  DENSE_ELEM(J,0,1) = ONE;
  DENSE_ELEM(J,1,0) = -TWO * P1_ETA * y0 * y1 - ONE;
  DENSE_ELEM(J,1,1) = P1_ETA * (ONE - SQR(y0));
}
/*
 *  function calculates a jacobian matrix
 */
static
int nlsDenseJac(long int N, N_Vector vecX, N_Vector vecFX, DlsMat Jac, void *userData, N_Vector tmp1, N_Vector tmp2)
{
  NLS_KINSOL_USERDATA *kinsolUserData = (NLS_KINSOL_USERDATA*) userData;
  DATA* data = kinsolUserData->data;
  threadData_t *threadData = kinsolUserData->threadData;
  int sysNumber = kinsolUserData->sysNumber;
  NONLINEAR_SYSTEM_DATA *nlsData = &(data->simulationInfo->nonlinearSystemData[sysNumber]);
  NLS_KINSOL_DATA* kinsolData = (NLS_KINSOL_DATA*) nlsData->solverData;

  /* prepare variables */
  double *x = N_VGetArrayPointer(vecX);
  double *fx = N_VGetArrayPointer(vecFX);
  double *xScaling = NV_DATA_S(kinsolData->xScale);
  double *fRes = NV_DATA_S(kinsolData->fRes);
  double xsave, xscale, sign;
  double delta_hh;
  const double delta_h = sqrt(DBL_EPSILON*2e1);

  long int i,j;

  /* performance measurement */
  rt_ext_tp_tick(&nlsData->jacobianTimeClock);

  for(i = 0; i < N; i++)
  {
    xsave = x[i];
    delta_hh = delta_h * (fabs(xsave) + 1.0);
    if ((xsave + delta_hh >=  nlsData->max[i]))
      delta_hh *= -1;
    x[i] += delta_hh;

    /* Calculate difference quotient */
    nlsKinsolResiduals(vecX, kinsolData->fRes, userData);

    /* Calculate scaled difference quotient */
    delta_hh = 1. / delta_hh;

    for(j = 0; j < N; j++)
    {
      DENSE_ELEM(Jac, j, i) = (fRes[j] - fx[j]) * delta_hh;
    }
    x[i] = xsave;
  }

  /* debug */
  if (ACTIVE_STREAM(LOG_NLS_JAC)){
    infoStreamPrint(LOG_NLS_JAC, 0, "##KINSOL## omc dense matrix.");
    PrintMat(Jac);
  }

  /* performance measurement and statistics */
  nlsData->jacobianTime += rt_ext_tp_tock(&(nlsData->jacobianTimeClock));
  nlsData->numberOfJEval++;

  return 0;
}
Exemple #5
0
static int
JacRes(int N, realtype t, realtype cj, N_Vector y, N_Vector dy,
       N_Vector resvec, DlsMat J, void *jac_data,
       N_Vector tempv1, N_Vector tempv2, N_Vector tempv3)
{
  
  int i, j;
  realtype *ydata;
  cvodeData_t *data;
  data  = (cvodeData_t *) jac_data;
  ydata = NV_DATA_S(y);

  /* update ODE variables from CVODE */
  for ( i=0; i<data->model->neq; i++ ) {
    data->value[i] = ydata[i];
  }
  /* update algebraic constraint defined variables */

  /* update assignment rules */
  for ( i=0; i<data->model->nass; i++ ) {
    data->value[data->model->neq+i] =
      evaluateAST(data->model->assignment[i],data);
  }
  /* update time */
  data->currenttime = t;

  /* evaluate Jacobian*/
  for ( i=0; i<data->model->neq; i++ ) {
    for ( j=0; j<data->model->neq; j++ ) {
      DENSE_ELEM(J,i,j) = evaluateAST(data->model->jacob[i][j], data);
      if ( i == j )
	DENSE_ELEM(J, i, j) -= cj;
    }
  }
  
  for ( i=0; i<data->model->nalg; i++ ) 
    for ( j=0; j<data->model->nalg; j++ ) 
      DENSE_ELEM(J,i,j) = 1.; /* algebraic jacobian here!! */

  return (0);
}
Exemple #6
0
CAMLprim value c_densematrix_set(value vmatrix, value vi, value vj, value v)
{
    CAMLparam4(vmatrix, vi, vj, v);
    DlsMat m = DLSMAT(vmatrix);

    int i = Long_val(vi);
    int j = Long_val(vj);

#if SUNDIALS_ML_SAFE == 1
    if (i < 0 || i >= m->M) caml_invalid_argument("DenseMatrix.set: invalid i.");
    if (j < 0 || j >= m->N) caml_invalid_argument("DenseMatrix.set: invalid j.");
#endif

    DENSE_ELEM(m, i, j) = Double_val(v);
    CAMLreturn(caml_copy_double(v));
}
/* Jacobian routine to compute J(t,y) = df/dy. */
static int Jac(long int N, realtype t,
               N_Vector y, N_Vector fy, DlsMat J, void *user_data,
               N_Vector tmp1, N_Vector tmp2, N_Vector tmp3)
{
  realtype v = NV_Ith_S(y,1);    /* access current solution */
  realtype w = NV_Ith_S(y,2);
  SetToZero(J);                  /* initialize Jacobian to zero */

  /* Fill in the Jacobian of the ODE RHS function */
  DENSE_ELEM(J,0,0) = -0.04;
  DENSE_ELEM(J,0,1) = 1.e4*w;
  DENSE_ELEM(J,0,2) = 1.e4*v;

  DENSE_ELEM(J,1,0) = 0.04;
  DENSE_ELEM(J,1,1) = -1.e4*w - 6.e7*v;
  DENSE_ELEM(J,1,2) = -1.e4*v;

  DENSE_ELEM(J,2,1) = 6.e7*v;

  return 0;                      /* Return with success */
}
Exemple #8
0
/*
 * -----------------------------------------------------------------
 * cpDlsDenseProjDQJac 
 * -----------------------------------------------------------------
 * This routine generates a dense difference quotient approximation 
 * to the transpose of the Jacobian of c(t,y). It loads it into a 
 * dense matrix of type DlsMat stored column-wise with elements 
 * within each column 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 and 
 * N_VSetArrayPointer functions. 
 * Finally, the actual computation of the jth column of the Jacobian
 * transposed is done with a call to N_VLinearSum.
 * -----------------------------------------------------------------
 */ 
int cpDlsDenseProjDQJac(int Nc, int Ny, realtype t,
                        N_Vector y, N_Vector cy, 
                        DlsMat Jac, void *jac_data,
                        N_Vector c_tmp1, N_Vector c_tmp2)
{
  realtype inc, inc_inv, yj, srur;
  realtype *y_data, *ewt_data, *jthCol_data;
  N_Vector ctemp, jthCol;
  int i, j;
  int retval = 0;

  CPodeMem cp_mem;
  CPDlsProjMem cpdlsP_mem;

  /* jac_data points to cpode_mem */
  cp_mem = (CPodeMem) jac_data;
  cpdlsP_mem = (CPDlsProjMem) lmemP;

  /* Rename work vectors for readibility */
  ctemp  = c_tmp1; 
  jthCol = c_tmp2;

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

  /* Obtain pointer to the data for jthCol */
  jthCol_data = N_VGetArrayPointer(jthCol);

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

  /* Generate each column of the Jacobian G = dc/dy as delta(c)/delta(y_j). */
  for (j = 0; j < Ny; j++) {

    /* Save the y_j values. */
    yj = y_data[j];

    /* Set increment inc to y_j based on sqrt(uround)*abs(y_j), 
       with an adjustment using ewt_j if this is small */
    inc = MAX( srur * ABS(yj) , ONE/ewt_data[j] );
    inc = (yj + inc) - yj;

    /* Increment y_j, call cfun, and break on error return. */
    y_data[j]  += inc;
    retval = cfun(t, y, ctemp, c_data);
    nceDQ++;
    if (retval != 0) break;

    /* Generate the jth col of G(tn,y) */
    inc_inv = ONE/inc;
    N_VLinearSum(inc_inv, ctemp, -inc_inv, cy, jthCol);

    /* Copy the j-th column of G into the j-th row of Jac */
    for (i = 0; i < Nc ; i++) {
      DENSE_ELEM(Jac,j,i) = jthCol_data[i];
    }

    /* Reset y_j */     
    y_data[j] = yj;
  }

  return(retval);

}
static int jacDense(long int N,
                    N_Vector y, N_Vector f,
                    DlsMat J, void *user_data,
                    N_Vector tmp1, N_Vector tmp2)
{
    realtype *yd;

    yd = N_VGetArrayPointer_Serial(y);

    /* row 0 */
    DENSE_ELEM(J,0,0) = PT5 * cos(yd[0]*yd[1]) * yd[1] - PT5;
    DENSE_ELEM(J,0,1) = PT5 * cos(yd[0]*yd[1]) * yd[0] - PT25/PI;

    /* row 1 */
    DENSE_ELEM(J,1,0) = TWO * (ONE - PT25/PI) * (SUNRexp(TWO*yd[0]) - E);
    DENSE_ELEM(J,1,1) = E/PI;

    /* row 2 */
    DENSE_ELEM(J,2,0) = -ONE;
    DENSE_ELEM(J,2,2) =  ONE;

    /* row 3 */
    DENSE_ELEM(J,3,0) = -ONE;
    DENSE_ELEM(J,3,3) =  ONE;

    /* row 4 */
    DENSE_ELEM(J,4,1) = -ONE;
    DENSE_ELEM(J,4,4) =  ONE;

    /* row 5 */
    DENSE_ELEM(J,5,1) = -ONE;
    DENSE_ELEM(J,5,5) =  ONE;


    return(0);
}