/*
  We integrate over each cell

  (i, j+1)----(i+1, j+1)
      | \         |
      |  \        |
      |   \       |
      |    \      |
      |     \     |
      |      \    |
      |       \   |
  (i,   j)----(i+1, j)
*/
PetscErrorCode ComputeRHS(KSP ksp, Vec b, void *ctx)
{
  UserContext    *user = (UserContext*)ctx;
  PetscScalar    phi   = user->phi;
  PetscScalar    *array;
  PetscInt       ne,nc,i;
  const PetscInt *e;
  PetscErrorCode ierr;
  Vec            blocal;
  DM             da;

  PetscFunctionBeginUser;
  ierr = KSPGetDM(ksp,&da);CHKERRQ(ierr);
  /* access a local vector with room for the ghost points */
  ierr = DMGetLocalVector(da,&blocal);CHKERRQ(ierr);
  ierr = VecGetArray(blocal, (PetscScalar**) &array);CHKERRQ(ierr);

  /* access the list of elements on this processor and loop over them */
  ierr = DMDAGetElements(da,&ne,&nc,&e);CHKERRQ(ierr);
  for (i=0; i<ne; i++) {

    /* this is nonsense, but set each nodal value to phi (will actually do integration over element */
    array[e[3*i]]   = phi;
    array[e[3*i+1]] = phi;
    array[e[3*i+2]] = phi;
  }
  ierr = VecRestoreArray(blocal, (PetscScalar**) &array);CHKERRQ(ierr);
  ierr = DMDARestoreElements(da,&ne,&nc,&e);CHKERRQ(ierr);

  /* add our partial sums over all processors into b */
  ierr = DMLocalToGlobalBegin(da,blocal,ADD_VALUES,b);CHKERRQ(ierr);
  ierr = DMLocalToGlobalEnd(da,blocal, ADD_VALUES,b);CHKERRQ(ierr);
  ierr = DMRestoreLocalVector(da,&blocal);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
/* Average the velocity (u,v) at time t^n over each element for time n+\phi */
PetscErrorCode CalculateElementVelocity(DM da, UserContext *user)
{
  PetscScalar    *u_n,   *v_n;
  PetscScalar    *u_phi, *v_phi;
  const PetscInt *necon;
  PetscInt       j, e, ne, nc;
  PetscErrorCode ierr;

  PetscFunctionBeginUser;
  ierr = DMDAGetElements(da, &ne, &nc, &necon);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.u, &u_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.v, &v_n);CHKERRQ(ierr);
  ierr = PetscMalloc(ne*sizeof(PetscScalar),&u_phi);CHKERRQ(ierr);
  ierr = PetscMalloc(ne*sizeof(PetscScalar),&v_phi);CHKERRQ(ierr);
  for (e = 0; e < ne; e++) {
    u_phi[e] = 0.0;
    v_phi[e] = 0.0;
    for (j = 0; j < 3; j++) {
      u_phi[e] += u_n[necon[3*e+j]];
      v_phi[e] += v_n[necon[3*e+j]];
    }
    u_phi[e] /= 3.0;
    v_phi[e] /= 3.0;
  }
  ierr = PetscFree(u_phi);CHKERRQ(ierr);
  ierr = PetscFree(v_phi);CHKERRQ(ierr);
  ierr = DMDARestoreElements(da, &ne,&nc, &necon);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.u, &u_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.v, &v_n);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
PetscErrorCode CreateStructures(DM da, UserContext *user)
{
  const PetscInt *necon;
  PetscInt       ne,nc;
  PetscErrorCode ierr;

  PetscFunctionBeginUser;
  ierr = DMDAGetElements(da,&ne,&nc,&necon);CHKERRQ(ierr);
  ierr = DMDARestoreElements(da,&ne,&nc,&necon);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_n.rho);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_n.rho_u);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_n.rho_v);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_n.rho_e);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_n.p);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_n.u);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_n.v);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_n.t);CHKERRQ(ierr);
  ierr = VecCreate(PETSC_COMM_WORLD, &user->sol_phi.rho);CHKERRQ(ierr);
  ierr = VecSetSizes(user->sol_phi.rho, ne, PETSC_DECIDE);CHKERRQ(ierr);
  ierr = VecSetType(user->sol_phi.rho,VECMPI);CHKERRQ(ierr);
  ierr = VecDuplicate(user->sol_phi.rho, &user->sol_phi.rho_u);CHKERRQ(ierr);
  ierr = VecDuplicate(user->sol_phi.rho, &user->sol_phi.rho_v);CHKERRQ(ierr);
  ierr = VecDuplicate(user->sol_phi.rho, &user->sol_phi.u);CHKERRQ(ierr);
  ierr = VecDuplicate(user->sol_phi.rho, &user->sol_phi.v);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_np1.rho);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_np1.rho_u);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_np1.rho_v);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_np1.rho_e);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_np1.p);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_np1.u);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->sol_np1.v);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->mu);CHKERRQ(ierr);
  ierr = DMCreateGlobalVector(da, &user->kappa);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
/*
  We integrate over each cell

  (i, j+1)----(i+1, j+1)
      | \         |
      |  \        |
      |   \       |
      |    \      |
      |     \     |
      |      \    |
      |       \   |
  (i,   j)----(i+1, j)

However, the element stiffness matrix for the identity in linear elements is

  1  /2 1 1\
  -  |1 2 1|
  12 \1 1 2/

no matter what the shape of the triangle. The Laplacian stiffness matrix is

  1  /         (x_2 - x_1)^2 + (y_2 - y_1)^2           -(x_2 - x_0)(x_2 - x_1) - (y_2 - y_1)(y_2 - y_0)  (x_1 - x_0)(x_2 - x_1) + (y_1 - y_0)(y_2 - y_1)\
  -  |-(x_2 - x_0)(x_2 - x_1) - (y_2 - y_1)(y_2 - y_0)           (x_2 - x_0)^2 + (y_2 - y_0)^2          -(x_1 - x_0)(x_2 - x_0) - (y_1 - y_0)(y_2 - y_0)|
  A  \ (x_1 - x_0)(x_2 - x_1) + (y_1 - y_0)(y_2 - y_1) -(x_1 - x_0)(x_2 - x_0) - (y_1 - y_0)(y_2 - y_0)           (x_1 - x_0)^2 + (y_1 - y_0)^2         /

where A is the area of the triangle, and (x_i, y_i) is its i'th vertex.
*/
PetscErrorCode ComputeMatrix(KSP ksp, Mat J, Mat jac, MatStructure *flag,void *ctx)
{
  UserContext *user = (UserContext*)ctx;
  /* not being used!
  PetscScalar    identity[9] = {0.16666666667, 0.08333333333, 0.08333333333,
                                0.08333333333, 0.16666666667, 0.08333333333,
                                0.08333333333, 0.08333333333, 0.16666666667};
  */
  PetscScalar    values[3][3];
  PetscInt       idx[3];
  PetscScalar    hx, hy, hx2, hy2, area,phi_dt2;
  PetscInt       i,mx,my,xm,ym,xs,ys;
  PetscInt       ne,nc;
  const PetscInt *e;
  PetscErrorCode ierr;
  DM             da;

  PetscFunctionBeginUser;
  ierr    = KSPGetDM(ksp,&da);CHKERRQ(ierr);
  ierr    = DMDAGetInfo(da, 0, &mx, &my, 0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
  ierr    = DMDAGetCorners(da,&xs,&ys,0,&xm,&ym,0);CHKERRQ(ierr);
  hx      = 1.0 / (mx-1);
  hy      = 1.0 / (my-1);
  area    = 0.5*hx*hy;
  phi_dt2 = user->phi*user->dt*user->dt;
  hx2     = hx*hx/area*phi_dt2;
  hy2     = hy*hy/area*phi_dt2;

  /* initially all elements have identical geometry so all element stiffness are identical */
  values[0][0] = hx2 + hy2; values[0][1] = -hy2; values[0][2] = -hx2;
  values[1][0] = -hy2;      values[1][1] = hy2;  values[1][2] = 0.0;
  values[2][0] = -hx2;      values[2][1] = 0.0;  values[2][2] = hx2;

  ierr = DMDAGetElements(da,&ne,&nc,&e);CHKERRQ(ierr);
  for (i=0; i<ne; i++) {
    idx[0] = e[3*i];
    idx[1] = e[3*i+1];
    idx[2] = e[3*i+2];
    ierr   = MatSetValuesLocal(jac,3,idx,3,idx,(PetscScalar*)values,ADD_VALUES);CHKERRQ(ierr);
  }
  ierr = DMDARestoreElements(da,&ne,&nc,&e);CHKERRQ(ierr);
  ierr = MatAssemblyBegin(jac, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(jac, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
PetscErrorCode ComputeCorrector(DM da, Vec uOld, Vec u)
{
  Vec            uOldLocal, uLocal;
  PetscScalar    *cOld;
  PetscScalar    *c;
  PetscInt       i,ne,nc;
  const PetscInt *e;
  PetscErrorCode ierr;

  PetscFunctionBeginUser;
  ierr = VecSet(u,0.0);CHKERRQ(ierr);
  ierr = DMGetLocalVector(da, &uOldLocal);CHKERRQ(ierr);
  ierr = DMGetLocalVector(da, &uLocal);CHKERRQ(ierr);
  ierr = VecSet(uLocal,0.0);CHKERRQ(ierr);
  ierr = DMGlobalToLocalBegin(da, uOld, INSERT_VALUES, uOldLocal);CHKERRQ(ierr);
  ierr = DMGlobalToLocalEnd(da, uOld, INSERT_VALUES, uOldLocal);CHKERRQ(ierr);
  ierr = VecGetArray(uOldLocal, &cOld);CHKERRQ(ierr);
  ierr = VecGetArray(uLocal,    &c);CHKERRQ(ierr);

  /* access the list of elements on this processor and loop over them */
  ierr = DMDAGetElements(da,&ne,&nc,&e);CHKERRQ(ierr);
  for (i=0; i<ne; i++) {

    /* this is nonsense, but copy each nodal value*/
    c[e[3*i]]   = cOld[e[3*i]];
    c[e[3*i+1]] = cOld[e[3*i+1]];
    c[e[3*i+2]] = cOld[e[3*i+2]];
  }
  ierr = DMDARestoreElements(da,&ne,&nc,&e);CHKERRQ(ierr);
  ierr = VecRestoreArray(uOldLocal, &cOld);CHKERRQ(ierr);
  ierr = VecRestoreArray(uLocal,    &c);CHKERRQ(ierr);
  ierr = DMLocalToGlobalBegin(da, uLocal, ADD_VALUES,u);CHKERRQ(ierr);
  ierr = DMLocalToGlobalEnd(da, uLocal, ADD_VALUES,u);CHKERRQ(ierr);
  ierr = DMRestoreLocalVector(da, &uOldLocal);CHKERRQ(ierr);
  ierr = DMRestoreLocalVector(da, &uLocal);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Exemple #6
0
PetscErrorCode SetUpMatrices(AppCtx* user)
{
  PetscErrorCode    ierr;
  PetscInt          nele,nen,i;
  const PetscInt    *ele;
  PetscScalar       dt=user->dt;
  Vec               coords;
  const PetscScalar *_coords;
  PetscScalar       x[3],y[3],xx[3],yy[3],w;
  PetscInt          idx[3];
  PetscScalar       phi[3],phider[3][2];
  PetscScalar       eM_0[3][3],eM_2[3][3];
  Mat               M=user->M;
  PetscScalar       gamma=user->gamma,theta_c=user->theta_c;
  PetscInt          m;
  PetscInt          j,k;
  PetscInt          row,cols[6],r;
  PetscScalar       vals[6];
  PetscInt          n,rstart;
  IS                isrow,iscol;

  PetscFunctionBegin;
  /* Get ghosted coordinates */
  ierr = DMDAGetGhostedCoordinates(user->da,&coords);CHKERRQ(ierr);
  ierr = VecGetArrayRead(coords,&_coords);CHKERRQ(ierr);

  /* Get local element info */
  ierr = DMDAGetElements(user->da,&nele,&nen,&ele);CHKERRQ(ierr);
  for(i=0;i < nele;i++) {
    idx[0] = ele[3*i]; idx[1] = ele[3*i+1]; idx[2] = ele[3*i+2];
    x[0] = _coords[2*idx[0]]; y[0] = _coords[2*idx[0]+1];
    x[1] = _coords[2*idx[1]]; y[1] = _coords[2*idx[1]+1];
    x[2] = _coords[2*idx[2]]; y[2] = _coords[2*idx[2]+1];
    
    ierr = PetscMemzero(xx,3*sizeof(PetscScalar));CHKERRQ(ierr);
    ierr = PetscMemzero(yy,3*sizeof(PetscScalar));CHKERRQ(ierr);
    Gausspoints(xx,yy,&w,x,y);
    
    eM_0[0][0]=eM_0[0][1]=eM_0[0][2]=0.0;
    eM_0[1][0]=eM_0[1][1]=eM_0[1][2]=0.0;
    eM_0[2][0]=eM_0[2][1]=eM_0[2][2]=0.0;
    eM_2[0][0]=eM_2[0][1]=eM_2[0][2]=0.0;
    eM_2[1][0]=eM_2[1][1]=eM_2[1][2]=0.0;
    eM_2[2][0]=eM_2[2][1]=eM_2[2][2]=0.0;


    for(m=0;m<3;m++) {
      ierr = PetscMemzero(phi,3*sizeof(PetscScalar));CHKERRQ(ierr);
      phider[0][0]=phider[0][1]=0.0;
      phider[1][0]=phider[1][1]=0.0;
      phider[2][0]=phider[2][1]=0.0;
      
      ShapefunctionsT3(phi,phider,xx[m],yy[m],x,y);

      for(j=0;j<3;j++) {
	for(k=0;k<3;k++) {
	  eM_0[k][j] += phi[j]*phi[k]*w;
	  eM_2[k][j] += phider[j][0]*phider[k][0]*w + phider[j][1]*phider[k][1]*w;
	}
      }
    }

    for(r=0;r<3;r++) {
      row = 2*idx[r];
      cols[0] = 2*idx[0];     vals[0] = dt*eM_2[r][0];
      cols[1] = 2*idx[0]+1;   vals[1] = eM_0[r][0];
      cols[2] = 2*idx[1];     vals[2] = dt*eM_2[r][1];
      cols[3] = 2*idx[1]+1;   vals[3] = eM_0[r][1];
      cols[4] = 2*idx[2];     vals[4] = dt*eM_2[r][2];
      cols[5] = 2*idx[2]+1;   vals[5] = eM_0[r][2];

      /* Insert values in matrix M for 1st dof */
      ierr = MatSetValuesLocal(M,1,&row,6,cols,vals,ADD_VALUES);CHKERRQ(ierr);
      row = 2*idx[r]+1;
      cols[0] = 2*idx[0];     vals[0] = -eM_0[r][0];
      cols[1] = 2*idx[0]+1;   vals[1] = gamma*eM_2[r][0]-theta_c*eM_0[r][0];
      cols[2] = 2*idx[1];     vals[2] = -eM_0[r][1];
      cols[3] = 2*idx[1]+1;   vals[3] = gamma*eM_2[r][1]-theta_c*eM_0[r][1];
      cols[4] = 2*idx[2];     vals[4] = -eM_0[r][2];
      cols[5] = 2*idx[2]+1;   vals[5] = gamma*eM_2[r][2]-theta_c*eM_2[r][2];

      /* Insert values in matrix M for 2nd dof */
      ierr = MatSetValuesLocal(M,1,&row,6,cols,vals,ADD_VALUES);CHKERRQ(ierr);           
    }
  }

  ierr = DMDARestoreElements(user->da,&nele,&nen,&ele);CHKERRQ(ierr);
  ierr = VecRestoreArrayRead(coords,&_coords);CHKERRQ(ierr);

  ierr = MatAssemblyBegin(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

  /* Create ISs to extract matrix M_0 from M */

  ierr = MatGetLocalSize(M,&n,PETSC_NULL);CHKERRQ(ierr);
  ierr = MatGetOwnershipRange(M,&rstart,PETSC_NULL);CHKERRQ(ierr);
  ierr = ISCreateStride(PETSC_COMM_WORLD,n/2,rstart,2,&isrow);CHKERRQ(ierr);
  ierr = ISCreateStride(PETSC_COMM_WORLD,n/2,rstart+1,2,&iscol);CHKERRQ(ierr);

  /* Extract M_0 from M */
  ierr = MatGetSubMatrix(M,isrow,iscol,MAT_INITIAL_MATRIX,&user->M_0);CHKERRQ(ierr);
  ierr = VecCreate(PETSC_COMM_WORLD,&user->u);CHKERRQ(ierr);
  ierr = VecSetSizes(user->u,n/2,PETSC_DECIDE);CHKERRQ(ierr);
  ierr = VecSetFromOptions(user->u);CHKERRQ(ierr);
  ierr = VecDuplicate(user->u,&user->work1);CHKERRQ(ierr);
  ierr = ISDestroy(&isrow);CHKERRQ(ierr);
  ierr = ISDestroy(&iscol);CHKERRQ(ierr);

  PetscFunctionReturn(0);
}
/* Notice that this requires the previous momentum solution.

The element stiffness matrix for the identity in linear elements is

  1  /2 1 1\
  -  |1 2 1|
  12 \1 1 2/

  no matter what the shape of the triangle. */
PetscErrorCode TaylorGalerkinStepIIMassEnergy(DM da, UserContext *user)
{
  MPI_Comm       comm;
  Mat            mat;
  Vec            rhs_m, rhs_e;
  PetscScalar    identity[9] = {0.16666666667, 0.08333333333, 0.08333333333,
                                0.08333333333, 0.16666666667, 0.08333333333,
                                0.08333333333, 0.08333333333, 0.16666666667};
  PetscScalar    *u_n,       *v_n,     *p_n,     *t_n,     *mu_n,    *kappa_n;
  PetscScalar    *rho_n,     *rho_u_n, *rho_v_n, *rho_e_n;
  PetscScalar    *u_phi,     *v_phi;
  PetscScalar    *rho_u_np1, *rho_v_np1;
  PetscInt       idx[3];
  PetscScalar    psi_x[3], psi_y[3];
  PetscScalar    values_m[3];
  PetscScalar    values_e[3];
  PetscScalar    phi = user->phi;
  PetscScalar    mu, kappa, tau_xx, tau_xy, tau_yy, q_x, q_y;
  PetscReal      hx, hy, area;
  KSP            ksp;
  const PetscInt *necon;
  PetscInt       j, k, e, ne, nc, mx, my;
  PetscErrorCode ierr;

  PetscFunctionBeginUser;
  ierr = PetscObjectGetComm((PetscObject) da, &comm);CHKERRQ(ierr);
  ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr);
  ierr = DMCreateMatrix(da, &mat);CHKERRQ(ierr);
  ierr = MatSetOption(mat,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
  ierr = DMGetGlobalVector(da, &rhs_m);CHKERRQ(ierr);
  ierr = DMGetGlobalVector(da, &rhs_e);CHKERRQ(ierr);
  ierr = KSPCreate(comm, &ksp);CHKERRQ(ierr);
  ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);

  ierr = DMDAGetInfo(da, 0, &mx, &my, 0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
  hx   = 1.0 / (PetscReal)(mx-1);
  hy   = 1.0 / (PetscReal)(my-1);
  area = 0.5*hx*hy;
  ierr = VecGetArray(user->sol_n.u,       &u_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.v,       &v_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.p,       &p_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.t,       &t_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->mu,            &mu_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->kappa,         &kappa_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.rho,     &rho_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.rho_u,   &rho_u_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.rho_v,   &rho_v_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.rho_e,   &rho_e_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_phi.u,     &u_phi);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_phi.v,     &v_phi);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_np1.rho_u, &rho_u_np1);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_np1.rho_v, &rho_v_np1);CHKERRQ(ierr);
  ierr = DMDAGetElements(da, &ne, &nc, &necon);CHKERRQ(ierr);
  for (e = 0; e < ne; e++) {
    for (j = 0; j < 3; j++) {
      idx[j]      = necon[3*e+j];
      values_m[j] = 0.0;
      values_e[j] = 0.0;
    }
    /* Get basis function deriatives (we need the orientation of the element here) */
    if (idx[1] > idx[0]) {
      psi_x[0] = -hy; psi_x[1] =  hy; psi_x[2] = 0.0;
      psi_y[0] = -hx; psi_y[1] = 0.0; psi_y[2] =  hx;
    } else {
      psi_x[0] =  hy; psi_x[1] = -hy; psi_x[2] = 0.0;
      psi_y[0] =  hx; psi_y[1] = 0.0; psi_y[2] = -hx;
    }
    /*  <\nabla\psi, F^*>: Divergence of the predicted convective fluxes */
    for (j = 0; j < 3; j++) {
      values_m[j] += (psi_x[j]*(phi*rho_u_np1[idx[j]] + rho_u_n[idx[j]]) + psi_y[j]*(rho_v_np1[idx[j]] + rho_v_n[idx[j]]))/3.0;
      values_e[j] += values_m[j]*((rho_e_n[idx[j]] + p_n[idx[j]]) / rho_n[idx[j]]);
    }
    /*  -<\nabla\psi, F^n_v>: Divergence of the viscous fluxes */
    for (j = 0; j < 3; j++) {
      /* \tau_{xx} = 2/3 \mu(T) (2 {\partial u\over\partial x} - {\partial v\over\partial y}) */
      /* \tau_{xy} =     \mu(T) (  {\partial u\over\partial y} + {\partial v\over\partial x}) */
      /* \tau_{yy} = 2/3 \mu(T) (2 {\partial v\over\partial y} - {\partial u\over\partial x}) */
      /* q_x       = -\kappa(T) {\partial T\over\partial x} */
      /* q_y       = -\kappa(T) {\partial T\over\partial y} */

      /* above code commeted out - causing ininitialized variables. */
      q_x =0; q_y =0;

      mu     = 0.0;
      kappa  = 0.0;
      tau_xx = 0.0;
      tau_xy = 0.0;
      tau_yy = 0.0;
      for (k = 0; k < 3; k++) {
        mu     += mu_n[idx[k]];
        kappa  += kappa_n[idx[k]];
        tau_xx += 2.0*psi_x[k]*u_n[idx[k]] - psi_y[k]*v_n[idx[k]];
        tau_xy +=     psi_y[k]*u_n[idx[k]] + psi_x[k]*v_n[idx[k]];
        tau_yy += 2.0*psi_y[k]*v_n[idx[k]] - psi_x[k]*u_n[idx[k]];
        q_x    += psi_x[k]*t_n[idx[k]];
        q_y    += psi_y[k]*t_n[idx[k]];
      }
      mu          /= 3.0;
      kappa       /= 3.0;
      tau_xx      *= (2.0/3.0)*mu;
      tau_xy      *= mu;
      tau_yy      *= (2.0/3.0)*mu;
      values_e[j] -= area*(psi_x[j]*(u_phi[e]*tau_xx + v_phi[e]*tau_xy + q_x) + psi_y[j]*(u_phi[e]*tau_xy + v_phi[e]*tau_yy + q_y));
    }
    /* Accumulate to global structures */
    ierr = VecSetValuesLocal(rhs_m, 3, idx, values_m, ADD_VALUES);CHKERRQ(ierr);
    ierr = VecSetValuesLocal(rhs_e, 3, idx, values_e, ADD_VALUES);CHKERRQ(ierr);
    ierr = MatSetValuesLocal(mat, 3, idx, 3, idx, identity, ADD_VALUES);CHKERRQ(ierr);
  }
  ierr = DMDARestoreElements(da, &ne, &nc, &necon);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.u,       &u_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.v,       &v_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.p,       &p_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.t,       &t_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->mu,            &mu_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->kappa,         &kappa_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.rho,     &rho_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.rho_u,   &rho_u_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.rho_v,   &rho_v_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.rho_e,   &rho_e_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_phi.u,     &u_phi);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_phi.v,     &v_phi);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_np1.rho_u, &rho_u_np1);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_np1.rho_v, &rho_v_np1);CHKERRQ(ierr);

  ierr = VecAssemblyBegin(rhs_m);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(rhs_e);CHKERRQ(ierr);
  ierr = MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(rhs_m);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(rhs_e);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = VecScale(rhs_m, user->dt);CHKERRQ(ierr);
  ierr = VecScale(rhs_e, user->dt);CHKERRQ(ierr);

  ierr = KSPSetOperators(ksp, mat, mat, DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
  ierr = KSPSolve(ksp, rhs_m, user->sol_np1.rho);CHKERRQ(ierr);
  ierr = KSPSolve(ksp, rhs_e, user->sol_np1.rho_e);CHKERRQ(ierr);
  ierr = KSPDestroy(&ksp);CHKERRQ(ierr);
  ierr = MatDestroy(&mat);CHKERRQ(ierr);
  ierr = DMRestoreGlobalVector(da, &rhs_m);CHKERRQ(ierr);
  ierr = DMRestoreGlobalVector(da, &rhs_e);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
/*
The element stiffness matrix for the identity in linear elements is

  1  /2 1 1\
  -  |1 2 1|
  12 \1 1 2/

  no matter what the shape of the triangle. */
PetscErrorCode TaylorGalerkinStepIIMomentum(DM da, UserContext *user)
{
  MPI_Comm       comm;
  KSP            ksp;
  Mat            mat;
  Vec            rhs_u, rhs_v;
  PetscScalar    identity[9] = {0.16666666667, 0.08333333333, 0.08333333333,
                                0.08333333333, 0.16666666667, 0.08333333333,
                                0.08333333333, 0.08333333333, 0.16666666667};
  PetscScalar    *u_n,       *v_n,      *mu_n;
  PetscScalar    *u_phi,     *v_phi;
  PetscScalar    *rho_u_phi, *rho_v_phi;
  PetscInt       idx[3];
  PetscScalar    values_u[3];
  PetscScalar    values_v[3];
  PetscScalar    psi_x[3], psi_y[3];
  PetscScalar    mu, tau_xx, tau_xy, tau_yy;
  PetscReal      hx, hy, area;
  const PetscInt *necon;
  PetscInt       j, k, e, ne, nc, mx, my;
  PetscErrorCode ierr;

  PetscFunctionBeginUser;
  ierr = PetscObjectGetComm((PetscObject) da, &comm);CHKERRQ(ierr);
  ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr);
  ierr = DMCreateMatrix(da, &mat);CHKERRQ(ierr);
  ierr = MatSetOption(mat,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
  ierr = DMGetGlobalVector(da, &rhs_u);CHKERRQ(ierr);
  ierr = DMGetGlobalVector(da, &rhs_v);CHKERRQ(ierr);
  ierr = KSPCreate(comm, &ksp);CHKERRQ(ierr);
  ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);

  ierr = DMDAGetInfo(da, 0, &mx, &my, 0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
  hx   = 1.0 / (PetscReal)(mx-1);
  hy   = 1.0 / (PetscReal)(my-1);
  area = 0.5*hx*hy;
  ierr = VecGetArray(user->sol_n.u,       &u_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.v,       &v_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->mu,            &mu_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_phi.u,     &u_phi);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_phi.v,     &v_phi);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_phi.rho_u, &rho_u_phi);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_phi.rho_v, &rho_v_phi);CHKERRQ(ierr);
  ierr = DMDAGetElements(da, &ne, &nc, &necon);CHKERRQ(ierr);
  for (e = 0; e < ne; e++) {
    for (j = 0; j < 3; j++) {
      idx[j]      = necon[3*e+j];
      values_u[j] = 0.0;
      values_v[j] = 0.0;
    }
    /* Get basis function deriatives (we need the orientation of the element here) */
    if (idx[1] > idx[0]) {
      psi_x[0] = -hy; psi_x[1] =  hy; psi_x[2] = 0.0;
      psi_y[0] = -hx; psi_y[1] = 0.0; psi_y[2] =  hx;
    } else {
      psi_x[0] =  hy; psi_x[1] = -hy; psi_x[2] = 0.0;
      psi_y[0] =  hx; psi_y[1] = 0.0; psi_y[2] = -hx;
    }
    /*  <\nabla\psi, F^{n+\phi}_e>: Divergence of the element-averaged convective fluxes */
    for (j = 0; j < 3; j++) {
      values_u[j] += psi_x[j]*rho_u_phi[e]*u_phi[e] + psi_y[j]*rho_u_phi[e]*v_phi[e];
      values_v[j] += psi_x[j]*rho_v_phi[e]*u_phi[e] + psi_y[j]*rho_v_phi[e]*v_phi[e];
    }
    /*  -<\nabla\psi, F^n_v>: Divergence of the viscous fluxes */
    for (j = 0; j < 3; j++) {
      /* \tau_{xx} = 2/3 \mu(T) (2 {\partial u\over\partial x} - {\partial v\over\partial y}) */
      /* \tau_{xy} =     \mu(T) (  {\partial u\over\partial y} + {\partial v\over\partial x}) */
      /* \tau_{yy} = 2/3 \mu(T) (2 {\partial v\over\partial y} - {\partial u\over\partial x}) */
      mu     = 0.0;
      tau_xx = 0.0;
      tau_xy = 0.0;
      tau_yy = 0.0;
      for (k = 0; k < 3; k++) {
        mu     += mu_n[idx[k]];
        tau_xx += 2.0*psi_x[k]*u_n[idx[k]] - psi_y[k]*v_n[idx[k]];
        tau_xy +=     psi_y[k]*u_n[idx[k]] + psi_x[k]*v_n[idx[k]];
        tau_yy += 2.0*psi_y[k]*v_n[idx[k]] - psi_x[k]*u_n[idx[k]];
      }
      mu          /= 3.0;
      tau_xx      *= (2.0/3.0)*mu;
      tau_xy      *= mu;
      tau_yy      *= (2.0/3.0)*mu;
      values_u[j] -= area*(psi_x[j]*tau_xx + psi_y[j]*tau_xy);
      values_v[j] -= area*(psi_x[j]*tau_xy + psi_y[j]*tau_yy);
    }
    /* Accumulate to global structures */
    ierr = VecSetValuesLocal(rhs_u, 3, idx, values_u, ADD_VALUES);CHKERRQ(ierr);
    ierr = VecSetValuesLocal(rhs_v, 3, idx, values_v, ADD_VALUES);CHKERRQ(ierr);
    ierr = MatSetValuesLocal(mat, 3, idx, 3, idx, identity, ADD_VALUES);CHKERRQ(ierr);
  }
  ierr = DMDARestoreElements(da, &ne, &nc, &necon);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.u,       &u_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.v,       &v_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->mu,            &mu_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_phi.u,     &u_phi);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_phi.v,     &v_phi);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_phi.rho_u, &rho_u_phi);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_phi.rho_v, &rho_v_phi);CHKERRQ(ierr);

  ierr = VecAssemblyBegin(rhs_u);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(rhs_v);CHKERRQ(ierr);
  ierr = MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(rhs_u);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(rhs_v);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = VecScale(rhs_u,user->dt);CHKERRQ(ierr);
  ierr = VecScale(rhs_v,user->dt);CHKERRQ(ierr);

  ierr = KSPSetOperators(ksp, mat, mat, DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
  ierr = KSPSolve(ksp, rhs_u, user->sol_np1.rho_u);CHKERRQ(ierr);
  ierr = KSPSolve(ksp, rhs_v, user->sol_np1.rho_v);CHKERRQ(ierr);
  ierr = KSPDestroy(&ksp);CHKERRQ(ierr);
  ierr = MatDestroy(&mat);CHKERRQ(ierr);
  ierr = DMRestoreGlobalVector(da, &rhs_u);CHKERRQ(ierr);
  ierr = DMRestoreGlobalVector(da, &rhs_v);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
/* This is equation 32,

   U^{n+\phi}_E = {1\over Vol_E} \left(\int_\Omega [N]{U^n} d\Omega - \phi\Delta t \int_\Omega [\nabla N]\cdot{F^n} d\Omega \right) + \phi\Delta t Q^n

which is really simple for linear elements

   U^{n+\phi}_E = {1\over3} \sum^3_{i=1} U^n_i - \phi\Delta t [\nabla N]\cdot{F^n} + \phi\Delta t Q^n

where

   U^{n+\phi}_E = {\rho  \rho u  \rho v}^{n+\phi}_E

and the x and y components of the convective fluxes F are

   f^n = {\rho u  \rho u^2  \rho uv}^n      g^n = {\rho v  \rho uv  \rho v^2}^n
*/
PetscErrorCode TaylorGalerkinStepI(DM da, UserContext *user)
{
  PetscScalar    phi_dt = user->phi*user->dt;
  PetscScalar    *u_n,     *v_n;
  PetscScalar    *rho_n,   *rho_u_n,   *rho_v_n;
  PetscScalar    *rho_phi, *rho_u_phi, *rho_v_phi;
  PetscScalar    Fx_x, Fy_y;
  PetscScalar    psi_x[3], psi_y[3];
  PetscInt       idx[3];
  PetscReal      hx, hy;
  const PetscInt *necon;
  PetscInt       j, e, ne, nc, mx, my;
  PetscErrorCode ierr;

  PetscFunctionBeginUser;
  ierr = DMDAGetInfo(da, 0, &mx, &my, 0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr);
  hx   = 1.0 / (PetscReal)(mx-1);
  hy   = 1.0 / (PetscReal)(my-1);
  ierr = VecSet(user->sol_phi.rho,0.0);CHKERRQ(ierr);
  ierr = VecSet(user->sol_phi.rho_u,0.0);CHKERRQ(ierr);
  ierr = VecSet(user->sol_phi.rho_v,0.0);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.u,       &u_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.v,       &v_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.rho,     &rho_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.rho_u,   &rho_u_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_n.rho_v,   &rho_v_n);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_phi.rho,   &rho_phi);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_phi.rho_u, &rho_u_phi);CHKERRQ(ierr);
  ierr = VecGetArray(user->sol_phi.rho_v, &rho_v_phi);CHKERRQ(ierr);
  ierr = DMDAGetElements(da, &ne, &nc, &necon);CHKERRQ(ierr);
  for (e = 0; e < ne; e++) {
    /* Average the existing fields over the element */
    for (j = 0; j < 3; j++) {
      idx[j]        = necon[3*e+j];
      rho_phi[e]   += rho_n[idx[j]];
      rho_u_phi[e] += rho_u_n[idx[j]];
      rho_v_phi[e] += rho_v_n[idx[j]];
    }
    rho_phi[e]   /= 3.0;
    rho_u_phi[e] /= 3.0;
    rho_v_phi[e] /= 3.0;
    /* Get basis function deriatives (we need the orientation of the element here) */
    if (idx[1] > idx[0]) {
      psi_x[0] = -hy; psi_x[1] =  hy; psi_x[2] = 0.0;
      psi_y[0] = -hx; psi_y[1] = 0.0; psi_y[2] =  hx;
    } else {
      psi_x[0] =  hy; psi_x[1] = -hy; psi_x[2] = 0.0;
      psi_y[0] =  hx; psi_y[1] = 0.0; psi_y[2] = -hx;
    }
    /* Determine the convective fluxes for \rho^{n+\phi} */
    Fx_x = 0.0; Fy_y = 0.0;
    for (j = 0; j < 3; j++) {
      Fx_x += psi_x[j]*rho_u_n[idx[j]];
      Fy_y += psi_y[j]*rho_v_n[idx[j]];
    }
    rho_phi[e] -= phi_dt*(Fx_x + Fy_y);
    /* Determine the convective fluxes for (\rho u)^{n+\phi} */
    Fx_x = 0.0; Fy_y = 0.0;
    for (j = 0; j < 3; j++) {
      Fx_x += psi_x[j]*rho_u_n[idx[j]]*u_n[idx[j]];
      Fy_y += psi_y[j]*rho_v_n[idx[j]]*u_n[idx[j]];
    }
    rho_u_phi[e] -= phi_dt*(Fx_x + Fy_y);
    /* Determine the convective fluxes for (\rho v)^{n+\phi} */
    Fx_x = 0.0; Fy_y = 0.0;
    for (j = 0; j < 3; j++) {
      Fx_x += psi_x[j]*rho_u_n[idx[j]]*v_n[idx[j]];
      Fy_y += psi_y[j]*rho_v_n[idx[j]]*v_n[idx[j]];
    }
    rho_v_phi[e] -= phi_dt*(Fx_x + Fy_y);
  }
  ierr = DMDARestoreElements(da, &ne, &nc, &necon);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.u,       &u_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.v,       &v_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.rho,     &rho_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.rho_u,   &rho_u_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_n.rho_v,   &rho_v_n);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_phi.rho,   &rho_phi);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_phi.rho_u, &rho_u_phi);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->sol_phi.rho_v, &rho_v_phi);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Exemple #10
0
PetscErrorCode SetUpMatrices(AppCtx *user)
{
  PetscErrorCode ierr;
  PetscInt       nele,nen,i,n;
  const PetscInt *ele;
  PetscScalar    dt=user->dt,h;

  PetscInt    idx[2];
  PetscScalar eM_0[2][2],eM_2[2][2];
  Mat         M  =user->M;
  Mat         M_0=user->M_0;
  PetscInt    Mda;


  PetscFunctionBeginUser;
  ierr = MatGetLocalSize(M,&n,NULL);CHKERRQ(ierr);
  ierr = DMDAGetInfo(user->da1,NULL,&Mda,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr);

  if (user->periodic) h = (user->xmax-user->xmin)/Mda;
  else h = (user->xmax-user->xmin)/(Mda-1.0);

  if (user->lumpedmass) {
    eM_0[0][0] = h/2.0;
    eM_0[1][1] = h/2.0;
    eM_0[0][1] = eM_0[1][0] = 0.0;
  } else {
    eM_0[0][0]=eM_0[1][1]=h/3.0;
    eM_0[0][1]=eM_0[1][0]=h/6.0;
  }
  eM_2[0][0]=eM_2[1][1]=1.0/h;
  eM_2[0][1]=eM_2[1][0]=-1.0/h;

  /* Get local element info */
  ierr = DMDAGetElements(user->da1,&nele,&nen,&ele);CHKERRQ(ierr);
  for (i=0; i < nele; i++) {

    idx[0] = ele[2*i]; idx[1] = ele[2*i+1];

    PetscInt    row,cols[4],r,row_M_0,cols2[2];
    PetscScalar vals[4],vals_M_0[2],vals2[2];

    for (r=0; r<2; r++) {
      row_M_0    = idx[r];
      vals_M_0[0]=eM_0[r][0];
      vals_M_0[1]=eM_0[r][1];

      ierr = MatSetValuesLocal(M_0,1,&row_M_0,2,idx,vals_M_0,ADD_VALUES);CHKERRQ(ierr);

      row     = 3*idx[r];
      cols[0] = 3*idx[0];     vals[0] = dt*eM_2[r][0]*user->Mv;
      cols[1] = 3*idx[1];     vals[1] = dt*eM_2[r][1]*user->Mv;
      cols[2] = 3*idx[0]+1;   vals[2] = eM_0[r][0];
      cols[3] = 3*idx[1]+1;   vals[3] = eM_0[r][1];

      /* Insert values in matrix M for 1st dof */
      ierr = MatSetValuesLocal(M,1,&row,4,cols,vals,ADD_VALUES);CHKERRQ(ierr);

      row     = 3*idx[r]+1;
      cols[0] = 3*idx[0];     vals[0] = -eM_0[r][0];
      cols[1] = 3*idx[1];     vals[1] = -eM_0[r][1];
      cols[2] = 3*idx[0]+1;   vals[2] = 2.0*user->kav*eM_2[r][0];
      cols[3] = 3*idx[1]+1;   vals[3] = 2.0*user->kav*eM_2[r][1];

      /* Insert values in matrix M for 2nd dof */
      ierr = MatSetValuesLocal(M,1,&row,4,cols,vals,ADD_VALUES);CHKERRQ(ierr);


      row      = 3*idx[r]+2;
      cols2[0] = 3*idx[0]+2;   vals2[0] = eM_0[r][0] + user->dt*2.0*user->L*user->kaeta*eM_2[r][0];
      cols2[1] = 3*idx[1]+2;   vals2[1] = eM_0[r][1] + user->dt*2.0*user->L*user->kaeta*eM_2[r][1];

      ierr = MatSetValuesLocal(M,1,&row,2,cols2,vals2,ADD_VALUES);CHKERRQ(ierr);
    }
  }

  ierr = MatAssemblyBegin(M_0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(M_0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

  ierr = MatAssemblyBegin(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

  ierr = DMDARestoreElements(user->da1,&nele,&nen,&ele);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Exemple #11
0
PetscErrorCode SetInitialGuess(Vec X,AppCtx *user)
{
  PetscErrorCode ierr;

  PetscInt          n,i,Mda;
  PetscScalar       *xx,*cv_p,*wv_p,*eta_p;
  PetscViewer       view_out;

  /* needed for the void growth case */
  PetscScalar       xmid,cv_v=1.0,cv_m=user->Sv*user->cv0,eta_v=1.0,eta_m=0.0,h,lambda;
  PetscInt          nele,nen,idx[2];
  const PetscInt    *ele;
  PetscScalar       x[2];
  Vec               coords;
  const PetscScalar *_coords;
  PetscScalar       xwidth = user->xmax - user->xmin;

  PetscFunctionBeginUser;
  ierr = VecGetLocalSize(X,&n);CHKERRQ(ierr);

  ierr = DMDAGetInfo(user->da2,NULL,&Mda,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr);
  ierr = DMGetCoordinatesLocal(user->da2,&coords);CHKERRQ(ierr);
  ierr = VecGetArrayRead(coords,&_coords);CHKERRQ(ierr);

  if (user->periodic) h = (user->xmax-user->xmin)/Mda;
  else                h = (user->xmax-user->xmin)/(Mda-1.0);

  xmid   = (user->xmax + user->xmin)/2.0;
  lambda = 4.0*h;

  ierr = DMDAGetElements(user->da2,&nele,&nen,&ele);CHKERRQ(ierr);
  for (i=0; i < nele; i++) {
    idx[0] = ele[2*i]; idx[1] = ele[2*i+1];

    x[0] = _coords[idx[0]];
    x[1] = _coords[idx[1]];


    PetscInt    k;
    PetscScalar vals_DDcv[2],vals_cv[2],vals_eta[2],s,hhr,r;
    for (k=0; k < 2; k++) {
      s = PetscAbs(x[k] - xmid);
      if (s <= xwidth*(5.0/64.0)) {
        vals_cv[k]   = cv_v;
        vals_eta[k]  = eta_v;
        vals_DDcv[k] = 0.0;
      } else if (s> xwidth*(5.0/64.0) && s<= xwidth*(7.0/64.0)) {
        /*r = (s - xwidth*(6.0/64.0))/(0.5*lambda);*/
        r            = (s - xwidth*(6.0/64.0))/(xwidth/64.0);
        hhr          = 0.25*(-r*r*r + 3*r + 2);
        vals_cv[k]   = cv_m + (1.0 - hhr)*(cv_v - cv_m);
        vals_eta[k]  = eta_m + (1.0 - hhr)*(eta_v - eta_m);
        vals_DDcv[k] = (cv_v - cv_m)*r*6.0/(lambda*lambda);
      } else {
        vals_cv[k]   = cv_m;
        vals_eta[k]  = eta_m;
        vals_DDcv[k] = 0.0;
      }
    }

    ierr = VecSetValuesLocal(user->cv,2,idx,vals_cv,INSERT_VALUES);CHKERRQ(ierr);
    ierr = VecSetValuesLocal(user->eta,2,idx,vals_eta,INSERT_VALUES);CHKERRQ(ierr);
    ierr = VecSetValuesLocal(user->work2,2,idx,vals_DDcv,INSERT_VALUES);CHKERRQ(ierr);

  }
  ierr = DMDARestoreElements(user->da2,&nele,&nen,&ele);CHKERRQ(ierr);
  ierr = VecRestoreArrayRead(coords,&_coords);CHKERRQ(ierr);

  ierr = VecAssemblyBegin(user->cv);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(user->cv);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(user->eta);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(user->eta);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(user->work2);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(user->work2);CHKERRQ(ierr);

  ierr = DPsi(user);CHKERRQ(ierr);
  ierr = VecCopy(user->DPsiv,user->wv);CHKERRQ(ierr);
  ierr = VecAXPY(user->wv,-2.0*user->kav,user->work2);CHKERRQ(ierr);

  ierr = VecGetArray(X,&xx);CHKERRQ(ierr);
  ierr = VecGetArray(user->wv,&wv_p);CHKERRQ(ierr);
  ierr = VecGetArray(user->cv,&cv_p);CHKERRQ(ierr);
  ierr = VecGetArray(user->eta,&eta_p);CHKERRQ(ierr);

  for (i=0; i<n/3; i++) {
    xx[3*i]  =wv_p[i];
    xx[3*i+1]=cv_p[i];
    xx[3*i+2]=eta_p[i];
  }

  ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"file_initial",FILE_MODE_WRITE,&view_out);CHKERRQ(ierr);
  ierr = VecView(user->wv,view_out);CHKERRQ(ierr);
  ierr = VecView(user->cv,view_out);CHKERRQ(ierr);
  ierr = VecView(user->eta,view_out);CHKERRQ(ierr);
  ierr = PetscViewerDestroy(&view_out);CHKERRQ(ierr);

  ierr = VecRestoreArray(X,&xx);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->wv,&wv_p);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->cv,&cv_p);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->eta,&eta_p);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Exemple #12
0
PetscErrorCode SetUpMatrices(AppCtx *user)
{
  PetscErrorCode    ierr;
  PetscInt          nele,nen,i,j;
  const PetscInt    *ele;
  PetscScalar       dt=user->dt;
  PetscScalar       y[3];
  PetscInt          idx[3];
  PetscScalar       eM_0[3][3],eM_2_odd[3][3],eM_2_even[3][3];
  Mat               M      =user->M;
  PetscScalar       epsilon=user->epsilon;
  PetscScalar       hx;
  PetscInt          n,Mda,Nda;
  DM                da;

  PetscFunctionBeginUser;
  /* Create the mass matrix M_0 */
  ierr = MatGetLocalSize(M,&n,NULL);CHKERRQ(ierr);


  /* ierr = MatCreate(PETSC_COMM_WORLD,&user->M_0);CHKERRQ(ierr);*/
  ierr = DMDAGetInfo(user->da,NULL,&Mda,&Nda,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  hx   = 1.0/(Mda-1);
  ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,Mda,Nda,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&da);CHKERRQ(ierr);
  ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr);
  ierr = DMCreateMatrix(da,&user->M_0);CHKERRQ(ierr);
  ierr = DMDestroy(&da);CHKERRQ(ierr);

  eM_0[0][0]=eM_0[1][1]=eM_0[2][2]=hx*hx/12.0;
  eM_0[0][1]=eM_0[0][2]=eM_0[1][0]=eM_0[1][2]=eM_0[2][0]=eM_0[2][1]=hx*hx/24.0;

  eM_2_odd[0][0] = eM_2_odd[0][1] = eM_2_odd[0][2] = 0.0;
  eM_2_odd[1][0] = eM_2_odd[1][1] = eM_2_odd[1][2] = 0.0;
  eM_2_odd[2][0] = eM_2_odd[2][1] = eM_2_odd[2][2] = 0.0;

  eM_2_odd[0][0]=1.0;
  eM_2_odd[1][1]=eM_2_odd[2][2]=0.5;
  eM_2_odd[0][1]=eM_2_odd[0][2]=eM_2_odd[1][0]=eM_2_odd[2][0]=-0.5;

  eM_2_even[0][0] = eM_2_even[0][1] = eM_2_even[0][2] = 0.0;
  eM_2_even[0][0] = eM_2_even[0][1] = eM_2_even[0][2] = 0.0;
  eM_2_even[0][0] = eM_2_even[0][1] = eM_2_even[0][2] = 0.0;

  eM_2_even[1][1]=1;
  eM_2_even[0][0]=eM_2_even[2][2]=0.5;
  eM_2_even[0][1]=eM_2_even[1][0]=eM_2_even[1][2]=eM_2_even[2][1]=-0.5;

  /* Get local element info */
  ierr = DMDAGetElements(user->da,&nele,&nen,&ele);CHKERRQ(ierr);
  for (i=0; i < nele; i++) {
    idx[0] = ele[3*i]; idx[1] = ele[3*i+1]; idx[2] = ele[3*i+2];

    PetscInt    row,cols[3],r,row_M_0;
    PetscScalar vals[3],vals_M_0[3];

    for (r=0; r<3; r++) {
      row_M_0 = idx[r];

      vals_M_0[0]=eM_0[r][0];
      vals_M_0[1]=eM_0[r][1];
      vals_M_0[2]=eM_0[r][2];

      ierr = MatSetValues(user->M_0,1,&row_M_0,3,idx,vals_M_0,ADD_VALUES);CHKERRQ(ierr);

      if (y[1]==y[0]) {
        row     = 4*idx[r];
        cols[0] = 4*idx[0];     vals[0] = eM_0[r][0]+dt*epsilon*epsilon*eM_2_odd[r][0];
        cols[1] = 4*idx[1];     vals[1] = eM_0[r][1]+dt*epsilon*epsilon*eM_2_odd[r][1];
        cols[2] = 4*idx[2];     vals[2] = eM_0[r][2]+dt*epsilon*epsilon*eM_2_odd[r][2];
        /* Insert values in matrix M for 1st dof */
        ierr = MatSetValuesLocal(M,1,&row,3,cols,vals,ADD_VALUES);CHKERRQ(ierr);

        row     = 4*idx[r]+1;
        cols[0] = 4*idx[0]+1;   vals[0] = eM_0[r][0]+dt*epsilon*epsilon*eM_2_odd[r][0];
        cols[1] = 4*idx[1]+1;   vals[1] = eM_0[r][1]+dt*epsilon*epsilon*eM_2_odd[r][1];
        cols[2] = 4*idx[2]+1;   vals[2] = eM_0[r][2]+dt*epsilon*epsilon*eM_2_odd[r][2];
        /* Insert values in matrix M for 2nd dof */
        ierr = MatSetValuesLocal(M,1,&row,3,cols,vals,ADD_VALUES);CHKERRQ(ierr);

        row     = 4*idx[r]+2;
        cols[0] = 4*idx[0]+2;   vals[0] = eM_0[r][0]+dt*epsilon*epsilon*eM_2_odd[r][0];
        cols[1] = 4*idx[1]+2;   vals[1] = eM_0[r][1]+dt*epsilon*epsilon*eM_2_odd[r][1];
        cols[2] = 4*idx[2]+2;   vals[2] = eM_0[r][2]+dt*epsilon*epsilon*eM_2_odd[r][2];
        /* Insert values in matrix M for 3nd dof */
        ierr = MatSetValuesLocal(M,1,&row,3,cols,vals,ADD_VALUES);CHKERRQ(ierr);
      } else {
        row     = 4*idx[r];
        cols[0] = 4*idx[0];     vals[0] = eM_0[r][0]+dt*epsilon*epsilon*eM_2_even[r][0];
        cols[1] = 4*idx[1];     vals[1] = eM_0[r][1]+dt*epsilon*epsilon*eM_2_even[r][1];
        cols[2] = 4*idx[2];     vals[2] = eM_0[r][2]+dt*epsilon*epsilon*eM_2_even[r][2];
        /* Insert values in matrix M for 1st dof */
        ierr = MatSetValuesLocal(M,1,&row,3,cols,vals,ADD_VALUES);CHKERRQ(ierr);

        row     = 4*idx[r]+1;
        cols[0] = 4*idx[0]+1;   vals[0] = eM_0[r][0]+dt*epsilon*epsilon*eM_2_even[r][0];
        cols[1] = 4*idx[1]+1;   vals[1] = eM_0[r][1]+dt*epsilon*epsilon*eM_2_even[r][1];
        cols[2] = 4*idx[2]+1;   vals[2] = eM_0[r][2]+dt*epsilon*epsilon*eM_2_even[r][2];
        /* Insert values in matrix M for 2nd dof */
        ierr = MatSetValuesLocal(M,1,&row,3,cols,vals,ADD_VALUES);CHKERRQ(ierr);

        row     = 4*idx[r]+2;
        cols[0] = 4*idx[0]+2;   vals[0] = eM_0[r][0]+dt*epsilon*epsilon*eM_2_even[r][0];
        cols[1] = 4*idx[1]+2;   vals[1] = eM_0[r][1]+dt*epsilon*epsilon*eM_2_even[r][1];
        cols[2] = 4*idx[2]+2;   vals[2] = eM_0[r][2]+dt*epsilon*epsilon*eM_2_even[r][2];
        /* Insert values in matrix M for 3nd dof */
        ierr = MatSetValuesLocal(M,1,&row,3,cols,vals,ADD_VALUES);CHKERRQ(ierr);
      }
    }
  }

  ierr = MatAssemblyBegin(user->M_0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(user->M_0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

  ierr = MatAssemblyBegin(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

  PetscScalar vals[9];

  vals[0] = -1.0; vals[1] =  0.0; vals[2] =  0.0;
  vals[3] =  0.0; vals[4] = -1.0; vals[5] =  0.0;
  vals[6] =  0.0; vals[7] =  0.0; vals[8] = -1.0;


  for (j=0; j < nele; j++) {
    idx[0] = ele[3*j]; idx[1] = ele[3*j+1]; idx[2] = ele[3*j+2];

    PetscInt r,rows[3],cols[3];
    for (r=0; r<3; r++) {

      rows[0] = 4*idx[0]+r;     cols[0] = 4*idx[0]+3;
      rows[1] = 4*idx[1]+r;   cols[1] = 4*idx[1]+3;
      rows[2] = 4*idx[2]+r;   cols[2] = 4*idx[2]+3;

      ierr = MatSetValuesLocal(M,3,rows,3,cols,vals,INSERT_VALUES);CHKERRQ(ierr);
      ierr = MatSetValuesLocal(M,3,cols,3,rows,vals,INSERT_VALUES);CHKERRQ(ierr);

    }

  }

  ierr = DMDARestoreElements(user->da,&nele,&nen,&ele);CHKERRQ(ierr);

  ierr = MatAssemblyBegin(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);



  ierr = VecCreate(PETSC_COMM_WORLD,&user->u1);CHKERRQ(ierr);
  ierr = VecSetSizes(user->u1,n/4,PETSC_DECIDE);CHKERRQ(ierr);
  ierr = VecSetFromOptions(user->u1);CHKERRQ(ierr);
  ierr = VecDuplicate(user->u1,&user->u2);CHKERRQ(ierr);
  ierr = VecDuplicate(user->u1,&user->u3);CHKERRQ(ierr);
  ierr = VecDuplicate(user->u1,&user->work1);CHKERRQ(ierr);
  ierr = VecDuplicate(user->u1,&user->work2);CHKERRQ(ierr);
  ierr = VecDuplicate(user->u1,&user->work3);CHKERRQ(ierr);
  ierr = VecDuplicate(user->u1,&user->work4);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Exemple #13
0
PetscErrorCode SetInitialGuess(Vec X,AppCtx *user)
{
  PetscErrorCode    ierr;
  PetscInt          nele,nen,n,i;
  const PetscInt    *ele;
  Vec               coords, rand1, rand2;
  const PetscScalar *_coords;
  PetscScalar       x[3],y[3];
  PetscInt          idx[3];
  PetscScalar       *xx,*w1,*w2,*u1,*u2,*u3;
  PetscViewer       view_out;

  PetscFunctionBeginUser;
  /* Get ghosted coordinates */
  ierr = DMGetCoordinatesLocal(user->da,&coords);CHKERRQ(ierr);
  ierr = VecDuplicate(user->u1,&rand1);
  ierr = VecDuplicate(user->u1,&rand2);
  ierr = VecSetRandom(rand1,NULL);
  ierr = VecSetRandom(rand2,NULL);

  ierr = VecGetLocalSize(X,&n);CHKERRQ(ierr);
  ierr = VecGetArrayRead(coords,&_coords);CHKERRQ(ierr);
  ierr = VecGetArray(X,&xx);CHKERRQ(ierr);
  ierr = VecGetArray(user->work1,&w1);
  ierr = VecGetArray(user->work2,&w2);
  ierr = VecGetArray(user->u1,&u1);
  ierr = VecGetArray(user->u2,&u2);
  ierr = VecGetArray(user->u3,&u3);

  /* Get local element info */
  ierr = DMDAGetElements(user->da,&nele,&nen,&ele);CHKERRQ(ierr);
  for (i=0; i < nele; i++) {
    idx[0] = ele[3*i]; idx[1] = ele[3*i+1]; idx[2] = ele[3*i+2];
    x[0]   = _coords[2*idx[0]]; y[0] = _coords[2*idx[0]+1];
    x[1]   = _coords[2*idx[1]]; y[1] = _coords[2*idx[1]+1];
    x[2]   = _coords[2*idx[2]]; y[2] = _coords[2*idx[2]+1];

    PetscScalar vals1[3],vals2[3],valsrand[3];
    PetscInt    r;
    for (r=0; r<3; r++) {
      valsrand[r]=5*x[r]*(1-x[r])*y[r]*(1-y[r]);
      if (x[r]>=0.5 && y[r]>=0.5) {
        vals1[r]=0.75;
        vals2[r]=0.0;
      }
      if (x[r]>=0.5 && y[r]<0.5) {
        vals1[r]=0.0;
        vals2[r]=0.0;
      }
      if (x[r]<0.5 && y[r]>=0.5) {
        vals1[r]=0.0;
        vals2[r]=0.75;
      }
      if (x[r]<0.5 && y[r]<0.5) {
        vals1[r]=0.75;
        vals2[r]=0.0;
      }
    }

    ierr = VecSetValues(user->work1,3,idx,vals1,INSERT_VALUES);CHKERRQ(ierr);
    ierr = VecSetValues(user->work2,3,idx,vals2,INSERT_VALUES);CHKERRQ(ierr);
    ierr = VecSetValues(user->work3,3,idx,valsrand,INSERT_VALUES);CHKERRQ(ierr);
  }

  ierr = VecAssemblyBegin(user->work1);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(user->work1);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(user->work2);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(user->work2);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(user->work3);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(user->work3);CHKERRQ(ierr);

  ierr = VecAXPY(user->work1,1.0,user->work3);CHKERRQ(ierr);
  ierr = VecAXPY(user->work2,1.0,user->work3);CHKERRQ(ierr);

  for (i=0; i<n/4; i++) {
    xx[4*i] = w1[i];
    if (xx[4*i]>1) xx[4*i]=1;

    xx[4*i+1] = w2[i];
    if (xx[4*i+1]>1) xx[4*i+1]=1;

    if (xx[4*i]+xx[4*i+1]>1) xx[4*i+1] = 1.0 - xx[4*i];

    xx[4*i+2] = 1.0 - xx[4*i] - xx[4*i+1];
    xx[4*i+3] = 0.0;

    u1[i] = xx[4*i];
    u2[i] = xx[4*i+1];
    u3[i] = xx[4*i+2];
  }

  ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"file_initial",FILE_MODE_WRITE,&view_out);CHKERRQ(ierr);
  ierr = VecView(user->u1,view_out);CHKERRQ(ierr);
  ierr = VecView(user->u2,view_out);CHKERRQ(ierr);
  ierr = VecView(user->u3,view_out);CHKERRQ(ierr);
  PetscViewerDestroy(&view_out);

  ierr = DMDARestoreElements(user->da,&nele,&nen,&ele);CHKERRQ(ierr);
  ierr = VecRestoreArrayRead(coords,&_coords);CHKERRQ(ierr);
  ierr = VecRestoreArray(X,&xx);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->work2,&w1);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->work4,&w2);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->u1,&u1);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->u2,&u2);CHKERRQ(ierr);
  ierr = VecRestoreArray(user->u3,&u3);CHKERRQ(ierr);
  ierr = VecDestroy(&rand1);CHKERRQ(ierr);
  ierr = VecDestroy(&rand2);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}