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) */ 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); }
/* 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); }
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); }
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); }
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); }
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); }
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); }
PetscErrorCode SetUpMatrices(AppCtx *user) { PetscErrorCode ierr; PetscInt nele,nen,i,j,n; const PetscInt *ele; PetscScalar dt=user->dt,hx,hy; PetscInt idx[3],*nodes, *connect, k; PetscScalar eM_0[3][3],eM_2_even[3][3],eM_2_odd[3][3]; PetscScalar cv_sum, ci_sum; Mat M =user->M; Mat M_0=user->M_0; PetscInt Mda=user->Mda, Nda=user->Nda, ld, rd, ru, lu; PetscScalar *cv_p,*ci_p; PetscFunctionBeginUser; /* ierr = MatSetOption(M,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); ierr = MatSetOption(M_0,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);*/ /* Create the mass matrix M_0 */ ierr = VecGetArray(user->cv,&cv_p);CHKERRQ(ierr); ierr = VecGetArray(user->ci,&ci_p);CHKERRQ(ierr); ierr = MatGetLocalSize(M,&n,NULL);CHKERRQ(ierr); ierr = DMDAGetInfo(user->da1,NULL,&Mda,&Nda,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); ierr = PetscMalloc((Mda+1)*(Nda+1)*sizeof(PetscInt),&nodes);CHKERRQ(ierr); ierr = PetscMalloc(Mda*Nda*2*3*sizeof(PetscInt),&connect);CHKERRQ(ierr); hx = (user->xmax-user->xmin)/Mda; hy = (user->ymax-user->ymin)/Nda; for (j=0; j < Nda; j++) { for (i=0; i < Mda; i++) nodes[j*(Mda+1)+i] = j*Mda+i; nodes[j*(Mda+1)+Mda] = j*Mda; } for (i=0; i < Mda; i++) nodes[Nda*(Mda+1)+i] = i; nodes[Nda*(Mda+1)+Mda] = 0; k = 0; for (j=0; j<Nda; j++) { for (i=0; i<Mda; i++) { /* ld = nodes[j][i]; */ ld = nodes[j*(Mda+1)+i]; /* rd = nodes[j+1][i]; */ rd = nodes[(j+1)*(Mda+1)+i]; /* ru = nodes[j+1][i+1]; */ ru = nodes[(j+1)*(Mda+1)+i+1]; /* lu = nodes[j][i+1]; */ lu = nodes[j*(Mda+1)+i+1]; /* connect[k][0]=ld; */ connect[k*6]=ld; /* connect[k][1]=lu; */ connect[k*6+1]=lu; /* connect[k][2]=ru; */ connect[k*6+2]=rd; connect[k*6+3]=lu; connect[k*6+4]=ru; connect[k*6+5]=rd; k = k+1; } } eM_0[0][0]=eM_0[1][1]=eM_0[2][2]=hx*hy/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*hy/24.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_odd[1][2] = eM_2_odd[2][1] = 0.0; eM_2_even[1][1] = 1.0; 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; eM_2_even[0][2] = eM_2_even[2][0] = 0.0; for (k=0; k < Mda*Nda*2; k++) { idx[0] = connect[k*3]; idx[1] = connect[k*3+1]; idx[2] = connect[k*3+2]; PetscInt row,cols[6],r,row_M_0,cols3[3]; PetscScalar vals[6],vals_M_0[3],vals3[3]; for (r=0; r<3; r++) { row_M_0 = connect[k*3+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(M_0,1,&row_M_0,3,idx,vals_M_0,ADD_VALUES);CHKERRQ(ierr); /* cv_sum = (cv_p[idx[0]] + cv_p[idx[1]] + cv_p[idx[2]])*user->Dv/(3.0*user->kBT); */ /* ci_sum = (ci_p[idx[0]] + ci_p[idx[1]] + ci_p[idx[2]])*user->Di/(3.0*user->kBT); */ cv_sum = .0000069*user->Dv/user->kBT; ci_sum = .0000069*user->Di/user->kBT; if (k%2 == 0) { row = 5*idx[r]; cols[0] = 5*idx[0]; vals[0] = dt*eM_2_odd[r][0]*cv_sum; cols[1] = 5*idx[1]; vals[1] = dt*eM_2_odd[r][1]*cv_sum; cols[2] = 5*idx[2]; vals[2] = dt*eM_2_odd[r][2]*cv_sum; cols[3] = 5*idx[0]+1; vals[3] = eM_0[r][0]; cols[4] = 5*idx[1]+1; vals[4] = eM_0[r][1]; cols[5] = 5*idx[2]+1; vals[5] = eM_0[r][2]; ierr = MatSetValuesLocal(M,1,&row,6,cols,vals,ADD_VALUES);CHKERRQ(ierr); row = 5*idx[r]+1; cols[0] = 5*idx[0]; vals[0] = -1.0*eM_0[r][0]; cols[1] = 5*idx[1]; vals[1] = -1.0*eM_0[r][1]; cols[2] = 5*idx[2]; vals[2] = -1.0*eM_0[r][2]; cols[3] = 5*idx[0]+1; vals[3] = user->kav*eM_2_odd[r][0]; cols[4] = 5*idx[1]+1; vals[4] = user->kav*eM_2_odd[r][1]; cols[5] = 5*idx[2]+1; vals[5] = user->kav*eM_2_odd[r][2]; ierr = MatSetValuesLocal(M,1,&row,6,cols,vals,ADD_VALUES);CHKERRQ(ierr); row = 5*idx[r]+2; cols[0] = 5*idx[0]+2; vals[0] = dt*eM_2_odd[r][0]*ci_sum; cols[1] = 5*idx[1]+2; vals[1] = dt*eM_2_odd[r][1]*ci_sum; cols[2] = 5*idx[2]+2; vals[2] = dt*eM_2_odd[r][2]*ci_sum; cols[3] = 5*idx[0]+3; vals[3] = eM_0[r][0]; cols[4] = 5*idx[1]+3; vals[4] = eM_0[r][1]; cols[5] = 5*idx[2]+3; vals[5] = eM_0[r][2]; ierr = MatSetValuesLocal(M,1,&row,6,cols,vals,ADD_VALUES);CHKERRQ(ierr); row = 5*idx[r]+3; cols[0] = 5*idx[0]+2; vals[0] = -1.0*eM_0[r][0]; cols[1] = 5*idx[1]+2; vals[1] = -1.0*eM_0[r][1]; cols[2] = 5*idx[2]+2; vals[2] = -1.0*eM_0[r][2]; cols[3] = 5*idx[0]+3; vals[3] = user->kai*eM_2_odd[r][0]; cols[4] = 5*idx[1]+3; vals[4] = user->kai*eM_2_odd[r][1]; cols[5] = 5*idx[2]+3; vals[5] = user->kai*eM_2_odd[r][2]; ierr = MatSetValuesLocal(M,1,&row,6,cols,vals,ADD_VALUES);CHKERRQ(ierr); row = 5*idx[r]+4; /* cols3[0] = 5*idx[0]+4; vals3[0] = eM_0[r][0]/dt + user->L*user->kaeta*dt*eM_2_odd[r][0]; cols3[1] = 5*idx[1]+4; vals3[1] = eM_0[r][1]/dt + user->L*user->kaeta*dt*eM_2_odd[r][1]; cols3[2] = 5*idx[2]+4; vals3[2] = eM_0[r][2]/dt + user->L*user->kaeta*dt*eM_2_odd[r][2]; */ cols3[0] = 5*idx[0]+4; vals3[0] = eM_0[r][0]/dt + user->L*user->kaeta*eM_2_odd[r][0]; cols3[1] = 5*idx[1]+4; vals3[1] = eM_0[r][1]/dt + user->L*user->kaeta*eM_2_odd[r][1]; cols3[2] = 5*idx[2]+4; vals3[2] = eM_0[r][2]/dt + user->L*user->kaeta*eM_2_odd[r][2]; ierr = MatSetValuesLocal(M,1,&row,3,cols3,vals3,ADD_VALUES);CHKERRQ(ierr); } else { row = 5*idx[r]; cols[0] = 5*idx[0]; vals[0] = dt*eM_2_even[r][0]*cv_sum; cols[1] = 5*idx[1]; vals[1] = dt*eM_2_even[r][1]*cv_sum; cols[2] = 5*idx[2]; vals[2] = dt*eM_2_even[r][2]*cv_sum; cols[3] = 5*idx[0]+1; vals[3] = eM_0[r][0]; cols[4] = 5*idx[1]+1; vals[4] = eM_0[r][1]; cols[5] = 5*idx[2]+1; vals[5] = eM_0[r][2]; ierr = MatSetValuesLocal(M,1,&row,6,cols,vals,ADD_VALUES);CHKERRQ(ierr); row = 5*idx[r]+1; cols[0] = 5*idx[0]; vals[0] = -1.0*eM_0[r][0]; cols[1] = 5*idx[1]; vals[1] = -1.0*eM_0[r][1]; cols[2] = 5*idx[2]; vals[2] = -1.0*eM_0[r][2]; cols[3] = 5*idx[0]+1; vals[3] = user->kav*eM_2_even[r][0]; cols[4] = 5*idx[1]+1; vals[4] = user->kav*eM_2_even[r][1]; cols[5] = 5*idx[2]+1; vals[5] = user->kav*eM_2_even[r][2]; ierr = MatSetValuesLocal(M,1,&row,6,cols,vals,ADD_VALUES);CHKERRQ(ierr); row = 5*idx[r]+2; cols[0] = 5*idx[0]+2; vals[0] = dt*eM_2_even[r][0]*ci_sum; cols[1] = 5*idx[1]+2; vals[1] = dt*eM_2_even[r][1]*ci_sum; cols[2] = 5*idx[2]+2; vals[2] = dt*eM_2_even[r][2]*ci_sum; cols[3] = 5*idx[0]+3; vals[3] = eM_0[r][0]; cols[4] = 5*idx[1]+3; vals[4] = eM_0[r][1]; cols[5] = 5*idx[2]+3; vals[5] = eM_0[r][2]; ierr = MatSetValuesLocal(M,1,&row,6,cols,vals,ADD_VALUES);CHKERRQ(ierr); row = 5*idx[r]+3; cols[0] = 5*idx[0]+2; vals[0] = -1.0*eM_0[r][0]; cols[1] = 5*idx[1]+2; vals[1] = -1.0*eM_0[r][1]; cols[2] = 5*idx[2]+2; vals[2] = -1.0*eM_0[r][2]; cols[3] = 5*idx[0]+3; vals[3] = user->kai*eM_2_even[r][0]; cols[4] = 5*idx[1]+3; vals[4] = user->kai*eM_2_even[r][1]; cols[5] = 5*idx[2]+3; vals[5] = user->kai*eM_2_even[r][2]; ierr = MatSetValuesLocal(M,1,&row,6,cols,vals,ADD_VALUES);CHKERRQ(ierr); row = 5*idx[r]+4; /* cols3[0] = 5*idx[0]+4; vals3[0] = eM_0[r][0]/dt + user->L*user->kaeta*dt*eM_2_even[r][0]; cols3[1] = 5*idx[1]+4; vals3[1] = eM_0[r][1]/dt + user->L*user->kaeta*dt*eM_2_even[r][1]; cols3[2] = 5*idx[2]+4; vals3[2] = eM_0[r][2]/dt + user->L*user->kaeta*dt*eM_2_even[r][2]; */ cols3[0] = 5*idx[0]+4; vals3[0] = eM_0[r][0]/dt + user->L*user->kaeta*eM_2_even[r][0]; cols3[1] = 5*idx[1]+4; vals3[1] = eM_0[r][1]/dt + user->L*user->kaeta*eM_2_even[r][1]; cols3[2] = 5*idx[2]+4; vals3[2] = eM_0[r][2]/dt + user->L*user->kaeta*eM_2_even[r][2]; ierr = MatSetValuesLocal(M,1,&row,3,cols3,vals3,ADD_VALUES);CHKERRQ(ierr); } } } ierr = PetscFree(nodes);CHKERRQ(ierr); ierr = PetscFree(connect);CHKERRQ(ierr); ierr = VecRestoreArray(user->cv,&cv_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->ci,&ci_p);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); }