PetscErrorCode FormInitialSolution(TS ts,Vec X,void *ctx) { PetscScalar **x,*xc; PetscErrorCode ierr; struct {const char *name; PetscReal massfrac;} initial[] = { {"CH4", 0.0948178320887}, {"O2", 0.189635664177}, {"N2", 0.706766236705}, {"AR", 0.00878026702874} }; PetscInt i,j,xs,xm; DM dm; PetscFunctionBeginUser; ierr = VecZeroEntries(X);CHKERRQ(ierr); ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); ierr = DMDAGetCorners(dm,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); ierr = DMDAGetCoordinateArray(dm,&xc);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(dm,X,&x);CHKERRQ(ierr); for (i=xs; i<xs+xm; i++) { x[i][0] = 1.0 + .05*PetscSinScalar(2.*PETSC_PI*xc[i]); /* Non-dimensionalized by user->Tini */ for (j=0; j<sizeof(initial)/sizeof(initial[0]); j++) { int ispec = TC_getSpos(initial[j].name, strlen(initial[j].name)); if (ispec < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Could not find species %s",initial[j].name); ierr = PetscPrintf(PETSC_COMM_SELF,"Species %d: %s %g\n",j,initial[j].name,initial[j].massfrac);CHKERRQ(ierr); x[i][1+ispec] = initial[j].massfrac; } } ierr = DMDAVecRestoreArrayDOF(dm,X,&x);CHKERRQ(ierr); ierr = DMDARestoreCoordinateArray(dm,&xc);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Use TSMonitorLG to monitor the reactions in a particular cell */ static PetscErrorCode MonitorCell(TS ts,User user,PetscInt cell) { PetscErrorCode ierr; TSMonitorLGCtx ctx; char **snames; UserLGCtx *uctx; char label[128]; PetscReal temp,*xc; PetscMPIInt rank; PetscFunctionBegin; ierr = DMDAGetCoordinateArray(user->dm,&xc);CHKERRQ(ierr); temp = 1.0 + .05*PetscSinScalar(2.*PETSC_PI*xc[cell]); /* Non-dimensionalized by user->Tini */ ierr = DMDARestoreCoordinateArray(user->dm,&xc);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscSNPrintf(label,sizeof(label),"Initial Temperature %g Cell %d Rank %d",(double)user->Tini*temp,(int)cell,rank);CHKERRQ(ierr); ierr = TSMonitorLGCtxCreate(PETSC_COMM_SELF,NULL,label,PETSC_DECIDE,PETSC_DECIDE,600,400,1,&ctx);CHKERRQ(ierr); ierr = DMDAGetFieldNames(user->dm,(const char * const **)&snames);CHKERRQ(ierr); ierr = TSMonitorLGCtxSetVariableNames(ctx,(const char * const *)snames);CHKERRQ(ierr); ierr = PetscNew(&uctx);CHKERRQ(ierr); uctx->cell = cell; uctx->user = user; ierr = TSMonitorLGCtxSetTransform(ctx,(PetscErrorCode (*)(void*,Vec,Vec*))FormMoleFraction,(PetscErrorCode (*)(void*))MonitorCellDestroy,uctx);CHKERRQ(ierr); ierr = TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy);CHKERRQ(ierr); PetscFunctionReturn(0); }
// Formulas from page 22 of Hundsdorfer & Verwer (2003). Interpretation here is // to always generate 0.5 x 0.5 non-trivial patch in (0,L) x (0,L) domain. PetscErrorCode InitialState(Vec Y, double noiselevel, PatternCtx* user) { PetscErrorCode ierr; DMDALocalInfo info; int i,j; double sx,sy; const double ledge = (user->L - 0.5) / 2.0, // nontrivial initial values on redge = user->L - ledge; // ledge < x,y < redge DMDACoor2d **aC; Field **aY; ierr = VecSet(Y,0.0); CHKERRQ(ierr); if (noiselevel > 0.0) { // noise added to usual initial condition is uniform on [0,noiselevel], // independently for each location and component ierr = VecSetRandom(Y,NULL); CHKERRQ(ierr); ierr = VecScale(Y,noiselevel); CHKERRQ(ierr); } ierr = DMDAGetLocalInfo(user->da,&info); CHKERRQ(ierr); ierr = DMDAGetCoordinateArray(user->da,&aC); CHKERRQ(ierr); ierr = DMDAVecGetArray(user->da,Y,&aY); CHKERRQ(ierr); for (j = info.ys; j < info.ys+info.ym; j++) { for (i = info.xs; i < info.xs+info.xm; i++) { if ((aC[j][i].x >= ledge) && (aC[j][i].x <= redge) && (aC[j][i].y >= ledge) && (aC[j][i].y <= redge)) { sx = sin(4.0 * PETSC_PI * aC[j][i].x); sy = sin(4.0 * PETSC_PI * aC[j][i].y); aY[j][i].v += 0.5 * sx * sx * sy * sy; } aY[j][i].u += 1.0 - 2.0 * aY[j][i].v; } } ierr = DMDAVecRestoreArray(user->da,Y,&aY); CHKERRQ(ierr); ierr = DMDARestoreCoordinateArray(user->da,&aC); CHKERRQ(ierr); return 0; }