static PetscErrorCode FormMoleFraction(UserLGCtx *ctx,Vec massf,Vec *molef) { User user = ctx->user; PetscErrorCode ierr; PetscReal *M,tM=0; PetscInt i,n = user->Nspec+1; PetscScalar *mof; const PetscScalar **maf; PetscFunctionBegin; ierr = VecCreateSeq(PETSC_COMM_SELF,n,molef);CHKERRQ(ierr); ierr = PetscMalloc1(user->Nspec,&M);CHKERRQ(ierr); TC_getSmass(user->Nspec, M); ierr = DMDAVecGetArrayDOFRead(user->dm,massf,&maf);CHKERRQ(ierr); ierr = VecGetArray(*molef,&mof);CHKERRQ(ierr); mof[0] = maf[ctx->cell][0]; /* copy over temperature */ for (i=1; i<n; i++) tM += maf[ctx->cell][i]/M[i-1]; for (i=1; i<n; i++) { mof[i] = maf[ctx->cell][i]/(M[i-1]*tM); } ierr = DMDAVecRestoreArrayDOFRead(user->dm,massf,&maf);CHKERRQ(ierr); ierr = VecRestoreArray(*molef,&mof);CHKERRQ(ierr); ierr = PetscFree(M);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Applies the second order centered difference diffusion operator on a one dimensional periodic domain */ static PetscErrorCode FormDiffusionFunction(TS ts,PetscReal t,Vec X,Vec F,void *ptr) { User user = (User)ptr; PetscErrorCode ierr; PetscScalar **f; const PetscScalar **x; DM dm; PetscInt i,xs,xm,j,dof; Vec Xlocal; PetscReal idx; PetscFunctionBeginUser; ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); ierr = DMDAGetInfo(dm,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dof,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); ierr = DMGetLocalVector(dm,&Xlocal);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm,X,INSERT_VALUES,Xlocal);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm,X,INSERT_VALUES,Xlocal);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOFRead(dm,Xlocal,&x);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(dm,F,&f);CHKERRQ(ierr); ierr = DMDAGetCorners(dm,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); idx = 1.0*user->diffus/user->dx; for (i=xs; i<xs+xm; i++) { for (j=0; j<dof; j++) { f[i][j] += idx*(x[i+1][j] - 2.0*x[i][j] + x[i-1][j]); } } ierr = DMDAVecRestoreArrayDOFRead(dm,Xlocal,&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(dm,F,&f);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm,&Xlocal);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode FormRHSFunction(TS ts,PetscReal t,Vec X,Vec F,void *ptr) { User user = (User)ptr; PetscErrorCode ierr; PetscScalar **f; const PetscScalar **x; DM dm; PetscInt i,xs,xm; PetscFunctionBeginUser; if (user->reactions) { ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOFRead(dm,X,&x);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(dm,F,&f);CHKERRQ(ierr); ierr = DMDAGetCorners(dm,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); for (i=xs; i<xs+xm; i++) { ierr = PetscMemcpy(user->tchemwork,x[i],(user->Nspec+1)*sizeof(x[xs][0]));CHKERRQ(ierr); user->tchemwork[0] *= user->Tini; /* Dimensionalize */ ierr = TC_getSrc(user->tchemwork,user->Nspec+1,f[i]);TCCHKERRQ(ierr); f[i][0] /= user->Tini; /* Non-dimensionalize */ } ierr = DMDAVecRestoreArrayDOFRead(dm,X,&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(dm,F,&f);CHKERRQ(ierr); } else { ierr = VecZeroEntries(F);CHKERRQ(ierr); } if (user->diffusion) { ierr = FormDiffusionFunction(ts,t,X,F,ptr);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode FormRHSJacobian(TS ts,PetscReal t,Vec X,Mat Amat,Mat Pmat,void *ptr) { User user = (User)ptr; PetscErrorCode ierr; const PetscScalar **x; PetscInt M = user->Nspec+1,i,j,xs,xm;; DM dm; PetscFunctionBeginUser; if (user->reactions) { ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); ierr = MatZeroEntries(Pmat);CHKERRQ(ierr); ierr = MatSetOption(Pmat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); ierr = MatSetOption(Pmat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOFRead(dm,X,&x);CHKERRQ(ierr); ierr = DMDAGetCorners(dm,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); for (i=xs; i<xs+xm; i++) { ierr = PetscMemcpy(user->tchemwork,x[i],(user->Nspec+1)*sizeof(x[xs][0]));CHKERRQ(ierr); user->tchemwork[0] *= user->Tini; /* Dimensionalize temperature (first row) because that is what Tchem wants */ ierr = TC_getJacTYN(user->tchemwork,user->Nspec,user->Jdense,1);CHKERRQ(ierr); for (j=0; j<M; j++) user->Jdense[j + 0*M] /= user->Tini; /* Non-dimensionalize first column */ for (j=0; j<M; j++) user->Jdense[0 + j*M] /= user->Tini; /* Non-dimensionalize first row */ for (j=0; j<M; j++) user->rows[j] = i*M+j; ierr = MatSetValues(Pmat,M,user->rows,M,user->rows,user->Jdense,INSERT_VALUES);CHKERRQ(ierr); } ierr = DMDAVecRestoreArrayDOFRead(dm,X,&x);CHKERRQ(ierr); ierr = MatAssemblyBegin(Pmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Pmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } else { ierr = MatZeroEntries(Pmat);CHKERRQ(ierr); } if (user->diffusion) { ierr = FormDiffusionJacobian(ts,t,X,Amat,Pmat,ptr);CHKERRQ(ierr); } if (Amat != Pmat) { ierr = MatAssemblyBegin(Amat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Amat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscInt M = 10,N = 8,dof=1,s=1,bx=0,by=0,i,n,j,k,m,wrap,xs,ys; PetscErrorCode ierr; DM da,dac; PetscViewer viewer; Vec local,global,coors; PetscScalar ***xy,***aglobal; PetscDraw draw; char fname[16]; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; /* Create viewers */ ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"",PETSC_DECIDE,PETSC_DECIDE,600,200,&viewer);CHKERRQ(ierr); ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr); /* Read options */ ierr = PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-dof",&dof,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-s",&s,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-periodic_x",&wrap,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-periodic_y",&wrap,NULL);CHKERRQ(ierr); /* Create distributed array and get vectors */ ierr = DMDACreate2d(PETSC_COMM_WORLD,(DMBoundaryType)bx,(DMBoundaryType)by,DMDA_STENCIL_BOX,M,N,PETSC_DECIDE,PETSC_DECIDE,dof,s,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,0.0);CHKERRQ(ierr); for (i=0; i<dof; i++) { sprintf(fname,"Field %d",(int)i); ierr = DMDASetFieldName(da,i,fname);CHKERRQ(ierr); } ierr = DMView(da,viewer);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&coors);CHKERRQ(ierr); ierr = DMGetCoordinateDM(da,&dac);CHKERRQ(ierr); /* Set values into global vectors */ ierr = DMDAVecGetArrayDOFRead(dac,coors,&xy);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,global,&aglobal);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,&ys,0,&m,&n,0);CHKERRQ(ierr); for (k=0; k<dof; k++) { for (j=ys; j<ys+n; j++) { for (i=xs; i<xs+m; i++) { aglobal[j][i][k] = PetscSinScalar(2.0*PETSC_PI*(k+1)*xy[j][i][0]); } } } ierr = DMDAVecRestoreArrayDOF(da,global,&aglobal);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOFRead(dac,coors,&xy);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = VecSet(global,0.0);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(da,local,INSERT_VALUES,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(da,local,INSERT_VALUES,global);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(global,viewer);CHKERRQ(ierr); /* Free memory */ ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = VecDestroy(&local);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }