/* 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); }
static PetscErrorCode TSSetFromOptions_Pseudo(TS ts) { TS_Pseudo *pseudo = (TS_Pseudo*)ts->data; PetscErrorCode ierr; PetscBool flg = PETSC_FALSE; PetscViewer viewer; PetscFunctionBegin; ierr = PetscOptionsHead("Pseudo-timestepping options");CHKERRQ(ierr); ierr = PetscOptionsBool("-ts_monitor_pseudo","Monitor convergence","TSPseudoMonitorDefault",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ts),"stdout",&viewer);CHKERRQ(ierr); ierr = TSMonitorSet(ts,TSPseudoMonitorDefault,viewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-ts_pseudo_increment_dt_from_initial_dt","Increase dt as a ratio from original dt","TSPseudoIncrementDtFromInitialDt",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = TSPseudoIncrementDtFromInitialDt(ts);CHKERRQ(ierr); } ierr = PetscOptionsReal("-ts_pseudo_increment","Ratio to increase dt","TSPseudoSetTimeStepIncrement",pseudo->dt_increment,&pseudo->dt_increment,0);CHKERRQ(ierr); ierr = PetscOptionsReal("-ts_pseudo_max_dt","Maximum value for dt","TSPseudoSetMaxTimeStep",pseudo->dt_max,&pseudo->dt_max,0);CHKERRQ(ierr); ierr = SNESSetFromOptions(ts->snes);CHKERRQ(ierr); ierr = PetscOptionsTail();CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt time_steps = 100,steps; PetscMPIInt size; Vec global; PetscReal dt,ftime; TS ts; MatStructure A_structure; Mat A = 0; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-time",&time_steps,NULL);CHKERRQ(ierr); /* set initial conditions */ ierr = VecCreate(PETSC_COMM_WORLD,&global);CHKERRQ(ierr); ierr = VecSetSizes(global,PETSC_DECIDE,3);CHKERRQ(ierr); ierr = VecSetFromOptions(global);CHKERRQ(ierr); ierr = Initial(global,NULL);CHKERRQ(ierr); /* make timestep context */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSMonitorSet(ts,Monitor,NULL,NULL);CHKERRQ(ierr); dt = 0.1; /* The user provides the RHS and Jacobian */ ierr = TSSetRHSFunction(ts,NULL,RHSFunction,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,3,3);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = RHSJacobian(ts,0.0,global,&A,&A,&A_structure,NULL);CHKERRQ(ierr); ierr = TSSetRHSJacobian(ts,A,A,RHSJacobian,NULL);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr); ierr = TSSetDuration(ts,time_steps,1);CHKERRQ(ierr); ierr = TSSetSolution(ts,global);CHKERRQ(ierr); ierr = TSSolve(ts,global);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); /* free the memories */ ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFinalize(); return 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); }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec x; /* solution, residual vectors */ Mat A; /* Jacobian matrix */ PetscInt steps; PetscReal ftime = 0.5; PetscBool monitor = PETSC_FALSE; PetscScalar *x_ptr; PetscMPIInt size; struct _n_User user; PetscErrorCode ierr; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,NULL,help);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_SELF,1,"This is a uniprocessor example only!"); /* Register user-specified ARKIMEX method */ ierr = RegisterMyARK2();CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ user.imex = PETSC_TRUE; user.next_output = 0.0; user.mu = 1.0e6; ierr = PetscOptionsGetBool(NULL,NULL,"-imex",&user.imex,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-monitor",&monitor,NULL);CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Physical parameters",NULL); ierr = PetscOptionsReal("-mu","Stiffness parameter","<1.0e6>",user.mu,&user.mu,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd(); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create necessary matrix and vectors, solve same ODE on every process - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,2,2);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatCreateVecs(A,&x,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,RHSFunction,&user);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,IFunction,&user);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,A,A,IJacobian,&user);CHKERRQ(ierr); ierr = TSSetDuration(ts,PETSC_DEFAULT,ftime);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); if (monitor) { ierr = TSMonitorSet(ts,Monitor,&user,NULL);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecGetArray(x,&x_ptr);CHKERRQ(ierr); x_ptr[0] = 2.0; x_ptr[1] = -6.666665432100101e-01; ierr = VecRestoreArray(x,&x_ptr);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.001);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"steps %D, ftime %g\n",steps,(double)ftime);CHKERRQ(ierr); ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; int time; /* amount of loops */ struct in put; PetscScalar rh; /* relative humidity */ PetscScalar x; /* memory varialbe for relative humidity calculation */ PetscScalar deep_grnd_temp; /* temperature of ground under top soil surface layer */ PetscScalar emma; /* absorption-emission constant for air */ PetscScalar pressure1 = 101300; /* surface pressure */ PetscScalar mixratio; /* mixing ratio */ PetscScalar airtemp; /* temperature of air near boundary layer inversion */ PetscScalar dewtemp; /* dew point temperature */ PetscScalar sfctemp; /* temperature at surface */ PetscScalar pwat; /* total column precipitable water */ PetscScalar cloudTemp; /* temperature at base of cloud */ AppCtx user; /* user-defined work context */ MonitorCtx usermonitor; /* user-defined monitor context */ PetscMPIInt rank,size; TS ts; SNES snes; DM da; Vec T,rhs; /* solution vector */ Mat J; /* Jacobian matrix */ PetscReal ftime,dt; PetscInt steps,dof = 5; PetscBool use_coloring = PETSC_TRUE; MatFDColoring matfdcoloring = 0; PetscBool monitor_off = PETSC_FALSE; PetscInitialize(&argc,&argv,(char*)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); /* Inputs */ readinput(&put); sfctemp = put.Ts; dewtemp = put.Td; cloudTemp = put.Tc; airtemp = put.Ta; pwat = put.pwt; if (!rank) PetscPrintf(PETSC_COMM_SELF,"Initial Temperature = %g\n",sfctemp); /* input surface temperature */ deep_grnd_temp = sfctemp - 10; /* set underlying ground layer temperature */ emma = emission(pwat); /* accounts for radiative effects of water vapor */ /* Converts from Fahrenheit to Celsuis */ sfctemp = fahr_to_cel(sfctemp); airtemp = fahr_to_cel(airtemp); dewtemp = fahr_to_cel(dewtemp); cloudTemp = fahr_to_cel(cloudTemp); deep_grnd_temp = fahr_to_cel(deep_grnd_temp); /* Converts from Celsius to Kelvin */ sfctemp += 273; airtemp += 273; dewtemp += 273; cloudTemp += 273; deep_grnd_temp += 273; /* Calculates initial relative humidity */ x = calcmixingr(dewtemp,pressure1); mixratio = calcmixingr(sfctemp,pressure1); rh = (x/mixratio)*100; if (!rank) printf("Initial RH = %.1f percent\n\n",rh); /* prints initial relative humidity */ time = 3600*put.time; /* sets amount of timesteps to run model */ /* Configure PETSc TS solver */ /*------------------------------------------*/ /* Create grid */ ierr = DMDACreate2d(PETSC_COMM_WORLD,DMDA_BOUNDARY_PERIODIC,DMDA_BOUNDARY_PERIODIC,DMDA_STENCIL_STAR,-20,-20, PETSC_DECIDE,PETSC_DECIDE,dof,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr); /* Define output window for each variable of interest */ ierr = DMDASetFieldName(da,0,"Ts");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"Ta");CHKERRQ(ierr); ierr = DMDASetFieldName(da,2,"u");CHKERRQ(ierr); ierr = DMDASetFieldName(da,3,"v");CHKERRQ(ierr); ierr = DMDASetFieldName(da,4,"p");CHKERRQ(ierr); /* set values for appctx */ user.da = da; user.Ts = sfctemp; user.fract = put.fr; /* fraction of sky covered by clouds */ user.dewtemp = dewtemp; /* dew point temperature (mositure in air) */ user.csoil = 2000000; /* heat constant for layer */ user.dzlay = 0.08; /* thickness of top soil layer */ user.emma = emma; /* emission parameter */ user.wind = put.wnd; /* wind spped */ user.pressure1 = pressure1; /* sea level pressure */ user.airtemp = airtemp; /* temperature of air near boundar layer inversion */ user.Tc = cloudTemp; /* temperature at base of lowest cloud layer */ user.init = put.init; /* user chosen initiation scenario */ user.lat = 70*0.0174532; /* converts latitude degrees to latitude in radians */ user.deep_grnd_temp = deep_grnd_temp; /* temp in lowest ground layer */ /* set values for MonitorCtx */ usermonitor.drawcontours = PETSC_FALSE; ierr = PetscOptionsHasName(NULL,"-drawcontours",&usermonitor.drawcontours);CHKERRQ(ierr); if (usermonitor.drawcontours) { PetscReal bounds[] = {1000.0,-1000., -1000.,-1000., 1000.,-1000., 1000.,-1000., 1000,-1000, 100700,100800}; ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,0,0,0,300,300,&usermonitor.drawviewer);CHKERRQ(ierr); ierr = PetscViewerDrawSetBounds(usermonitor.drawviewer,dof,bounds);CHKERRQ(ierr); } usermonitor.interval = 1; ierr = PetscOptionsGetInt(NULL,"-monitor_interval",&usermonitor.interval,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DA; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&T);CHKERRQ(ierr); ierr = VecDuplicate(T,&rhs);CHKERRQ(ierr); /* r: vector to put the computed right hand side */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,rhs,RhsFunc,&user);CHKERRQ(ierr); /* Set Jacobian evaluation routine - use coloring to compute finite difference Jacobian efficiently */ ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(da,&J);CHKERRQ(ierr); ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); if (use_coloring) { ISColoring iscoloring; ierr = DMCreateColoring(da,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetUp(J,iscoloring,matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))SNESTSFormFunction,ts);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefaultColor,matfdcoloring);CHKERRQ(ierr); } else { ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefault,NULL);CHKERRQ(ierr); } /* Define what to print for ts_monitor option */ ierr = PetscOptionsHasName(NULL,"-monitor_off",&monitor_off);CHKERRQ(ierr); if (!monitor_off) { ierr = TSMonitorSet(ts,Monitor,&usermonitor,NULL);CHKERRQ(ierr); } ierr = FormInitialSolution(da,T,&user);CHKERRQ(ierr); dt = TIMESTEP; /* initial time step */ ftime = TIMESTEP*time; if (!rank) printf("time %d, ftime %g hour, TIMESTEP %g\n",time,ftime/3600,dt); ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr); ierr = TSSetDuration(ts,time,ftime);CHKERRQ(ierr); ierr = TSSetSolution(ts,T);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,T);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); if (!rank) PetscPrintf(PETSC_COMM_WORLD,"Solution T after %g hours %d steps\n",ftime/3600,steps); if (matfdcoloring) {ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);} if (usermonitor.drawcontours) { ierr = PetscViewerDestroy(&usermonitor.drawviewer);CHKERRQ(ierr); } ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = VecDestroy(&T);CHKERRQ(ierr); ierr = VecDestroy(&rhs);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); PetscFinalize(); return 0; }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec x; /* solution, residual vectors */ Mat A; /* Jacobian matrix */ Mat Jacp; /* JacobianP matrix */ PetscInt steps; PetscReal ftime =0.5; PetscBool monitor = PETSC_FALSE; PetscScalar *x_ptr; PetscMPIInt size; struct _n_User user; PetscErrorCode ierr; Vec lambda[2],mu[2]; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,NULL,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_SELF,1,"This is a uniprocessor example only!"); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ user.mu = 1; user.next_output = 0.0; ierr = PetscOptionsGetReal(NULL,NULL,"-mu",&user.mu,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-monitor",&monitor,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create necessary matrix and vectors, solve same ODE on every process - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,2,2);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatCreateVecs(A,&x,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&Jacp);CHKERRQ(ierr); ierr = MatSetSizes(Jacp,PETSC_DECIDE,PETSC_DECIDE,2,1);CHKERRQ(ierr); ierr = MatSetFromOptions(Jacp);CHKERRQ(ierr); ierr = MatSetUp(Jacp);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSRK);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,RHSFunction,&user);CHKERRQ(ierr); ierr = TSSetDuration(ts,PETSC_DEFAULT,ftime);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP);CHKERRQ(ierr); if (monitor) { ierr = TSMonitorSet(ts,Monitor,&user,NULL);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecGetArray(x,&x_ptr);CHKERRQ(ierr); x_ptr[0] = 2; x_ptr[1] = 0.66666654321; ierr = VecRestoreArray(x,&x_ptr);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.001);CHKERRQ(ierr); /* Have the TS save its trajectory so that TSAdjointSolve() may be used */ ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"mu %g, steps %D, ftime %g\n",(double)user.mu,steps,(double)ftime);CHKERRQ(ierr); ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Start the Adjoint model - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreateVecs(A,&lambda[0],NULL);CHKERRQ(ierr); ierr = MatCreateVecs(A,&lambda[1],NULL);CHKERRQ(ierr); /* Reset initial conditions for the adjoint integration */ ierr = VecGetArray(lambda[0],&x_ptr);CHKERRQ(ierr); x_ptr[0] = 1.0; x_ptr[1] = 0.0; ierr = VecRestoreArray(lambda[0],&x_ptr);CHKERRQ(ierr); ierr = VecGetArray(lambda[1],&x_ptr);CHKERRQ(ierr); x_ptr[0] = 0.0; x_ptr[1] = 1.0; ierr = VecRestoreArray(lambda[1],&x_ptr);CHKERRQ(ierr); ierr = MatCreateVecs(Jacp,&mu[0],NULL);CHKERRQ(ierr); ierr = MatCreateVecs(Jacp,&mu[1],NULL);CHKERRQ(ierr); ierr = VecGetArray(mu[0],&x_ptr);CHKERRQ(ierr); x_ptr[0] = 0.0; ierr = VecRestoreArray(mu[0],&x_ptr);CHKERRQ(ierr); ierr = VecGetArray(mu[1],&x_ptr);CHKERRQ(ierr); x_ptr[0] = 0.0; ierr = VecRestoreArray(mu[1],&x_ptr);CHKERRQ(ierr); ierr = TSSetCostGradients(ts,2,lambda,mu);CHKERRQ(ierr); /* Set RHS Jacobian for the adjoint integration */ ierr = TSSetRHSJacobian(ts,A,A,RHSJacobian,&user);CHKERRQ(ierr); /* Set RHS JacobianP */ ierr = TSAdjointSetRHSJacobian(ts,Jacp,RHSJacobianP,&user);CHKERRQ(ierr); ierr = TSAdjointSolve(ts);CHKERRQ(ierr); ierr = VecView(lambda[0],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(lambda[1],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(mu[0],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(mu[1],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&Jacp);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&lambda[0]);CHKERRQ(ierr); ierr = VecDestroy(&lambda[1]);CHKERRQ(ierr); ierr = VecDestroy(&mu[0]);CHKERRQ(ierr); ierr = VecDestroy(&mu[1]);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc, char **argv) { MPI_Comm comm; PetscMPIInt rank; PetscErrorCode ierr; User user; PetscLogDouble v1, v2; PetscInt nplot = 0; char fileName[2048]; ierr = PetscInitialize(&argc, &argv, (char*) 0, help);CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = PetscNew(&user);CHKERRQ(ierr); ierr = PetscNew(&user->algebra);CHKERRQ(ierr); ierr = PetscNew(&user->model);CHKERRQ(ierr); ierr = PetscNew(&user->model->physics);CHKERRQ(ierr); Algebra algebra = user->algebra; ierr = LoadOptions(comm, user);CHKERRQ(ierr); ierr = PetscTime(&v1);CHKERRQ(ierr); ierr = CreateMesh(comm, user);CHKERRQ(ierr); ierr = PetscTime(&v2);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Read and Distribute mesh takes %f sec \n", v2 - v1);CHKERRQ(ierr); ierr = SetUpLocalSpace(user);CHKERRQ(ierr); //Set up the dofs of each element ierr = ConstructGeometryFVM(&user->facegeom, &user->cellgeom, user);CHKERRQ(ierr); ierr = LimiterSetup(user);CHKERRQ(ierr); if (user->TimeIntegralMethod == EXPLICITMETHOD) { // explicit method if(user->myownexplicitmethod){// Using the fully explicit method based on my own routing ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully explicit method based on my own routing\n");CHKERRQ(ierr); user->current_time = user->initial_time; user->current_step = 1; ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr); ierr = VecSet(algebra->solution, 0);CHKERRQ(ierr); ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr); if(1){ PetscViewer viewer; ierr = OutputVTK(user->dm, "intialcondition.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->solution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Outputing the initial condition intialcondition.vtk!!! \n");CHKERRQ(ierr); } ierr = VecDuplicate(algebra->solution, &algebra->fn);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->oldsolution);CHKERRQ(ierr); if(user->Explicit_RK2||user->Explicit_RK4){ ierr = PetscPrintf(PETSC_COMM_WORLD,"Use the second order Runge Kutta method \n");CHKERRQ(ierr); }else{ ierr = PetscPrintf(PETSC_COMM_WORLD,"Use the first order forward Euler method \n");CHKERRQ(ierr); } nplot = 0; //the plot step while(user->current_time < (user->final_time - 0.05 * user->dt)){ user->current_time = user->current_time + user->dt; ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr); if(0){ PetscViewer viewer; ierr = OutputVTK(user->dm, "function.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->fn, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } if(user->Explicit_RK2){ /* U^n_1 = U^n + 0.5*dt*f(U^n) U^{n+1} = U^n + dt*f(U^n_1) */ ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr); //note that algebra->oldsolution and algebra->solution are both U^n ierr = VecAXPY(algebra->solution, 0.5*user->dt, algebra->fn);CHKERRQ(ierr); //U^n_1 = U^n + 0.5*dt*f(U^n), now algebra->solution is U^n_1, and algebra->fn is f(U^n) ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr); //algebra->fn is f(U^n_1) // reset the algebra->solution to U^n ierr = VecCopy(algebra->oldsolution, algebra->solution);CHKERRQ(ierr); ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr); // now algebra->solution is U^{n+1} = U^n + dt*f(U^n_1) }else if(user->Explicit_RK4){ /* refer to https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods k_1 = f(U^n) U^n_1 = U^n + 0.5*dt*k_1 k_2 = f(U^n_1) U^n_2 = U^n + 0.5*dt*k_2 k_3 = f(U^n_2) U^n_3 = U^n + 0.5*dt*k_3 k_4 = f(U^n_3) U^{n+1} = U^n + dt/6*(k_1 + 2*k_2 + 2*k_3 + k_4) */ Vec VecTemp; // store the U^n_1 Vec k1, k2, k3, k4; ierr = VecDuplicate(algebra->solution, &k1);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &k2);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &k3);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &k4);CHKERRQ(ierr); ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr); ierr = VecCopy(algebra->fn, k1);CHKERRQ(ierr); //note that algebra->oldsolution and algebra->solution are both U^n ierr = VecAXPY(algebra->solution, 0.5*user->dt, k1);CHKERRQ(ierr); //U^n_1 = U^n + 0.5*dt*k1, now algebra->solution is U^n_1, and algebra->fn is f(U^n) ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr); //algebra->fn is f(U^n_1) ierr = VecCopy(algebra->fn, k2);CHKERRQ(ierr); // reset the algebra->solution to U^n ierr = VecCopy(algebra->oldsolution, algebra->solution);CHKERRQ(ierr); ierr = VecAXPY(algebra->solution, 0.5*user->dt, k2);CHKERRQ(ierr); //U^n_2 = U^n + 0.5*dt*k2, now algebra->solution is U^n_2, and algebra->fn is f(U^n_1) ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr); //algebra->fn is f(U^n_2) ierr = VecCopy(algebra->fn, k3);CHKERRQ(ierr); // reset the algebra->solution to U^n ierr = VecCopy(algebra->oldsolution, algebra->solution);CHKERRQ(ierr); ierr = VecAXPY(algebra->solution, 0.5*user->dt, k3);CHKERRQ(ierr); //U^n_3 = U^n + 0.5*dt*k3, now algebra->solution is U^n_3, and algebra->fn is f(U^n_2) ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr); //algebra->fn is f(U^n_3) ierr = VecCopy(algebra->fn, k4);CHKERRQ(ierr); //U^{n+1} = U^n + dt/6*(k_1 + 2*k_2 + 2*k_3 + k_4) PetscReal temp; temp = user->dt/6; // reset the algebra->solution to U^n ierr = VecCopy(algebra->oldsolution, algebra->solution);CHKERRQ(ierr); ierr = VecAXPY(algebra->solution, temp, k1);CHKERRQ(ierr); // now algebra->solution is U^n + dt/6*k_1 ierr = VecAXPY(algebra->solution, 2*temp, k2);CHKERRQ(ierr); // now algebra->solution is U^n + dt/6*k_1 + 2*dt/6*k_2 ierr = VecAXPY(algebra->solution, 2*temp, k3);CHKERRQ(ierr); // now algebra->solution is U^n + dt/6*k_1 + 2*dt/6*k_2 + 2*dt/6*k_3 ierr = VecAXPY(algebra->solution, temp, k4);CHKERRQ(ierr); // now algebra->solution is U^n + dt/6*k_1 + 2*dt/6*k_2 + 2*dt/6*k_3 + dt/6*k_4 ierr = VecDestroy(&k1);CHKERRQ(ierr); ierr = VecDestroy(&k2);CHKERRQ(ierr); ierr = VecDestroy(&k3);CHKERRQ(ierr); ierr = VecDestroy(&k4);CHKERRQ(ierr); }else{ ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr); ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr); } {// Monitor the solution and function norms PetscReal norm; PetscLogDouble space =0; PetscInt size; PetscReal fnnorm; ierr = VecNorm(algebra->fn,NORM_2,&fnnorm);CHKERRQ(ierr); //ierr = VecView(algebra->fn, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecNorm(algebra->solution,NORM_2,&norm);CHKERRQ(ierr); ierr = VecGetSize(algebra->solution, &size);CHKERRQ(ierr); norm = norm/size; fnnorm = fnnorm/size; if (norm>1.e5) { SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_LIB, "The norm of the solution is: %f (current time: %f). The explicit method is going to DIVERGE!!!", norm, user->current_time); } if (user->current_step%10==0) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with solution norm = %g and founction norm = %g \n", user->current_step, user->current_time, norm, fnnorm);CHKERRQ(ierr); } // ierr = PetscMallocGetCurrentUsage(&space);CHKERRQ(ierr); // if (user->current_step%10==0) { // ierr = PetscPrintf(PETSC_COMM_WORLD,"Current space PetscMalloc()ed %g M\n", // space/(1024*1024));CHKERRQ(ierr); // } } { // Monitor the difference of two steps' solution PetscReal norm; ierr = VecAXPY(algebra->oldsolution, -1, algebra->solution);CHKERRQ(ierr); ierr = VecNorm(algebra->oldsolution,NORM_2,&norm);CHKERRQ(ierr); if (user->current_step%10==0) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with ||u_k-u_{k-1}|| = %g \n", user->current_step, user->current_time, norm);CHKERRQ(ierr); } if((norm<1.e-6)||(user->current_step > user->max_time_its)){ if(norm<1.e-6) ierr = PetscPrintf(PETSC_COMM_WORLD,"\n Convergence with ||u_k-u_{k-1}|| = %g < 1.e-6\n\n", norm);CHKERRQ(ierr); if(user->current_step > user->max_time_its) ierr = PetscPrintf(PETSC_COMM_WORLD,"\n Convergence with reaching the max time its\n\n");CHKERRQ(ierr); break; } } // output the solution if (user->output_solution && (user->current_step%user->steps_output==0)){ PetscViewer viewer; Vec solution_unscaled; // Note the the algebra->solution is scaled by the density, so this is for the unscaled solution nplot = user->current_step/user->steps_output; // update file name for the current time step ierr = VecDuplicate(algebra->solution, &solution_unscaled);CHKERRQ(ierr); ierr = ReformatSolution(algebra->solution, solution_unscaled, user);CHKERRQ(ierr); ierr = PetscSNPrintf(fileName, sizeof(fileName),"%s_%d.vtk",user->solutionfile, nplot);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Outputing solution %s (current time %f)\n", fileName, user->current_time);CHKERRQ(ierr); ierr = OutputVTK(user->dm, fileName, &viewer);CHKERRQ(ierr); ierr = VecView(solution_unscaled, viewer);CHKERRQ(ierr); ierr = VecDestroy(&solution_unscaled);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } user->current_step++; } ierr = VecDestroy(&algebra->fn);CHKERRQ(ierr); }else{ // Using the fully explicit method based on the PETSC TS routing PetscReal ftime; TS ts; TSConvergedReason reason; PetscInt nsteps; //PetscReal minRadius; //ierr = DMPlexTSGetGeometry(user->dm, NULL, NULL, &minRadius);CHKERRQ(ierr); //user->dt = 0.9*4 * minRadius / 1.0; ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully explicit method based on the PETSC TS routing\n");CHKERRQ(ierr); ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr); ierr = VecSet(algebra->solution, 0.0);CHKERRQ(ierr); ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr); ierr = TSCreate(comm, &ts);CHKERRQ(ierr); ierr = TSSetType(ts, TSEULER);CHKERRQ(ierr); ierr = TSSetDM(ts, user->dm);CHKERRQ(ierr); ierr = TSMonitorSet(ts,TSMonitorFunctionError,(void*)user,NULL);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts, NULL, MyRHSFunction, user);CHKERRQ(ierr); ierr = TSSetDuration(ts, 1000, user->final_time);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts, user->initial_time, user->dt);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSolve(ts, algebra->solution);CHKERRQ(ierr); ierr = TSGetSolveTime(ts, &ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts, &nsteps);CHKERRQ(ierr); ierr = TSGetConvergedReason(ts, &reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],ftime,nsteps);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); } if(user->benchmark_couette) { ierr = DMCreateGlobalVector(user->dm, &algebra->exactsolution);CHKERRQ(ierr); ierr = ComputeExactSolution(user->dm, user->current_time, algebra->exactsolution, user);CHKERRQ(ierr); } if(user->benchmark_couette) { PetscViewer viewer; PetscReal norm; ierr = OutputVTK(user->dm, "exact_solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecAXPY(algebra->exactsolution, -1, algebra->solution);CHKERRQ(ierr); ierr = VecNorm(algebra->exactsolution,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Final time at %f, Error: ||u_k-u|| = %g \n", user->current_time, norm);CHKERRQ(ierr); ierr = OutputVTK(user->dm, "Error.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = VecDestroy(&algebra->solution);CHKERRQ(ierr); if(user->myownexplicitmethod){ierr = VecDestroy(&algebra->oldsolution);CHKERRQ(ierr);} ierr = VecDestroy(&algebra->exactsolution);CHKERRQ(ierr); ierr = DMDestroy(&user->dm);CHKERRQ(ierr); } else if (user->TimeIntegralMethod == IMPLICITMETHOD) { // Using the fully implicit method ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully implicit method\n");CHKERRQ(ierr); ierr = SNESCreate(comm,&user->snes);CHKERRQ(ierr); ierr = SNESSetDM(user->snes,user->dm);CHKERRQ(ierr); ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->oldsolution);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->f);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->fn);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->oldfn);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr); ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr); ierr = DMSetMatType(user->dm, MATAIJ);CHKERRQ(ierr); // ierr = DMCreateMatrix(user->dm, &algebra->A);CHKERRQ(ierr); ierr = DMCreateMatrix(user->dm, &algebra->J);CHKERRQ(ierr); if (user->JdiffP) { /*Set up the preconditioner matrix*/ ierr = DMCreateMatrix(user->dm, &algebra->P);CHKERRQ(ierr); }else{ algebra->P = algebra->J; } ierr = MatSetOption(algebra->J, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);CHKERRQ(ierr); /*set nonlinear function */ ierr = SNESSetFunction(user->snes, algebra->f, FormFunction, (void*)user);CHKERRQ(ierr); /* compute Jacobian */ ierr = SNESSetJacobian(user->snes, algebra->J, algebra->P, FormJacobian, (void*)user);CHKERRQ(ierr); ierr = SNESSetFromOptions(user->snes);CHKERRQ(ierr); /* do the solve */ if (user->timestep == TIMESTEP_STEADY_STATE) { ierr = SolveSteadyState(user);CHKERRQ(ierr); } else { ierr = SolveTimeDependent(user);CHKERRQ(ierr); } if (user->output_solution){ PetscViewer viewer; Vec solution_unscaled; // Note the the algebra->solution is scaled by the density, so this is for the unscaled solution ierr = VecDuplicate(algebra->solution, &solution_unscaled);CHKERRQ(ierr); ierr = ReformatSolution(algebra->solution, solution_unscaled, user);CHKERRQ(ierr); ierr = OutputVTK(user->dm, "solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(solution_unscaled, viewer);CHKERRQ(ierr); ierr = VecDestroy(&solution_unscaled);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } if(user->benchmark_couette) { PetscViewer viewer; PetscReal norm; ierr = OutputVTK(user->dm, "exact_solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecAXPY(algebra->exactsolution, -1, algebra->solution);CHKERRQ(ierr); ierr = VecNorm(algebra->exactsolution,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error: ||u_k-u|| = %g \n", norm);CHKERRQ(ierr); ierr = OutputVTK(user->dm, "Error.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = VecDestroy(&algebra->solution);CHKERRQ(ierr); ierr = VecDestroy(&algebra->f);CHKERRQ(ierr); ierr = VecDestroy(&algebra->oldsolution);CHKERRQ(ierr); ierr = VecDestroy(&algebra->fn);CHKERRQ(ierr); ierr = VecDestroy(&algebra->oldfn);CHKERRQ(ierr); ierr = SNESDestroy(&user->snes);CHKERRQ(ierr); ierr = DMDestroy(&user->dm);CHKERRQ(ierr); } else { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"WRONG option for the time integral method. Using the option '-time_integral_method 0 or 1'"); } ierr = VecDestroy(&user->cellgeom);CHKERRQ(ierr); ierr = VecDestroy(&user->facegeom);CHKERRQ(ierr); ierr = DMDestroy(&user->dmGrad);CHKERRQ(ierr); ierr = PetscFunctionListDestroy(&LimitList);CHKERRQ(ierr); ierr = PetscFree(user->model->physics);CHKERRQ(ierr); ierr = PetscFree(user->algebra);CHKERRQ(ierr); ierr = PetscFree(user->model);CHKERRQ(ierr); ierr = PetscFree(user);CHKERRQ(ierr); { PetscLogDouble space =0; ierr = PetscMallocGetCurrentUsage(&space);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Unfreed space at the End %g M\n", space/(1024*1024));CHKERRQ(ierr); } ierr = PetscFinalize(); return(0); }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec x,r; /* solution, residual vectors */ PetscInt steps,maxsteps = 100; /* iterations for convergence */ PetscErrorCode ierr; DM da; PetscReal ftime; SNES ts_snes; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,(char*)0,help); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-8,-8,PETSC_DECIDE,PETSC_DECIDE, 2,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"u");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"v");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; then duplicate for remaining vectors that are the same types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,FormFunction,da);CHKERRQ(ierr); ierr = TSSetDuration(ts,maxsteps,1.0);CHKERRQ(ierr); ierr = TSMonitorSet(ts,MyTSMonitor,0,0);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); ierr = TSGetSNES(ts,&ts_snes); ierr = SNESMonitorSet(ts_snes,MySNESMonitor,NULL,NULL); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(da,x);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.0001);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetSolution(ts,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc, char *argv[]) { PetscErrorCode ierr; PetscMPIInt rank; AppCtx user; PetscInt p=2,N=64,C=1; PetscInt ng = p+2; /* integration in each direction */ PetscInt Nx,Ny; Vec U; /* solution vector */ Mat J; TS ts; PetscInt steps; PetscReal ftime; /* This code solve the dimensionless form of the isothermal Navier-Stokes-Korteweg equations as presented in: Gomez, Hughes, Nogueira, Calo Isogeometric analysis of the isothermal Navier-Stokes-Korteweg equations CMAME, 2010 Equation/section numbers reflect this publication. */ // Petsc Initialization rite of passage ierr = PetscInitialize(&argc,&argv,0,help);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRQ(ierr); // Define simulation specific parameters user.L0 = 1.0; // length scale user.C1x = 0.75; user.C1y = 0.50; // bubble centers user.C2x = 0.25; user.C2y = 0.50; user.C3x = 0.40; user.C3y = 0.75; user.R1 = 0.10; user.R2 = 0.15; user.R3 = 0.08; // bubble radii user.alpha = 2.0; // (Eq. 41) user.theta = 0.85; // temperature parameter (just before section 5.1) // Set discretization options ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "NavierStokesKorteweg Options", "IGA");CHKERRQ(ierr); ierr = PetscOptionsInt("-p", "polynomial order", __FILE__, p, &p, PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-C", "global continuity order", __FILE__, C, &C, PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-N", "number of elements (along one dimension)", __FILE__, N, &N, PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); // Compute simulation parameters user.h = user.L0/N; // characteristic length scale of mesh (Eq. 43, simplified for uniform elements) user.Ca = user.h/user.L0; // capillarity number (Eq. 38) user.Re = user.alpha/user.Ca; // Reynolds number (Eq. 39) // Test C < p if(p <= C){ SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Discretization inconsistent: polynomial order must be greater than degree of continuity"); } Nx=Ny=N; // Initialize B-spline space ierr = DMCreate(PETSC_COMM_WORLD,&user.iga);CHKERRQ(ierr); ierr = DMSetType(user.iga, DMIGA);CHKERRQ(ierr); ierr = DMIGAInitializeUniform2d(user.iga,PETSC_FALSE,2,3, p,Nx,C,0.0,1.0,PETSC_TRUE,ng, p,Ny,C,0.0,1.0,PETSC_TRUE,ng);CHKERRQ(ierr); ierr = DMCreateGlobalVector(user.iga,&U);CHKERRQ(ierr); ierr = FormInitialCondition(&user,U);CHKERRQ(ierr); ierr = DMIGASetFieldName(user.iga, 0, "density");CHKERRQ(ierr); ierr = DMIGASetFieldName(user.iga, 1, "velocity-u");CHKERRQ(ierr); ierr = DMIGASetFieldName(user.iga, 2, "velocity-v");CHKERRQ(ierr); ierr = DMCreateMatrix(user.iga, MATAIJ, &J);CHKERRQ(ierr); ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSALPHA);CHKERRQ(ierr); ierr = TSAlphaSetRadius(ts,0.5);CHKERRQ(ierr); ierr = TSSetDM(ts,user.iga);CHKERRQ(ierr); ierr = TSSetSolution(ts,U);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetIFunction(ts,PETSC_NULL,FormResidual,&user);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,J,J,FormTangent,&user);CHKERRQ(ierr); ierr = TSSetDuration(ts,1000000,1000.0);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,0.001);CHKERRQ(ierr); ierr = TSAlphaSetAdapt(ts,TSAlphaAdaptDefault,PETSC_NULL);CHKERRQ(ierr); ierr = TSMonitorSet(ts,OutputMonitor,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSolve(ts,U,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); // Cleanup ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&user.iga);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec x; /* solution, residual vectors */ Mat A; /* Jacobian matrix */ PetscInt steps; PetscReal ftime = 0.5; PetscBool monitor = PETSC_FALSE; PetscScalar *x_ptr; PetscMPIInt size; struct _n_User user; PetscErrorCode ierr; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,NULL,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_SELF,1,"This is a uniprocessor example only!"); ierr = RegisterMyARK2();CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ user.next_output = 0.0; ierr = PetscOptionsGetBool(NULL,"-monitor",&monitor,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create necessary matrix and vectors, solve same ODE on every process - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,2,2);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatCreateVecs(A,&x,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,IFunction,&user);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,A,A,IJacobian,&user);CHKERRQ(ierr); ierr = TSSetDuration(ts,PETSC_DEFAULT,ftime);CHKERRQ(ierr); if (monitor) { ierr = TSMonitorSet(ts,Monitor,&user,NULL);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecGetArray(x,&x_ptr);CHKERRQ(ierr); x_ptr[0] = -2; x_ptr[1] = -2.355301397608119909925287735864250951918; ierr = VecRestoreArray(x,&x_ptr);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.001);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"steps %D, ftime %g\n",steps,(double)ftime);CHKERRQ(ierr); ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt time_steps=100,iout,NOUT=1; PetscMPIInt size; Vec global; PetscReal dt,ftime,ftime_original; TS ts; PetscViewer viewfile; Mat J = 0; Vec x; Data data; PetscInt mn; PetscBool flg; MatColoring mc; ISColoring iscoloring; MatFDColoring matfdcoloring = 0; PetscBool fd_jacobian_coloring = PETSC_FALSE; SNES snes; KSP ksp; PC pc; PetscViewer viewer; char pcinfo[120],tsinfo[120]; TSType tstype; PetscBool sundials; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); /* set data */ data.m = 9; data.n = 9; data.a = 1.0; data.epsilon = 0.1; data.dx = 1.0/(data.m+1.0); data.dy = 1.0/(data.n+1.0); mn = (data.m)*(data.n); ierr = PetscOptionsGetInt(NULL,"-time",&time_steps,NULL);CHKERRQ(ierr); /* set initial conditions */ ierr = VecCreate(PETSC_COMM_WORLD,&global);CHKERRQ(ierr); ierr = VecSetSizes(global,PETSC_DECIDE,mn);CHKERRQ(ierr); ierr = VecSetFromOptions(global);CHKERRQ(ierr); ierr = Initial(global,&data);CHKERRQ(ierr); ierr = VecDuplicate(global,&x);CHKERRQ(ierr); /* create timestep context */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSMonitorSet(ts,Monitor,&data,NULL);CHKERRQ(ierr); #if defined(PETSC_HAVE_SUNDIALS) ierr = TSSetType(ts,TSSUNDIALS);CHKERRQ(ierr); #else ierr = TSSetType(ts,TSEULER);CHKERRQ(ierr); #endif dt = 0.1; ftime_original = data.tfinal = 1.0; ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr); ierr = TSSetDuration(ts,time_steps,ftime_original);CHKERRQ(ierr); ierr = TSSetSolution(ts,global);CHKERRQ(ierr); /* set user provided RHSFunction and RHSJacobian */ ierr = TSSetRHSFunction(ts,NULL,RHSFunction,&data);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&J);CHKERRQ(ierr); ierr = MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,mn,mn);CHKERRQ(ierr); ierr = MatSetFromOptions(J);CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(J,5,NULL);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(J,5,NULL,5,NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,"-ts_fd",&flg);CHKERRQ(ierr); if (!flg) { ierr = TSSetRHSJacobian(ts,J,J,RHSJacobian,&data);CHKERRQ(ierr); } else { ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,"-fd_color",&fd_jacobian_coloring);CHKERRQ(ierr); if (fd_jacobian_coloring) { /* Use finite differences with coloring */ /* Get data structure of J */ PetscBool pc_diagonal; ierr = PetscOptionsHasName(NULL,"-pc_diagonal",&pc_diagonal);CHKERRQ(ierr); if (pc_diagonal) { /* the preconditioner of J is a diagonal matrix */ PetscInt rstart,rend,i; PetscScalar zero=0.0; ierr = MatGetOwnershipRange(J,&rstart,&rend);CHKERRQ(ierr); for (i=rstart; i<rend; i++) { ierr = MatSetValues(J,1,&i,1,&i,&zero,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } else { /* Fill the structure using the expensive SNESComputeJacobianDefault. Temporarily set up the TS so we can call this function */ ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); ierr = TSSetUp(ts);CHKERRQ(ierr); ierr = SNESComputeJacobianDefault(snes,x,J,J,ts);CHKERRQ(ierr); } /* create coloring context */ ierr = MatColoringCreate(J,&mc);CHKERRQ(ierr); ierr = MatColoringSetType(mc,MATCOLORINGSL);CHKERRQ(ierr); ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); ierr = MatColoringApply(mc,&iscoloring);CHKERRQ(ierr); ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))SNESTSFormFunction,ts);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetUp(J,iscoloring,matfdcoloring);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefaultColor,matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); } else { /* Use finite differences (slow) */ ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefault,NULL);CHKERRQ(ierr); } } /* Pick up a Petsc preconditioner */ /* one can always set method or preconditioner during the run time */ ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCJACOBI);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSetUp(ts);CHKERRQ(ierr); /* Test TSSetPostStep() */ ierr = PetscOptionsHasName(NULL,"-test_PostStep",&flg);CHKERRQ(ierr); if (flg) { ierr = TSSetPostStep(ts,PostStep);CHKERRQ(ierr); } ierr = PetscOptionsGetInt(NULL,"-NOUT",&NOUT,NULL);CHKERRQ(ierr); for (iout=1; iout<=NOUT; iout++) { ierr = TSSetDuration(ts,time_steps,iout*ftime_original/NOUT);CHKERRQ(ierr); ierr = TSSolve(ts,global);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,ftime,dt);CHKERRQ(ierr); } /* Interpolate solution at tfinal */ ierr = TSGetSolution(ts,&global);CHKERRQ(ierr); ierr = TSInterpolate(ts,ftime_original,global);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,"-matlab_view",&flg);CHKERRQ(ierr); if (flg) { /* print solution into a MATLAB file */ ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,"out.m",&viewfile);CHKERRQ(ierr); ierr = PetscViewerSetFormat(viewfile,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); ierr = VecView(global,viewfile);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewfile);CHKERRQ(ierr); } /* display solver info for Sundials */ ierr = TSGetType(ts,&tstype);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&sundials);CHKERRQ(ierr); if (sundials) { ierr = PetscViewerStringOpen(PETSC_COMM_WORLD,tsinfo,120,&viewer);CHKERRQ(ierr); ierr = TSView(ts,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = PetscViewerStringOpen(PETSC_COMM_WORLD,pcinfo,120,&viewer);CHKERRQ(ierr); ierr = PCView(pc,viewer);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"%d Procs,%s TSType, %s Preconditioner\n",size,tsinfo,pcinfo);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } /* free the memories */ ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); if (fd_jacobian_coloring) {ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);} ierr = PetscFinalize(); return 0; }
/* * time_step solves for the time_dependence of the system * that was previously setup using the add_to_ham and add_lin * routines. Solver selection and parameters can be controlled via PETSc * command line options. Default solver is TSRK3BS * * Inputs: * Vec x: The density matrix, with appropriate inital conditions * double dt: initial timestep. For certain explicit methods, this timestep * can be changed, as those methods have adaptive time steps * double time_max: the maximum time to integrate to * int steps_max: max number of steps to take */ void time_step(Vec x, PetscReal init_time, PetscReal time_max,PetscReal dt,PetscInt steps_max){ PetscViewer mat_view; TS ts; /* timestepping context */ PetscInt i,j,Istart,Iend,steps,row,col; PetscScalar mat_tmp; PetscReal tmp_real; Mat AA; PetscInt nevents,direction; PetscBool terminate; operator op; int num_pop; double *populations; Mat solve_A,solve_stiff_A; PetscLogStagePop(); PetscLogStagePush(solve_stage); if (_lindblad_terms) { if (nid==0) { printf("Lindblad terms found, using Lindblad solver.\n"); } solve_A = full_A; if (_stiff_solver) { if(nid==0) printf("ERROR! Lindblad-stiff solver untested."); exit(0); } } else { if (nid==0) { printf("No Lindblad terms found, using (more efficient) Schrodinger solver.\n"); } solve_A = ham_A; solve_stiff_A = ham_stiff_A; if (_num_time_dep&&_stiff_solver) { if(nid==0) printf("ERROR! Schrodinger-stiff + timedep solver untested."); exit(0); } } /* Possibly print dense ham. No stabilization is needed? */ if (nid==0) { /* Print dense ham, if it was asked for */ if (_print_dense_ham){ FILE *fp_ham; fp_ham = fopen("ham","w"); if (nid==0){ for (i=0;i<total_levels;i++){ for (j=0;j<total_levels;j++){ fprintf(fp_ham,"%e %e ",PetscRealPart(_hamiltonian[i][j]),PetscImaginaryPart(_hamiltonian[i][j])); } fprintf(fp_ham,"\n"); } } fclose(fp_ham); for (i=0;i<total_levels;i++){ free(_hamiltonian[i]); } free(_hamiltonian); _print_dense_ham = 0; } } /* Remove stabilization if it was previously added */ if (stab_added){ if (nid==0) printf("Removing stabilization...\n"); /* * We add 1.0 in the 0th spot and every n+1 after */ if (nid==0) { row = 0; for (i=0;i<total_levels;i++){ col = i*(total_levels+1); mat_tmp = -1.0 + 0.*PETSC_i; MatSetValue(full_A,row,col,mat_tmp,ADD_VALUES); } } } MatGetOwnershipRange(solve_A,&Istart,&Iend); /* * Explicitly add 0.0 to all diagonal elements; * this fixes a 'matrix in wrong state' message that PETSc * gives if the diagonal was never initialized. */ //if (nid==0) printf("Adding 0 to diagonal elements...\n"); for (i=Istart;i<Iend;i++){ mat_tmp = 0 + 0.*PETSC_i; MatSetValue(solve_A,i,i,mat_tmp,ADD_VALUES); } if(_stiff_solver){ MatGetOwnershipRange(solve_stiff_A,&Istart,&Iend); for (i=Istart;i<Iend;i++){ mat_tmp = 0 + 0.*PETSC_i; MatSetValue(solve_stiff_A,i,i,mat_tmp,ADD_VALUES); } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -* * Create the timestepping solver and set various options * *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* * Create timestepping solver context */ TSCreate(PETSC_COMM_WORLD,&ts); TSSetProblemType(ts,TS_LINEAR); /* * Set function to get information at every timestep */ if (_ts_monitor!=NULL){ TSMonitorSet(ts,_ts_monitor,_tsctx,NULL); } /* * Set up ODE system */ TSSetRHSFunction(ts,NULL,TSComputeRHSFunctionLinear,NULL); if(_stiff_solver) { /* TSSetIFunction(ts,NULL,TSComputeRHSFunctionLinear,NULL); */ if (nid==0) { printf("Stiff solver not implemented!\n"); exit(0); } if(nid==0) printf("Using stiff solver - TSROSW\n"); } if(_num_time_dep+_num_time_dep_lin) { for(i=0;i<_num_time_dep;i++){ tmp_real = 0.0; _add_ops_to_mat_ham(tmp_real,solve_A,_time_dep_list[i].num_ops,_time_dep_list[i].ops); } for(i=0;i<_num_time_dep_lin;i++){ tmp_real = 0.0; _add_ops_to_mat_lin(tmp_real,solve_A,_time_dep_list_lin[i].num_ops,_time_dep_list_lin[i].ops); } /* Tell PETSc to assemble the matrix */ MatAssemblyBegin(solve_A,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(solve_A,MAT_FINAL_ASSEMBLY); if (nid==0) printf("Matrix Assembled.\n"); MatDuplicate(solve_A,MAT_COPY_VALUES,&AA); MatAssemblyBegin(AA,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(AA,MAT_FINAL_ASSEMBLY); TSSetRHSJacobian(ts,AA,AA,_RHS_time_dep_ham_p,NULL); } else { /* Tell PETSc to assemble the matrix */ MatAssemblyBegin(solve_A,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(solve_A,MAT_FINAL_ASSEMBLY); if (_stiff_solver){ MatAssemblyBegin(solve_stiff_A,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(solve_stiff_A,MAT_FINAL_ASSEMBLY); /* TSSetIJacobian(ts,solve_stiff_A,solve_stiff_A,TSComputeRHSJacobianConstant,NULL); */ if (nid==0) { printf("Stiff solver not implemented!\n"); exit(0); } } if (nid==0) printf("Matrix Assembled.\n"); TSSetRHSJacobian(ts,solve_A,solve_A,TSComputeRHSJacobianConstant,NULL); } /* Print information about the matrix. */ PetscViewerASCIIOpen(PETSC_COMM_WORLD,NULL,&mat_view); PetscViewerPushFormat(mat_view,PETSC_VIEWER_ASCII_INFO); /* PetscViewerPushFormat(mat_view,PETSC_VIEWER_ASCII_MATLAB); */ /* MatView(solve_A,mat_view); */ /* PetscInt ncols; */ /* const PetscInt *cols; */ /* const PetscScalar *vals; */ /* for(i=0;i<total_levels*total_levels;i++){ */ /* MatGetRow(solve_A,i,&ncols,&cols,&vals); */ /* for (j=0;j<ncols;j++){ */ /* if(PetscAbsComplex(vals[j])>1e-5){ */ /* printf("%d %d %lf %lf\n",i,cols[j],vals[j]); */ /* } */ /* } */ /* MatRestoreRow(solve_A,i,&ncols,&cols,&vals); */ /* } */ if(_stiff_solver){ MatView(solve_stiff_A,mat_view); } PetscViewerPopFormat(mat_view); PetscViewerDestroy(&mat_view); TSSetTimeStep(ts,dt); /* * Set default options, can be changed at runtime */ TSSetMaxSteps(ts,steps_max); TSSetMaxTime(ts,time_max); TSSetTime(ts,init_time); TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER); if (_stiff_solver) { TSSetType(ts,TSROSW); } else { TSSetType(ts,TSRK); TSRKSetType(ts,TSRK3BS); } /* If we have gates to apply, set up the event handler. */ if (_num_quantum_gates > 0) { nevents = 1; //Only one event for now (did we cross a gate?) direction = -1; //We only want to count an event if we go from positive to negative terminate = PETSC_FALSE; //Keep time stepping after we passed our event /* Arguments are: ts context, nevents, direction of zero crossing, whether to terminate, * a function to check event status, a function to apply events, private data context. */ TSSetEventHandler(ts,nevents,&direction,&terminate,_QG_EventFunction,_QG_PostEventFunction,NULL); } if (_num_circuits > 0) { nevents = 1; //Only one event for now (did we cross a gate?) direction = -1; //We only want to count an event if we go from positive to negative terminate = PETSC_FALSE; //Keep time stepping after we passed our event /* Arguments are: ts context, nevents, direction of zero crossing, whether to terminate, * a function to check event status, a function to apply events, private data context. */ TSSetEventHandler(ts,nevents,&direction,&terminate,_QC_EventFunction,_QC_PostEventFunction,NULL); } if (_discrete_ec > 0) { nevents = 1; //Only one event for now (did we cross an ec step?) direction = -1; //We only want to count an event if we go from positive to negative terminate = PETSC_FALSE; //Keep time stepping after we passed our event /* Arguments are: ts context, nevents, direction of zero crossing, whether to terminate, * a function to check event status, a function to apply events, private data context. */ TSSetEventHandler(ts,nevents,&direction,&terminate,_DQEC_EventFunction,_DQEC_PostEventFunction,NULL); } /* if (_lindblad_terms) { */ /* nevents = 1; //Only one event for now (did we cross a gate?) */ /* direction = 0; //We only want to count an event if we go from positive to negative */ /* terminate = PETSC_FALSE; //Keep time stepping after we passed our event */ /* TSSetEventHandler(ts,nevents,&direction,&terminate,_Normalize_EventFunction,_Normalize_PostEventFunction,NULL); */ /* } */ TSSetFromOptions(ts); TSSolve(ts,x); TSGetStepNumber(ts,&steps); num_pop = get_num_populations(); populations = malloc(num_pop*sizeof(double)); get_populations(x,&populations); /* if(nid==0){ */ /* printf("Final populations: "); */ /* for(i=0;i<num_pop;i++){ */ /* printf(" %e ",populations[i]); */ /* } */ /* printf("\n"); */ /* } */ /* PetscPrintf(PETSC_COMM_WORLD,"Steps %D\n",steps); */ /* Free work space */ TSDestroy(&ts); if(_num_time_dep+_num_time_dep_lin){ MatDestroy(&AA); } free(populations); PetscLogStagePop(); PetscLogStagePush(post_solve_stage); return; }
void set_monitor( Mon m ) { static Mon m_ = m; TSMonitorSet( ts, TimeStepper::Monitor_function<Mon>, &m_, NULL ); }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ PetscBool monitor = PETSC_FALSE; PetscScalar *x_ptr,*y_ptr; PetscMPIInt size; struct _n_User user; PetscErrorCode ierr; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,NULL,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_SELF,1,"This is a uniprocessor example only!"); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ user.next_output = 0.0; user.mu = 1.0e6; user.steps = 0; user.ftime = 0.5; ierr = PetscOptionsGetBool(NULL,NULL,"-monitor",&monitor,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-mu",&user.mu,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create necessary matrix and vectors, solve same ODE on every process - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&user.A);CHKERRQ(ierr); ierr = MatSetSizes(user.A,PETSC_DECIDE,PETSC_DECIDE,2,2);CHKERRQ(ierr); ierr = MatSetFromOptions(user.A);CHKERRQ(ierr); ierr = MatSetUp(user.A);CHKERRQ(ierr); ierr = MatCreateVecs(user.A,&user.x,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&user.Jacp);CHKERRQ(ierr); ierr = MatSetSizes(user.Jacp,PETSC_DECIDE,PETSC_DECIDE,2,1);CHKERRQ(ierr); ierr = MatSetFromOptions(user.Jacp);CHKERRQ(ierr); ierr = MatSetUp(user.Jacp);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,IFunction,&user);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,user.A,user.A,IJacobian,&user);CHKERRQ(ierr); ierr = TSSetMaxTime(ts,user.ftime);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP);CHKERRQ(ierr); if (monitor) { ierr = TSMonitorSet(ts,Monitor,&user,NULL);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecGetArray(user.x,&x_ptr);CHKERRQ(ierr); x_ptr[0] = 2.0; x_ptr[1] = -0.66666654321; ierr = VecRestoreArray(user.x,&x_ptr);CHKERRQ(ierr); ierr = TSSetTimeStep(ts,.0001);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Save trajectory of solution so that TSAdjointSolve() may be used - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSolve(ts,user.x);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&user.ftime);CHKERRQ(ierr); ierr = TSGetStepNumber(ts,&user.steps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adjoint model starts here - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreateVecs(user.A,&user.lambda[0],NULL);CHKERRQ(ierr); /* Set initial conditions for the adjoint integration */ ierr = VecGetArray(user.lambda[0],&y_ptr);CHKERRQ(ierr); y_ptr[0] = 1.0; y_ptr[1] = 0.0; ierr = VecRestoreArray(user.lambda[0],&y_ptr);CHKERRQ(ierr); ierr = MatCreateVecs(user.A,&user.lambda[1],NULL);CHKERRQ(ierr); ierr = VecGetArray(user.lambda[1],&y_ptr);CHKERRQ(ierr); y_ptr[0] = 0.0; y_ptr[1] = 1.0; ierr = VecRestoreArray(user.lambda[1],&y_ptr);CHKERRQ(ierr); ierr = MatCreateVecs(user.Jacp,&user.mup[0],NULL);CHKERRQ(ierr); ierr = VecGetArray(user.mup[0],&x_ptr);CHKERRQ(ierr); x_ptr[0] = 0.0; ierr = VecRestoreArray(user.mup[0],&x_ptr);CHKERRQ(ierr); ierr = MatCreateVecs(user.Jacp,&user.mup[1],NULL);CHKERRQ(ierr); ierr = VecGetArray(user.mup[1],&x_ptr);CHKERRQ(ierr); x_ptr[0] = 0.0; ierr = VecRestoreArray(user.mup[1],&x_ptr);CHKERRQ(ierr); ierr = TSSetCostGradients(ts,2,user.lambda,user.mup);CHKERRQ(ierr); /* Set RHS JacobianP */ ierr = TSSetRHSJacobianP(ts,user.Jacp,RHSJacobianP,&user);CHKERRQ(ierr); ierr = TSAdjointSolve(ts);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n sensitivity wrt initial conditions: d[y(tf)]/d[y0] d[y(tf)]/d[z0]\n");CHKERRQ(ierr); ierr = VecView(user.lambda[0],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n sensitivity wrt initial conditions: d[z(tf)]/d[y0] d[z(tf)]/d[z0]\n");CHKERRQ(ierr); ierr = VecView(user.lambda[1],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n sensitivity wrt parameters: d[y(tf)]/d[mu]\n");CHKERRQ(ierr); ierr = VecView(user.mup[0],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n sensivitity wrt parameters: d[z(tf)]/d[mu]\n");CHKERRQ(ierr); ierr = VecView(user.mup[1],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&user.A);CHKERRQ(ierr); ierr = MatDestroy(&user.Jacp);CHKERRQ(ierr); ierr = VecDestroy(&user.x);CHKERRQ(ierr); ierr = VecDestroy(&user.lambda[0]);CHKERRQ(ierr); ierr = VecDestroy(&user.lambda[1]);CHKERRQ(ierr); ierr = VecDestroy(&user.mup[0]);CHKERRQ(ierr); ierr = VecDestroy(&user.mup[1]);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return(ierr); }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec u; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscInt steps,maxsteps = 1000; /* iterations for convergence */ PetscErrorCode ierr; DM da; MatFDColoring matfdcoloring = PETSC_NULL; PetscReal ftime,dt; MonitorCtx usermonitor; /* user-defined monitor context */ AppCtx user; /* user-defined work context */ JacobianType jacType; PetscInitialize(&argc,&argv,(char *)0,help); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,-11,1,1,PETSC_NULL,&da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&u);CHKERRQ(ierr); /* Initialize user application context */ user.c = -30.0; user.boundary = 0; /* 0: Dirichlet BC; 1: Neumann BC */ user.viewJacobian = PETSC_FALSE; ierr = PetscOptionsGetInt(PETSC_NULL,"-boundary",&user.boundary,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-viewJacobian",&user.viewJacobian);CHKERRQ(ierr); usermonitor.drawcontours = PETSC_FALSE; ierr = PetscOptionsHasName(PETSC_NULL,"-drawcontours",&usermonitor.drawcontours);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSTHETA);CHKERRQ(ierr); ierr = TSThetaSetTheta(ts,1.0);CHKERRQ(ierr); /* Make the Theta method behave like backward Euler */ ierr = TSSetIFunction(ts,PETSC_NULL,FormIFunction,&user);CHKERRQ(ierr); ierr = DMCreateMatrix(da,MATAIJ,&J);CHKERRQ(ierr); jacType = JACOBIAN_ANALYTIC; /* use user-provide Jacobian */ ierr = TSSetIJacobian(ts,J,J,FormIJacobian,&user);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); /* Use TSGetDM() to access. Setting here allows easy use of geometric multigrid. */ ftime = 1.0; ierr = TSSetDuration(ts,maxsteps,ftime);CHKERRQ(ierr); ierr = TSMonitorSet(ts,MyTSMonitor,&usermonitor,PETSC_NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(ts,u,&user);CHKERRQ(ierr); ierr = TSSetSolution(ts,u);CHKERRQ(ierr); dt = .01; ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* Use slow fd Jacobian or fast fd Jacobian with colorings. Note: this requirs snes which is not created until TSSetUp()/TSSetFromOptions() is called */ ierr = PetscOptionsBegin(((PetscObject)da)->comm,PETSC_NULL,"Options for Jacobian evaluation",PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsEnum("-jac_type","Type of Jacobian","",JacobianTypes,(PetscEnum)jacType,(PetscEnum*)&jacType,0);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); if (jacType == JACOBIAN_FD_COLORING) { SNES snes; ISColoring iscoloring; ierr = DMCreateColoring(da,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))SNESTSFormFunction,ts);CHKERRQ(ierr); ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESDefaultComputeJacobianColor,matfdcoloring);CHKERRQ(ierr); } else if (jacType == JACOBIAN_FD_FULL){ SNES snes; ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESDefaultComputeJacobian,&user);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,u,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&J);CHKERRQ(ierr); if (matfdcoloring) {ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);} ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec ic; PetscBool monitor = PETSC_FALSE; PetscScalar *x_ptr; PetscMPIInt size; struct _n_User user; PetscErrorCode ierr; Tao tao; TaoConvergedReason reason; KSP ksp; PC pc; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,NULL,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_SELF,1,"This is a uniprocessor example only!"); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ user.mu = 1.0; user.next_output = 0.0; user.steps = 0; user.ftime = 0.5; ierr = PetscOptionsGetReal(NULL,"-mu",&user.mu,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-monitor",&monitor,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create necessary matrix and vectors, solve same ODE on every process - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&user.A);CHKERRQ(ierr); ierr = MatSetSizes(user.A,PETSC_DECIDE,PETSC_DECIDE,2,2);CHKERRQ(ierr); ierr = MatSetFromOptions(user.A);CHKERRQ(ierr); ierr = MatSetUp(user.A);CHKERRQ(ierr); ierr = MatCreateVecs(user.A,&user.x,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSRK);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,RHSFunction,&user);CHKERRQ(ierr); ierr = TSSetDuration(ts,PETSC_DEFAULT,user.ftime);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP);CHKERRQ(ierr); if (monitor) { ierr = TSMonitorSet(ts,Monitor,&user,NULL);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecGetArray(user.x,&x_ptr);CHKERRQ(ierr); x_ptr[0] = 2.0; x_ptr[1] = 0.66666654321; ierr = VecRestoreArray(user.x,&x_ptr);CHKERRQ(ierr); ierr = TSSetTime(ts,0.0);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"mu %g, steps %D, ftime %g\n",(double)user.mu,user.steps,(double)(user.ftime));CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Save trajectory of solution so that TSAdjointSolve() may be used - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,user.x);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&(user.ftime));CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&user.steps);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"mu %g, steps %D, ftime %g\n",(double)user.mu,user.steps,(double)user.ftime);CHKERRQ(ierr); ierr = VecGetArray(user.x,&x_ptr);CHKERRQ(ierr); user.x_ob[0] = x_ptr[0]; user.x_ob[1] = x_ptr[1]; ierr = MatCreateVecs(user.A,&user.lambda[0],NULL);CHKERRQ(ierr); /* Create TAO solver and set desired solution method */ ierr = TaoCreate(PETSC_COMM_WORLD,&tao);CHKERRQ(ierr); ierr = TaoSetType(tao,TAOCG);CHKERRQ(ierr); /* Set initial solution guess */ ierr = MatCreateVecs(user.A,&ic,NULL);CHKERRQ(ierr); ierr = VecGetArray(ic,&x_ptr);CHKERRQ(ierr); x_ptr[0] = 2.1; x_ptr[1] = 0.7; ierr = VecRestoreArray(ic,&x_ptr);CHKERRQ(ierr); ierr = TaoSetInitialVector(tao,ic);CHKERRQ(ierr); /* Set routine for function and gradient evaluation */ ierr = TaoSetObjectiveAndGradientRoutine(tao,FormFunctionGradient,(void *)&user);CHKERRQ(ierr); /* Check for any TAO command line options */ ierr = TaoSetFromOptions(tao);CHKERRQ(ierr); ierr = TaoGetKSP(tao,&ksp);CHKERRQ(ierr); if (ksp) { ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); } ierr = TaoSetTolerances(tao,1e-10,1e-10,1e-10,PETSC_DEFAULT,PETSC_DEFAULT); /* SOLVE THE APPLICATION */ ierr = TaoSolve(tao); CHKERRQ(ierr); /* Get information on termination */ ierr = TaoGetConvergedReason(tao,&reason);CHKERRQ(ierr); if (reason <= 0){ ierr=PetscPrintf(MPI_COMM_WORLD, "Try another method! \n");CHKERRQ(ierr); } /* Free TAO data structures */ ierr = TaoDestroy(&tao);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&user.A);CHKERRQ(ierr); ierr = VecDestroy(&user.x);CHKERRQ(ierr); ierr = VecDestroy(&user.lambda[0]);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = VecDestroy(&ic);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; DM da; /* structured grid topology object */ TS ts; /* time-stepping object (contains snes) */ SNES snes; /* Newton solver object */ Vec X,residual; /* solution, residual */ Mat J; /* Jacobian matrix */ PetscInt Mx,My,fsteps,steps; ISColoring iscoloring; PetscReal tstart,tend,ftime,secperday=3600.0*24.0,Y0; PetscBool fdflg = PETSC_FALSE, mfileflg = PETSC_FALSE, optflg = PETSC_FALSE; char mfile[PETSC_MAX_PATH_LEN] = "out.m"; MatFDColoring matfdcoloring; PorousCtx user; /* user-defined work context */ PetscInitialize(&argc,&argv,(char *)0,help); ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE, // correct for zero Dirichlet DMDA_STENCIL_STAR, // nonlinear diffusion but diffusivity // depends on soln W not grad W -21,-21, // default to 20x20 grid but override with // -da_grid_x, -da_grid_y (or -da_refine) PETSC_DECIDE,PETSC_DECIDE, // num of procs in each dim 2, // dof = 2: node = (W,Y) // or node = (P,dPsqr) // or node = (ddxE,ddyN) 1, // s = 1 (stencil extends out one cell) PETSC_NULL,PETSC_NULL, // no specify proc decomposition &da);CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); /* get Vecs and Mats for this grid */ ierr = DMCreateGlobalVector(da,&X);CHKERRQ(ierr); ierr = VecDuplicate(X,&residual);CHKERRQ(ierr); ierr = VecDuplicate(X,&user.geom);CHKERRQ(ierr); ierr = DMGetMatrix(da,MATAIJ,&J);CHKERRQ(ierr); /* set up contexts */ tstart = 10.0 * secperday; /* 10 days in seconds */ tend = 30.0 * secperday; steps = 20; Y0 = 1.0; /* initial value of Y, for computing initial value of P; note Ymin = 0.1 is different */ user.da = da; ierr = DefaultContext(&user);CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "","options to (W,P)-space better hydrology model alt","");CHKERRQ(ierr); { ierr = PetscOptionsReal("-alt_sigma","nonlinear power","", user.sigma,&user.sigma,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Ymin", "min capacity thickness (esp. in pressure computation)","", user.Ymin,&user.Ymin,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Wmin", "min water amount (esp. in pressure computation)","", user.Wmin,&user.Wmin,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Y0", "constant initial capacity thickness","", Y0,&Y0,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Cmelt", "additional coefficient for amount of melt","", user.Cmelt,&user.Cmelt,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Creep", "creep closure coefficient","", user.Creep,&user.Creep,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_L","half-width of square region in meters","", user.L,&user.L,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_tstart_days","start time in days","", tstart/secperday,&tstart,&optflg);CHKERRQ(ierr); if (optflg) { tstart *= secperday; } ierr = PetscOptionsReal("-alt_tend_days","end time in days","", tend/secperday,&tend,&optflg);CHKERRQ(ierr); if (optflg) { tend *= secperday; } ierr = PetscOptionsInt("-alt_steps","number of timesteps to take","", steps,&steps,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-alt_converge_check", "run silent and check for convergence", "",user.run_silent,&user.run_silent,PETSC_NULL); CHKERRQ(ierr); ierr = PetscOptionsString("-mfile", "name of Matlab file to write results","", mfile,mfile,PETSC_MAX_PATH_LEN,&mfileflg); CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* fix remaining parameters */ ierr = DerivedConstants(&user);CHKERRQ(ierr); ierr = VecStrideSet(user.geom,0,user.H0);CHKERRQ(ierr); /* H(x,y) = H0 */ ierr = VecStrideSet(user.geom,1,0.0);CHKERRQ(ierr); /* b(x,y) = 0 */ ierr = DMDASetUniformCoordinates(da, // square domain -user.L, user.L, -user.L, user.L, 0.0, 1.0);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); user.dx = 2.0 * user.L / (Mx-1); user.dy = 2.0 * user.L / (My-1); /* setup TS = timestepping object */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,residual,RHSFunction,&user);CHKERRQ(ierr); /* use coloring to compute rhs Jacobian efficiently */ ierr = PetscOptionsGetBool(PETSC_NULL,"-fd",&fdflg,PETSC_NULL);CHKERRQ(ierr); if (fdflg){ ierr = DMGetColoring(da,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode (*)(void))RHSFunction,&user);CHKERRQ(ierr); ierr = TSSetRHSJacobian(ts,J,J,TSDefaultComputeJacobianColor, matfdcoloring);CHKERRQ(ierr); } else { /* default case */ ierr = TSSetRHSJacobian(ts,J,J,RHSJacobian,&user);CHKERRQ(ierr); } /* set initial state: W = barenblatt, P = pi (W/Y0)^sigma */ ierr = InitialState(da,&user,tstart,Y0,X);CHKERRQ(ierr); /* set up times for time-stepping */ ierr = TSSetInitialTimeStep(ts,tstart, (tend - tstart) / (PetscReal)steps);CHKERRQ(ierr); ierr = TSSetDuration(ts,steps,tend);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,PETSC_TRUE);CHKERRQ(ierr); ierr = TSMonitorSet(ts,MyTSMonitor,&user,PETSC_NULL);CHKERRQ(ierr); /* Set SNESVI type and supply upper and lower bounds. */ ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = SNESVISetComputeVariableBounds(snes,FormPositivityBounds); CHKERRQ(ierr); /* ask user to finalize settings */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* report on setup */ if (!user.run_silent) { ierr = PetscPrintf(PETSC_COMM_WORLD, "setup done: square side length = %.3f km\n" " grid Mx,My = %d,%d\n" " spacing dx,dy = %.3f,%.3f m\n" " times tstart:dt:tend = %.3f:%.3f:%.3f days\n", 2.0 * user.L / 1000.0, Mx, My, user.dx, user.dy, tstart / secperday, (tend-tstart)/(steps*secperday), tend / secperday); CHKERRQ(ierr); } if (mfileflg) { if (!user.run_silent) { ierr = PetscPrintf(PETSC_COMM_WORLD, "writing initial W,P and geometry H,b to Matlab file %s ...\n", mfile);CHKERRQ(ierr); } ierr = print2vecmatlab(da,X,"W_init","P_init",mfile,PETSC_FALSE);CHKERRQ(ierr); ierr = print2vecmatlab(da,user.geom,"H","b",mfile,PETSC_TRUE);CHKERRQ(ierr); } /* run time-stepping with implicit steps */ ierr = TSSolve(ts,X,&ftime);CHKERRQ(ierr); /* make a report on run and final state */ ierr = TSGetTimeStepNumber(ts,&fsteps);CHKERRQ(ierr); if ((!user.run_silent) && (ftime != tend)) { ierr = PetscPrintf(PETSC_COMM_WORLD, "***WARNING3***: reported final time wrong: ftime(=%.12e) != tend(=%.12e) (days)\n", ftime / secperday, tend / secperday);CHKERRQ(ierr); } if ((!user.run_silent) && (fsteps != steps)) { ierr = PetscPrintf(PETSC_COMM_WORLD, "***WARNING4***: reported number of steps wrong: fsteps(=%D) != steps(=%D)\n", fsteps, steps);CHKERRQ(ierr); } if (mfileflg) { if (!user.run_silent) { ierr = PetscPrintf(PETSC_COMM_WORLD, "writing final fields to %s ...\n",mfile);CHKERRQ(ierr); } ierr = print2vecmatlab(da,X,"W_final","P_final",mfile,PETSC_TRUE);CHKERRQ(ierr); ierr = printfigurematlab(da,2,"W_init","W_final",mfile,PETSC_TRUE);CHKERRQ(ierr); ierr = printfigurematlab(da,3,"P_init","P_final",mfile,PETSC_TRUE);CHKERRQ(ierr); } if (user.run_silent) { ierr = PetscPrintf(PETSC_COMM_WORLD, "%6d %6d %9.3f %.12e\n", Mx, My, (tend-tstart)/secperday, user.maxrnorm);CHKERRQ(ierr); } /* Free work space. */ ierr = MatDestroy(&J);CHKERRQ(ierr); if (fdflg) { ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); } ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&user.geom);CHKERRQ(ierr); ierr = VecDestroy(&residual);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); PetscFunctionReturn((PetscInt)(user.not_converged_warning)); }
int main(int argc,char **argv) { PetscFunctionList plist = NULL; char pname[256]; TS ts; /* nonlinear solver */ Vec x,r; /* solution, residual vectors */ Mat A; /* Jacobian matrix */ Problem problem; PetscBool use_monitor; PetscInt steps,maxsteps = 1000,nonlinits,linits,snesfails,rejects; PetscReal ftime; MonitorCtx mon; PetscErrorCode ierr; PetscMPIInt size; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,(char*)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Only for sequential runs"); /* Register the available problems */ ierr = PetscFunctionListAdd(&plist,"rober",&RoberCreate);CHKERRQ(ierr); ierr = PetscFunctionListAdd(&plist,"ce",&CECreate);CHKERRQ(ierr); ierr = PetscFunctionListAdd(&plist,"orego",&OregoCreate);CHKERRQ(ierr); ierr = PetscStrcpy(pname,"ce");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Timestepping benchmark options","");CHKERRQ(ierr); { ierr = PetscOptionsFList("-problem_type","Name of problem to run","",plist,pname,pname,sizeof(pname),NULL);CHKERRQ(ierr); use_monitor = PETSC_FALSE; ierr = PetscOptionsBool("-monitor_error","Display errors relative to exact solutions","",use_monitor,&use_monitor,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* Create the new problem */ ierr = PetscNew(&problem);CHKERRQ(ierr); problem->comm = MPI_COMM_WORLD; { PetscErrorCode (*pcreate)(Problem); ierr = PetscFunctionListFind(plist,pname,&pcreate);CHKERRQ(ierr); if (!pcreate) SETERRQ1(PETSC_COMM_SELF,1,"No problem '%s'",pname); ierr = (*pcreate)(problem);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create necessary matrix and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,problem->n,problem->n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatGetVecs(A,&x,NULL);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); mon.comm = PETSC_COMM_WORLD; mon.problem = problem; ierr = VecDuplicate(x,&mon.x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSROSW);CHKERRQ(ierr); /* Rosenbrock-W */ ierr = TSSetIFunction(ts,NULL,problem->function,problem->data);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,A,A,problem->jacobian,problem->data);CHKERRQ(ierr); ierr = TSSetDuration(ts,maxsteps,problem->final_time);CHKERRQ(ierr); ierr = TSSetMaxStepRejections(ts,10);CHKERRQ(ierr); ierr = TSSetMaxSNESFailures(ts,-1);CHKERRQ(ierr); /* unlimited */ if (use_monitor) { ierr = TSMonitorSet(ts,&MonitorError,&mon,NULL);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = (*problem->solution)(0,x,problem->data);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.001);CHKERRQ(ierr); ierr = TSSetSolution(ts,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); ierr = TSGetSNESFailures(ts,&snesfails);CHKERRQ(ierr); ierr = TSGetStepRejections(ts,&rejects);CHKERRQ(ierr); ierr = TSGetSNESIterations(ts,&nonlinits);CHKERRQ(ierr); ierr = TSGetKSPIterations(ts,&linits);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"steps %D (%D rejected, %D SNES fails), ftime %G, nonlinits %D, linits %D\n",steps,rejects,snesfails,ftime,nonlinits,linits);CHKERRQ(ierr); if (problem->hasexact) { ierr = MonitorError(ts,steps,ftime,x,&mon);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = VecDestroy(&mon.x);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); if (problem->destroy) { ierr = (*problem->destroy)(problem);CHKERRQ(ierr); } ierr = PetscFree(problem);CHKERRQ(ierr); ierr = PetscFunctionListDestroy(&plist);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc,char **argv) { TS ts; /* time integration context */ Vec X; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscErrorCode ierr; PetscScalar *x; PetscReal ftime; PetscInt i,steps,nits,lits; PetscBool view_final; Ctx ctx; PetscInitialize(&argc,&argv,(char*)0,help); ctx.n = 3; ierr = PetscOptionsGetInt(NULL,NULL,"-n",&ctx.n,NULL);CHKERRQ(ierr); if (ctx.n < 2) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"The dimension specified with -n must be at least 2"); view_final = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL,"-view_final",&view_final,NULL);CHKERRQ(ierr); ctx.monitor_short = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL,"-monitor_short",&ctx.monitor_short,NULL);CHKERRQ(ierr); /* Create Jacobian matrix data structure and state vector */ ierr = MatCreate(PETSC_COMM_WORLD,&J);CHKERRQ(ierr); ierr = MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,ctx.n,ctx.n);CHKERRQ(ierr); ierr = MatSetFromOptions(J);CHKERRQ(ierr); ierr = MatSetUp(J);CHKERRQ(ierr); ierr = MatCreateVecs(J,&X,NULL);CHKERRQ(ierr); /* Create time integration context */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSPSEUDO);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,FormIFunction,&ctx);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,J,J,FormIJacobian,&ctx);CHKERRQ(ierr); ierr = TSSetDuration(ts,1000,1e14);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,1e-3);CHKERRQ(ierr); ierr = TSMonitorSet(ts,MonitorObjective,&ctx,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize time integrator; set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Evaluate initial guess; then solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecSet(X,0.0);CHKERRQ(ierr); ierr = VecGetArray(X,&x);CHKERRQ(ierr); #if 1 x[0] = 5.; x[1] = -5.; for (i=2; i<ctx.n; i++) x[i] = 5.; #else x[0] = 1.0; x[1] = 15.0; for (i=2; i<ctx.n; i++) x[i] = 10.0; #endif ierr = VecRestoreArray(X,&x);CHKERRQ(ierr); ierr = TSSolve(ts,X);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); ierr = TSGetSNESIterations(ts,&nits);CHKERRQ(ierr); ierr = TSGetKSPIterations(ts,&lits);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Time integrator took (%D,%D,%D) iterations to reach final time %g\n",steps,nits,lits,(double)ftime);CHKERRQ(ierr); if (view_final) { ierr = VecView(X,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
/* FormFunction - Evaluates the function and corresponding gradient. Input Parameters: tao - the Tao context X - the input vector ptr - optional user-defined context, as set by TaoSetObjectiveAndGradientRoutine() Output Parameters: f - the newly evaluated function */ PetscErrorCode FormFunction(Tao tao,Vec P,PetscReal *f,void *ctx0) { TS ts; SNES snes_alg; PetscErrorCode ierr; Userctx *ctx = (Userctx*)ctx0; Vec X; Mat J; /* sensitivity context */ PetscScalar *x_ptr; PetscViewer Xview,Ybusview; Vec F_alg; Vec Xdot; PetscInt row_loc,col_loc; PetscScalar val; ierr = VecGetArray(P,&x_ptr);CHKERRQ(ierr); PG[0] = x_ptr[0]; PG[1] = x_ptr[1]; PG[2] = x_ptr[2]; ierr = VecRestoreArray(P,&x_ptr);CHKERRQ(ierr); ctx->stepnum = 0; ierr = VecZeroEntries(ctx->vec_q);CHKERRQ(ierr); /* Read initial voltage vector and Ybus */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"X.bin",FILE_MODE_READ,&Xview);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"Ybus.bin",FILE_MODE_READ,&Ybusview);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&ctx->V0);CHKERRQ(ierr); ierr = VecSetSizes(ctx->V0,PETSC_DECIDE,ctx->neqs_net);CHKERRQ(ierr); ierr = VecLoad(ctx->V0,Xview);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&ctx->Ybus);CHKERRQ(ierr); ierr = MatSetSizes(ctx->Ybus,PETSC_DECIDE,PETSC_DECIDE,ctx->neqs_net,ctx->neqs_net);CHKERRQ(ierr); ierr = MatSetType(ctx->Ybus,MATBAIJ);CHKERRQ(ierr); /* ierr = MatSetBlockSize(ctx->Ybus,2);CHKERRQ(ierr); */ ierr = MatLoad(ctx->Ybus,Ybusview);CHKERRQ(ierr); ierr = PetscViewerDestroy(&Xview);CHKERRQ(ierr); ierr = PetscViewerDestroy(&Ybusview);CHKERRQ(ierr); ierr = DMCreateGlobalVector(ctx->dmpgrid,&X);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&J);CHKERRQ(ierr); ierr = MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,ctx->neqs_pgrid,ctx->neqs_pgrid);CHKERRQ(ierr); ierr = MatSetFromOptions(J);CHKERRQ(ierr); ierr = PreallocateJacobian(J,ctx);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,(TSIFunction) IFunction,ctx);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,J,J,(TSIJacobian)IJacobian,ctx);CHKERRQ(ierr); ierr = TSSetApplicationContext(ts,ctx);CHKERRQ(ierr); ierr = TSMonitorSet(ts,MonitorUpdateQ,ctx,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SetInitialGuess(X,ctx);CHKERRQ(ierr); ierr = VecDuplicate(X,&F_alg);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes_alg);CHKERRQ(ierr); ierr = SNESSetFunction(snes_alg,F_alg,AlgFunction,ctx);CHKERRQ(ierr); ierr = MatZeroEntries(J);CHKERRQ(ierr); ierr = SNESSetJacobian(snes_alg,J,J,AlgJacobian,ctx);CHKERRQ(ierr); ierr = SNESSetOptionsPrefix(snes_alg,"alg_");CHKERRQ(ierr); ierr = SNESSetFromOptions(snes_alg);CHKERRQ(ierr); ctx->alg_flg = PETSC_TRUE; /* Solve the algebraic equations */ ierr = SNESSolve(snes_alg,NULL,X);CHKERRQ(ierr); /* Just to set up the Jacobian structure */ ierr = VecDuplicate(X,&Xdot);CHKERRQ(ierr); ierr = IJacobian(ts,0.0,X,Xdot,0.0,J,J,ctx);CHKERRQ(ierr); ierr = VecDestroy(&Xdot);CHKERRQ(ierr); ctx->stepnum++; ierr = TSSetDuration(ts,1000,ctx->tfaulton);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,0.01);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* ierr = TSSetPostStep(ts,SaveSolution);CHKERRQ(ierr); */ ctx->alg_flg = PETSC_FALSE; /* Prefault period */ ierr = TSSolve(ts,X);CHKERRQ(ierr); /* Create the nonlinear solver for solving the algebraic system */ /* Note that although the algebraic system needs to be solved only for Idq and V, we reuse the entire system including xgen. The xgen variables are held constant by setting their residuals to 0 and putting a 1 on the Jacobian diagonal for xgen rows */ ierr = MatZeroEntries(J);CHKERRQ(ierr); /* Apply disturbance - resistive fault at ctx->faultbus */ /* This is done by adding shunt conductance to the diagonal location in the Ybus matrix */ row_loc = 2*ctx->faultbus; col_loc = 2*ctx->faultbus+1; /* Location for G */ val = 1/ctx->Rfault; ierr = MatSetValues(ctx->Ybus,1,&row_loc,1,&col_loc,&val,ADD_VALUES);CHKERRQ(ierr); row_loc = 2*ctx->faultbus+1; col_loc = 2*ctx->faultbus; /* Location for G */ val = 1/ctx->Rfault; ierr = MatSetValues(ctx->Ybus,1,&row_loc,1,&col_loc,&val,ADD_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(ctx->Ybus,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(ctx->Ybus,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ctx->alg_flg = PETSC_TRUE; /* Solve the algebraic equations */ ierr = SNESSolve(snes_alg,NULL,X);CHKERRQ(ierr); ctx->stepnum++; /* Disturbance period */ ierr = TSSetDuration(ts,1000,ctx->tfaultoff);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,ctx->tfaulton,.01);CHKERRQ(ierr); ctx->alg_flg = PETSC_FALSE; ierr = TSSolve(ts,X);CHKERRQ(ierr); /* Remove the fault */ row_loc = 2*ctx->faultbus; col_loc = 2*ctx->faultbus+1; val = -1/ctx->Rfault; ierr = MatSetValues(ctx->Ybus,1,&row_loc,1,&col_loc,&val,ADD_VALUES);CHKERRQ(ierr); row_loc = 2*ctx->faultbus+1; col_loc = 2*ctx->faultbus; val = -1/ctx->Rfault; ierr = MatSetValues(ctx->Ybus,1,&row_loc,1,&col_loc,&val,ADD_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(ctx->Ybus,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(ctx->Ybus,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatZeroEntries(J);CHKERRQ(ierr); ctx->alg_flg = PETSC_TRUE; /* Solve the algebraic equations */ ierr = SNESSolve(snes_alg,NULL,X);CHKERRQ(ierr); ctx->stepnum++; /* Post-disturbance period */ ierr = TSSetDuration(ts,1000,ctx->tmax);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,ctx->tfaultoff,.01);CHKERRQ(ierr); ctx->alg_flg = PETSC_TRUE; ierr = TSSolve(ts,X);CHKERRQ(ierr); ierr = VecGetArray(ctx->vec_q,&x_ptr);CHKERRQ(ierr); *f = x_ptr[0]; ierr = VecRestoreArray(ctx->vec_q,&x_ptr);CHKERRQ(ierr); ierr = MatDestroy(&ctx->Ybus);CHKERRQ(ierr); ierr = VecDestroy(&ctx->V0);CHKERRQ(ierr); ierr = SNESDestroy(&snes_alg);CHKERRQ(ierr); ierr = VecDestroy(&F_alg);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); return 0; }
/* ------------------------------------------------------- */ int main(int argc,char ** argv) { PetscErrorCode ierr; Wash wash; Junction junctions,junction; Pipe pipe,pipes; PetscInt numEdges,numVertices,KeyPipe,KeyJunction; int *edgelist = NULL; PetscInt i,e,v,eStart,eEnd,vStart,vEnd,pipeOffset,key,frombType,tobType; PetscInt vfrom,vto,vkey,fromOffset,toOffset,type,varoffset,pipeoffset; PetscInt from_nedge_in,from_nedge_out,to_nedge_in; const PetscInt *cone; DM networkdm; PetscMPIInt size,rank; PetscReal ftime = 2500.0; Vec X; TS ts; PetscInt maxsteps=-1,steps; TSConvergedReason reason; PetscBool viewpipes; PetscInt pipesCase; DMNetworkMonitor monitor; DMNetworkComponentGenericDataType *nwarr; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); /* Create and setup network */ /*--------------------------*/ ierr = DMNetworkCreate(PETSC_COMM_WORLD,&networkdm);CHKERRQ(ierr); if (size == 1) { ierr = DMNetworkMonitorCreate(networkdm,&monitor);CHKERRQ(ierr); } /* Register the components in the network */ ierr = DMNetworkRegisterComponent(networkdm,"junctionstruct",sizeof(struct _p_Junction),&KeyJunction);CHKERRQ(ierr); ierr = DMNetworkRegisterComponent(networkdm,"pipestruct",sizeof(struct _p_Pipe),&KeyPipe);CHKERRQ(ierr); /* Set global number of pipes, edges, and vertices */ pipesCase = 2; ierr = PetscOptionsGetInt(NULL,NULL, "-case", &pipesCase, NULL);CHKERRQ(ierr); ierr = WashNetworkCreate(PETSC_COMM_WORLD,pipesCase,&wash,&edgelist);CHKERRQ(ierr); numEdges = wash->nedge; numVertices = wash->nvertex; junctions = wash->junction; pipes = wash->pipe; /* Set number of vertices and edges */ ierr = DMNetworkSetSizes(networkdm,numVertices,numEdges,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); /* Add edge connectivity */ ierr = DMNetworkSetEdgeList(networkdm,edgelist);CHKERRQ(ierr); /* Set up the network layout */ ierr = DMNetworkLayoutSetUp(networkdm);CHKERRQ(ierr); /* Add EDGEDATA component to all edges -- currently networkdm is a sequential network */ ierr = DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd);CHKERRQ(ierr); ierr = DMNetworkGetVertexRange(networkdm,&vStart,&vEnd);CHKERRQ(ierr); for (e = eStart; e < eEnd; e++) { /* Add Pipe component to all edges -- create pipe here */ ierr = DMNetworkAddComponent(networkdm,e,KeyPipe,&pipes[e-eStart]);CHKERRQ(ierr); /* Add number of variables to each edge */ ierr = DMNetworkAddNumVariables(networkdm,e,2*pipes[e-eStart].nnodes);CHKERRQ(ierr); if (size == 1) { /* Add monitor -- show Q_{pipes[e-eStart].id}? */ ierr = DMNetworkMonitorAdd(monitor, "Pipe Q", e, pipes[e-eStart].nnodes, 0, 2, -0.8, 0.8, PETSC_TRUE);CHKERRQ(ierr); ierr = DMNetworkMonitorAdd(monitor, "Pipe H", e, pipes[e-eStart].nnodes, 1, 2, -400.0, 800.0, PETSC_TRUE);CHKERRQ(ierr); } } /* Add Junction component to all vertices */ for (v = vStart; v < vEnd; v++) { ierr = DMNetworkAddComponent(networkdm,v,KeyJunction,&junctions[v-vStart]);CHKERRQ(ierr); /* Add number of variables to vertex */ ierr = DMNetworkAddNumVariables(networkdm,v,2);CHKERRQ(ierr); } /* Set up DM for use */ ierr = DMSetUp(networkdm);CHKERRQ(ierr); ierr = WashNetworkCleanUp(wash,edgelist);CHKERRQ(ierr); /* Network partitioning and distribution of data */ if (size > 1) { DM distnetworkdm; ierr = DMNetworkDistribute(networkdm,0,&distnetworkdm);CHKERRQ(ierr); ierr = DMDestroy(&networkdm);CHKERRQ(ierr); networkdm = distnetworkdm; } /* PipeSetUp -- each process only sets its own pipes */ /*---------------------------------------------------*/ ierr = DMNetworkGetComponentDataArray(networkdm,&nwarr);CHKERRQ(ierr); ierr = DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd);CHKERRQ(ierr); for (e=eStart; e<eEnd; e++) { /* each edge has only one component, pipe */ ierr = DMNetworkGetComponentTypeOffset(networkdm,e,0,&type,&pipeoffset);CHKERRQ(ierr); ierr = DMNetworkGetVariableOffset(networkdm,e,&varoffset);CHKERRQ(ierr); pipe = (Pipe)(nwarr + pipeoffset); /* Setup conntected vertices */ ierr = DMNetworkGetConnectedNodes(networkdm,e,&cone);CHKERRQ(ierr); vfrom = cone[0]; /* local ordering */ vto = cone[1]; /* vfrom */ ierr = DMNetworkGetComponentTypeOffset(networkdm,vfrom,0,&vkey,&fromOffset);CHKERRQ(ierr); junction = (Junction)(nwarr+fromOffset); from_nedge_in = junction->nedges_in; from_nedge_out = junction->nedges_out; /* vto */ ierr = DMNetworkGetComponentTypeOffset(networkdm,vto,0,&vkey,&toOffset);CHKERRQ(ierr); junction = (Junction)(nwarr+toOffset); to_nedge_in = junction->nedges_in; pipe->comm = PETSC_COMM_SELF; /* must be set here, otherwise crashes in my mac??? */ wash->nnodes_loc += pipe->nnodes; /* local total num of nodes, will be used by PipesView() */ ierr = PipeSetParameters(pipe, 600.0, /* length */ pipe->nnodes, /* nnodes -- rm from PipeSetParameters */ 0.5, /* diameter */ 1200.0, /* a */ 0.018);CHKERRQ(ierr); /* friction */ /* set boundary conditions for this pipe */ if (from_nedge_in <= 1 && from_nedge_out > 0) { frombType = 0; } else { frombType = 1; } if (to_nedge_in == 1) { tobType = 0; } else { tobType = 1; } if (frombType == 0) { pipe->boundary.Q0 = PIPE_CHARACTERISTIC; /* will be obtained from characteristic */ pipe->boundary.H0 = wash->H0; } else { pipe->boundary.Q0 = wash->Q0; pipe->boundary.H0 = PIPE_CHARACTERISTIC; /* will be obtained from characteristic */ } if (tobType == 0) { pipe->boundary.QL = wash->QL; pipe->boundary.HL = PIPE_CHARACTERISTIC; /* will be obtained from characteristic */ } else { pipe->boundary.QL = PIPE_CHARACTERISTIC; /* will be obtained from characteristic */ pipe->boundary.HL = wash->HL; } ierr = PipeSetUp(pipe);CHKERRQ(ierr); } /* create vectors */ ierr = DMCreateGlobalVector(networkdm,&X);CHKERRQ(ierr); ierr = DMCreateLocalVector(networkdm,&wash->localX);CHKERRQ(ierr); ierr = DMCreateLocalVector(networkdm,&wash->localXdot);CHKERRQ(ierr); /* Setup solver */ /*--------------------------------------------------------*/ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetDM(ts,(DM)networkdm);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,WASHIFunction,wash);CHKERRQ(ierr); ierr = TSSetDuration(ts,maxsteps,ftime);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,0.1);CHKERRQ(ierr); ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); if (size == 1) { ierr = TSMonitorSet(ts, TSDMNetworkMonitor, monitor, NULL);CHKERRQ(ierr); } ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = WASHSetInitialSolution(networkdm,X,wash);CHKERRQ(ierr); ierr = TSSolve(ts,X);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); ierr = TSGetConvergedReason(ts,&reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],(double)ftime,steps);CHKERRQ(ierr); /* ierr = VecView(X,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */ /* View solution q and h */ /* --------------------- */ viewpipes = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL, "-pipe_view", &viewpipes,NULL);CHKERRQ(ierr); if (viewpipes) { ierr = PipesView(X,networkdm,wash);CHKERRQ(ierr); } /* Free spaces */ /* ----------- */ ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&wash->localX);CHKERRQ(ierr); ierr = VecDestroy(&wash->localXdot);CHKERRQ(ierr); /* Destroy objects from each pipe that are created in PipeSetUp() */ ierr = DMNetworkGetEdgeRange(networkdm,&eStart, &eEnd);CHKERRQ(ierr); for (i = eStart; i < eEnd; i++) { ierr = DMNetworkGetComponentTypeOffset(networkdm,i,0,&key,&pipeOffset);CHKERRQ(ierr); pipe = (Pipe)(nwarr+pipeOffset); ierr = DMDestroy(&(pipe->da));CHKERRQ(ierr); ierr = VecDestroy(&pipe->x);CHKERRQ(ierr); } if (size == 1) { ierr = DMNetworkMonitorDestroy(&monitor);CHKERRQ(ierr); } ierr = DMDestroy(&networkdm);CHKERRQ(ierr); ierr = PetscFree(wash);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc, char **argv) { MPI_Comm comm; PetscMPIInt rank; PetscErrorCode ierr; User user; PetscLogDouble v1, v2; PetscInt nplot = 0; char filename1[2048], fileName[2048]; PetscBool set = PETSC_FALSE; PetscInt steps_output; ierr = PetscInitialize(&argc, &argv, (char*) 0, help);CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = PetscNew(&user);CHKERRQ(ierr); ierr = PetscNew(&user->algebra);CHKERRQ(ierr); ierr = PetscNew(&user->model);CHKERRQ(ierr); ierr = PetscNew(&user->model->physics);CHKERRQ(ierr); Algebra algebra = user->algebra; ierr = LoadOptions(comm, user);CHKERRQ(ierr); ierr = PetscTime(&v1);CHKERRQ(ierr); ierr = CreateMesh(comm, user);CHKERRQ(ierr); ierr = PetscTime(&v2);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Read and Distribute mesh takes %f sec \n", v2 - v1);CHKERRQ(ierr); ierr = SetUpLocalSpace(user);CHKERRQ(ierr); //Set up the dofs of each element ierr = ConstructGeometryFVM(&user->facegeom, &user->cellgeom, user);CHKERRQ(ierr); ierr = LimiterSetup(user);CHKERRQ(ierr); if(user->output_solution){ // the output file options ierr = PetscOptionsBegin(PETSC_COMM_WORLD,0,"Options for output solution",0);CHKERRQ(ierr); ierr = PetscOptionsString("-solutionfile", "solution file", "AeroSim.c", filename1,filename1, 2048, &set);CHKERRQ(ierr); if(!set){SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,"please use option -solutionfile to specify solution file name \n");} ierr = PetscOptionsInt("-steps_output", "the number of time steps between two outputs", "", steps_output, &steps_output, &set);CHKERRQ(ierr); if(!set){ steps_output = 1;} ierr = PetscOptionsEnd();CHKERRQ(ierr); } if (user->TimeIntegralMethod == EXPLICITMETHOD) { if(user->myownexplicitmethod){ ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully explicit method based on my own routing\n");CHKERRQ(ierr); user->current_time = user->initial_time; user->current_step = 1; ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr); ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->fn);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->oldsolution);CHKERRQ(ierr); if(user->Explicit_RK2){ ierr = PetscPrintf(PETSC_COMM_WORLD,"Use the second order Runge Kutta method \n");CHKERRQ(ierr); }else{ ierr = PetscPrintf(PETSC_COMM_WORLD,"Use the first order forward Euler method \n");CHKERRQ(ierr); } nplot = 0; //the plot step while(user->current_time < (user->final_time - 0.05 * user->dt)){ user->current_time = user->current_time + user->dt; ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr); PetscReal fnnorm; ierr = VecNorm(algebra->fn,NORM_INFINITY,&fnnorm);CHKERRQ(ierr); if(0){ PetscViewer viewer; ierr = OutputVTK(user->dm, "function.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->fn, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with founction norm = %g \n", user->current_step, user->current_time, fnnorm);CHKERRQ(ierr); //break; } if(user->Explicit_RK2){ ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr);//U^n ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr);//U^{(1)} ierr = FormTimeStepFunction(user, algebra, algebra->solution, algebra->fn);CHKERRQ(ierr);//f(U^{(1)}) ierr = VecAXPY(algebra->solution, 1.0, algebra->oldsolution);CHKERRQ(ierr);//U^n + U^{(1)} ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr);// + dt*f(U^{(1)}) ierr = VecScale(algebra->solution, 0.5);CHKERRQ(ierr); }else{ ierr = VecCopy(algebra->solution, algebra->oldsolution);CHKERRQ(ierr); ierr = VecAXPY(algebra->solution, user->dt, algebra->fn);CHKERRQ(ierr); } {// Monitor the solution and function norms PetscReal norm; PetscLogDouble space =0; PetscInt size; ierr = VecNorm(algebra->solution,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = VecGetSize(algebra->solution, &size);CHKERRQ(ierr); norm = norm/size; if (norm>1.e5) { SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_LIB, "The norm of the solution is: %f (current time: %f). The explicit method is going to DIVERGE!!!", norm, user->current_time); } if (user->current_step%10==0) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with solution norm = %g and founction norm = %g \n", user->current_step, user->current_time, norm, fnnorm);CHKERRQ(ierr); } ierr = PetscMallocGetCurrentUsage(&space);CHKERRQ(ierr); // if (user->current_step%10==0) { // ierr = PetscPrintf(PETSC_COMM_WORLD,"Current space PetscMalloc()ed %g M\n", // space/(1024*1024));CHKERRQ(ierr); // } } { // Monitor the difference of two steps' solution PetscReal norm; ierr = VecAXPY(algebra->oldsolution, -1, algebra->solution);CHKERRQ(ierr); ierr = VecNorm(algebra->oldsolution,NORM_INFINITY,&norm);CHKERRQ(ierr); if (user->current_step%10==0) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Step %D at time %g with ||u_k-u_{k-1}|| = %g \n", user->current_step, user->current_time, norm);CHKERRQ(ierr); } if((norm<1.e-6)||(user->current_step > user->max_time_its)) break; } // output the solution if (user->output_solution && (user->current_step%steps_output==0)){ PetscViewer viewer; // update file name for the current time step ierr = PetscSNPrintf(fileName, sizeof(fileName),"%s_%d.vtk",filename1, nplot);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Outputing solution %s (current time %f)\n", fileName, user->current_time);CHKERRQ(ierr); ierr = OutputVTK(user->dm, fileName, &viewer);CHKERRQ(ierr); ierr = VecView(algebra->solution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); nplot++; } user->current_step++; } ierr = VecDestroy(&algebra->fn);CHKERRQ(ierr); }else{ PetscReal ftime; TS ts; TSConvergedReason reason; PetscInt nsteps; ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully explicit method based on the PETSC TS routing\n");CHKERRQ(ierr); ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr); ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr); ierr = TSCreate(comm, &ts);CHKERRQ(ierr); ierr = TSSetType(ts, TSEULER);CHKERRQ(ierr); ierr = TSSetDM(ts, user->dm);CHKERRQ(ierr); ierr = TSMonitorSet(ts,TSMonitorFunctionError,&user,NULL);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts, NULL, MyRHSFunction, user);CHKERRQ(ierr); ierr = TSSetDuration(ts, 1000, user->final_time);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts, user->initial_time, user->dt);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSolve(ts, algebra->solution);CHKERRQ(ierr); ierr = TSGetSolveTime(ts, &ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts, &nsteps);CHKERRQ(ierr); ierr = TSGetConvergedReason(ts, &reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],ftime,nsteps);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); } if(user->benchmark_couette) { ierr = DMCreateGlobalVector(user->dm, &algebra->exactsolution);CHKERRQ(ierr); ierr = ComputeExactSolution(user->dm, user->final_time, algebra->exactsolution, user);CHKERRQ(ierr); } if (user->output_solution){ PetscViewer viewer; ierr = OutputVTK(user->dm, "solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->solution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } if(user->benchmark_couette) { PetscViewer viewer; PetscReal norm; ierr = OutputVTK(user->dm, "exact_solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecAXPY(algebra->exactsolution, -1, algebra->solution);CHKERRQ(ierr); ierr = VecNorm(algebra->exactsolution,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Final time at %f, Error: ||u_k-u|| = %g \n", user->final_time, norm);CHKERRQ(ierr); ierr = OutputVTK(user->dm, "Error.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = VecDestroy(&algebra->solution);CHKERRQ(ierr); ierr = VecDestroy(&algebra->oldsolution);CHKERRQ(ierr); ierr = DMDestroy(&user->dm);CHKERRQ(ierr); } else if (user->TimeIntegralMethod == IMPLICITMETHOD) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Using the fully implicit method\n");CHKERRQ(ierr); ierr = SNESCreate(comm,&user->snes);CHKERRQ(ierr); ierr = SNESSetDM(user->snes,user->dm);CHKERRQ(ierr); ierr = DMCreateGlobalVector(user->dm, &algebra->solution);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->oldsolution);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->f);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->fn);CHKERRQ(ierr); ierr = VecDuplicate(algebra->solution, &algebra->oldfn);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) algebra->solution, "solution");CHKERRQ(ierr); ierr = SetInitialCondition(user->dm, algebra->solution, user);CHKERRQ(ierr); ierr = DMSetMatType(user->dm, MATAIJ);CHKERRQ(ierr); // ierr = DMCreateMatrix(user->dm, &algebra->A);CHKERRQ(ierr); ierr = DMCreateMatrix(user->dm, &algebra->J);CHKERRQ(ierr); if (user->JdiffP) { /*Set up the preconditioner matrix*/ ierr = DMCreateMatrix(user->dm, &algebra->P);CHKERRQ(ierr); }else{ algebra->P = algebra->J; } ierr = MatSetOption(algebra->J, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);CHKERRQ(ierr); /*set nonlinear function */ ierr = SNESSetFunction(user->snes, algebra->f, FormFunction, (void*)user);CHKERRQ(ierr); /* compute Jacobian */ ierr = SNESSetJacobian(user->snes, algebra->J, algebra->P, FormJacobian, (void*)user);CHKERRQ(ierr); ierr = SNESSetFromOptions(user->snes);CHKERRQ(ierr); /* do the solve */ if (user->timestep == TIMESTEP_STEADY_STATE) { ierr = SolveSteadyState(user);CHKERRQ(ierr); } else { ierr = SolveTimeDependent(user);CHKERRQ(ierr); } if (user->output_solution){ PetscViewer viewer; ierr = OutputVTK(user->dm, "solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->solution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } if(user->benchmark_couette) { PetscViewer viewer; PetscReal norm; ierr = OutputVTK(user->dm, "exact_solution.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecAXPY(algebra->exactsolution, -1, algebra->solution);CHKERRQ(ierr); ierr = VecNorm(algebra->exactsolution,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error: ||u_k-u|| = %g \n", norm);CHKERRQ(ierr); ierr = OutputVTK(user->dm, "Error.vtk", &viewer);CHKERRQ(ierr); ierr = VecView(algebra->exactsolution, viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = VecDestroy(&algebra->solution);CHKERRQ(ierr); ierr = VecDestroy(&algebra->f);CHKERRQ(ierr); ierr = VecDestroy(&algebra->oldsolution);CHKERRQ(ierr); ierr = VecDestroy(&algebra->fn);CHKERRQ(ierr); ierr = VecDestroy(&algebra->oldfn);CHKERRQ(ierr); ierr = SNESDestroy(&user->snes);CHKERRQ(ierr); ierr = DMDestroy(&user->dm);CHKERRQ(ierr); } else { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"WRONG option for the time integral method. Using the option '-time_integral_method 0 or 1'"); } ierr = VecDestroy(&user->cellgeom);CHKERRQ(ierr); ierr = VecDestroy(&user->facegeom);CHKERRQ(ierr); ierr = DMDestroy(&user->dmGrad);CHKERRQ(ierr); ierr = PetscFunctionListDestroy(&LimitList);CHKERRQ(ierr); ierr = PetscFree(user->model->physics);CHKERRQ(ierr); ierr = PetscFree(user->algebra);CHKERRQ(ierr); ierr = PetscFree(user->model);CHKERRQ(ierr); ierr = PetscFree(user);CHKERRQ(ierr); { PetscLogDouble space =0; ierr = PetscMallocGetCurrentUsage(&space);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Unfreed space at the End %g M\n", space/(1024*1024));CHKERRQ(ierr); } ierr = PetscFinalize(); return(0); }
int main(int argc,char **argv) { TS ts; /* time integrator */ Vec x,r; /* solution, residual vectors */ PetscInt steps,Mx; PetscErrorCode ierr; DM da; PetscReal dt; UserCtx ctx; PetscBool mymonitor; PetscViewer viewer; PetscBool flg; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ctx.kappa = 1.0; ierr = PetscOptionsGetReal(NULL,NULL,"-kappa",&ctx.kappa,NULL);CHKERRQ(ierr); ctx.allencahn = PETSC_FALSE; ierr = PetscOptionsHasName(NULL,NULL,"-allen-cahn",&ctx.allencahn);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL,"-mymonitor",&mymonitor);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, 10,1,2,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"Heat equation: u");CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&Mx,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); dt = 1.0/(ctx.kappa*Mx*Mx); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; then duplicate for remaining vectors that are the same types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,FormFunction,&ctx);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(da,x);CHKERRQ(ierr); ierr = TSSetTimeStep(ts,dt);CHKERRQ(ierr); ierr = TSSetMaxTime(ts,.02);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_INTERPOLATE);CHKERRQ(ierr); ierr = TSSetSolution(ts,x);CHKERRQ(ierr); if (mymonitor) { ctx.ports = NULL; ierr = TSMonitorSet(ts,MyMonitor,&ctx,MyDestroy);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = TSGetStepNumber(ts,&steps);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL,"-square_initial",&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"InitialSolution.heat",FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = VecView(x,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }