int main(int argc,char **argv) { PetscDraw draw; PetscDrawLG lg; PetscDrawAxis axis; PetscInt n = 15,i,x = 0,y = 0,width = 400,height = 300,nports = 1; PetscBool useports,flg; const char *xlabel,*ylabel,*toplabel,*legend; PetscReal xd,yd; PetscDrawViewPorts *ports = NULL; PetscErrorCode ierr; toplabel = "Top Label"; xlabel = "X-axis Label"; ylabel = "Y-axis Label"; legend = "Legend"; ierr = PetscInitialize(&argc,&argv,NULL,help);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-x",&x,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-y",&y,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-width",&width,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-height",&height,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-nports",&nports,&useports);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL,"-nolegend",&flg);CHKERRQ(ierr); if (flg) legend = NULL; ierr = PetscOptionsHasName(NULL,NULL,"-notoplabel",&flg);CHKERRQ(ierr); if (flg) toplabel = NULL; ierr = PetscOptionsHasName(NULL,NULL,"-noxlabel",&flg);CHKERRQ(ierr); if (flg) xlabel = NULL; ierr = PetscOptionsHasName(NULL,NULL,"-noylabel",&flg);CHKERRQ(ierr); if (flg) ylabel = NULL; ierr = PetscOptionsHasName(NULL,NULL,"-nolabels",&flg);CHKERRQ(ierr); if (flg) {toplabel = NULL; xlabel = NULL; ylabel = NULL;} ierr = PetscDrawCreate(PETSC_COMM_WORLD,0,"Title",x,y,width,height,&draw);CHKERRQ(ierr); ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); if (useports) { ierr = PetscDrawViewPortsCreate(draw,nports,&ports);CHKERRQ(ierr); ierr = PetscDrawViewPortsSet(ports,0);CHKERRQ(ierr); } ierr = PetscDrawLGCreate(draw,1,&lg);CHKERRQ(ierr); ierr = PetscDrawLGSetUseMarkers(lg,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr); ierr = PetscDrawAxisSetColors(axis,PETSC_DRAW_BLACK,PETSC_DRAW_RED,PETSC_DRAW_BLUE);CHKERRQ(ierr); ierr = PetscDrawAxisSetLabels(axis,toplabel,xlabel,ylabel);CHKERRQ(ierr); ierr = PetscDrawLGSetLegend(lg,&legend);CHKERRQ(ierr); ierr = PetscDrawLGSetFromOptions(lg);CHKERRQ(ierr); for (i=0; i<=n; i++) { xd = (PetscReal)(i - 5); yd = xd*xd; ierr = PetscDrawLGAddPoint(lg,&xd,&yd);CHKERRQ(ierr); } ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); ierr = PetscDrawViewPortsDestroy(ports);CHKERRQ(ierr); ierr = PetscDrawLGDestroy(&lg);CHKERRQ(ierr); ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
Draw( unsigned dim_, const MPI_Comm comm ) : dim( dim_ ) { // static unsigned w{0}; window = _draw_window_num_; _draw_window_num_ += 1; viewer = PETSC_VIEWER_DRAW_( comm ); PetscViewerDrawGetDraw( viewer, static_cast<int>( window ), &draw ); PetscViewerDrawGetDrawLG( viewer, static_cast<int>( window ), &lg ); PetscDrawSetDoubleBuffer( draw ); PetscDrawLGSetDimension( lg, static_cast<int>( dim ) ); PetscDrawLGGetAxis( lg, &axis ); }
/*@C DMNetworkMonitorAdd - Adds a new viewer to monitor Collective on DMNetworkMonitor Input Parameters: + monitor - the monitor . name - name of viewer . element - vertex / edge number . nodes - number of nodes . start - variable starting offset . blocksize - variable blocksize . xmin - xmin (or PETSC_DECIDE) for viewer . xmax - xmax (or PETSC_DECIDE) for viewer . ymin - ymin for viewer . ymax - ymax for viewer - hold - determines if plot limits should be held Level: intermediate Notes: This is written to be independent of the semantics associated to the variables at a given network vertex / edge. Precisely, the parameters nodes, start and blocksize allow you to select a general strided subarray of the variables to monitor. .seealso: DMNetworkMonitorCreate(), DMNetworkMonitorDestroy() @*/ PetscErrorCode DMNetworkMonitorAdd(DMNetworkMonitor monitor,const char *name,PetscInt element,PetscInt nodes,PetscInt start,PetscInt blocksize,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax,PetscBool hold) { PetscErrorCode ierr; PetscDrawLG drawlg; PetscDrawAxis axis; PetscMPIInt rank, size; DMNetworkMonitorList node; char titleBuffer[64]; PetscInt vStart,vEnd,eStart,eEnd; PetscFunctionBegin; ierr = MPI_Comm_rank(monitor->comm, &rank);CHKERRQ(ierr); ierr = MPI_Comm_size(monitor->comm, &size);CHKERRQ(ierr); ierr = DMNetworkGetVertexRange(monitor->network, &vStart, &vEnd);CHKERRQ(ierr); ierr = DMNetworkGetEdgeRange(monitor->network, &eStart, &eEnd);CHKERRQ(ierr); /* Make window title */ if (vStart <= element && element < vEnd) { ierr = PetscSNPrintf(titleBuffer, 64, "%s @ vertex %d [%d / %d]", name, element - vStart, rank, size-1);CHKERRQ(ierr); } else if (eStart <= element && element < eEnd) { ierr = PetscSNPrintf(titleBuffer, 64, "%s @ edge %d [%d / %d]", name, element - eStart, rank, size-1);CHKERRQ(ierr); } else { /* vertex / edge is not on local machine, so skip! */ PetscFunctionReturn(0); } ierr = PetscMalloc1(1, &node);CHKERRQ(ierr); /* Setup viewer. */ ierr = PetscViewerDrawOpen(monitor->comm, NULL, titleBuffer, PETSC_DECIDE, PETSC_DECIDE, PETSC_DRAW_QUARTER_SIZE, PETSC_DRAW_QUARTER_SIZE, &(node->viewer));CHKERRQ(ierr); ierr = PetscViewerPushFormat(node->viewer, PETSC_VIEWER_DRAW_LG_XRANGE);CHKERRQ(ierr); ierr = PetscViewerDrawGetDrawLG(node->viewer, 0, &drawlg);CHKERRQ(ierr); ierr = PetscDrawLGGetAxis(drawlg, &axis);CHKERRQ(ierr); if (xmin != PETSC_DECIDE && xmax != PETSC_DECIDE) { ierr = PetscDrawAxisSetLimits(axis, xmin, xmax, ymin, ymax);CHKERRQ(ierr); } else { ierr = PetscDrawAxisSetLimits(axis, 0, nodes-1, ymin, ymax);CHKERRQ(ierr); } ierr = PetscDrawAxisSetHoldLimits(axis, hold);CHKERRQ(ierr); /* Setup vector storage for drawing. */ ierr = VecCreateSeq(PETSC_COMM_SELF, nodes, &(node->v));CHKERRQ(ierr); node->element = element; node->nodes = nodes; node->start = start; node->blocksize = blocksize; node->next = monitor->firstnode; monitor->firstnode = node; PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscDraw draw; PetscDrawLG lg; PetscDrawAxis axis; PetscInt n = 20,i,x = 0,y = 0,width = 300,height = 300,nports = 1; PetscTruth flg; const char *xlabel,*ylabel,*toplabel; PetscReal xd,yd; PetscDrawViewPorts *ports; PetscErrorCode ierr; xlabel = "X-axis Label";toplabel = "Top Label";ylabel = "Y-axis Label"; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-width",&width,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-height",&height,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-n",&n,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-nolabels",&flg);CHKERRQ(ierr); if (flg) { xlabel = (char *)0; toplabel = (char *)0; } ierr = PetscDrawCreate(PETSC_COMM_SELF,0,"Title",x,y,width,height,&draw);CHKERRQ(ierr); ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-nports",&nports,PETSC_NULL);CHKERRQ(ierr); ierr = PetscDrawViewPortsCreate(draw,nports,&ports);CHKERRQ(ierr); ierr = PetscDrawViewPortsSet(ports,0);CHKERRQ(ierr); ierr = PetscDrawLGCreate(draw,1,&lg);CHKERRQ(ierr); ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr); ierr = PetscDrawAxisSetColors(axis,PETSC_DRAW_BLACK,PETSC_DRAW_RED,PETSC_DRAW_BLUE);CHKERRQ(ierr); ierr = PetscDrawAxisSetLabels(axis,toplabel,xlabel,ylabel);CHKERRQ(ierr); for (i=0; i<n ; i++) { xd = (PetscReal)(i - 5); yd = xd*xd; ierr = PetscDrawLGAddPoint(lg,&xd,&yd);CHKERRQ(ierr); } ierr = PetscDrawLGIndicateDataPoints(lg);CHKERRQ(ierr); ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); ierr = PetscDrawString(draw,-3.,150.0,PETSC_DRAW_BLUE,"A legend");CHKERRQ(ierr); ierr = PetscDrawFlush(draw);CHKERRQ(ierr); ierr = PetscSleep(2);CHKERRQ(ierr); ierr = PetscDrawViewPortsDestroy(ports);CHKERRQ(ierr); ierr = PetscDrawLGDestroy(lg);CHKERRQ(ierr); ierr = PetscDrawDestroy(draw);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
/*@C KSPMonitorLGResidualNormCreate - Creates a line graph context for use with KSP to monitor convergence of preconditioned residual norms. Collective on KSP Input Parameters: + comm - communicator context . host - the X display to open, or null for the local machine . label - the title to put in the title bar . x, y - the screen coordinates of the upper left coordinate of the window - m, n - the screen width and height in pixels Output Parameter: . lgctx - the drawing context Options Database Key: . -ksp_monitor_lg_residualnorm - Sets line graph monitor Notes: Use PetscDrawLGDestroy() to destroy this line graph. Level: intermediate .keywords: KSP, monitor, line graph, residual, create .seealso: KSPMonitorSet(), KSPMonitorLGTrueResidualCreate() @*/ PetscErrorCode KSPMonitorLGResidualNormCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx) { PetscDraw draw; PetscErrorCode ierr; PetscDrawAxis axis; PetscDrawLG lg; PetscFunctionBegin; ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); ierr = PetscDrawLGCreate(draw,1,&lg);CHKERRQ(ierr); ierr = PetscDrawLGSetFromOptions(lg);CHKERRQ(ierr); ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr); ierr = PetscDrawAxisSetLabels(axis,"Convergence","Iteration","Residual Norm");CHKERRQ(ierr); ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); *lgctx = lg; PetscFunctionReturn(0); }
/*@C KSPMonitorLGResidualNormCreate - Creates a line graph context for use with KSP to monitor convergence of preconditioned residual norms. Collective on KSP Input Parameters: + host - the X display to open, or null for the local machine . label - the title to put in the title bar . x, y - the screen coordinates of the upper left coordinate of the window - m, n - the screen width and height in pixels Output Parameter: . draw - the drawing context Options Database Key: . -ksp_monitor_lg_residualnorm - Sets line graph monitor Notes: Use KSPMonitorLGResidualNormDestroy() to destroy this line graph; do not use PetscDrawLGDestroy(). Level: intermediate .keywords: KSP, monitor, line graph, residual, create .seealso: KSPMonitorLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorLGTrueResidualCreate() @*/ PetscErrorCode KSPMonitorLGResidualNormCreate(const char host[],const char label[],int x,int y,int m,int n,PetscObject **objs) { PetscDraw win; PetscErrorCode ierr; PetscDrawAxis axis; PetscDrawLG draw; PetscFunctionBegin; ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&win);CHKERRQ(ierr); ierr = PetscDrawSetFromOptions(win);CHKERRQ(ierr); ierr = PetscDrawLGCreate(win,1,&draw);CHKERRQ(ierr); ierr = PetscDrawLGSetFromOptions(draw);CHKERRQ(ierr); ierr = PetscDrawLGGetAxis(draw,&axis);CHKERRQ(ierr); ierr = PetscDrawAxisSetLabels(axis,"Convergence","Iteration","Residual Norm");CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)draw,(PetscObject)win);CHKERRQ(ierr); ierr = PetscMalloc1(2,objs);CHKERRQ(ierr); (*objs)[0] = (PetscObject)draw; (*objs)[1] = (PetscObject)win; PetscFunctionReturn(0); }
PetscErrorCode TSMonitorLGDMDARay(TS ts, PetscInt step, PetscReal ptime, Vec u, void *ctx) { TSMonitorDMDARayCtx *rayctx = (TSMonitorDMDARayCtx *) ctx; TSMonitorLGCtx lgctx = (TSMonitorLGCtx) rayctx->lgctx; Vec v = rayctx->ray; const PetscScalar *a; PetscInt dim; PetscErrorCode ierr; PetscFunctionBegin; ierr = VecScatterBegin(rayctx->scatter, u, v, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(rayctx->scatter, u, v, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); if (!step) { PetscDrawAxis axis; ierr = PetscDrawLGGetAxis(lgctx->lg, &axis);CHKERRQ(ierr); ierr = PetscDrawAxisSetLabels(axis, "Solution Ray as function of time", "Time", "Solution");CHKERRQ(ierr); ierr = VecGetLocalSize(rayctx->ray, &dim);CHKERRQ(ierr); ierr = PetscDrawLGSetDimension(lgctx->lg, dim);CHKERRQ(ierr); ierr = PetscDrawLGReset(lgctx->lg);CHKERRQ(ierr); } ierr = VecGetArrayRead(v, &a);CHKERRQ(ierr); #if defined(PETSC_USE_COMPLEX) { PetscReal *areal; PetscInt i,n; ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr); ierr = PetscMalloc1(n, &areal);CHKERRQ(ierr); for (i = 0; i < n; ++i) areal[i] = PetscRealPart(a[i]); ierr = PetscDrawLGAddCommonPoint(lgctx->lg, ptime, areal);CHKERRQ(ierr); ierr = PetscFree(areal);CHKERRQ(ierr); } #else ierr = PetscDrawLGAddCommonPoint(lgctx->lg, ptime, a);CHKERRQ(ierr); #endif ierr = VecRestoreArrayRead(v, &a);CHKERRQ(ierr); if (((lgctx->howoften > 0) && (!(step % lgctx->howoften))) || ((lgctx->howoften == -1) && ts->reason)) { ierr = PetscDrawLGDraw(lgctx->lg);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@C KSPMonitorSNESLGResidualNormCreate - Creates a line graph context for use with KSP to monitor convergence of preconditioned residual norms. Collective on KSP Input Parameters: + comm - communicator context . host - the X display to open, or null for the local machine . label - the title to put in the title bar . x, y - the screen coordinates of the upper left coordinate of the window - m, n - the screen width and height in pixels Output Parameter: . draw - the drawing context Options Database Key: . -ksp_monitor_lg_residualnorm - Sets line graph monitor Notes: Use KSPMonitorSNESLGResidualNormDestroy() to destroy this line graph; do not use PetscDrawLGDestroy(). Level: intermediate .keywords: KSP, monitor, line graph, residual, create .seealso: KSPMonitorSNESLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorSNESLGTrueResidualCreate() @*/ PetscErrorCode KSPMonitorSNESLGResidualNormCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscObject **objs) { PetscDraw draw; PetscErrorCode ierr; PetscDrawAxis axis; PetscDrawLG lg; const char *names[] = {"Linear residual","Nonlinear residual"}; PetscFunctionBegin; ierr = PetscDrawCreate(comm,host,label,x,y,m,n,&draw);CHKERRQ(ierr); ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); ierr = PetscDrawLGCreate(draw,2,&lg);CHKERRQ(ierr); ierr = PetscDrawLGSetLegend(lg,names);CHKERRQ(ierr); ierr = PetscDrawLGSetFromOptions(lg);CHKERRQ(ierr); ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr); ierr = PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");CHKERRQ(ierr); ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); ierr = PetscMalloc1(2,objs);CHKERRQ(ierr); (*objs)[1] = (PetscObject)lg; PetscFunctionReturn(0); }
/*@C KSPMonitorSNESLGResidualNormCreate - Creates a line graph context for use with KSP to monitor convergence of preconditioned residual norms. Collective on KSP Input Parameters: + host - the X display to open, or null for the local machine . label - the title to put in the title bar . x, y - the screen coordinates of the upper left coordinate of the window - m, n - the screen width and height in pixels Output Parameter: . draw - the drawing context Options Database Key: . -ksp_monitor_lg_residualnorm - Sets line graph monitor Notes: Use KSPMonitorSNESLGResidualNormDestroy() to destroy this line graph; do not use PetscDrawLGDestroy(). Level: intermediate .keywords: KSP, monitor, line graph, residual, create .seealso: KSPMonitorSNESLGResidualNormDestroy(), KSPMonitorSet(), KSPMonitorSNESLGTrueResidualCreate() @*/ PetscErrorCode KSPMonitorSNESLGResidualNormCreate(const char host[],const char label[],int x,int y,int m,int n,PetscObject **objs) { PetscDraw draw; PetscErrorCode ierr; PetscDrawAxis axis; PetscDrawLG drawlg; const char *names[] = {"Linear residual","Nonlinear residual"}; PetscFunctionBegin; ierr = PetscDrawCreate(PETSC_COMM_SELF,host,label,x,y,m,n,&draw);CHKERRQ(ierr); ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); ierr = PetscDrawLGCreate(draw,2,&drawlg);CHKERRQ(ierr); ierr = PetscDrawLGSetFromOptions(drawlg);CHKERRQ(ierr); ierr = PetscDrawLGGetAxis(drawlg,&axis);CHKERRQ(ierr); ierr = PetscDrawAxisSetLabels(axis,"Convergence of Residual Norm","Iteration","Residual Norm");CHKERRQ(ierr); ierr = PetscDrawLGSetLegend(drawlg,names);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)drawlg,(PetscObject)draw);CHKERRQ(ierr); ierr = PetscMalloc1(3,objs);CHKERRQ(ierr); (*objs)[1] = (PetscObject)drawlg; (*objs)[2] = (PetscObject)draw; PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscDrawLG lg; PetscErrorCode ierr; PetscInt Mx = 100,i; PetscReal x,hx = .1/Mx,pause,xx[3],yy[3]; PetscDraw draw; const char *const legend[] = {"(1 - u^2)^2","1 - u^2","-(1 - u)log(1 - u)"}; PetscDrawAxis axis; static PetscDrawViewPorts *ports = 0; PetscFunctionBegin; PetscInitialize(&argc,&argv,0,help); ierr = PetscViewerDrawResize(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),1200,800);CHKERRQ(ierr); ierr = PetscViewerDrawGetDrawLG(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),0,&lg);CHKERRQ(ierr); ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr); if (!ports) { ierr = PetscDrawViewPortsCreateRect(draw,1,2,&ports);CHKERRQ(ierr); } ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr); ierr = PetscDrawLGReset(lg);CHKERRQ(ierr); /* Plot the energies */ ierr = PetscDrawLGSetDimension(lg,3);CHKERRQ(ierr); ierr = PetscDrawViewPortsSet(ports,1);CHKERRQ(ierr); x = .9; for (i=0; i<Mx; i++) { xx[0] = xx[1] = xx[2] = x; yy[0] = (1.-x*x)*(1. - x*x); yy[1] = (1. - x*x); yy[2] = -(1.-x)*PetscLogScalar(1.-x); ierr = PetscDrawLGAddPoint(lg,xx,yy);CHKERRQ(ierr); x += hx; } ierr = PetscDrawGetPause(draw,&pause);CHKERRQ(ierr); ierr = PetscDrawSetPause(draw,0.0);CHKERRQ(ierr); ierr = PetscDrawAxisSetLabels(axis,"Energy","","");CHKERRQ(ierr); ierr = PetscDrawLGSetLegend(lg,legend);CHKERRQ(ierr); ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); /* Plot the forces */ ierr = PetscDrawViewPortsSet(ports,0);CHKERRQ(ierr); ierr = PetscDrawLGReset(lg);CHKERRQ(ierr); x = .9; for (i=0; i<Mx; i++) { xx[0] = xx[1] = xx[2] = x; yy[0] = x*x*x - x; yy[1] = -x; yy[2] = 1.0 + PetscLogScalar(1. - x); ierr = PetscDrawLGAddPoint(lg,xx,yy);CHKERRQ(ierr); x += hx; } ierr = PetscDrawAxisSetLabels(axis,"Derivative","","");CHKERRQ(ierr); ierr = PetscDrawLGSetLegend(lg,PETSC_NULL);CHKERRQ(ierr); ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); ierr = PetscDrawSetPause(draw,pause);CHKERRQ(ierr); ierr = PetscDrawPause(draw);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* This routine is not parallel */ PetscErrorCode MyMonitor(TS ts,PetscInt step,PetscReal time,Vec U,void *ptr) { UserCtx *ctx = (UserCtx*)ptr; PetscDrawLG lg; PetscErrorCode ierr; PetscScalar *u; PetscInt Mx,i,xs,xm,cnt; PetscReal x,y,hx,pause,sx,len,max,xx[2],yy[2]; PetscDraw draw; Vec localU; DM da; int colors[] = {PETSC_DRAW_YELLOW,PETSC_DRAW_RED,PETSC_DRAW_BLUE}; const char*const legend[] = {"-kappa (\\grad u,\\grad u)","(1 - u^2)^2"}; PetscDrawAxis axis; PetscDrawViewPorts *ports; PetscReal vbounds[] = {-1.1,1.1}; PetscFunctionBegin; ierr = PetscViewerDrawSetBounds(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),1,vbounds);CHKERRQ(ierr); ierr = PetscViewerDrawResize(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),1200,800);CHKERRQ(ierr); ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = DMGetLocalVector(da,&localU);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); hx = 1.0/(PetscReal)Mx; sx = 1.0/(hx*hx); ierr = DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);CHKERRQ(ierr); ierr = DMDAVecGetArrayRead(da,localU,&u);CHKERRQ(ierr); ierr = PetscViewerDrawGetDrawLG(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),1,&lg);CHKERRQ(ierr); ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr); if (!ctx->ports) { ierr = PetscDrawViewPortsCreateRect(draw,1,3,&ctx->ports);CHKERRQ(ierr); } ports = ctx->ports; ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr); ierr = PetscDrawLGReset(lg);CHKERRQ(ierr); xx[0] = 0.0; xx[1] = 1.0; cnt = 2; ierr = PetscOptionsGetRealArray(NULL,NULL,"-zoom",xx,&cnt,NULL);CHKERRQ(ierr); xs = xx[0]/hx; xm = (xx[1] - xx[0])/hx; /* Plot the energies */ ierr = PetscDrawLGSetDimension(lg,1 + (ctx->allencahn ? 1 : 0));CHKERRQ(ierr); ierr = PetscDrawLGSetColors(lg,colors+1);CHKERRQ(ierr); ierr = PetscDrawViewPortsSet(ports,2);CHKERRQ(ierr); x = hx*xs; for (i=xs; i<xs+xm; i++) { xx[0] = xx[1] = x; yy[0] = PetscRealPart(.25*ctx->kappa*(u[i-1] - u[i+1])*(u[i-1] - u[i+1])*sx); if (ctx->allencahn) yy[1] = .25*PetscRealPart((1. - u[i]*u[i])*(1. - u[i]*u[i])); ierr = PetscDrawLGAddPoint(lg,xx,yy);CHKERRQ(ierr); x += hx; } ierr = PetscDrawGetPause(draw,&pause);CHKERRQ(ierr); ierr = PetscDrawSetPause(draw,0.0);CHKERRQ(ierr); ierr = PetscDrawAxisSetLabels(axis,"Energy","","");CHKERRQ(ierr); ierr = PetscDrawLGSetLegend(lg,legend);CHKERRQ(ierr); ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); /* Plot the forces */ ierr = PetscDrawViewPortsSet(ports,1);CHKERRQ(ierr); ierr = PetscDrawLGReset(lg);CHKERRQ(ierr); x = xs*hx;; max = 0.; for (i=xs; i<xs+xm; i++) { xx[0] = xx[1] = x; yy[0] = PetscRealPart(ctx->kappa*(u[i-1] + u[i+1] - 2.0*u[i])*sx); max = PetscMax(max,PetscAbs(yy[0])); if (ctx->allencahn) { yy[1] = PetscRealPart(u[i] - u[i]*u[i]*u[i]); max = PetscMax(max,PetscAbs(yy[1])); } ierr = PetscDrawLGAddPoint(lg,xx,yy);CHKERRQ(ierr); x += hx; } ierr = PetscDrawAxisSetLabels(axis,"Right hand side","","");CHKERRQ(ierr); ierr = PetscDrawLGSetLegend(lg,NULL);CHKERRQ(ierr); ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); /* Plot the solution */ ierr = PetscDrawLGSetDimension(lg,1);CHKERRQ(ierr); ierr = PetscDrawViewPortsSet(ports,0);CHKERRQ(ierr); ierr = PetscDrawLGReset(lg);CHKERRQ(ierr); x = hx*xs; ierr = PetscDrawLGSetLimits(lg,x,x+(xm-1)*hx,-1.1,1.1);CHKERRQ(ierr); ierr = PetscDrawLGSetColors(lg,colors);CHKERRQ(ierr); for (i=xs; i<xs+xm; i++) { xx[0] = x; yy[0] = PetscRealPart(u[i]); ierr = PetscDrawLGAddPoint(lg,xx,yy);CHKERRQ(ierr); x += hx; } ierr = PetscDrawAxisSetLabels(axis,"Solution","","");CHKERRQ(ierr); ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); /* Print the forces as arrows on the solution */ x = hx*xs; cnt = xm/60; cnt = (!cnt) ? 1 : cnt; for (i=xs; i<xs+xm; i += cnt) { y = PetscRealPart(u[i]); len = .5*PetscRealPart(ctx->kappa*(u[i-1] + u[i+1] - 2.0*u[i])*sx)/max; ierr = PetscDrawArrow(draw,x,y,x,y+len,PETSC_DRAW_RED);CHKERRQ(ierr); if (ctx->allencahn) { len = .5*PetscRealPart(u[i] - u[i]*u[i]*u[i])/max; ierr = PetscDrawArrow(draw,x,y,x,y+len,PETSC_DRAW_BLUE);CHKERRQ(ierr); } x += cnt*hx; } ierr = DMDAVecRestoreArrayRead(da,localU,&x);CHKERRQ(ierr); ierr = DMRestoreLocalVector(da,&localU);CHKERRQ(ierr); ierr = PetscDrawStringSetSize(draw,.2,.2);CHKERRQ(ierr); ierr = PetscDrawFlush(draw);CHKERRQ(ierr); ierr = PetscDrawSetPause(draw,pause);CHKERRQ(ierr); ierr = PetscDrawPause(draw);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Run with -build_twosided allreduce -pc_type bjacobi -sub_pc_type lu -q 16 -ksp_rtol 1.e-34 (or 1.e-14 for double precision) -q <q> number of spectral elements to use -N <N> maximum number of GLL points per element */ int main(int argc,char **args) { PetscErrorCode ierr; PetscGLL gll; PetscInt N = 80,n,q = 8,xs,xn,j,l; PetscReal **A; Mat K; KSP ksp; PC pc; Vec x,b; PetscInt *rows; PetscReal norm,xc,yc,h; PetscScalar *f; PetscDraw draw; PetscDrawLG lg; PetscDrawAxis axis; DM da; PetscMPIInt rank,size; ierr = PetscInitialize(&argc,&args,NULL,NULL);if (ierr) return ierr; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-q",&q,NULL);CHKERRQ(ierr); ierr = PetscDrawCreate(PETSC_COMM_WORLD,NULL,"Log(Error norm) vs Number of GLL points",0,0,500,500,&draw);CHKERRQ(ierr); ierr = PetscDrawSetFromOptions(draw);CHKERRQ(ierr); ierr = PetscDrawLGCreate(draw,1,&lg);CHKERRQ(ierr); ierr = PetscDrawLGSetUseMarkers(lg,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscDrawLGGetAxis(lg,&axis);CHKERRQ(ierr); ierr = PetscDrawAxisSetLabels(axis,NULL,"Number of GLL points","Log(Error Norm)");CHKERRQ(ierr); for (n=4; n<N; n+=2) { /* da contains the information about the parallel layout of the elements */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,q*(n-1)+1,1,1,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMDAGetInfo(da,NULL,&q,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); q = (q-1)/(n-1); /* number of spectral elements */ /* gll simply contains the GLL node and weight values */ ierr = PetscGLLCreate(n,PETSCGLL_VIA_LINEARALGEBRA,&gll);CHKERRQ(ierr); ierr = DMDASetGLLCoordinates(da,&gll);CHKERRQ(ierr); /* Creates the element stiffness matrix for the given gll */ ierr = PetscGLLElementLaplacianCreate(&gll,&A);CHKERRQ(ierr); /* Scale the element stiffness and weights by the size of the element */ h = 2.0/q; for (j=0; j<n; j++) { gll.weights[j] *= .5*h; for (l=0; l<n; l++) { A[j][l] = 2.*A[j][l]/h; } } /* Create the global stiffness matrix and add the element stiffness for each local element */ ierr = DMCreateMatrix(da,&K);CHKERRQ(ierr); ierr = MatSetOption(K,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,NULL,NULL,&xn,NULL,NULL);CHKERRQ(ierr); xs = xs/(n-1); xn = xn/(n-1); ierr = PetscMalloc1(n,&rows);CHKERRQ(ierr); /* loop over local elements */ for (j=xs; j<xs+xn; j++) { for (l=0; l<n; l++) rows[l] = j*(n-1)+l; ierr = MatSetValues(K,n,rows,n,rows,&A[0][0],ADD_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(K,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(K,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCreateVecs(K,&x,&b);CHKERRQ(ierr); ierr = ComputeRhs(da,&gll,b);CHKERRQ(ierr); /* Replace the first and last rows/columns of the matrix with the identity to obtain the zero Dirichlet boundary conditions */ rows[0] = 0; rows[1] = q*(n-1); ierr = MatZeroRowsColumns(K,2,rows,1.0,x,b);CHKERRQ(ierr); ierr = PetscFree(rows);CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,K,K);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCLU);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); /* compute the error to the continium problem */ ierr = ComputeSolution(da,&gll,b);CHKERRQ(ierr); ierr = VecAXPY(x,-1.0,b);CHKERRQ(ierr); /* compute the L^2 norm of the error */ ierr = VecGetArray(x,&f);CHKERRQ(ierr); ierr = PetscGLLIntegrate(&gll,f,&norm);CHKERRQ(ierr); ierr = VecRestoreArray(x,&f);CHKERRQ(ierr); norm = PetscSqrtReal(norm); ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"L^2 norm of the error %D %g\n",n,(double)norm);CHKERRQ(ierr); if (n > 10 && norm > 1.e-8) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Slower convergence than expected"); xc = (PetscReal)n; yc = PetscLog10Real(norm); ierr = PetscDrawLGAddPoint(lg,&xc,&yc);CHKERRQ(ierr); ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = MatDestroy(&K);CHKERRQ(ierr); ierr = PetscGLLElementLaplacianDestroy(&gll,&A);CHKERRQ(ierr); ierr = PetscGLLDestroy(&gll);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); } ierr = PetscDrawLGDestroy(&lg);CHKERRQ(ierr); ierr = PetscDrawDestroy(&draw);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }