Date: 2022-03-04T17:39:32+00:00

Actual source code: tsmon.c

      1: #include <petsc/private/tsimpl.h>
      2: #include <petscdm.h>
      3: #include <petscdraw.h>

      5: /*@C
      6:    TSMonitor - Runs all user-provided monitor routines set using TSMonitorSet()

      8:    Collective on TS

     10:    Input Parameters:
     11: +  ts - time stepping context obtained from TSCreate()
     12: .  step - step number that has just completed
     13: .  ptime - model time of the state
     14: -  u - state at the current model time

     16:    Notes:
     17:    TSMonitor() is typically used automatically within the time stepping implementations.
     18:    Users would almost never call this routine directly.

     20:    A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions

     22:    Level: developer

     24: @*/
     25: PetscErrorCode TSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec u)
     26: {
     27:   DM             dm;
     28:   PetscInt       i,n = ts->numbermonitors;

     35:   TSGetDM(ts,&dm);
     36:   DMSetOutputSequenceNumber(dm,step,ptime);

     38:   VecLockReadPush(u);
     39:   for (i=0; i<n; i++) {
     40:     (*ts->monitor[i])(ts,step,ptime,u,ts->monitorcontext[i]);
     41:   }
     42:   VecLockReadPop(u);
     43:   return(0);
     44: }

     46: /*@C
     47:    TSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user

     49:    Collective on TS

     51:    Input Parameters:
     52: +  ts - TS object you wish to monitor
     53: .  name - the monitor type one is seeking
     54: .  help - message indicating what monitoring is done
     55: .  manual - manual page for the monitor
     56: .  monitor - the monitor function
     57: -  monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the TS or PetscViewer objects

     59:    Level: developer

     61: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
     62:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
     63:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
     64:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
     65:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
     66:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
     67:           PetscOptionsFList(), PetscOptionsEList()
     68: @*/
     69: PetscErrorCode  TSMonitorSetFromOptions(TS ts,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(TS,PetscViewerAndFormat*))
     70: {
     71:   PetscErrorCode    ierr;
     72:   PetscViewer       viewer;
     73:   PetscViewerFormat format;
     74:   PetscBool         flg;

     77:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts),((PetscObject) ts)->options,((PetscObject)ts)->prefix,name,&viewer,&format,&flg);
     78:   if (flg) {
     79:     PetscViewerAndFormat *vf;
     80:     PetscViewerAndFormatCreate(viewer,format,&vf);
     81:     PetscObjectDereference((PetscObject)viewer);
     82:     if (monitorsetup) {
     83:       (*monitorsetup)(ts,vf);
     84:     }
     85:     TSMonitorSet(ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
     86:   }
     87:   return(0);
     88: }

     90: /*@C
     91:    TSMonitorSet - Sets an ADDITIONAL function that is to be used at every
     92:    timestep to display the iteration's  progress.

     94:    Logically Collective on TS

     96:    Input Parameters:
     97: +  ts - the TS context obtained from TSCreate()
     98: .  monitor - monitoring routine
     99: .  mctx - [optional] user-defined context for private data for the
    100:              monitor routine (use NULL if no context is desired)
    101: -  monitordestroy - [optional] routine that frees monitor context
    102:           (may be NULL)

    104:    Calling sequence of monitor:
    105: $    PetscErrorCode monitor(TS ts,PetscInt steps,PetscReal time,Vec u,void *mctx)

    107: +    ts - the TS context
    108: .    steps - iteration number (after the final time step the monitor routine may be called with a step of -1, this indicates the solution has been interpolated to this time)
    109: .    time - current time
    110: .    u - current iterate
    111: -    mctx - [optional] monitoring context

    113:    Notes:
    114:    This routine adds an additional monitor to the list of monitors that
    115:    already has been loaded.

    117:    Fortran Notes:
    118:     Only a single monitor function can be set for each TS object

    120:    Level: intermediate

    122: .seealso: TSMonitorDefault(), TSMonitorCancel()
    123: @*/
    124: PetscErrorCode  TSMonitorSet(TS ts,PetscErrorCode (*monitor)(TS,PetscInt,PetscReal,Vec,void*),void *mctx,PetscErrorCode (*mdestroy)(void**))
    125: {
    127:   PetscInt       i;
    128:   PetscBool      identical;

    132:   for (i=0; i<ts->numbermonitors;i++) {
    133:     PetscMonitorCompare((PetscErrorCode (*)(void))monitor,mctx,mdestroy,(PetscErrorCode (*)(void))ts->monitor[i],ts->monitorcontext[i],ts->monitordestroy[i],&identical);
    134:     if (identical) return(0);
    135:   }
    136:   if (ts->numbermonitors >= MAXTSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
    137:   ts->monitor[ts->numbermonitors]          = monitor;
    138:   ts->monitordestroy[ts->numbermonitors]   = mdestroy;
    139:   ts->monitorcontext[ts->numbermonitors++] = (void*)mctx;
    140:   return(0);
    141: }

    143: /*@C
    144:    TSMonitorCancel - Clears all the monitors that have been set on a time-step object.

    146:    Logically Collective on TS

    148:    Input Parameters:
    149: .  ts - the TS context obtained from TSCreate()

    151:    Notes:
    152:    There is no way to remove a single, specific monitor.

    154:    Level: intermediate

    156: .seealso: TSMonitorDefault(), TSMonitorSet()
    157: @*/
    158: PetscErrorCode  TSMonitorCancel(TS ts)
    159: {
    161:   PetscInt       i;

    165:   for (i=0; i<ts->numbermonitors; i++) {
    166:     if (ts->monitordestroy[i]) {
    167:       (*ts->monitordestroy[i])(&ts->monitorcontext[i]);
    168:     }
    169:   }
    170:   ts->numbermonitors = 0;
    171:   return(0);
    172: }

    174: /*@C
    175:    TSMonitorDefault - The Default monitor, prints the timestep and time for each step

    177:    Level: intermediate

    179: .seealso:  TSMonitorSet()
    180: @*/
    181: PetscErrorCode TSMonitorDefault(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
    182: {
    184:   PetscViewer    viewer =  vf->viewer;
    185:   PetscBool      iascii,ibinary;

    189:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    190:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
    191:   PetscViewerPushFormat(viewer,vf->format);
    192:   if (iascii) {
    193:     PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);
    194:     if (step == -1) { /* this indicates it is an interpolated solution */
    195:       PetscViewerASCIIPrintf(viewer,"Interpolated solution at time %g between steps %D and %D\n",(double)ptime,ts->steps-1,ts->steps);
    196:     } else {
    197:       PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)\n" : "\n");
    198:     }
    199:     PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);
    200:   } else if (ibinary) {
    201:     PetscMPIInt rank;
    202:     MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    203:     if (!rank) {
    204:       PetscBool skipHeader;
    205:       PetscInt  classid = REAL_FILE_CLASSID;

    207:       PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);
    208:       if (!skipHeader) {
    209:          PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT);
    210:        }
    211:       PetscRealView(1,&ptime,viewer);
    212:     } else {
    213:       PetscRealView(0,&ptime,viewer);
    214:     }
    215:   }
    216:   PetscViewerPopFormat(viewer);
    217:   return(0);
    218: }

    220: /*@C
    221:    TSMonitorExtreme - Prints the extreme values of the solution at each timestep

    223:    Level: intermediate

    225: .seealso:  TSMonitorSet()
    226: @*/
    227: PetscErrorCode TSMonitorExtreme(TS ts,PetscInt step,PetscReal ptime,Vec v,PetscViewerAndFormat *vf)
    228: {
    230:   PetscViewer    viewer =  vf->viewer;
    231:   PetscBool      iascii;
    232:   PetscReal      max,min;

    236:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    237:   PetscViewerPushFormat(viewer,vf->format);
    238:   if (iascii) {
    239:     VecMax(v,NULL,&max);
    240:     VecMin(v,NULL,&min);
    241:     PetscViewerASCIIAddTab(viewer,((PetscObject)ts)->tablevel);
    242:     PetscViewerASCIIPrintf(viewer,"%D TS dt %g time %g%s max %g min %g\n",step,(double)ts->time_step,(double)ptime,ts->steprollback ? " (r)" : "",(double)max,(double)min);
    243:     PetscViewerASCIISubtractTab(viewer,((PetscObject)ts)->tablevel);
    244:   }
    245:   PetscViewerPopFormat(viewer);
    246:   return(0);
    247: }

    249: /*@C
    250:    TSMonitorLGCtxCreate - Creates a TSMonitorLGCtx context for use with
    251:    TS to monitor the solution process graphically in various ways

    253:    Collective on TS

    255:    Input Parameters:
    256: +  host - the X display to open, or null for the local machine
    257: .  label - the title to put in the title bar
    258: .  x, y - the screen coordinates of the upper left coordinate of the window
    259: .  m, n - the screen width and height in pixels
    260: -  howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time

    262:    Output Parameter:
    263: .  ctx - the context

    265:    Options Database Key:
    266: +  -ts_monitor_lg_timestep - automatically sets line graph monitor
    267: +  -ts_monitor_lg_timestep_log - automatically sets line graph monitor
    268: .  -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling TSMonitorLGSetDisplayVariables() or TSMonitorLGCtxSetDisplayVariables())
    269: .  -ts_monitor_lg_error -  monitor the error
    270: .  -ts_monitor_lg_ksp_iterations - monitor the number of KSP iterations needed for each timestep
    271: .  -ts_monitor_lg_snes_iterations - monitor the number of SNES iterations needed for each timestep
    272: -  -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true

    274:    Notes:
    275:    Use TSMonitorLGCtxDestroy() to destroy.

    277:    One can provide a function that transforms the solution before plotting it with TSMonitorLGCtxSetTransform() or TSMonitorLGSetTransform()

    279:    Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a TS object as the
    280:    first argument (if that TS object does not have a TSMonitorLGCtx associated with it the function call is ignored) and the second takes a TSMonitorLGCtx object
    281:    as the first argument.

    283:    One can control the names displayed for each solution or error variable with TSMonitorLGCtxSetVariableNames() or TSMonitorLGSetVariableNames()

    285:    Level: intermediate

    287: .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError(), TSMonitorDefault(), VecView(),
    288:            TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
    289:            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
    290:            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
    291:            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()

    293: @*/
    294: PetscErrorCode  TSMonitorLGCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorLGCtx *ctx)
    295: {
    296:   PetscDraw      draw;

    300:   PetscNew(ctx);
    301:   PetscDrawCreate(comm,host,label,x,y,m,n,&draw);
    302:   PetscDrawSetFromOptions(draw);
    303:   PetscDrawLGCreate(draw,1,&(*ctx)->lg);
    304:   PetscDrawLGSetFromOptions((*ctx)->lg);
    305:   PetscDrawDestroy(&draw);
    306:   (*ctx)->howoften = howoften;
    307:   return(0);
    308: }

    310: PetscErrorCode TSMonitorLGTimeStep(TS ts,PetscInt step,PetscReal ptime,Vec v,void *monctx)
    311: {
    312:   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
    313:   PetscReal      x   = ptime,y;

    317:   if (step < 0) return(0); /* -1 indicates an interpolated solution */
    318:   if (!step) {
    319:     PetscDrawAxis axis;
    320:     const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step";
    321:     PetscDrawLGGetAxis(ctx->lg,&axis);
    322:     PetscDrawAxisSetLabels(axis,"Timestep as function of time","Time",ylabel);
    323:     PetscDrawLGReset(ctx->lg);
    324:   }
    325:   TSGetTimeStep(ts,&y);
    326:   if (ctx->semilogy) y = PetscLog10Real(y);
    327:   PetscDrawLGAddPoint(ctx->lg,&x,&y);
    328:   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
    329:     PetscDrawLGDraw(ctx->lg);
    330:     PetscDrawLGSave(ctx->lg);
    331:   }
    332:   return(0);
    333: }

    335: /*@C
    336:    TSMonitorLGCtxDestroy - Destroys a line graph context that was created
    337:    with TSMonitorLGCtxCreate().

    339:    Collective on TSMonitorLGCtx

    341:    Input Parameter:
    342: .  ctx - the monitor context

    344:    Level: intermediate

    346: .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep();
    347: @*/
    348: PetscErrorCode  TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx)
    349: {

    353:   if ((*ctx)->transformdestroy) {
    354:     ((*ctx)->transformdestroy)((*ctx)->transformctx);
    355:   }
    356:   PetscDrawLGDestroy(&(*ctx)->lg);
    357:   PetscStrArrayDestroy(&(*ctx)->names);
    358:   PetscStrArrayDestroy(&(*ctx)->displaynames);
    359:   PetscFree((*ctx)->displayvariables);
    360:   PetscFree((*ctx)->displayvalues);
    361:   PetscFree(*ctx);
    362:   return(0);
    363: }

    365: /*

    367:   Creates a TS Monitor SPCtx for use with DM Swarm particle visualizations

    369: */
    370: PetscErrorCode TSMonitorSPCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorSPCtx *ctx)
    371: {
    372:   PetscDraw      draw;

    376:   PetscNew(ctx);
    377:   PetscDrawCreate(comm,host,label,x,y,m,n,&draw);
    378:   PetscDrawSetFromOptions(draw);
    379:   PetscDrawSPCreate(draw,1,&(*ctx)->sp);
    380:   PetscDrawDestroy(&draw);
    381:   (*ctx)->howoften = howoften;
    382:   return(0);

    384: }

    386: /*
    387:   Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate
    388: */
    389: PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx)
    390: {

    395:   PetscDrawSPDestroy(&(*ctx)->sp);
    396:   PetscFree(*ctx);

    398:   return(0);

    400: }

    402: /*@C
    403:    TSMonitorDrawSolution - Monitors progress of the TS solvers by calling
    404:    VecView() for the solution at each timestep

    406:    Collective on TS

    408:    Input Parameters:
    409: +  ts - the TS context
    410: .  step - current time-step
    411: .  ptime - current time
    412: -  dummy - either a viewer or NULL

    414:    Options Database:
    415: .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution

    417:    Notes:
    418:     the initial solution and current solution are not display with a common axis scaling so generally the option -ts_monitor_draw_solution_initial
    419:        will look bad

    421:    Level: intermediate

    423: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
    424: @*/
    425: PetscErrorCode  TSMonitorDrawSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
    426: {
    427:   PetscErrorCode   ierr;
    428:   TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy;
    429:   PetscDraw        draw;

    432:   if (!step && ictx->showinitial) {
    433:     if (!ictx->initialsolution) {
    434:       VecDuplicate(u,&ictx->initialsolution);
    435:     }
    436:     VecCopy(u,ictx->initialsolution);
    437:   }
    438:   if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) return(0);

    440:   if (ictx->showinitial) {
    441:     PetscReal pause;
    442:     PetscViewerDrawGetPause(ictx->viewer,&pause);
    443:     PetscViewerDrawSetPause(ictx->viewer,0.0);
    444:     VecView(ictx->initialsolution,ictx->viewer);
    445:     PetscViewerDrawSetPause(ictx->viewer,pause);
    446:     PetscViewerDrawSetHold(ictx->viewer,PETSC_TRUE);
    447:   }
    448:   VecView(u,ictx->viewer);
    449:   if (ictx->showtimestepandtime) {
    450:     PetscReal xl,yl,xr,yr,h;
    451:     char      time[32];

    453:     PetscViewerDrawGetDraw(ictx->viewer,0,&draw);
    454:     PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);
    455:     PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);
    456:     h    = yl + .95*(yr - yl);
    457:     PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);
    458:     PetscDrawFlush(draw);
    459:   }

    461:   if (ictx->showinitial) {
    462:     PetscViewerDrawSetHold(ictx->viewer,PETSC_FALSE);
    463:   }
    464:   return(0);
    465: }

    467: /*@C
    468:    TSMonitorDrawSolutionPhase - Monitors progress of the TS solvers by plotting the solution as a phase diagram

    470:    Collective on TS

    472:    Input Parameters:
    473: +  ts - the TS context
    474: .  step - current time-step
    475: .  ptime - current time
    476: -  dummy - either a viewer or NULL

    478:    Level: intermediate

    480: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
    481: @*/
    482: PetscErrorCode  TSMonitorDrawSolutionPhase(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
    483: {
    484:   PetscErrorCode    ierr;
    485:   TSMonitorDrawCtx  ictx = (TSMonitorDrawCtx)dummy;
    486:   PetscDraw         draw;
    487:   PetscDrawAxis     axis;
    488:   PetscInt          n;
    489:   PetscMPIInt       size;
    490:   PetscReal         U0,U1,xl,yl,xr,yr,h;
    491:   char              time[32];
    492:   const PetscScalar *U;

    495:   MPI_Comm_size(PetscObjectComm((PetscObject)ts),&size);
    496:   if (size != 1) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only allowed for sequential runs");
    497:   VecGetSize(u,&n);
    498:   if (n != 2) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Only for ODEs with two unknowns");

    500:   PetscViewerDrawGetDraw(ictx->viewer,0,&draw);
    501:   PetscViewerDrawGetDrawAxis(ictx->viewer,0,&axis);
    502:   PetscDrawAxisGetLimits(axis,&xl,&xr,&yl,&yr);
    503:   if (!step) {
    504:     PetscDrawClear(draw);
    505:     PetscDrawAxisDraw(axis);
    506:   }

    508:   VecGetArrayRead(u,&U);
    509:   U0 = PetscRealPart(U[0]);
    510:   U1 = PetscRealPart(U[1]);
    511:   VecRestoreArrayRead(u,&U);
    512:   if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) return(0);

    514:   PetscDrawCollectiveBegin(draw);
    515:   PetscDrawPoint(draw,U0,U1,PETSC_DRAW_BLACK);
    516:   if (ictx->showtimestepandtime) {
    517:     PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);
    518:     PetscSNPrintf(time,32,"Timestep %d Time %g",(int)step,(double)ptime);
    519:     h    = yl + .95*(yr - yl);
    520:     PetscDrawStringCentered(draw,.5*(xl+xr),h,PETSC_DRAW_BLACK,time);
    521:   }
    522:   PetscDrawCollectiveEnd(draw);
    523:   PetscDrawFlush(draw);
    524:   PetscDrawPause(draw);
    525:   PetscDrawSave(draw);
    526:   return(0);
    527: }

    529: /*@C
    530:    TSMonitorDrawCtxDestroy - Destroys the monitor context for TSMonitorDrawSolution()

    532:    Collective on TS

    534:    Input Parameters:
    535: .    ctx - the monitor context

    537:    Level: intermediate

    539: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawSolution(), TSMonitorDrawError()
    540: @*/
    541: PetscErrorCode  TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx)
    542: {

    546:   PetscViewerDestroy(&(*ictx)->viewer);
    547:   VecDestroy(&(*ictx)->initialsolution);
    548:   PetscFree(*ictx);
    549:   return(0);
    550: }

    552: /*@C
    553:    TSMonitorDrawCtxCreate - Creates the monitor context for TSMonitorDrawCtx

    555:    Collective on TS

    557:    Input Parameter:
    558: .    ts - time-step context

    560:    Output Patameter:
    561: .    ctx - the monitor context

    563:    Options Database:
    564: .   -ts_monitor_draw_solution_initial - show initial solution as well as current solution

    566:    Level: intermediate

    568: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorDrawCtx()
    569: @*/
    570: PetscErrorCode  TSMonitorDrawCtxCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscInt howoften,TSMonitorDrawCtx *ctx)
    571: {
    572:   PetscErrorCode   ierr;

    575:   PetscNew(ctx);
    576:   PetscViewerDrawOpen(comm,host,label,x,y,m,n,&(*ctx)->viewer);
    577:   PetscViewerSetFromOptions((*ctx)->viewer);

    579:   (*ctx)->howoften    = howoften;
    580:   (*ctx)->showinitial = PETSC_FALSE;
    581:   PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_initial",&(*ctx)->showinitial,NULL);

    583:   (*ctx)->showtimestepandtime = PETSC_FALSE;
    584:   PetscOptionsGetBool(NULL,NULL,"-ts_monitor_draw_solution_show_time",&(*ctx)->showtimestepandtime,NULL);
    585:   return(0);
    586: }

    588: /*@C
    589:    TSMonitorDrawSolutionFunction - Monitors progress of the TS solvers by calling
    590:    VecView() for the solution provided by TSSetSolutionFunction() at each timestep

    592:    Collective on TS

    594:    Input Parameters:
    595: +  ts - the TS context
    596: .  step - current time-step
    597: .  ptime - current time
    598: -  dummy - either a viewer or NULL

    600:    Options Database:
    601: .  -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided TSSetSolutionFunction()

    603:    Level: intermediate

    605: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
    606: @*/
    607: PetscErrorCode  TSMonitorDrawSolutionFunction(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
    608: {
    609:   PetscErrorCode   ierr;
    610:   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
    611:   PetscViewer      viewer = ctx->viewer;
    612:   Vec              work;

    615:   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) return(0);
    616:   VecDuplicate(u,&work);
    617:   TSComputeSolutionFunction(ts,ptime,work);
    618:   VecView(work,viewer);
    619:   VecDestroy(&work);
    620:   return(0);
    621: }

    623: /*@C
    624:    TSMonitorDrawError - Monitors progress of the TS solvers by calling
    625:    VecView() for the error at each timestep

    627:    Collective on TS

    629:    Input Parameters:
    630: +  ts - the TS context
    631: .  step - current time-step
    632: .  ptime - current time
    633: -  dummy - either a viewer or NULL

    635:    Options Database:
    636: .  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction()

    638:    Level: intermediate

    640: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
    641: @*/
    642: PetscErrorCode  TSMonitorDrawError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
    643: {
    644:   PetscErrorCode   ierr;
    645:   TSMonitorDrawCtx ctx    = (TSMonitorDrawCtx)dummy;
    646:   PetscViewer      viewer = ctx->viewer;
    647:   Vec              work;

    650:   if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) return(0);
    651:   VecDuplicate(u,&work);
    652:   TSComputeSolutionFunction(ts,ptime,work);
    653:   VecAXPY(work,-1.0,u);
    654:   VecView(work,viewer);
    655:   VecDestroy(&work);
    656:   return(0);
    657: }

    659: /*@C
    660:    TSMonitorSolution - Monitors progress of the TS solvers by VecView() for the solution at each timestep. Normally the viewer is a binary file or a PetscDraw object

    662:    Collective on TS

    664:    Input Parameters:
    665: +  ts - the TS context
    666: .  step - current time-step
    667: .  ptime - current time
    668: .  u - current state
    669: -  vf - viewer and its format

    671:    Level: intermediate

    673: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
    674: @*/
    675: PetscErrorCode  TSMonitorSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
    676: {

    680:   PetscViewerPushFormat(vf->viewer,vf->format);
    681:   VecView(u,vf->viewer);
    682:   PetscViewerPopFormat(vf->viewer);
    683:   return(0);
    684: }

    686: /*@C
    687:    TSMonitorSolutionVTK - Monitors progress of the TS solvers by VecView() for the solution at each timestep.

    689:    Collective on TS

    691:    Input Parameters:
    692: +  ts - the TS context
    693: .  step - current time-step
    694: .  ptime - current time
    695: .  u - current state
    696: -  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)

    698:    Level: intermediate

    700:    Notes:
    701:    The VTK format does not allow writing multiple time steps in the same file, therefore a different file will be written for each time step.
    702:    These are named according to the file name template.

    704:    This function is normally passed as an argument to TSMonitorSet() along with TSMonitorSolutionVTKDestroy().

    706: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView()
    707: @*/
    708: PetscErrorCode TSMonitorSolutionVTK(TS ts,PetscInt step,PetscReal ptime,Vec u,void *filenametemplate)
    709: {
    711:   char           filename[PETSC_MAX_PATH_LEN];
    712:   PetscViewer    viewer;

    715:   if (step < 0) return(0); /* -1 indicates interpolated solution */
    716:   PetscSNPrintf(filename,sizeof(filename),(const char*)filenametemplate,step);
    717:   PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts),filename,FILE_MODE_WRITE,&viewer);
    718:   VecView(u,viewer);
    719:   PetscViewerDestroy(&viewer);
    720:   return(0);
    721: }

    723: /*@C
    724:    TSMonitorSolutionVTKDestroy - Destroy context for monitoring

    726:    Collective on TS

    728:    Input Parameters:
    729: .  filenametemplate - string containing a format specifier for the integer time step (e.g. %03D)

    731:    Level: intermediate

    733:    Note:
    734:    This function is normally passed to TSMonitorSet() along with TSMonitorSolutionVTK().

    736: .seealso: TSMonitorSet(), TSMonitorSolutionVTK()
    737: @*/
    738: PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate)
    739: {

    743:   PetscFree(*(char**)filenametemplate);
    744:   return(0);
    745: }

    747: /*@C
    748:    TSMonitorLGSolution - Monitors progress of the TS solvers by plotting each component of the solution vector
    749:        in a time based line graph

    751:    Collective on TS

    753:    Input Parameters:
    754: +  ts - the TS context
    755: .  step - current time-step
    756: .  ptime - current time
    757: .  u - current solution
    758: -  dctx - the TSMonitorLGCtx object that contains all the options for the monitoring, this is created with TSMonitorLGCtxCreate()

    760:    Options Database:
    761: .   -ts_monitor_lg_solution_variables

    763:    Level: intermediate

    765:    Notes:
    766:     Each process in a parallel run displays its component solutions in a separate window

    768: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGCtxCreate(), TSMonitorLGCtxSetVariableNames(), TSMonitorLGCtxGetVariableNames(),
    769:            TSMonitorLGSetVariableNames(), TSMonitorLGGetVariableNames(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetDisplayVariables(),
    770:            TSMonitorLGCtxSetTransform(), TSMonitorLGSetTransform(), TSMonitorLGError(), TSMonitorLGSNESIterations(), TSMonitorLGKSPIterations(),
    771:            TSMonitorEnvelopeCtxCreate(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxDestroy(), TSMonitorEnvelop()
    772: @*/
    773: PetscErrorCode  TSMonitorLGSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
    774: {
    775:   PetscErrorCode    ierr;
    776:   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dctx;
    777:   const PetscScalar *yy;
    778:   Vec               v;

    781:   if (step < 0) return(0); /* -1 indicates interpolated solution */
    782:   if (!step) {
    783:     PetscDrawAxis axis;
    784:     PetscInt      dim;
    785:     PetscDrawLGGetAxis(ctx->lg,&axis);
    786:     PetscDrawAxisSetLabels(axis,"Solution as function of time","Time","Solution");
    787:     if (!ctx->names) {
    788:       PetscBool flg;
    789:       /* user provides names of variables to plot but no names has been set so assume names are integer values */
    790:       PetscOptionsHasName(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",&flg);
    791:       if (flg) {
    792:         PetscInt i,n;
    793:         char     **names;
    794:         VecGetSize(u,&n);
    795:         PetscMalloc1(n+1,&names);
    796:         for (i=0; i<n; i++) {
    797:           PetscMalloc1(5,&names[i]);
    798:           PetscSNPrintf(names[i],5,"%D",i);
    799:         }
    800:         names[n] = NULL;
    801:         ctx->names = names;
    802:       }
    803:     }
    804:     if (ctx->names && !ctx->displaynames) {
    805:       char      **displaynames;
    806:       PetscBool flg;
    807:       VecGetLocalSize(u,&dim);
    808:       PetscCalloc1(dim+1,&displaynames);
    809:       PetscOptionsGetStringArray(((PetscObject)ts)->options,((PetscObject)ts)->prefix,"-ts_monitor_lg_solution_variables",displaynames,&dim,&flg);
    810:       if (flg) {
    811:         TSMonitorLGCtxSetDisplayVariables(ctx,(const char *const *)displaynames);
    812:       }
    813:       PetscStrArrayDestroy(&displaynames);
    814:     }
    815:     if (ctx->displaynames) {
    816:       PetscDrawLGSetDimension(ctx->lg,ctx->ndisplayvariables);
    817:       PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->displaynames);
    818:     } else if (ctx->names) {
    819:       VecGetLocalSize(u,&dim);
    820:       PetscDrawLGSetDimension(ctx->lg,dim);
    821:       PetscDrawLGSetLegend(ctx->lg,(const char *const *)ctx->names);
    822:     } else {
    823:       VecGetLocalSize(u,&dim);
    824:       PetscDrawLGSetDimension(ctx->lg,dim);
    825:     }
    826:     PetscDrawLGReset(ctx->lg);
    827:   }

    829:   if (!ctx->transform) v = u;
    830:   else {(*ctx->transform)(ctx->transformctx,u,&v);}
    831:   VecGetArrayRead(v,&yy);
    832:   if (ctx->displaynames) {
    833:     PetscInt i;
    834:     for (i=0; i<ctx->ndisplayvariables; i++)
    835:       ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]);
    836:     PetscDrawLGAddCommonPoint(ctx->lg,ptime,ctx->displayvalues);
    837:   } else {
    838: #if defined(PETSC_USE_COMPLEX)
    839:     PetscInt  i,n;
    840:     PetscReal *yreal;
    841:     VecGetLocalSize(v,&n);
    842:     PetscMalloc1(n,&yreal);
    843:     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
    844:     PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);
    845:     PetscFree(yreal);
    846: #else
    847:     PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);
    848: #endif
    849:   }
    850:   VecRestoreArrayRead(v,&yy);
    851:   if (ctx->transform) {VecDestroy(&v);}

    853:   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
    854:     PetscDrawLGDraw(ctx->lg);
    855:     PetscDrawLGSave(ctx->lg);
    856:   }
    857:   return(0);
    858: }

    860: /*@C
    861:    TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot

    863:    Collective on TS

    865:    Input Parameters:
    866: +  ts - the TS context
    867: -  names - the names of the components, final string must be NULL

    869:    Level: intermediate

    871:    Notes:
    872:     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored

    874: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGCtxSetVariableNames()
    875: @*/
    876: PetscErrorCode  TSMonitorLGSetVariableNames(TS ts,const char * const *names)
    877: {
    878:   PetscErrorCode    ierr;
    879:   PetscInt          i;

    882:   for (i=0; i<ts->numbermonitors; i++) {
    883:     if (ts->monitor[i] == TSMonitorLGSolution) {
    884:       TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i],names);
    885:       break;
    886:     }
    887:   }
    888:   return(0);
    889: }

    891: /*@C
    892:    TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot

    894:    Collective on TS

    896:    Input Parameters:
    897: +  ts - the TS context
    898: -  names - the names of the components, final string must be NULL

    900:    Level: intermediate

    902: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables(), TSMonitorLGSetVariableNames()
    903: @*/
    904: PetscErrorCode  TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx,const char * const *names)
    905: {
    906:   PetscErrorCode    ierr;

    909:   PetscStrArrayDestroy(&ctx->names);
    910:   PetscStrArrayallocpy(names,&ctx->names);
    911:   return(0);
    912: }

    914: /*@C
    915:    TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot

    917:    Collective on TS

    919:    Input Parameter:
    920: .  ts - the TS context

    922:    Output Parameter:
    923: .  names - the names of the components, final string must be NULL

    925:    Level: intermediate

    927:    Notes:
    928:     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored

    930: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
    931: @*/
    932: PetscErrorCode  TSMonitorLGGetVariableNames(TS ts,const char *const **names)
    933: {
    934:   PetscInt       i;

    937:   *names = NULL;
    938:   for (i=0; i<ts->numbermonitors; i++) {
    939:     if (ts->monitor[i] == TSMonitorLGSolution) {
    940:       TSMonitorLGCtx  ctx = (TSMonitorLGCtx) ts->monitorcontext[i];
    941:       *names = (const char *const *)ctx->names;
    942:       break;
    943:     }
    944:   }
    945:   return(0);
    946: }

    948: /*@C
    949:    TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor

    951:    Collective on TS

    953:    Input Parameters:
    954: +  ctx - the TSMonitorLG context
    955: -  displaynames - the names of the components, final string must be NULL

    957:    Level: intermediate

    959: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
    960: @*/
    961: PetscErrorCode  TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx,const char * const *displaynames)
    962: {
    963:   PetscInt          j = 0,k;
    964:   PetscErrorCode    ierr;

    967:   if (!ctx->names) return(0);
    968:   PetscStrArrayDestroy(&ctx->displaynames);
    969:   PetscStrArrayallocpy(displaynames,&ctx->displaynames);
    970:   while (displaynames[j]) j++;
    971:   ctx->ndisplayvariables = j;
    972:   PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvariables);
    973:   PetscMalloc1(ctx->ndisplayvariables,&ctx->displayvalues);
    974:   j = 0;
    975:   while (displaynames[j]) {
    976:     k = 0;
    977:     while (ctx->names[k]) {
    978:       PetscBool flg;
    979:       PetscStrcmp(displaynames[j],ctx->names[k],&flg);
    980:       if (flg) {
    981:         ctx->displayvariables[j] = k;
    982:         break;
    983:       }
    984:       k++;
    985:     }
    986:     j++;
    987:   }
    988:   return(0);
    989: }

    991: /*@C
    992:    TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor

    994:    Collective on TS

    996:    Input Parameters:
    997: +  ts - the TS context
    998: -  displaynames - the names of the components, final string must be NULL

    1000:    Notes:
    1001:     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored

    1003:    Level: intermediate

    1005: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames()
    1006: @*/
    1007: PetscErrorCode  TSMonitorLGSetDisplayVariables(TS ts,const char * const *displaynames)
    1008: {
    1009:   PetscInt          i;
    1010:   PetscErrorCode    ierr;

    1013:   for (i=0; i<ts->numbermonitors; i++) {
    1014:     if (ts->monitor[i] == TSMonitorLGSolution) {
    1015:       TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i],displaynames);
    1016:       break;
    1017:     }
    1018:   }
    1019:   return(0);
    1020: }

    1022: /*@C
    1023:    TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed

    1025:    Collective on TS

    1027:    Input Parameters:
    1028: +  ts - the TS context
    1029: .  transform - the transform function
    1030: .  destroy - function to destroy the optional context
    1031: -  ctx - optional context used by transform function

    1033:    Notes:
    1034:     If the TS object does not have a TSMonitorLGCtx associated with it then this function is ignored

    1036:    Level: intermediate

    1038: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGCtxSetTransform()
    1039: @*/
    1040: PetscErrorCode  TSMonitorLGSetTransform(TS ts,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
    1041: {
    1042:   PetscInt          i;
    1043:   PetscErrorCode    ierr;

    1046:   for (i=0; i<ts->numbermonitors; i++) {
    1047:     if (ts->monitor[i] == TSMonitorLGSolution) {
    1048:       TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i],transform,destroy,tctx);
    1049:     }
    1050:   }
    1051:   return(0);
    1052: }

    1054: /*@C
    1055:    TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed

    1057:    Collective on TSLGCtx

    1059:    Input Parameters:
    1060: +  ts - the TS context
    1061: .  transform - the transform function
    1062: .  destroy - function to destroy the optional context
    1063: -  ctx - optional context used by transform function

    1065:    Level: intermediate

    1067: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetVariableNames(), TSMonitorLGSetTransform()
    1068: @*/
    1069: PetscErrorCode  TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx,PetscErrorCode (*transform)(void*,Vec,Vec*),PetscErrorCode (*destroy)(void*),void *tctx)
    1070: {
    1072:   ctx->transform    = transform;
    1073:   ctx->transformdestroy = destroy;
    1074:   ctx->transformctx = tctx;
    1075:   return(0);
    1076: }

    1078: /*@C
    1079:    TSMonitorLGError - Monitors progress of the TS solvers by plotting each component of the error
    1080:        in a time based line graph

    1082:    Collective on TS

    1084:    Input Parameters:
    1085: +  ts - the TS context
    1086: .  step - current time-step
    1087: .  ptime - current time
    1088: .  u - current solution
    1089: -  dctx - TSMonitorLGCtx object created with TSMonitorLGCtxCreate()

    1091:    Level: intermediate

    1093:    Notes:
    1094:     Each process in a parallel run displays its component errors in a separate window

    1096:    The user must provide the solution using TSSetSolutionFunction() to use this monitor.

    1098:    Options Database Keys:
    1099: .  -ts_monitor_lg_error - create a graphical monitor of error history

    1101: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
    1102: @*/
    1103: PetscErrorCode  TSMonitorLGError(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dummy)
    1104: {
    1105:   PetscErrorCode    ierr;
    1106:   TSMonitorLGCtx    ctx = (TSMonitorLGCtx)dummy;
    1107:   const PetscScalar *yy;
    1108:   Vec               y;

    1111:   if (!step) {
    1112:     PetscDrawAxis axis;
    1113:     PetscInt      dim;
    1114:     PetscDrawLGGetAxis(ctx->lg,&axis);
    1115:     PetscDrawAxisSetLabels(axis,"Error in solution as function of time","Time","Error");
    1116:     VecGetLocalSize(u,&dim);
    1117:     PetscDrawLGSetDimension(ctx->lg,dim);
    1118:     PetscDrawLGReset(ctx->lg);
    1119:   }
    1120:   VecDuplicate(u,&y);
    1121:   TSComputeSolutionFunction(ts,ptime,y);
    1122:   VecAXPY(y,-1.0,u);
    1123:   VecGetArrayRead(y,&yy);
    1124: #if defined(PETSC_USE_COMPLEX)
    1125:   {
    1126:     PetscReal *yreal;
    1127:     PetscInt  i,n;
    1128:     VecGetLocalSize(y,&n);
    1129:     PetscMalloc1(n,&yreal);
    1130:     for (i=0; i<n; i++) yreal[i] = PetscRealPart(yy[i]);
    1131:     PetscDrawLGAddCommonPoint(ctx->lg,ptime,yreal);
    1132:     PetscFree(yreal);
    1133:   }
    1134: #else
    1135:   PetscDrawLGAddCommonPoint(ctx->lg,ptime,yy);
    1136: #endif
    1137:   VecRestoreArrayRead(y,&yy);
    1138:   VecDestroy(&y);
    1139:   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
    1140:     PetscDrawLGDraw(ctx->lg);
    1141:     PetscDrawLGSave(ctx->lg);
    1142:   }
    1143:   return(0);
    1144: }

    1146: /*@C
    1147:    TSMonitorSPSwarmSolution - Graphically displays phase plots of DMSwarm particles on a scatter plot

    1149:    Input Parameters:
    1150: +  ts - the TS context
    1151: .  step - current time-step
    1152: .  ptime - current time
    1153: .  u - current solution
    1154: -  dctx - the TSMonitorSPCtx object that contains all the options for the monitoring, this is created with TSMonitorSPCtxCreate()

    1156:    Options Database:
    1157: .   -ts_monitor_sp_swarm

    1159:    Level: intermediate

    1161: @*/
    1162: PetscErrorCode TSMonitorSPSwarmSolution(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
    1163: {
    1164:   PetscErrorCode    ierr;
    1165:   TSMonitorSPCtx    ctx = (TSMonitorSPCtx)dctx;
    1166:   const PetscScalar *yy;
    1167:   PetscReal       *y,*x;
    1168:   PetscInt          Np, p, dim=2;
    1169:   DM                dm;

    1172:   if (step < 0) return(0); /* -1 indicates interpolated solution */
    1173:   if (!step) {
    1174:     PetscDrawAxis axis;
    1175:     PetscDrawSPGetAxis(ctx->sp,&axis);
    1176:     PetscDrawAxisSetLabels(axis,"Particles","X","Y");
    1177:     PetscDrawAxisSetLimits(axis, -5, 5, -5, 5);
    1178:     PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE);
    1179:     TSGetDM(ts, &dm);
    1180:     DMGetDimension(dm, &dim);
    1181:     if (dim!=2) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Dimensions improper for monitor arguments! Current support: two dimensions.");
    1182:     VecGetLocalSize(u, &Np);
    1183:     Np /= 2*dim;
    1184:     PetscDrawSPSetDimension(ctx->sp, Np);
    1185:     PetscDrawSPReset(ctx->sp);
    1186:   }
    1187:   VecGetLocalSize(u, &Np);
    1188:   Np /= 2*dim;
    1189:   VecGetArrayRead(u,&yy);
    1190:   PetscMalloc2(Np, &x, Np, &y);
    1191:   /* get points from solution vector */
    1192:   for (p=0; p<Np; ++p) {
    1193:     x[p] = PetscRealPart(yy[2*dim*p]);
    1194:     y[p] = PetscRealPart(yy[2*dim*p+1]);
    1195:   }
    1196:   VecRestoreArrayRead(u,&yy);
    1197:   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) {
    1198:     PetscDrawSPAddPoint(ctx->sp,x,y);
    1199:     PetscDrawSPDraw(ctx->sp,PETSC_FALSE);
    1200:     PetscDrawSPSave(ctx->sp);
    1201:   }
    1202:   PetscFree2(x, y);
    1203:   return(0);
    1204: }

    1206: /*@C
    1207:    TSMonitorError - Monitors progress of the TS solvers by printing the 2 norm of the error at each timestep

    1209:    Collective on TS

    1211:    Input Parameters:
    1212: +  ts - the TS context
    1213: .  step - current time-step
    1214: .  ptime - current time
    1215: .  u - current solution
    1216: -  dctx - unused context

    1218:    Level: intermediate

    1220:    The user must provide the solution using TSSetSolutionFunction() to use this monitor.

    1222:    Options Database Keys:
    1223: .  -ts_monitor_error - create a graphical monitor of error history

    1225: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSSetSolutionFunction()
    1226: @*/
    1227: PetscErrorCode  TSMonitorError(TS ts,PetscInt step,PetscReal ptime,Vec u,PetscViewerAndFormat *vf)
    1228: {
    1229:   PetscErrorCode    ierr;
    1230:   Vec               y;
    1231:   PetscReal         nrm;
    1232:   PetscBool         flg;

    1235:   VecDuplicate(u,&y);
    1236:   TSComputeSolutionFunction(ts,ptime,y);
    1237:   VecAXPY(y,-1.0,u);
    1238:   PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERASCII,&flg);
    1239:   if (flg) {
    1240:     VecNorm(y,NORM_2,&nrm);
    1241:     PetscViewerASCIIPrintf(vf->viewer,"2-norm of error %g\n",(double)nrm);
    1242:   }
    1243:   PetscObjectTypeCompare((PetscObject)vf->viewer,PETSCVIEWERDRAW,&flg);
    1244:   if (flg) {
    1245:     VecView(y,vf->viewer);
    1246:   }
    1247:   VecDestroy(&y);
    1248:   return(0);
    1249: }

    1251: PetscErrorCode TSMonitorLGSNESIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
    1252: {
    1253:   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
    1254:   PetscReal      x   = ptime,y;
    1256:   PetscInt       its;

    1259:   if (n < 0) return(0); /* -1 indicates interpolated solution */
    1260:   if (!n) {
    1261:     PetscDrawAxis axis;
    1262:     PetscDrawLGGetAxis(ctx->lg,&axis);
    1263:     PetscDrawAxisSetLabels(axis,"Nonlinear iterations as function of time","Time","SNES Iterations");
    1264:     PetscDrawLGReset(ctx->lg);
    1265:     ctx->snes_its = 0;
    1266:   }
    1267:   TSGetSNESIterations(ts,&its);
    1268:   y    = its - ctx->snes_its;
    1269:   PetscDrawLGAddPoint(ctx->lg,&x,&y);
    1270:   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
    1271:     PetscDrawLGDraw(ctx->lg);
    1272:     PetscDrawLGSave(ctx->lg);
    1273:   }
    1274:   ctx->snes_its = its;
    1275:   return(0);
    1276: }

    1278: PetscErrorCode TSMonitorLGKSPIterations(TS ts,PetscInt n,PetscReal ptime,Vec v,void *monctx)
    1279: {
    1280:   TSMonitorLGCtx ctx = (TSMonitorLGCtx) monctx;
    1281:   PetscReal      x   = ptime,y;
    1283:   PetscInt       its;

    1286:   if (n < 0) return(0); /* -1 indicates interpolated solution */
    1287:   if (!n) {
    1288:     PetscDrawAxis axis;
    1289:     PetscDrawLGGetAxis(ctx->lg,&axis);
    1290:     PetscDrawAxisSetLabels(axis,"Linear iterations as function of time","Time","KSP Iterations");
    1291:     PetscDrawLGReset(ctx->lg);
    1292:     ctx->ksp_its = 0;
    1293:   }
    1294:   TSGetKSPIterations(ts,&its);
    1295:   y    = its - ctx->ksp_its;
    1296:   PetscDrawLGAddPoint(ctx->lg,&x,&y);
    1297:   if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) {
    1298:     PetscDrawLGDraw(ctx->lg);
    1299:     PetscDrawLGSave(ctx->lg);
    1300:   }
    1301:   ctx->ksp_its = its;
    1302:   return(0);
    1303: }

    1305: /*@C
    1306:    TSMonitorEnvelopeCtxCreate - Creates a context for use with TSMonitorEnvelope()

    1308:    Collective on TS

    1310:    Input Parameters:
    1311: .  ts  - the ODE solver object

    1313:    Output Parameter:
    1314: .  ctx - the context

    1316:    Level: intermediate

    1318: .seealso: TSMonitorLGTimeStep(), TSMonitorSet(), TSMonitorLGSolution(), TSMonitorLGError()

    1320: @*/
    1321: PetscErrorCode  TSMonitorEnvelopeCtxCreate(TS ts,TSMonitorEnvelopeCtx *ctx)
    1322: {

    1326:   PetscNew(ctx);
    1327:   return(0);
    1328: }

    1330: /*@C
    1331:    TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution

    1333:    Collective on TS

    1335:    Input Parameters:
    1336: +  ts - the TS context
    1337: .  step - current time-step
    1338: .  ptime - current time
    1339: .  u  - current solution
    1340: -  dctx - the envelope context

    1342:    Options Database:
    1343: .  -ts_monitor_envelope

    1345:    Level: intermediate

    1347:    Notes:
    1348:     after a solve you can use TSMonitorEnvelopeGetBounds() to access the envelope

    1350: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorEnvelopeGetBounds(), TSMonitorEnvelopeCtxCreate()
    1351: @*/
    1352: PetscErrorCode  TSMonitorEnvelope(TS ts,PetscInt step,PetscReal ptime,Vec u,void *dctx)
    1353: {
    1354:   PetscErrorCode       ierr;
    1355:   TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx;

    1358:   if (!ctx->max) {
    1359:     VecDuplicate(u,&ctx->max);
    1360:     VecDuplicate(u,&ctx->min);
    1361:     VecCopy(u,ctx->max);
    1362:     VecCopy(u,ctx->min);
    1363:   } else {
    1364:     VecPointwiseMax(ctx->max,u,ctx->max);
    1365:     VecPointwiseMin(ctx->min,u,ctx->min);
    1366:   }
    1367:   return(0);
    1368: }

    1370: /*@C
    1371:    TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution

    1373:    Collective on TS

    1375:    Input Parameter:
    1376: .  ts - the TS context

    1378:    Output Parameters:
    1379: +  max - the maximum values
    1380: -  min - the minimum values

    1382:    Notes:
    1383:     If the TS does not have a TSMonitorEnvelopeCtx associated with it then this function is ignored

    1385:    Level: intermediate

    1387: .seealso: TSMonitorSet(), TSMonitorDefault(), VecView(), TSMonitorLGSetDisplayVariables()
    1388: @*/
    1389: PetscErrorCode  TSMonitorEnvelopeGetBounds(TS ts,Vec *max,Vec *min)
    1390: {
    1391:   PetscInt i;

    1394:   if (max) *max = NULL;
    1395:   if (min) *min = NULL;
    1396:   for (i=0; i<ts->numbermonitors; i++) {
    1397:     if (ts->monitor[i] == TSMonitorEnvelope) {
    1398:       TSMonitorEnvelopeCtx  ctx = (TSMonitorEnvelopeCtx) ts->monitorcontext[i];
    1399:       if (max) *max = ctx->max;
    1400:       if (min) *min = ctx->min;
    1401:       break;
    1402:     }
    1403:   }
    1404:   return(0);
    1405: }

    1407: /*@C
    1408:    TSMonitorEnvelopeCtxDestroy - Destroys a context that was created  with TSMonitorEnvelopeCtxCreate().

    1410:    Collective on TSMonitorEnvelopeCtx

    1412:    Input Parameter:
    1413: .  ctx - the monitor context

    1415:    Level: intermediate

    1417: .seealso: TSMonitorLGCtxCreate(),  TSMonitorSet(), TSMonitorLGTimeStep()
    1418: @*/
    1419: PetscErrorCode  TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx)
    1420: {

    1424:   VecDestroy(&(*ctx)->min);
    1425:   VecDestroy(&(*ctx)->max);
    1426:   PetscFree(*ctx);
    1427:   return(0);
    1428: }

    1430: /*@C
    1431:   TSDMSwarmMonitorMoments - Monitors the first three moments of a DMSarm being evolved by the TS

    1433:   Not collective

    1435:   Input Parameters:
    1436: + ts   - the TS context
    1437: . step - current timestep
    1438: . t    - current time
    1439: . u    - current solution
    1440: - ctx  - not used

    1442:   Options Database:
    1443: . -ts_dmswarm_monitor_moments

    1445:   Level: intermediate

    1447:   Notes:
    1448:   This requires a DMSwarm be attached to the TS.

    1450: .seealso: TSMonitorSet(), TSMonitorDefault(), DMSWARM
    1451: @*/
    1452: PetscErrorCode TSDMSwarmMonitorMoments(TS ts, PetscInt step, PetscReal t, Vec U, PetscViewerAndFormat *vf)
    1453: {
    1454:   DM                 sw;
    1455:   const PetscScalar *u;
    1456:   PetscReal          m = 1.0, totE = 0., totMom[3] = {0., 0., 0.};
    1457:   PetscInt           dim, d, Np, p;
    1458:   MPI_Comm           comm;
    1459:   PetscErrorCode     ierr;

    1462:   TSGetDM(ts, &sw);
    1463:   if (!sw || step%ts->monitorFrequency != 0) return(0);
    1464:   PetscObjectGetComm((PetscObject) ts, &comm);
    1465:   DMGetDimension(sw, &dim);
    1466:   VecGetLocalSize(U, &Np);
    1467:   Np  /= dim;
    1468:   VecGetArrayRead(U, &u);
    1469:   for (p = 0; p < Np; ++p) {
    1470:     for (d = 0; d < dim; ++d) {
    1471:       totE      += PetscRealPart(u[p*dim+d]*u[p*dim+d]);
    1472:       totMom[d] += PetscRealPart(u[p*dim+d]);
    1473:     }
    1474:   }
    1475:   VecRestoreArrayRead(U, &u);
    1476:   for (d = 0; d < dim; ++d) totMom[d] *= m;
    1477:   totE *= 0.5*m;
    1478:   PetscPrintf(comm, "Step %4D Total Energy: %10.8lf", step, (double) totE);
    1479:   for (d = 0; d < dim; ++d) {PetscPrintf(comm, "    Total Momentum %c: %10.8lf", 'x'+d, (double) totMom[d]);}
    1480:   PetscPrintf(comm, "\n");
    1481:   return(0);
    1482: }