static void SetSource(ProblemData d)
{
  int *l_m, *m_start;
  realtype *xmin, *xmax, *dx;
  realtype x[DIM], g, *pdata;
  int i[DIM];

  l_m  = d->l_m;
  m_start = d->m_start;
  xmin = d->xmin;
  xmax = d->xmax;
  dx = d->dx;


  pdata = NV_DATA_P(d->p);

  for(i[0]=0; i[0]<l_m[0]; i[0]++) {
    x[0] = xmin[0] + (m_start[0]+i[0]) * dx[0];
    for(i[1]=0; i[1]<l_m[1]; i[1]++) {
      x[1] = xmin[1] + (m_start[1]+i[1]) * dx[1];
#ifdef USE3D
      for(i[2]=0; i[2]<l_m[2]; i[2]++) {
        x[2] = xmin[2] + (m_start[2]+i[2]) * dx[2];
        
        g = G1_AMPL 
          * SUNRexp( -SUNSQR(G1_X-x[0])/SUNSQR(G1_SIGMA) )
          * SUNRexp( -SUNSQR(G1_Y-x[1])/SUNSQR(G1_SIGMA) )
          * SUNRexp( -SUNSQR(G1_Z-x[2])/SUNSQR(G1_SIGMA) );
        
        g += G2_AMPL 
          * SUNRexp( -SUNSQR(G2_X-x[0])/SUNSQR(G2_SIGMA) )
          * SUNRexp( -SUNSQR(G2_Y-x[1])/SUNSQR(G2_SIGMA) )
          * SUNRexp( -SUNSQR(G2_Z-x[2])/SUNSQR(G2_SIGMA) );
        
        if( g < G_MIN ) g = ZERO;

        IJth(pdata, i) = g;
      }
#else
      g = G1_AMPL 
        * SUNRexp( -SUNSQR(G1_X-x[0])/SUNSQR(G1_SIGMA) )
        * SUNRexp( -SUNSQR(G1_Y-x[1])/SUNSQR(G1_SIGMA) );

      g += G2_AMPL 
        * SUNRexp( -SUNSQR(G2_X-x[0])/SUNSQR(G2_SIGMA) )
        * SUNRexp( -SUNSQR(G2_Y-x[1])/SUNSQR(G2_SIGMA) );
      
      if( g < G_MIN ) g = ZERO;

      IJth(pdata, i) = g;
#endif 
    }
  }
}
Example #2
0
static int func(N_Vector u, N_Vector f, void *user_data)
{
  realtype *udata, *fdata;
  realtype x1, l1, L1, x2, l2, L2;
  realtype *lb, *ub;
  UserData data;
  
  data = (UserData)user_data;
  lb = data->lb;
  ub = data->ub;

  udata = N_VGetArrayPointer_Serial(u);
  fdata = N_VGetArrayPointer_Serial(f);

  x1 = udata[0];
  x2 = udata[1];
  l1 = udata[2];
  L1 = udata[3];
  l2 = udata[4];
  L2 = udata[5];

  fdata[0] = PT5 * sin(x1*x2) - PT25 * x2 / PI - PT5 * x1;
  fdata[1] = (ONE - PT25/PI)*(SUNRexp(TWO*x1)-E) + E*x2/PI - TWO*E*x1;
  fdata[2] = l1 - x1 + lb[0];
  fdata[3] = L1 - x1 + ub[0];
  fdata[4] = l2 - x2 + lb[1];
  fdata[5] = L2 - x2 + ub[1];

  return(0);
}
Example #3
0
static void SetIC(N_Vector u, UserData data)
{
  int i, j;
  realtype x, y, dx, dy;
  realtype *udata;

  /* Extract needed constants from data */

  dx = data->dx;
  dy = data->dy;

  /* Set pointer to data array in vector u. */

  udata = N_VGetArrayPointer_Serial(u);

  /* Load initial profile into u vector */
  
  for (j=1; j <= MY; j++) {
    y = j*dy;
    for (i=1; i <= MX; i++) {
      x = i*dx;
      IJth(udata,i,j) = x*(XMAX - x)*y*(YMAX - y)*SUNRexp(FIVE*x*y);
    }
  }  
}
Example #4
0
static void SetIC(N_Vector u, realtype dx)
{
  int i;
  realtype x;
  realtype *udata;

  /* Set pointer to data array and get local length of u. */
  udata = NV_DATA_S(u);

  /* Load initial profile into u vector */
  for (i=0; i<NEQ; i++) {
    x = (i+1)*dx;
    udata[i] = x*(XMAX - x)*SUNRexp(RCONST(2.0)*x);
  }  
}
static void SetIC(N_Vector u, realtype dx, sunindextype my_length, sunindextype my_base)
{
  int i;
  sunindextype iglobal;
  realtype x;
  realtype *udata;

  /* Set pointer to data array and get local length of u */
  udata = N_VGetArrayPointer_Parallel(u);
  my_length = N_VGetLocalLength_Parallel(u);

  /* Load initial profile into u vector */
  for (i=1; i<=my_length; i++) {
    iglobal = my_base + i;
    x = iglobal*dx;
    udata[i-1] = x*(XMAX - x)*SUNRexp(TWO*x);
  }  
}
Example #6
0
static void SetIC(HYPRE_IJVector Uij, realtype dx, long int my_length,
                  long int my_base)
{
  int i;
  HYPRE_Int *iglobal;
  realtype x;
  realtype *udata;

  /* Set pointer to data array and get local length of u. */
  udata   = (realtype*) malloc(my_length*sizeof(realtype));
  iglobal = (HYPRE_Int*) malloc(my_length*sizeof(HYPRE_Int));

  /* Load initial profile into u vector */
  for (i = 0; i < my_length; i++) {
    iglobal[i] = my_base + i;
    x = (iglobal[i] + 1)*dx;
    udata[i] = x*(XMAX - x)*SUNRexp(RCONST(2.0)*x);
  }
  HYPRE_IJVectorSetValues(Uij, my_length, iglobal, udata);
  free(iglobal);
  free(udata);
}
Example #7
0
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);
}
Example #8
0
static int f(realtype t, N_Vector u, N_Vector udot,void *user_data)
{
  realtype q3, c1, c2, c1dn, c2dn, c1up, c2up, c1lt, c2lt;
  realtype c1rt, c2rt, cydn, cyup, hord1, hord2, horad1, horad2;
  realtype qq1, qq2, qq3, qq4, rkin1, rkin2, s, vertd1, vertd2, ydn, yup;
  realtype q4coef, dely, verdco, hordco, horaco;
  realtype *udata, *dudata;
  int idn, iup, ileft, iright, jx, jy;
  UserData data;

  data = (UserData) user_data;
  udata = N_VGetArrayPointer_Serial(u);
  dudata = N_VGetArrayPointer_Serial(udot);

  /* Set diurnal rate coefficients. */

  s = sin(data->om*t);
  if (s > ZERO) {
    q3 = SUNRexp(-A3/s);
    data->q4 = SUNRexp(-A4/s);
  } else {
    q3 = ZERO;
    data->q4 = ZERO;
  }

  /* Make local copies of problem variables, for efficiency. */

  q4coef = data->q4;
  dely = data->dy;
  verdco = data->vdco;
  hordco  = data->hdco;
  horaco  = data->haco;

  /* Loop over all grid points. */

  for (jy = 0; jy < MY; jy++) {

    /* Set vertical diffusion coefficients at jy +- 1/2 */

    ydn = YMIN + (jy - RCONST(0.5))*dely;
    yup = ydn + dely;
    cydn = verdco*SUNRexp(RCONST(0.2)*ydn);
    cyup = verdco*SUNRexp(RCONST(0.2)*yup);
    idn = (jy == 0) ? 1 : -1;
    iup = (jy == MY-1) ? -1 : 1;
    for (jx = 0; jx < MX; jx++) {

      /* Extract c1 and c2, and set kinetic rate terms. */

      c1 = IJKth(udata,1,jx,jy); 
      c2 = IJKth(udata,2,jx,jy);
      qq1 = Q1*c1*C3;
      qq2 = Q2*c1*c2;
      qq3 = q3*C3;
      qq4 = q4coef*c2;
      rkin1 = -qq1 - qq2 + TWO*qq3 + qq4;
      rkin2 = qq1 - qq2 - qq4;

      /* Set vertical diffusion terms. */

      c1dn = IJKth(udata,1,jx,jy+idn);
      c2dn = IJKth(udata,2,jx,jy+idn);
      c1up = IJKth(udata,1,jx,jy+iup);
      c2up = IJKth(udata,2,jx,jy+iup);
      vertd1 = cyup*(c1up - c1) - cydn*(c1 - c1dn);
      vertd2 = cyup*(c2up - c2) - cydn*(c2 - c2dn);

      /* Set horizontal diffusion and advection terms. */

      ileft = (jx == 0) ? 1 : -1;
      iright =(jx == MX-1) ? -1 : 1;
      c1lt = IJKth(udata,1,jx+ileft,jy); 
      c2lt = IJKth(udata,2,jx+ileft,jy);
      c1rt = IJKth(udata,1,jx+iright,jy);
      c2rt = IJKth(udata,2,jx+iright,jy);
      hord1 = hordco*(c1rt - TWO*c1 + c1lt);
      hord2 = hordco*(c2rt - TWO*c2 + c2lt);
      horad1 = horaco*(c1rt - c1lt);
      horad2 = horaco*(c2rt - c2lt);

      /* Load all terms into udot. */

      IJKth(dudata, 1, jx, jy) = vertd1 + hord1 + horad1 + rkin1; 
      IJKth(dudata, 2, jx, jy) = vertd2 + hord2 + horad2 + rkin2;
    }
  }

  return(0);
}
Example #9
0
static int Precond(realtype tn, N_Vector u, N_Vector fu,
                   booleantype jok, booleantype *jcurPtr, realtype gamma,
                   void *user_data, N_Vector vtemp1, N_Vector vtemp2,
                   N_Vector vtemp3)
{
  realtype c1, c2, cydn, cyup, diag, ydn, yup, q4coef, dely, verdco, hordco;
  realtype **(*P)[MY], **(*Jbd)[MY];
  long int *(*pivot)[MY], ier;
  int jx, jy;
  realtype *udata, **a, **j;
  UserData data;
  
  /* Make local copies of pointers in user_data, and of pointer to u's data */
  
  data = (UserData) user_data;
  P = data->P;
  Jbd = data->Jbd;
  pivot = data->pivot;
  udata = N_VGetArrayPointer_Serial(u);
  
  if (jok) {
    
    /* jok = TRUE: Copy Jbd to P */
    
    for (jy=0; jy < MY; jy++)
      for (jx=0; jx < MX; jx++)
        denseCopy(Jbd[jx][jy], P[jx][jy], NUM_SPECIES, NUM_SPECIES);
    
    *jcurPtr = FALSE;
    
  }
  
  else {
    /* jok = FALSE: Generate Jbd from scratch and copy to P */
    
    /* Make local copies of problem variables, for efficiency. */
    
    q4coef = data->q4;
    dely = data->dy;
    verdco = data->vdco;
    hordco  = data->hdco;
    
    /* Compute 2x2 diagonal Jacobian blocks (using q4 values 
       computed on the last f call).  Load into P. */
    
    for (jy=0; jy < MY; jy++) {
      ydn = YMIN + (jy - RCONST(0.5))*dely;
      yup = ydn + dely;
      cydn = verdco*SUNRexp(RCONST(0.2)*ydn);
      cyup = verdco*SUNRexp(RCONST(0.2)*yup);
      diag = -(cydn + cyup + TWO*hordco);
      for (jx=0; jx < MX; jx++) {
        c1 = IJKth(udata,1,jx,jy);
        c2 = IJKth(udata,2,jx,jy);
        j = Jbd[jx][jy];
        a = P[jx][jy];
        IJth(j,1,1) = (-Q1*C3 - Q2*c2) + diag;
        IJth(j,1,2) = -Q2*c1 + q4coef;
        IJth(j,2,1) = Q1*C3 - Q2*c2;
        IJth(j,2,2) = (-Q2*c1 - q4coef) + diag;
        denseCopy(j, a, NUM_SPECIES, NUM_SPECIES);
      }
    }
    
    *jcurPtr = TRUE;
    
  }
  
  /* Scale by -gamma */
  
  for (jy=0; jy < MY; jy++)
    for (jx=0; jx < MX; jx++)
      denseScale(-gamma, P[jx][jy], NUM_SPECIES, NUM_SPECIES);
  
  /* Add identity matrix and do LU decompositions on blocks in place. */
  
  for (jx=0; jx < MX; jx++) {
    for (jy=0; jy < MY; jy++) {
      denseAddIdentity(P[jx][jy], NUM_SPECIES);
      ier = denseGETRF(P[jx][jy], NUM_SPECIES, NUM_SPECIES, pivot[jx][jy]);
      if (ier != 0) return(1);
    }
  }
  
  return(0);
}
Example #10
0
static int jtv(N_Vector v, N_Vector Jv, realtype t,
               N_Vector u, N_Vector fu,
               void *user_data, N_Vector tmp)
{
  realtype c1, c2, c1dn, c2dn, c1up, c2up, c1lt, c2lt, c1rt, c2rt;
  realtype v1, v2, v1dn, v2dn, v1up, v2up, v1lt, v2lt, v1rt, v2rt;
  realtype Jv1, Jv2;
  realtype cydn, cyup;
  realtype s, ydn, yup;
  realtype q4coef, dely, verdco, hordco, horaco;
  int jx, jy, idn, iup, ileft, iright;
  realtype *udata, *vdata, *Jvdata;
  UserData data;

  data = (UserData) user_data;

  udata = N_VGetArrayPointer_Serial(u);
  vdata = N_VGetArrayPointer_Serial(v);
  Jvdata = N_VGetArrayPointer_Serial(Jv);

  /* Set diurnal rate coefficients. */

  s = sin(data->om*t);
  if (s > ZERO) {
    data->q4 = SUNRexp(-A4/s);
  } else {
    data->q4 = ZERO;
  }

  /* Make local copies of problem variables, for efficiency. */

  q4coef = data->q4;
  dely = data->dy;
  verdco = data->vdco;
  hordco  = data->hdco;
  horaco  = data->haco;

  /* Loop over all grid points. */

  for (jy=0; jy < MY; jy++) {

    /* Set vertical diffusion coefficients at jy +- 1/2 */

    ydn = YMIN + (jy - RCONST(0.5))*dely;
    yup = ydn + dely;

    cydn = verdco*SUNRexp(RCONST(0.2)*ydn);
    cyup = verdco*SUNRexp(RCONST(0.2)*yup);

    idn = (jy == 0) ? 1 : -1;
    iup = (jy == MY-1) ? -1 : 1;

    for (jx=0; jx < MX; jx++) {

      Jv1 = ZERO;
      Jv2 = ZERO;

      /* Extract c1 and c2 at the current location and at neighbors */

      c1 = IJKth(udata,1,jx,jy); 
      c2 = IJKth(udata,2,jx,jy);

      v1 = IJKth(vdata,1,jx,jy); 
      v2 = IJKth(vdata,2,jx,jy);

      c1dn = IJKth(udata,1,jx,jy+idn);
      c2dn = IJKth(udata,2,jx,jy+idn);
      c1up = IJKth(udata,1,jx,jy+iup);
      c2up = IJKth(udata,2,jx,jy+iup);

      v1dn = IJKth(vdata,1,jx,jy+idn);
      v2dn = IJKth(vdata,2,jx,jy+idn);
      v1up = IJKth(vdata,1,jx,jy+iup);
      v2up = IJKth(vdata,2,jx,jy+iup);

      ileft = (jx == 0) ? 1 : -1;
      iright =(jx == MX-1) ? -1 : 1;

      c1lt = IJKth(udata,1,jx+ileft,jy); 
      c2lt = IJKth(udata,2,jx+ileft,jy);
      c1rt = IJKth(udata,1,jx+iright,jy);
      c2rt = IJKth(udata,2,jx+iright,jy);

      v1lt = IJKth(vdata,1,jx+ileft,jy); 
      v2lt = IJKth(vdata,2,jx+ileft,jy);
      v1rt = IJKth(vdata,1,jx+iright,jy);
      v2rt = IJKth(vdata,2,jx+iright,jy);

      /* Set kinetic rate terms. */

      /* 
	 rkin1 = -Q1*C3 * c1 - Q2 * c1*c2 + q4coef * c2  + TWO*C3*q3;
	 rkin2 =  Q1*C3 * c1 - Q2 * c1*c2 - q4coef * c2;
      */

      Jv1 += -(Q1*C3 + Q2*c2) * v1  +  (q4coef - Q2*c1) * v2;
      Jv2 +=  (Q1*C3 - Q2*c2) * v1  -  (q4coef + Q2*c1) * v2;

      /* Set vertical diffusion terms. */

      /* 
	 vertd1 = -(cyup+cydn) * c1 + cyup * c1up + cydn * c1dn;
	 vertd2 = -(cyup+cydn) * c2 + cyup * c2up + cydn * c2dn;
      */

      Jv1 += -(cyup+cydn) * v1  +  cyup * v1up  +  cydn * v1dn;
      Jv2 += -(cyup+cydn) * v2  +  cyup * v2up  +  cydn * v2dn;

      /* Set horizontal diffusion and advection terms. */

      /* 
	 hord1 = hordco*(c1rt - TWO*c1 + c1lt);
	 hord2 = hordco*(c2rt - TWO*c2 + c2lt);
      */

      Jv1 += hordco*(v1rt - TWO*v1 + v1lt);
      Jv2 += hordco*(v2rt - TWO*v2 + v2lt);

      /* 
	 horad1 = horaco*(c1rt - c1lt);
	 horad2 = horaco*(c2rt - c2lt);
      */

      Jv1 += horaco*(v1rt - v1lt);
      Jv2 += horaco*(v2rt - v2lt);

      /* Load two components of J*v */

      /* 
	 IJKth(dudata, 1, jx, jy) = vertd1 + hord1 + horad1 + rkin1; 
	 IJKth(dudata, 2, jx, jy) = vertd2 + hord2 + horad2 + rkin2;
      */

      IJKth(Jvdata, 1, jx, jy) = Jv1;
      IJKth(Jvdata, 2, jx, jy) = Jv2;

    }

  }

  return(0);

}
Example #11
0
static int jac(N_Vector y, N_Vector f,
               SlsMat J, void *user_data,
               N_Vector tmp1, N_Vector tmp2)
{
    realtype *yd;
    int *rowptrs;
    int *colvals;
    realtype *data;

    yd = N_VGetArrayPointer_Serial(y);
    rowptrs = (*J->rowptrs);
    colvals = (*J->colvals);
    data    = J->data;

    SparseSetMatToZero(J);

    rowptrs[0] =  0;
    rowptrs[1] =  2;
    rowptrs[2] =  4;
    rowptrs[3] =  6;
    rowptrs[4] =  8;
    rowptrs[5] = 10;
    rowptrs[6] = 12;

    /* row 0 */
    data[0] = PT5 * cos(yd[0]*yd[1]) * yd[1] - PT5;
    colvals[0] = 0;
    data[1] = PT5 * cos(yd[0]*yd[1]) * yd[0] - PT25/PI;
    colvals[1] = 1;

    /* row 1 */
    data[2] = TWO * (ONE - PT25/PI) * (SUNRexp(TWO*yd[0]) - E);
    colvals[2] = 0;
    data[3] = E/PI;
    colvals[3] = 1;

    /* row 2 */
    data[4] = -ONE;
    colvals[4] = 0;
    data[5] =  ONE;
    colvals[5] = 2;

    /* row 3 */
    data[6] = -ONE;
    colvals[6] = 0;
    data[7] =  ONE;
    colvals[7] = 3;

    /* row 4 */
    data[8] = -ONE;
    colvals[8] = 1;
    data[9] =  ONE;
    colvals[9] = 4;

    /* row 5 */
    data[10] = -ONE;
    colvals[10] = 1;
    data[11] =  ONE;
    colvals[11] = 5;

    return(0);

}
static int flocal(long int Nlocal, realtype t, N_Vector u,
                  N_Vector udot, void *user_data)
{
  realtype *uext;
  realtype q3, c1, c2, c1dn, c2dn, c1up, c2up, c1lt, c2lt;
  realtype c1rt, c2rt, cydn, cyup, hord1, hord2, horad1, horad2;
  realtype qq1, qq2, qq3, qq4, rkin1, rkin2, s, vertd1, vertd2, ydn, yup;
  realtype q4coef, dely, verdco, hordco, horaco;
  int i, lx, ly, jx, jy;
  int isubx, isuby;
  long int nvmxsub, nvmxsub2, offsetu, offsetue;
  UserData data;
  realtype *uarray, *duarray;

  uarray = N_VGetArrayPointer_Parallel(u);
  duarray = N_VGetArrayPointer_Parallel(udot);

  /* Get subgrid indices, array sizes, extended work array uext */

  data = (UserData) user_data;
  isubx = data->isubx;   isuby = data->isuby;
  nvmxsub = data->nvmxsub; nvmxsub2 = data->nvmxsub2;
  uext = data->uext;

  /* Copy local segment of u vector into the working extended array uext */

  offsetu = 0;
  offsetue = nvmxsub2 + NVARS;
  for (ly = 0; ly < MYSUB; ly++) {
    for (i = 0; i < nvmxsub; i++) uext[offsetue+i] = uarray[offsetu+i];
    offsetu = offsetu + nvmxsub;
    offsetue = offsetue + nvmxsub2;
  }

  /* To facilitate homogeneous Neumann boundary conditions, when this is
  a boundary PE, copy data from the first interior mesh line of u to uext */

  /* If isuby = 0, copy x-line 2 of u to uext */
  if (isuby == 0) {
    for (i = 0; i < nvmxsub; i++) uext[NVARS+i] = uarray[nvmxsub+i];
  }

  /* If isuby = NPEY-1, copy x-line MYSUB-1 of u to uext */
  if (isuby == NPEY-1) {
    offsetu = (MYSUB-2)*nvmxsub;
    offsetue = (MYSUB+1)*nvmxsub2 + NVARS;
    for (i = 0; i < nvmxsub; i++) uext[offsetue+i] = uarray[offsetu+i];
  }

  /* If isubx = 0, copy y-line 2 of u to uext */
  if (isubx == 0) {
    for (ly = 0; ly < MYSUB; ly++) {
      offsetu = ly*nvmxsub + NVARS;
      offsetue = (ly+1)*nvmxsub2;
      for (i = 0; i < NVARS; i++) uext[offsetue+i] = uarray[offsetu+i];
    }
  }

  /* If isubx = NPEX-1, copy y-line MXSUB-1 of u to uext */
  if (isubx == NPEX-1) {
    for (ly = 0; ly < MYSUB; ly++) {
      offsetu = (ly+1)*nvmxsub - 2*NVARS;
      offsetue = (ly+2)*nvmxsub2 - NVARS;
      for (i = 0; i < NVARS; i++) uext[offsetue+i] = uarray[offsetu+i];
    }
  }

  /* Make local copies of problem variables, for efficiency */

  dely = data->dy;
  verdco = data->vdco;
  hordco = data->hdco;
  horaco = data->haco;

  /* Set diurnal rate coefficients as functions of t, and save q4 in 
  data block for use by preconditioner evaluation routine            */

  s = sin((data->om)*t);
  if (s > ZERO) {
    q3 = SUNRexp(-A3/s);
    q4coef = SUNRexp(-A4/s);
  } else {
    q3 = ZERO;
    q4coef = ZERO;
  }
  data->q4 = q4coef;


  /* Loop over all grid points in local subgrid */

  for (ly = 0; ly < MYSUB; ly++) {

    jy = ly + isuby*MYSUB;

    /* Set vertical diffusion coefficients at jy +- 1/2 */

    ydn = YMIN + (jy - RCONST(0.5))*dely;
    yup = ydn + dely;
    cydn = verdco*SUNRexp(RCONST(0.2)*ydn);
    cyup = verdco*SUNRexp(RCONST(0.2)*yup);
    for (lx = 0; lx < MXSUB; lx++) {

      jx = lx + isubx*MXSUB;

      /* Extract c1 and c2, and set kinetic rate terms */

      offsetue = (lx+1)*NVARS + (ly+1)*nvmxsub2;
      c1 = uext[offsetue];
      c2 = uext[offsetue+1];
      qq1 = Q1*c1*C3;
      qq2 = Q2*c1*c2;
      qq3 = q3*C3;
      qq4 = q4coef*c2;
      rkin1 = -qq1 - qq2 + 2.0*qq3 + qq4;
      rkin2 = qq1 - qq2 - qq4;

      /* Set vertical diffusion terms */

      c1dn = uext[offsetue-nvmxsub2];
      c2dn = uext[offsetue-nvmxsub2+1];
      c1up = uext[offsetue+nvmxsub2];
      c2up = uext[offsetue+nvmxsub2+1];
      vertd1 = cyup*(c1up - c1) - cydn*(c1 - c1dn);
      vertd2 = cyup*(c2up - c2) - cydn*(c2 - c2dn);

      /* Set horizontal diffusion and advection terms */

      c1lt = uext[offsetue-2];
      c2lt = uext[offsetue-1];
      c1rt = uext[offsetue+2];
      c2rt = uext[offsetue+3];
      hord1 = hordco*(c1rt - RCONST(2.0)*c1 + c1lt);
      hord2 = hordco*(c2rt - RCONST(2.0)*c2 + c2lt);
      horad1 = horaco*(c1rt - c1lt);
      horad2 = horaco*(c2rt - c2lt);

      /* Load all terms into duarray */

      offsetu = lx*NVARS + ly*nvmxsub;
      duarray[offsetu]   = vertd1 + hord1 + horad1 + rkin1; 
      duarray[offsetu+1] = vertd2 + hord2 + horad2 + rkin2;
    }
  }

  return(0);
}
Example #13
0
static int Precond(realtype tn, N_Vector u, N_Vector fu,
                   booleantype jok, booleantype *jcurPtr, 
                   realtype gamma, void *user_data, 
                   N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3)
{
  realtype c1, c2, cydn, cyup, diag, ydn, yup, q4coef, dely, verdco, hordco;
  realtype **(*P)[MYSUB], **(*Jbd)[MYSUB];
  int nvmxsub, ier, offset;
  long int *(*pivot)[MYSUB];
  int lx, ly, jy, isuby;
  realtype *udata, **a, **j;
  HYPRE_ParVector uhyp;
  UserData data;
  
  /* Make local copies of pointers in user_data, pointer to u's data,
     and PE index pair */
  data = (UserData) user_data;
  P = data->P;
  Jbd = data->Jbd;
  pivot = data->pivot;
  isuby = data->isuby;
  nvmxsub = data->nvmxsub;

  uhyp  = N_VGetVector_ParHyp(u);
  udata = hypre_VectorData(hypre_ParVectorLocalVector(uhyp));

  if (jok) {

    /* jok = TRUE: Copy Jbd to P */
    for (ly = 0; ly < MYSUB; ly++)
      for (lx = 0; lx < MXSUB; lx++)
        denseCopy(Jbd[lx][ly], P[lx][ly], NVARS, NVARS);

  *jcurPtr = FALSE;

  }

  else {

    /* jok = FALSE: Generate Jbd from scratch and copy to P */

    /* Make local copies of problem variables, for efficiency */
    q4coef = data->q4;
    dely = data->dy;
    verdco = data->vdco;
    hordco  = data->hdco;
    
    /* Compute 2x2 diagonal Jacobian blocks (using q4 values 
     c*omputed on the last f call).  Load into P. */
    for (ly = 0; ly < MYSUB; ly++) {
      jy = ly + isuby*MYSUB;
      ydn = YMIN + (jy - RCONST(0.5))*dely;
      yup = ydn + dely;
      cydn = verdco*SUNRexp(RCONST(0.2)*ydn);
      cyup = verdco*SUNRexp(RCONST(0.2)*yup);
      diag = -(cydn + cyup + RCONST(2.0)*hordco);
      for (lx = 0; lx < MXSUB; lx++) {
        offset = lx*NVARS + ly*nvmxsub;
        c1 = udata[offset];
        c2 = udata[offset+1];
        j = Jbd[lx][ly];
        a = P[lx][ly];
        IJth(j,1,1) = (-Q1*C3 - Q2*c2) + diag;
        IJth(j,1,2) = -Q2*c1 + q4coef;
        IJth(j,2,1) = Q1*C3 - Q2*c2;
        IJth(j,2,2) = (-Q2*c1 - q4coef) + diag;
        denseCopy(j, a, NVARS, NVARS);
      }
    }

    *jcurPtr = TRUE;

  }

  /* Scale by -gamma */
  for (ly = 0; ly < MYSUB; ly++)
    for (lx = 0; lx < MXSUB; lx++)
      denseScale(-gamma, P[lx][ly], NVARS, NVARS);

  /* Add identity matrix and do LU decompositions on blocks in place */
  for (lx = 0; lx < MXSUB; lx++) {
    for (ly = 0; ly < MYSUB; ly++) {
      denseAddIdentity(P[lx][ly], NVARS);
      ier = denseGETRF(P[lx][ly], NVARS, NVARS, pivot[lx][ly]);
      if (ier != 0) return(1);
    }
  }

  return(0);
}