14036925cSBarry Smith 24036925cSBarry Smith #include <petsc-private/tsimpl.h> /*I "petscts.h" I*/ 34036925cSBarry Smith 44036925cSBarry Smith /* ------------------------------------------------------------------------*/ 54036925cSBarry Smith struct _n_TSMonitorSPEigCtx { 64036925cSBarry Smith PetscDrawSP drawsp; 74036925cSBarry Smith KSP ksp; 84036925cSBarry Smith PetscInt howoften; /* when > 0 uses step % howoften, when negative only final solution plotted */ 9b51f60e1SBarry Smith PetscBool computeexplicitly; 10b51f60e1SBarry Smith MPI_Comm comm; 11b51f60e1SBarry Smith PetscRandom rand; 12b51f60e1SBarry Smith PetscScalar shift; 134036925cSBarry Smith }; 144036925cSBarry Smith 154036925cSBarry Smith 164036925cSBarry Smith #undef __FUNCT__ 174036925cSBarry Smith #define __FUNCT__ "TSMonitorSPEigCtxCreate" 184036925cSBarry Smith /*@C 194036925cSBarry Smith TSMonitorSPEigCtxCreate - Creates a context for use with TS to monitor the eigenvalues of the linearized operator 204036925cSBarry Smith 214036925cSBarry Smith Collective on TS 224036925cSBarry Smith 234036925cSBarry Smith Input Parameters: 244036925cSBarry Smith + host - the X display to open, or null for the local machine 254036925cSBarry Smith . label - the title to put in the title bar 264036925cSBarry Smith . x, y - the screen coordinates of the upper left coordinate of the window 274036925cSBarry Smith . m, n - the screen width and height in pixels 284036925cSBarry Smith - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 294036925cSBarry Smith 304036925cSBarry Smith Output Parameter: 314036925cSBarry Smith . ctx - the context 324036925cSBarry Smith 334036925cSBarry Smith Options Database Key: 34b51f60e1SBarry Smith . -ts_monitor_sp_eig - plot egienvalues of linearized right hand side 354036925cSBarry Smith 364036925cSBarry Smith Notes: 374036925cSBarry Smith Use TSMonitorSPEigCtxDestroy() to destroy. 384036925cSBarry Smith 39b51f60e1SBarry Smith Currently only works if the Jacobian is provided explicitly. 40b51f60e1SBarry Smith 41b51f60e1SBarry Smith Currently only works for ODEs u_t - F(t,u) = 0; that is with no mass matrix. 42b51f60e1SBarry Smith 434036925cSBarry Smith Level: intermediate 444036925cSBarry Smith 454036925cSBarry Smith .keywords: TS, monitor, line graph, residual, seealso 464036925cSBarry Smith 474036925cSBarry Smith .seealso: TSMonitorSPEigTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError() 484036925cSBarry Smith 494036925cSBarry Smith @*/ 504036925cSBarry Smith PetscErrorCode TSMonitorSPEigCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorSPEigCtx *ctx) 514036925cSBarry Smith { 524036925cSBarry Smith PetscDraw win; 534036925cSBarry Smith PetscErrorCode ierr; 544036925cSBarry Smith PC pc; 554036925cSBarry Smith 564036925cSBarry Smith PetscFunctionBegin; 574036925cSBarry Smith ierr = PetscNew(struct _n_TSMonitorSPEigCtx,ctx);CHKERRQ(ierr); 58b51f60e1SBarry Smith ierr = PetscRandomCreate(comm,&(*ctx)->rand);CHKERRQ(ierr); 59b51f60e1SBarry Smith ierr = PetscRandomSetFromOptions((*ctx)->rand);CHKERRQ(ierr); 604036925cSBarry Smith ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&win);CHKERRQ(ierr); 614036925cSBarry Smith ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr); 624036925cSBarry Smith ierr = PetscDrawSPCreate(win,1,&(*ctx)->drawsp);CHKERRQ(ierr); 634036925cSBarry Smith ierr = KSPCreate(comm,&(*ctx)->ksp);CHKERRQ(ierr); 64b51f60e1SBarry Smith ierr = KSPSetOptionsPrefix((*ctx)->ksp,"ts_monitor_sp_eig_");CHKERRQ(ierr); /* this is wrong, used use also prefix from the TS */ 654036925cSBarry Smith ierr = KSPSetType((*ctx)->ksp,KSPGMRES);CHKERRQ(ierr); 664036925cSBarry Smith ierr = KSPGMRESSetRestart((*ctx)->ksp,200);CHKERRQ(ierr); 674036925cSBarry Smith ierr = KSPSetTolerances((*ctx)->ksp,1.e-10,PETSC_DEFAULT,PETSC_DEFAULT,200);CHKERRQ(ierr); 684036925cSBarry Smith ierr = KSPSetComputeSingularValues((*ctx)->ksp,PETSC_TRUE);CHKERRQ(ierr); 694036925cSBarry Smith ierr = KSPSetFromOptions((*ctx)->ksp);CHKERRQ(ierr); 704036925cSBarry Smith ierr = KSPGetPC((*ctx)->ksp,&pc);CHKERRQ(ierr); 714036925cSBarry Smith ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 724036925cSBarry Smith (*ctx)->howoften = howoften; 73b51f60e1SBarry Smith (*ctx)->computeexplicitly = PETSC_FALSE; 74b51f60e1SBarry Smith ierr = PetscOptionsGetBool(PETSC_NULL,"-ts_monitor_sp_eig_explicitly",&(*ctx)->computeexplicitly,PETSC_NULL);CHKERRQ(ierr); 75b51f60e1SBarry Smith (*ctx)->shift = 0.0; 76b51f60e1SBarry Smith ierr = PetscOptionsGetScalar(PETSC_NULL,"-ts_monitor_sp_eig_shift",&(*ctx)->shift,PETSC_NULL);CHKERRQ(ierr); 77b51f60e1SBarry Smith (*ctx)->comm = comm; 784036925cSBarry Smith PetscFunctionReturn(0); 794036925cSBarry Smith } 804036925cSBarry Smith 814036925cSBarry Smith #undef __FUNCT__ 824036925cSBarry Smith #define __FUNCT__ "TSMonitorSPEig" 834036925cSBarry Smith PetscErrorCode TSMonitorSPEig(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx) 844036925cSBarry Smith { 854036925cSBarry Smith TSMonitorSPEigCtx ctx = (TSMonitorSPEigCtx) monctx; 864036925cSBarry Smith PetscErrorCode ierr; 874036925cSBarry Smith KSP ksp = ctx->ksp; 88b51f60e1SBarry Smith PetscInt n,N,nits,neig,i,its = 200; 894036925cSBarry Smith PetscReal *r,*c; 904036925cSBarry Smith PetscDrawSP drawsp = ctx->drawsp; 914036925cSBarry Smith MatStructure structure; 924036925cSBarry Smith Mat A,B; 934036925cSBarry Smith Vec xdot; 944036925cSBarry Smith SNES snes; 954036925cSBarry Smith 964036925cSBarry Smith PetscFunctionBegin; 974036925cSBarry Smith if (!step) PetscFunctionReturn(0); 984036925cSBarry Smith if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && (step == -1))){ 994036925cSBarry Smith ierr = VecDuplicate(v,&xdot);CHKERRQ(ierr); 1004036925cSBarry Smith ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 1014036925cSBarry Smith ierr = SNESGetJacobian(snes,&A,&B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 102*a174af7bSBarry Smith ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&B);CHKERRQ(ierr); 103b51f60e1SBarry Smith /* 104b51f60e1SBarry Smith This doesn't work because methods keep and use internal information about the shift so it 105b51f60e1SBarry Smith seems we would need code for each method to trick the correct Jacobian in being computed. 106b51f60e1SBarry Smith ts->time_step = PETSC_MAX_REAL; 1073d39420eSBarry Smith ierr = SNESComputeJacobian(snes,v,&A,&B,&structure);CHKERRQ(ierr); 108b51f60e1SBarry Smith */ 109*a174af7bSBarry Smith ierr = TSComputeIJacobian(ts,ptime,v,xdot,0.0,&B,&B,&structure,PETSC_FALSE);CHKERRQ(ierr); 110*a174af7bSBarry Smith ierr = MatScale(B,-1.0*ts->time_step);CHKERRQ(ierr); 111*a174af7bSBarry Smith ierr = MatShift(B,ctx->shift);CHKERRQ(ierr); 112*a174af7bSBarry Smith 113*a174af7bSBarry Smith ierr = KSPSetOperators(ksp,B,B,structure);CHKERRQ(ierr); 114b51f60e1SBarry Smith ierr = VecGetSize(v,&n);CHKERRQ(ierr); 115b51f60e1SBarry Smith if (n < 200) its = n; 116b51f60e1SBarry Smith ierr = KSPSetTolerances(ksp,1.e-10,PETSC_DEFAULT,PETSC_DEFAULT,its);CHKERRQ(ierr); 1174036925cSBarry Smith ierr = VecSetRandom(xdot,ctx->rand);CHKERRQ(ierr); 1184036925cSBarry Smith ierr = KSPSolve(ksp,xdot,xdot);CHKERRQ(ierr); 1194036925cSBarry Smith ierr = VecDestroy(&xdot);CHKERRQ(ierr); 1204036925cSBarry Smith ierr = KSPGetIterationNumber(ksp,&nits);CHKERRQ(ierr); 121b51f60e1SBarry Smith N = nits+2; 1224036925cSBarry Smith 1234036925cSBarry Smith if (nits) { 124*a174af7bSBarry Smith PetscDraw draw; 125b51f60e1SBarry Smith ierr = PetscDrawSPReset(drawsp);CHKERRQ(ierr); 126*a174af7bSBarry Smith ierr = PetscDrawSPSetLimits(drawsp,-2.1,.1,-1.1,1.1);CHKERRQ(ierr); 127*a174af7bSBarry Smith ierr = PetscMalloc2(PetscMax(n,N),PetscReal,&r,PetscMax(n,N),PetscReal,&c);CHKERRQ(ierr); 128b51f60e1SBarry Smith if (ctx->computeexplicitly) { 129b51f60e1SBarry Smith ierr = KSPComputeEigenvaluesExplicitly(ksp,n,r,c);CHKERRQ(ierr); 130b51f60e1SBarry Smith neig = n; 131b51f60e1SBarry Smith } else { 132b51f60e1SBarry Smith ierr = KSPComputeEigenvalues(ksp,N,r,c,&neig);CHKERRQ(ierr); 133b51f60e1SBarry Smith } 1344036925cSBarry Smith for (i=0; i<neig; i++) { 135b51f60e1SBarry Smith r[i] -= ctx->shift; 136b51f60e1SBarry Smith ierr = PetscPrintf(ctx->comm,"%g + %g i\n",r[i],c[i]);CHKERRQ(ierr); 1374036925cSBarry Smith ierr = PetscDrawSPAddPoint(drawsp,r+i,c+i);CHKERRQ(ierr); 1384036925cSBarry Smith } 139*a174af7bSBarry Smith ierr = PetscDrawSPDraw(drawsp,PETSC_TRUE);CHKERRQ(ierr); 140*a174af7bSBarry Smith ierr = PetscDrawSPGetDraw(drawsp,&draw);CHKERRQ(ierr); 141*a174af7bSBarry Smith ierr = PetscDrawEllipse(draw,-1.0,0.0,2.0,2.0,PETSC_DRAW_CYAN);CHKERRQ(ierr); 142*a174af7bSBarry Smith ierr = PetscDrawSPDraw(drawsp,PETSC_FALSE);CHKERRQ(ierr); 1434036925cSBarry Smith ierr = PetscFree2(r,c);CHKERRQ(ierr); 1444036925cSBarry Smith } 145*a174af7bSBarry Smith ierr = MatDestroy(&B);CHKERRQ(ierr); 1464036925cSBarry Smith } 1474036925cSBarry Smith PetscFunctionReturn(0); 1484036925cSBarry Smith } 1494036925cSBarry Smith 1504036925cSBarry Smith #undef __FUNCT__ 1514036925cSBarry Smith #define __FUNCT__ "TSMonitorSPEigCtxDestroy" 1524036925cSBarry Smith /*@C 1534036925cSBarry Smith TSMonitorSPEigCtxDestroy - Destroys a scatter plot context that was created with TSMonitorSPEigCtxCreate(). 1544036925cSBarry Smith 1554036925cSBarry Smith Collective on TSMonitorSPEigCtx 1564036925cSBarry Smith 1574036925cSBarry Smith Input Parameter: 1584036925cSBarry Smith . ctx - the monitor context 1594036925cSBarry Smith 1604036925cSBarry Smith Level: intermediate 1614036925cSBarry Smith 1624036925cSBarry Smith .keywords: TS, monitor, line graph, destroy 1634036925cSBarry Smith 1644036925cSBarry Smith .seealso: TSMonitorSPEigCtxCreate(), TSMonitorSet(), TSMonitorSPEig(); 1654036925cSBarry Smith @*/ 1664036925cSBarry Smith PetscErrorCode TSMonitorSPEigCtxDestroy(TSMonitorSPEigCtx *ctx) 1674036925cSBarry Smith { 1684036925cSBarry Smith PetscDraw draw; 1694036925cSBarry Smith PetscErrorCode ierr; 1704036925cSBarry Smith 1714036925cSBarry Smith PetscFunctionBegin; 1724036925cSBarry Smith ierr = PetscDrawSPGetDraw((*ctx)->drawsp,&draw);CHKERRQ(ierr); 1734036925cSBarry Smith ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); 1744036925cSBarry Smith ierr = PetscDrawSPDestroy(&(*ctx)->drawsp);CHKERRQ(ierr); 1754036925cSBarry Smith ierr = KSPDestroy(&(*ctx)->ksp);CHKERRQ(ierr); 1764036925cSBarry Smith ierr = PetscRandomDestroy(&(*ctx)->rand);CHKERRQ(ierr); 1774036925cSBarry Smith ierr = PetscFree(*ctx);CHKERRQ(ierr); 1784036925cSBarry Smith PetscFunctionReturn(0); 1794036925cSBarry Smith } 1804036925cSBarry Smith 181