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); }
PetscErrorCode FormInitialSolution(TS ts, Vec U, void *ctx) { /* User user = (User) ctx; */ DM dm, cdm; DMDALocalInfo info; Vec C; Field *u; PetscScalar *x; const PetscReal sigma = 1.0; PetscInt i; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = TSGetDM(ts, &dm); ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &C);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dm, &info);CHKERRQ(ierr); ierr = DMDAVecGetArray(dm, U, &u);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(cdm, C, &x);CHKERRQ(ierr); for (i = info.xs; i < info.xs+info.xm; ++i) { u[i].u = 1.5 * PetscExpScalar(-PetscSqr(x[i] - 10)/PetscSqr(sigma)); u[i].v = 0.0; u[i].th = 0.0; } ierr = DMDAVecRestoreArray(dm, U, &u);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayRead(cdm, C, &x);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Solution - Computes the exact solution at a given time. Input Parameters: t - current time solution - vector in which exact solution will be computed appctx - user-defined application context Output Parameter: solution - vector with the newly computed exact solution */ PetscErrorCode Solution(TS ts,PetscReal t,Vec U,AppCtx *appctx) { PetscScalar *u,ex1,ex2,sc1,sc2,h; PetscErrorCode ierr; PetscInt i,mstart,mend,xm,M; DM da; ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&mstart,0,0,&xm,0,0);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&M,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); h = 1.0/M; mend = mstart + xm; /* Get a pointer to vector data. */ ierr = DMDAVecGetArray(da,U,&u);CHKERRQ(ierr); /* Simply write the solution directly into the array locations. Alternatively, we culd use VecSetValues() or VecSetValuesLocal(). */ ex1 = PetscExpScalar(-36.*PETSC_PI*PETSC_PI*appctx->d*t); ex2 = PetscExpScalar(-4.*PETSC_PI*PETSC_PI*appctx->d*t); sc1 = PETSC_PI*6.*h; sc2 = PETSC_PI*2.*h; for (i=mstart; i<mend; i++) u[i] = PetscSinScalar(sc1*(PetscReal)i + appctx->a*PETSC_PI*6.*t)*ex1 + 3.*PetscSinScalar(sc2*(PetscReal)i + appctx->a*PETSC_PI*2.*t)*ex2; /* Restore vector */ ierr = DMDAVecRestoreArray(da,U,&u);CHKERRQ(ierr); return 0; }
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); }
/* IJacobian - Compute IJacobian = dF/dU + a dF/dUdot */ PetscErrorCode FormIJacobian(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal a, Mat J, Mat Jpre, void *ctx) { User user = (User) ctx; DM dm, cdm; DMDALocalInfo info; Vec C; Field *u, *udot; PetscScalar *x; PetscInt i; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dm, &info);CHKERRQ(ierr); ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &C);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(dm, U, &u);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(dm, Udot, &udot);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(cdm, C, &x);CHKERRQ(ierr); for (i = info.xs; i < info.xs+info.xm; ++i) { if (i == 0) { const PetscScalar hx = x[i+1] - x[i]; const PetscInt row = i, col[] = {i,i+1}; const PetscScalar dxx0 = PetscSqr(user->c)/hx,dxxR = -PetscSqr(user->c)/hx; const PetscScalar vals[3][2][3] = {{{a*hx, 0,0},{0,0, 0}}, {{0,a*hx+dxx0,0},{0,dxxR,0}}, {{0,0, a*hx},{0,0, 0}}}; ierr = MatSetValuesBlocked(Jpre, 1, &row, 2, col, &vals[0][0][0], INSERT_VALUES);CHKERRQ(ierr); } else if (i == info.mx-1) { const PetscScalar hx = x[i+1] - x[i]; const PetscInt row = i, col[] = {i-1,i}; const PetscScalar dxxL = -PetscSqr(user->c)/hx, dxx0 = PetscSqr(user->c)/hx; const PetscScalar vals[3][2][3] = {{{0,0, 0},{a*hx, 0,0}}, {{0,dxxL,0},{0,a*hx+dxx0,0}}, {{0,0, 0},{0,0, a*hx}}}; ierr = MatSetValuesBlocked(Jpre, 1, &row, 2, col, &vals[0][0][0], INSERT_VALUES);CHKERRQ(ierr); } else { const PetscScalar hx = x[i+1] - x[i]; const PetscInt row = i, col[] = {i-1,i,i+1}; const PetscScalar dxxL = -PetscSqr(user->c)/hx, dxx0 = 2.*PetscSqr(user->c)/hx,dxxR = -PetscSqr(user->c)/hx; const PetscScalar vals[3][3][3] = {{{0,0, 0},{a*hx, 0,0},{0,0, 0}}, {{0,dxxL,0},{0,a*hx+dxx0,0},{0,dxxR,0}}, {{0,0, 0},{0,0, a*hx},{0,0, 0}}}; ierr = MatSetValuesBlocked(Jpre, 1, &row, 3, col, &vals[0][0][0], INSERT_VALUES);CHKERRQ(ierr); } } ierr = DMDAVecRestoreArrayRead(dm, U, &u);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayRead(dm, Udot, &udot);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayRead(cdm, C, &x);CHKERRQ(ierr); ierr = MatAssemblyBegin(Jpre, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Jpre, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (J != Jpre) { ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/* InitialConditions - Computes the solution at the initial time. Input Parameter: u - uninitialized solution vector (global) appctx - user-defined application context Output Parameter: u - vector with solution at initial time (global) */ PetscErrorCode InitialConditions(TS ts,Vec U,AppCtx *appctx) { PetscScalar *u; PetscErrorCode ierr; PetscInt i,mstart,mend,um,M; DM da; PetscReal h; ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&mstart,0,0,&um,0,0);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&M,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); h = 1.0/M; mend = mstart + um; /* Get a pointer to vector data. - For default PETSc vectors, VecGetArray() returns a pointer to the data array. Otherwise, the routine is implementation dependent. - You MUST call VecRestoreArray() when you no longer need access to the array. - Note that the Fortran interface to VecGetArray() differs from the C version. See the users manual for details. */ ierr = DMDAVecGetArray(da,U,&u);CHKERRQ(ierr); /* We initialize the solution array by simply writing the solution directly into the array locations. Alternatively, we could use VecSetValues() or VecSetValuesLocal(). */ for (i=mstart; i<mend; i++) u[i] = PetscSinReal(PETSC_PI*i*6.*h) + 3.*PetscSinReal(PETSC_PI*i*2.*h); /* Restore vector */ ierr = DMDAVecRestoreArray(da,U,&u);CHKERRQ(ierr); return 0; }
/* Solution - Computes the exact solution at a given time Input Parameters: t - current time solution - vector in which exact solution will be computed appctx - user-defined application context Output Parameter: solution - vector with the newly computed exact solution u(x,t) = sin(6*PI*(x - a*t)) + 3 * sin(2*PI*(x - a*t)) */ PetscErrorCode Solution(TS ts,PetscReal t,Vec U,AppCtx *appctx) { PetscScalar *u; PetscReal a=appctx->a,h,PI6,PI2; PetscErrorCode ierr; PetscInt i,mstart,mend,um,M; DM da; ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&mstart,0,0,&um,0,0);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&M,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); h = 1.0/M; mend = mstart + um; /* Get a pointer to vector data. */ ierr = DMDAVecGetArray(da,U,&u);CHKERRQ(ierr); /* u[i] = sin(6*PI*(x[i] - a*t)) + 3 * sin(2*PI*(x[i] - a*t)) */ PI6 = PETSC_PI*6.; PI2 = PETSC_PI*2.; for (i=mstart; i<mend; i++) { u[i] = PetscSinReal(PI6*(i*h - a*t)) + 3.*PetscSinReal(PI2*(i*h - a*t)); } /* Restore vector */ ierr = DMDAVecRestoreArray(da,U,&u);CHKERRQ(ierr); return 0; }
static PetscErrorCode FormIFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ptr) { User user = (User)ptr; DM da; DMDALocalInfo info; PetscInt i; Field *x,*xdot,*f; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); /* Get pointers to vector data */ ierr = DMDAVecGetArray(da,X,&x);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,Xdot,&xdot);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,F,&f);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (i=info.xs; i<info.xs+info.xm; i++) { f[i][0] = xdot[i][0] + user->k[0]*x[i][0] - user->k[1]*x[i][1] - user->s[0]; f[i][1] = xdot[i][1] - user->k[0]*x[i][0] + user->k[1]*x[i][1] - user->s[1]; } /* Restore vectors */ ierr = DMDAVecRestoreArray(da,X,&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da,Xdot,&xdot);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da,F,&f);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode FormInitialSolution(TS ts,Vec X,void *ctx) { User user = (User)ctx; DM da; PetscInt i; DMDALocalInfo info; Field *x; PetscReal hx; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = TSGetDM(ts,&da); ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); hx = 1.0/(PetscReal)info.mx; /* Get pointers to vector data */ ierr = DMDAVecGetArray(da,X,&x);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (i=info.xs; i<info.xs+info.xm; i++) { PetscReal r = (i+1)*hx,ik = user->k[1] != 0.0 ? 1.0/user->k[1] : 1.0; x[i][0] = 1 + user->s[1]*r; x[i][1] = user->k[0]*ik*x[i][0] + user->s[1]*ik; } ierr = DMDAVecRestoreArray(da,X,&x);CHKERRQ(ierr); PetscFunctionReturn(0); }
int TSFunction_Sundials(realtype t,N_Vector y,N_Vector ydot,void *ctx) { TS ts = (TS) ctx; DM dm; DMTS tsdm; TSIFunction ifunction; MPI_Comm comm; TS_Sundials *cvode = (TS_Sundials*)ts->data; Vec yy = cvode->w1,yyd = cvode->w2,yydot = cvode->ydot; PetscScalar *y_data,*ydot_data; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr); /* Make the PETSc work vectors yy and yyd point to the arrays in the SUNDIALS vectors y and ydot respectively*/ y_data = (PetscScalar*) N_VGetArrayPointer(y); ydot_data = (PetscScalar*) N_VGetArrayPointer(ydot); ierr = VecPlaceArray(yy,y_data);CHKERRABORT(comm,ierr); ierr = VecPlaceArray(yyd,ydot_data);CHKERRABORT(comm,ierr); /* Now compute the right hand side function, via IFunction unless only the more efficient RHSFunction is set */ ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); ierr = DMGetDMTS(dm,&tsdm);CHKERRQ(ierr); ierr = DMTSGetIFunction(dm,&ifunction,NULL);CHKERRQ(ierr); if (!ifunction) { ierr = TSComputeRHSFunction(ts,t,yy,yyd);CHKERRQ(ierr); } else { /* If rhsfunction is also set, this computes both parts and shifts them to the right */ ierr = VecZeroEntries(yydot);CHKERRQ(ierr); ierr = TSComputeIFunction(ts,t,yy,yydot,yyd,PETSC_FALSE);CHKERRABORT(comm,ierr); ierr = VecScale(yyd,-1.);CHKERRQ(ierr); } ierr = VecResetArray(yy);CHKERRABORT(comm,ierr); ierr = VecResetArray(yyd);CHKERRABORT(comm,ierr); PetscFunctionReturn(0); }
/* ------------------------------------------------------------------- */ PetscErrorCode FormInitialSolution(TS ts, Vec U, void * /*ptr*/) { DM da; PetscReal c = -30.0; PetscErrorCode ierr; PetscInt i, j, xs, ys, xm, ym, Mx, My; PetscScalar ** u; PetscReal hx, hy, x, y, r; PetscFunctionBeginUser; ierr = TSGetDM(ts, &da); CHKERRQ(ierr); ierr = DMDAGetInfo(da, PETSC_IGNORE, &Mx, &My, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE, PETSC_IGNORE); CHKERRQ(ierr); hx = 1.0 / (PetscReal)(Mx - 1); hy = 1.0 / (PetscReal)(My - 1); /* Get pointers to vector data */ ierr = DMDAVecGetArray(da, U, &u); CHKERRQ(ierr); /* Get local grid boundaries */ ierr = DMDAGetCorners(da, &xs, &ys, NULL, &xm, &ym, NULL); CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (j = ys; j < ys + ym; j++) { y = j * hy; for (i = xs; i < xs + xm; i++) { x = i * hx; r = PetscSqrtReal((x - .5) * (x - .5) + (y - .5) * (y - .5)); if (r < .125) u[j][i] = PetscExpReal(c * r * r * r); else u[j][i] = 0.0; } } /* Restore vectors */ ierr = DMDAVecRestoreArray(da, U, &u); CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode FormRHSFunction(TS ts, PetscReal t, Vec U, Vec F, void *ctx) { User user = (User) ctx; DM dm, cdm; DMDALocalInfo info; Vec C; Field *f; const Field *u; const PetscScalar *x; PetscInt i; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &C);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dm, &info);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(dm, U, &u);CHKERRQ(ierr); ierr = DMDAVecGetArray(dm, F, &f);CHKERRQ(ierr); ierr = DMDAVecGetArray(cdm, C, &x);CHKERRQ(ierr); for (i = info.xs; i < info.xs+info.xm; ++i) { const PetscScalar hx = i+1 == info.xs+info.xm ? x[i] - x[i-1] : x[i+1] - x[i]; f[i].u = hx*(u[i].v); f[i].v = -hx*(PetscSqr(user->gammaTilde)*u[i].u + (PetscSqr(user->gamma) / user->xi)*(u[i].th + log(u[i].v + 1))); f[i].th = -hx*(u[i].v + 1)*(u[i].th + (1 + user->epsilon)*log(u[i].v + 1)); } ierr = DMDAVecRestoreArrayRead(dm, U, &u);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dm, F, &f);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayRead(cdm, C, &x);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode TSComputeRHSJacobian_DMDA(TS ts,PetscReal ptime,Vec X,Mat *A,Mat *B,MatStructure *mstr,void *ctx) { PetscErrorCode ierr; DM dm; DMTS_DA *dmdats = (DMTS_DA*)ctx; DMDALocalInfo info; Vec Xloc; void *x; PetscFunctionBegin; if (!dmdats->rhsfunctionlocal) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Corrupt context"); ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); if (dmdats->rhsjacobianlocal) { ierr = DMGetLocalVector(dm,&Xloc);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr); ierr = DMDAVecGetArray(dm,Xloc,&x);CHKERRQ(ierr); CHKMEMQ; ierr = (*dmdats->rhsjacobianlocal)(&info,ptime,x,*A,*B,mstr,dmdats->rhsjacobianlocalctx);CHKERRQ(ierr); CHKMEMQ; ierr = DMDAVecRestoreArray(dm,Xloc,&x);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm,&Xloc);CHKERRQ(ierr); } else SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"TSComputeRHSJacobian_DMDA() called without calling DMDATSSetRHSJacobian()"); /* This will be redundant if the user called both, but it's too common to forget. */ if (*A != *B) { ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode TSSetUp_Theta(TS ts) { TS_Theta *th = (TS_Theta*)ts->data; PetscErrorCode ierr; SNES snes; TSAdapt adapt; DM dm; PetscFunctionBegin; ierr = VecDuplicate(ts->vec_sol,&th->X);CHKERRQ(ierr); ierr = VecDuplicate(ts->vec_sol,&th->Xdot);CHKERRQ(ierr); ierr = VecDuplicate(ts->vec_sol,&th->X0);CHKERRQ(ierr); ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); if (dm) { ierr = DMCoarsenHookAdd(dm,DMCoarsenHook_TSTheta,DMRestrictHook_TSTheta,ts);CHKERRQ(ierr); ierr = DMSubDomainHookAdd(dm,DMSubDomainHook_TSTheta,DMSubDomainRestrictHook_TSTheta,ts);CHKERRQ(ierr); } if (th->Theta == 0.5 && th->endpoint) th->order = 2; else th->order = 1; ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); if (!th->adapt) { ierr = TSAdaptSetType(adapt,TSADAPTNONE);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode FormInitialSolution(TS ts,Vec X,void *ctx) { User user = (User)ctx; DM da; PetscInt i; DMDALocalInfo info; Field *x; PetscReal hx; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = TSGetDM(ts,&da); ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); hx = 1.0/(PetscReal)(info.mx-1); /* Get pointers to vector data */ ierr = DMDAVecGetArray(da,X,&x);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (i=info.xs; i<info.xs+info.xm; i++) { PetscReal xi = i*hx; x[i].u = user->uleft*(1.-xi) + user->uright*xi + sin(2.*PETSC_PI*xi); x[i].v = user->vleft*(1.-xi) + user->vright*xi; } ierr = DMDAVecRestoreArray(da,X,&x);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode FormRHSFunction(TS ts,PetscReal t,Vec X,Vec F,void *ptr) { User user = (User)ptr; DM da; DMDALocalInfo info; PetscInt i; PetscReal hx; Field *x,*f; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); hx = 1.0/(PetscReal)(info.mx-1); /* Get pointers to vector data */ ierr = DMDAVecGetArray(da,X,&x);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,F,&f);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (i=info.xs; i<info.xs+info.xm; i++) { PetscScalar u = x[i].u,v = x[i].v; f[i].u = hx*(user->A + u*u*v - (user->B+1)*u); f[i].v = hx*(user->B*u - u*u*v); } /* Restore vectors */ ierr = DMDAVecRestoreArray(da,X,&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da,F,&f);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); }
/* Produces the second order centered difference diffusion operator on a one dimensional periodic domain */ static PetscErrorCode FormDiffusionJacobian(TS ts,PetscReal t,Vec X,Mat Amat,Mat Pmat,void *ptr) { User user = (User)ptr; PetscErrorCode ierr; DM dm; PetscInt i,xs,xm,j,dof; PetscReal idx,values[3]; MatStencil row,col[3]; 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 = DMDAGetCorners(dm,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); idx = 1.0*user->diffus/user->dx; values[0] = idx; values[1] = -2.0*idx; values[2] = idx; for (i=xs; i<xs+xm; i++) { for (j=0; j<dof; j++) { row.i = i; row.c = j; col[0].i = i-1; col[0].c = j; col[1].i = i; col[1].c = j; col[2].i = i+1; col[2].c = j; ierr = MatSetValuesStencil(Pmat,1,&row,3,col,values,ADD_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(Pmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(Pmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* RHSFunction - Evaluates nonlinear function, F(u). Input Parameters: . ts - the TS context . U - input vector . ptr - optional user-defined context, as set by TSSetFunction() Output Parameter: . F - function vector */ PetscErrorCode RHSFunction(TS ts,PetscReal ftime,Vec U,Vec F,void *ptr) { /* PETSC_UNUSED AppCtx *user=(AppCtx*)ptr; */ DM da; PetscErrorCode ierr; PetscInt i,j,Mx,My,xs,ys,xm,ym; PetscReal two = 2.0,hx,hy,sx,sy; PetscScalar u,uxx,uyy,**uarray,**f; Vec localU; PetscFunctionBeginUser; ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMGetLocalVector(da,&localU);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE); hx = 1.0/(PetscReal)(Mx-1); sx = 1.0/(hx*hx); hy = 1.0/(PetscReal)(My-1); sy = 1.0/(hy*hy); /* Scatter ghost points to local vector,using the 2-step process DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ ierr = DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); /* Get pointers to vector data */ ierr = DMDAVecGetArray(da,localU,&uarray);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,F,&f);CHKERRQ(ierr); /* Get local grid boundaries */ ierr = DMDAGetCorners(da,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { if (i == 0 || j == 0 || i == Mx-1 || j == My-1) { f[j][i] = uarray[j][i]; continue; } u = uarray[j][i]; uxx = (-two*u + uarray[j][i-1] + uarray[j][i+1])*sx; uyy = (-two*u + uarray[j-1][i] + uarray[j+1][i])*sy; f[j][i] = uxx + uyy; } } /* Restore vectors */ ierr = DMDAVecRestoreArray(da,localU,&uarray);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da,F,&f);CHKERRQ(ierr); ierr = DMRestoreLocalVector(da,&localU);CHKERRQ(ierr); ierr = PetscLogFlops(11.0*ym*xm);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* * This is a modified version of PETSc/src/ts/examples/tutorials/ex15.c * to demonstrate how MOOSE interact with an external solver package */ PetscErrorCode externalPETScDiffusionFDMSolve(TS ts, Vec u, PetscReal dt, PetscReal time) { PetscErrorCode ierr; #if !PETSC_VERSION_LESS_THAN(3, 8, 0) PetscInt current_step; #endif DM da; PetscFunctionBeginUser; ierr = TSGetDM(ts, &da); CHKERRQ(ierr); #if !PETSC_VERSION_LESS_THAN(3, 7, 0) PetscOptionsSetValue(NULL, "-ts_monitor", NULL); PetscOptionsSetValue(NULL, "-snes_monitor", NULL); PetscOptionsSetValue(NULL, "-ksp_monitor", NULL); #else PetscOptionsSetValue("-ts_monitor", NULL); PetscOptionsSetValue("-snes_monitor", NULL); PetscOptionsSetValue("-ksp_monitor", NULL); #endif /*ierr = TSSetMaxTime(ts,1.0);CHKERRQ(ierr);*/ ierr = TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER); CHKERRQ(ierr); ierr = TSSetSolution(ts, u); CHKERRQ(ierr); ierr = TSSetTimeStep(ts, dt); CHKERRQ(ierr); ierr = TSSetTime(ts, time - dt); CHKERRQ(ierr); #if !PETSC_VERSION_LESS_THAN(3, 8, 0) ierr = TSGetStepNumber(ts, ¤t_step); CHKERRQ(ierr); ierr = TSSetMaxSteps(ts, current_step + 1); CHKERRQ(ierr); #else SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Require PETSc-3.8.x or higher "); #endif /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Sets various TS parameters from user options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts, u); CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode FormResidual(TS ts,PetscReal t,Vec U,Vec Udot,Vec R,void *user) { PetscFunctionBegin; PetscErrorCode ierr; DMDALocalInfo info; DM dm; Vec localU,localUdot,localR; // local versions Field **h,**hdot,**r; /* get the da from the snes */ ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); /* handle the vec U */ ierr = DMGetLocalVector(dm,&localU);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm,U,INSERT_VALUES,localU);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm,U,INSERT_VALUES,localU);CHKERRQ(ierr); /* handle the vec Udot */ ierr = DMGetLocalVector(dm,&localUdot);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm,Udot,INSERT_VALUES,localUdot);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm,Udot,INSERT_VALUES,localUdot);CHKERRQ(ierr); /* handle the vec R */ ierr = DMGetLocalVector(dm,&localR);CHKERRQ(ierr); ierr = VecZeroEntries(localR);CHKERRQ(ierr); /* Get the arrays from the vectors */ ierr = DMIGAVecGetArray(dm,localU,&h);CHKERRQ(ierr); ierr = DMIGAVecGetArray(dm,localUdot,&hdot);CHKERRQ(ierr); ierr = DMIGAVecGetArray(dm,localR,&r);CHKERRQ(ierr); /* Grab the local info and call the local residual routine */ ierr = DMIGAGetLocalInfo(dm,&info);CHKERRQ(ierr);CHKERRQ(ierr); ierr = FormResidualLocal(&info,t,h,hdot,r,(AppCtx *) user);CHKERRQ(ierr); /* Restore the arrays */ ierr = DMIGAVecRestoreArray(dm,localR,&r);CHKERRQ(ierr); ierr = DMIGAVecRestoreArray(dm,localUdot,&hdot);CHKERRQ(ierr); ierr = DMIGAVecRestoreArray(dm,localU,&h);CHKERRQ(ierr); /* Add contributions back to global R */ ierr = VecZeroEntries(R);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(dm,localR,ADD_VALUES,R);CHKERRQ(ierr); // this one adds the values ierr = DMLocalToGlobalEnd(dm,localR,ADD_VALUES,R);CHKERRQ(ierr); /* Restore the local vectors */ ierr = DMRestoreLocalVector(dm,&localU);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm,&localUdot);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm,&localR);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* FormFunction - Evaluates nonlinear function, F(x). Input Parameters: . ts - the TS context . X - input vector . ptr - optional user-defined context, as set by SNESSetFunction() Output Parameter: . F - function vector */ PetscErrorCode FormFunction(TS ts,PetscReal ftime,Vec X,Vec F,void *ptr) { DM da; PetscErrorCode ierr; PetscInt i,Mx,xs,xm; PetscReal hx,sx; PetscScalar *x,*f; Vec localX; UserCtx *ctx = (UserCtx*)ptr; PetscFunctionBegin; ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); hx = 1.0/(PetscReal)Mx; sx = 1.0/(hx*hx); /* Scatter ghost points to local vector,using the 2-step process DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); /* Get pointers to vector data */ ierr = DMDAVecGetArrayRead(da,localX,&x);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,F,&f);CHKERRQ(ierr); /* Get local grid boundaries */ ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (i=xs; i<xs+xm; i++) { f[i] = ctx->kappa*(x[i-1] + x[i+1] - 2.0*x[i])*sx; if (ctx->allencahn) f[i] += (x[i] - x[i]*x[i]*x[i]); } /* Restore vectors */ ierr = DMDAVecRestoreArrayRead(da,localX,&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da,F,&f);CHKERRQ(ierr); ierr = DMRestoreLocalVector(da,&localX);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode FormIFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ptr) { User user = (User)ptr; DM da; DMDALocalInfo info; PetscInt i; Field *x,*xdot,*f; PetscReal hx; Vec Xloc; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); hx = 1.0/(PetscReal)(info.mx-1); /* Scatter ghost points to local vector,using the 2-step process DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ ierr = DMGetLocalVector(da,&Xloc);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); /* Get pointers to vector data */ ierr = DMDAVecGetArray(da,Xloc,&x);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,Xdot,&xdot);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,F,&f);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (i=info.xs; i<info.xs+info.xm; i++) { if (i == 0) { f[i].u = hx * (x[i].u - user->uleft); f[i].v = hx * (x[i].v - user->vleft); } else if (i == info.mx-1) { f[i].u = hx * (x[i].u - user->uright); f[i].v = hx * (x[i].v - user->vright); } else { f[i].u = hx * xdot[i].u - user->alpha * (x[i-1].u - 2.*x[i].u + x[i+1].u) / hx; f[i].v = hx * xdot[i].v - user->alpha * (x[i-1].v - 2.*x[i].v + x[i+1].v) / hx; } } /* Restore vectors */ ierr = DMDAVecRestoreArray(da,Xloc,&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da,Xdot,&xdot);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da,F,&f);CHKERRQ(ierr); ierr = DMRestoreLocalVector(da,&Xloc);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode FormRHSFunction(TS ts,PetscReal t,Vec X,Vec F,void *ptr) { User user = (User)ptr; DM da; Vec Xloc; DMDALocalInfo info; PetscInt i,j; PetscReal hx; Field *f; const Field *x; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); hx = 1.0/(PetscReal)info.mx; /* Scatter ghost points to local vector,using the 2-step process DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ ierr = DMGetLocalVector(da,&Xloc);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); /* Get pointers to vector data */ ierr = DMDAVecGetArrayRead(da,Xloc,(void*)&x);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,F,&f);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (i=info.xs; i<info.xs+info.xm; i++) { const PetscReal *a = user->a; PetscReal u0t[2]; u0t[0] = 1.0 - PetscPowRealInt(PetscSinReal(12*t),4); u0t[1] = 0.0; for (j=0; j<2; j++) { if (i == 0) f[i][j] = a[j]/hx*(1./3*u0t[j] + 0.5*x[i][j] - x[i+1][j] + 1./6*x[i+2][j]); else if (i == 1) f[i][j] = a[j]/hx*(-1./12*u0t[j] + 2./3*x[i-1][j] - 2./3*x[i+1][j] + 1./12*x[i+2][j]); else if (i == info.mx-2) f[i][j] = a[j]/hx*(-1./6*x[i-2][j] + x[i-1][j] - 0.5*x[i][j] - 1./3*x[i+1][j]); else if (i == info.mx-1) f[i][j] = a[j]/hx*(-x[i][j] + x[i-1][j]); else f[i][j] = a[j]/hx*(-1./12*x[i-2][j] + 2./3*x[i-1][j] - 2./3*x[i+1][j] + 1./12*x[i+2][j]); } } /* Restore vectors */ ierr = DMDAVecRestoreArrayRead(da,Xloc,(void*)&x);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da,F,&f);CHKERRQ(ierr); ierr = DMRestoreLocalVector(da,&Xloc);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Sets up a monitor that will display He as a function of space and cluster size for each time step */ PetscErrorCode MyMonitorSetUp(TS ts) { DM da; PetscErrorCode ierr; PetscInt xi,xs,xm,*idx,M,xj,cnt = 0,dof = 3*N + N*N; const PetscInt *lx; Vec C; MyMonitorCtx *ctx; PetscBool flg; IS is; char ycoor[32]; PetscReal valuebounds[4] = {0, 1.2, 0, 1.2}; PetscFunctionBeginUser; ierr = PetscOptionsHasName(PETSC_NULL,"-mymonitor",&flg);CHKERRQ(ierr); if (!flg) PetscFunctionReturn(0); ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = PetscNew(MyMonitorCtx,&ctx);CHKERRQ(ierr); ierr = PetscViewerDrawOpen(((PetscObject)da)->comm,PETSC_NULL,"",PETSC_DECIDE,PETSC_DECIDE,600,400,&ctx->viewer);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&M,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); ierr = DMDAGetOwnershipRanges(da,&lx,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = DMDACreate2d(((PetscObject)da)->comm,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,M,N,PETSC_DETERMINE,1,2,1,lx,PETSC_NULL,&ctx->da);CHKERRQ(ierr); ierr = DMDASetFieldName(ctx->da,0,"He");CHKERRQ(ierr); ierr = DMDASetFieldName(ctx->da,1,"V");CHKERRQ(ierr); ierr = DMDASetCoordinateName(ctx->da,0,"X coordinate direction");CHKERRQ(ierr); ierr = PetscSNPrintf(ycoor,32,"%D ... Cluster size ... 1",N);CHKERRQ(ierr); ierr = DMDASetCoordinateName(ctx->da,1,ycoor);CHKERRQ(ierr); ierr = DMCreateGlobalVector(ctx->da,&ctx->He);CHKERRQ(ierr); ierr = PetscMalloc(2*N*xm*sizeof(PetscInt),&idx);CHKERRQ(ierr); cnt = 0; for (xj=0; xj<N; xj++) { for (xi=xs; xi<xs+xm; xi++) { idx[cnt++] = dof*xi + xj; idx[cnt++] = dof*xi + xj + N; } } ierr = ISCreateGeneral(((PetscObject)ts)->comm,2*N*xm,idx,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); ierr = TSGetSolution(ts,&C);CHKERRQ(ierr); ierr = VecScatterCreate(C,is,ctx->He,PETSC_NULL,&ctx->scatter);CHKERRQ(ierr); ierr = ISDestroy(&is);CHKERRQ(ierr); /* sets the bounds on the contour plot values so the colors mean the same thing for different timesteps */ ierr = PetscViewerDrawSetBounds(ctx->viewer,2,valuebounds);CHKERRQ(ierr); ierr = TSMonitorSet(ts,MyMonitorMonitor,ctx,MyMonitorDestroy);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode FormTangent(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat *A,Mat *B,MatStructure *flag,void *ctx) { PetscFunctionBegin; PetscErrorCode ierr; SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "FormTangent not implemented, use -snes_mf"); DMDALocalInfo info; DM da_dof; Vec localU,localUdot; // local versions Field **h,**hdot; /* get the da from the snes */ ierr = TSGetDM(ts,(DM*)&da_dof);CHKERRQ(ierr); /* handle the vec U */ ierr = DMGetLocalVector(da_dof,&localU);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da_dof,U,INSERT_VALUES,localU);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da_dof,U,INSERT_VALUES,localU);CHKERRQ(ierr); /* handle the vec Udot */ ierr = DMGetLocalVector(da_dof,&localUdot);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da_dof,Udot,INSERT_VALUES,localUdot);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da_dof,Udot,INSERT_VALUES,localUdot);CHKERRQ(ierr); /* Get the arrays from the vectors */ ierr = DMDAVecGetArray(da_dof,localU,&h);CHKERRQ(ierr); ierr = DMDAVecGetArray(da_dof,localUdot,&hdot);CHKERRQ(ierr); /* Grab the local info and call the local tangent routine */ ierr = DMDAGetLocalInfo(da_dof,&info);CHKERRQ(ierr);CHKERRQ(ierr); ierr = MatZeroEntries(*B);CHKERRQ(ierr); // pre-zero the matrix ierr = FormTangentLocal(&info,t,h,hdot,shift,B,(AppCtx *) ctx);CHKERRQ(ierr); ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); if (*A != *B) { // then we could be matrix free ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); } *flag = SAME_NONZERO_PATTERN; /* the sparsity pattern does not change */ ierr = DMDAVecRestoreArray(da_dof,localUdot,&hdot);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da_dof,localU,&h);CHKERRQ(ierr); /* Restore the arrays and local vectors */ ierr = DMRestoreLocalVector(da_dof,&localU);CHKERRQ(ierr); ierr = DMRestoreLocalVector(da_dof,&localUdot);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* This function should eventually replace: DMDAComputeFunction() and DMDAComputeFunction1() */ static PetscErrorCode TSComputeIFunction_DMDA(TS ts,PetscReal ptime,Vec X,Vec Xdot,Vec F,void *ctx) { PetscErrorCode ierr; DM dm; DMTS_DA *dmdats = (DMTS_DA*)ctx; DMDALocalInfo info; Vec Xloc; void *x,*f,*xdot; PetscFunctionBegin; PetscValidHeaderSpecific(ts,TS_CLASSID,1); PetscValidHeaderSpecific(X,VEC_CLASSID,2); PetscValidHeaderSpecific(F,VEC_CLASSID,3); if (!dmdats->ifunctionlocal) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_PLIB,"Corrupt context"); ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); ierr = DMGetLocalVector(dm,&Xloc);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr); ierr = DMDAVecGetArray(dm,Xloc,&x);CHKERRQ(ierr); ierr = DMDAVecGetArray(dm,Xdot,&xdot);CHKERRQ(ierr); switch (dmdats->ifunctionlocalimode) { case INSERT_VALUES: { ierr = DMDAVecGetArray(dm,F,&f);CHKERRQ(ierr); CHKMEMQ; ierr = (*dmdats->ifunctionlocal)(&info,ptime,x,xdot,f,dmdats->ifunctionlocalctx);CHKERRQ(ierr); CHKMEMQ; ierr = DMDAVecRestoreArray(dm,F,&f);CHKERRQ(ierr); } break; case ADD_VALUES: { Vec Floc; ierr = DMGetLocalVector(dm,&Floc);CHKERRQ(ierr); ierr = VecZeroEntries(Floc);CHKERRQ(ierr); ierr = DMDAVecGetArray(dm,Floc,&f);CHKERRQ(ierr); CHKMEMQ; ierr = (*dmdats->ifunctionlocal)(&info,ptime,x,xdot,f,dmdats->ifunctionlocalctx);CHKERRQ(ierr); CHKMEMQ; ierr = DMDAVecRestoreArray(dm,Floc,&f);CHKERRQ(ierr); ierr = VecZeroEntries(F);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(dm,Floc,ADD_VALUES,F);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(dm,Floc,ADD_VALUES,F);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm,&Floc);CHKERRQ(ierr); } break; default: SETERRQ1(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_INCOMP,"Cannot use imode=%d",(int)dmdats->ifunctionlocalimode); } ierr = DMDAVecRestoreArray(dm,Xloc,&x);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm,&Xloc);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dm,Xdot,&xdot);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode FormIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal a,Mat *J,Mat *Jpre,MatStructure *str,void *ctx) { PetscErrorCode ierr; PetscInt i,rstart,rend,Mx; PetscReal hx,sx; AppCtx *user = (AppCtx*)ctx; DM da; MatStencil col[3],row; PetscInt nc; PetscScalar vals[3]; PetscFunctionBegin; ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = MatGetOwnershipRange(*Jpre,&rstart,&rend);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE); hx = 1.0/(PetscReal)(Mx-1); sx = 1.0/(hx*hx); for (i=rstart; i<rend; i++) { nc = 0; row.i = i; if (user->boundary == 0 && (i == 0 || i == Mx-1)) { col[nc].i = i; vals[nc++] = 1.0; } else if (user->boundary > 0 && i == 0) { /* Left Neumann */ col[nc].i = i; vals[nc++] = 1.0; col[nc].i = i+1; vals[nc++] = -1.0; } else if (user->boundary > 0 && i == Mx-1) { /* Right Neumann */ col[nc].i = i-1; vals[nc++] = -1.0; col[nc].i = i; vals[nc++] = 1.0; } else { /* Interior */ col[nc].i = i-1; vals[nc++] = -1.0*sx; col[nc].i = i; vals[nc++] = 2.0*sx + a; col[nc].i = i+1; vals[nc++] = -1.0*sx; } ierr = MatSetValuesStencil(*Jpre,1,&row,nc,col,vals,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(*Jpre,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*Jpre,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (*J != *Jpre) { ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } if (user->viewJacobian){ ierr = PetscPrintf(((PetscObject)*Jpre)->comm,"Jpre:\n");CHKERRQ(ierr); ierr = MatView(*Jpre,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode FormIFunction(TS ts, PetscReal t, Vec U, Vec Udot, Vec F, void *ctx) { User user = (User) ctx; DM dm, cdm; DMDALocalInfo info; Vec Uloc, C; Field *u, *udot, *f; PetscScalar *x; PetscInt i; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dm, &info);CHKERRQ(ierr); ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &C);CHKERRQ(ierr); ierr = DMGetLocalVector(dm, &Uloc);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm, U, INSERT_VALUES, Uloc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm, U, INSERT_VALUES, Uloc);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(dm, Uloc, &u);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(dm, Udot, &udot);CHKERRQ(ierr); ierr = DMDAVecGetArray(dm, F, &f);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(cdm, C, &x);CHKERRQ(ierr); for (i = info.xs; i < info.xs+info.xm; ++i) { if (i == 0) { const PetscScalar hx = x[i+1] - x[i]; f[i].u = hx * udot[i].u; f[i].v = hx * udot[i].v - PetscSqr(user->c) * (u[i+1].u - u[i].u) / hx; f[i].th = hx * udot[i].th; } else if (i == info.mx-1) { const PetscScalar hx = x[i] - x[i-1]; f[i].u = hx * udot[i].u; f[i].v = hx * udot[i].v - PetscSqr(user->c) * (u[i-1].u - u[i].u) / hx; f[i].th = hx * udot[i].th; } else { const PetscScalar hx = x[i+1] - x[i]; f[i].u = hx * udot[i].u; f[i].v = hx * udot[i].v - PetscSqr(user->c) * (u[i-1].u - 2.*u[i].u + u[i+1].u) / hx; f[i].th = hx * udot[i].th; } } ierr = DMDAVecRestoreArrayRead(dm, Uloc, &u);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayRead(dm, Udot, &udot);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(dm, F, &f);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayRead(cdm, C, &x);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm, &Uloc);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Use Lax-Wendroff method to evaluate F(u,t) = du/dt + a * du/dx */ PetscErrorCode IFunction_LaxWendroff(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void* ctx) { PetscErrorCode ierr; AppCtx *appctx=(AppCtx*)ctx; PetscInt mstart,mend,M,i,um; DM da; Vec Uold,localUold; PetscScalar *uarray,*f,*uoldarray,h,RFlux,LFlux,lambda; PetscReal dt,a; PetscFunctionBegin; ierr = TSGetTimeStep(ts,&dt);CHKERRQ(ierr); ierr = TSGetSolution(ts,&Uold);CHKERRQ(ierr); ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&M,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&mstart,0,0,&um,0,0);CHKERRQ(ierr); h = 1.0/M; mend = mstart + um; /* printf(" mstart %d, um %d\n",mstart,um); */ ierr = DMGetLocalVector(da,&localUold);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,Uold,INSERT_VALUES,localUold);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,Uold,INSERT_VALUES,localUold);CHKERRQ(ierr); /* Get pointers to vector data */ ierr = DMDAVecGetArrayRead(da,U,&uarray);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(da,localUold,&uoldarray);CHKERRQ(ierr); ierr = DMDAVecGetArray(da,F,&f);CHKERRQ(ierr); /* advection -- finite volume (appctx->a < 0 -- can be relaxed?) */ lambda = dt/h; a = appctx->a; for (i=mstart; i<mend; i++) { RFlux = 0.5 * a * (uoldarray[i+1] + uoldarray[i]) - a*a*0.5*lambda * (uoldarray[i+1] - uoldarray[i]); LFlux = 0.5 * a * (uoldarray[i-1] + uoldarray[i]) - a*a*0.5*lambda * (uoldarray[i] - uoldarray[i-1]); f[i] = uarray[i] - uoldarray[i] + lambda * (RFlux - LFlux); } /* Restore vectors */ ierr = DMDAVecRestoreArrayRead(da,U,&uarray);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayRead(da,localUold,&uoldarray);CHKERRQ(ierr); ierr = DMDAVecRestoreArray(da,F,&f);CHKERRQ(ierr); ierr = DMRestoreLocalVector(da,&localUold);CHKERRQ(ierr); PetscFunctionReturn(0); }