1d0c080abSJoseph Pusztay #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 2d0c080abSJoseph Pusztay #include <petscdm.h> 307eaae0cSMatthew G. Knepley #include <petscds.h> 4ab43fcacSJoe Pusztay #include <petscdmswarm.h> 5d0c080abSJoseph Pusztay #include <petscdraw.h> 6d0c080abSJoseph Pusztay 7d0c080abSJoseph Pusztay /*@C 8bcf0153eSBarry Smith TSMonitor - Runs all user-provided monitor routines set using `TSMonitorSet()` 9d0c080abSJoseph Pusztay 10c3339decSBarry Smith Collective 11d0c080abSJoseph Pusztay 12d0c080abSJoseph Pusztay Input Parameters: 13bcf0153eSBarry Smith + ts - time stepping context obtained from `TSCreate()` 14d0c080abSJoseph Pusztay . step - step number that has just completed 15d0c080abSJoseph Pusztay . ptime - model time of the state 16d0c080abSJoseph Pusztay - u - state at the current model time 17d0c080abSJoseph Pusztay 18bcf0153eSBarry Smith Level: developer 19bcf0153eSBarry Smith 20d0c080abSJoseph Pusztay Notes: 21bcf0153eSBarry Smith `TSMonitor()` is typically used automatically within the time stepping implementations. 22d0c080abSJoseph Pusztay Users would almost never call this routine directly. 23d0c080abSJoseph Pusztay 24d0c080abSJoseph Pusztay A step of -1 indicates that the monitor is being called on a solution obtained by interpolating from computed solutions 25d0c080abSJoseph Pusztay 26bcf0153eSBarry Smith .seealso: `TS`, `TSMonitorSet()`, `TSMonitorSetFromOptions()` 27d0c080abSJoseph Pusztay @*/ 28d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitor(TS ts, PetscInt step, PetscReal ptime, Vec u) 29d71ae5a4SJacob Faibussowitsch { 30d0c080abSJoseph Pusztay DM dm; 31d0c080abSJoseph Pusztay PetscInt i, n = ts->numbermonitors; 32d0c080abSJoseph Pusztay 33d0c080abSJoseph Pusztay PetscFunctionBegin; 34d0c080abSJoseph Pusztay PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 35d0c080abSJoseph Pusztay PetscValidHeaderSpecific(u, VEC_CLASSID, 4); 36d0c080abSJoseph Pusztay 379566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 389566063dSJacob Faibussowitsch PetscCall(DMSetOutputSequenceNumber(dm, step, ptime)); 39d0c080abSJoseph Pusztay 409566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(u)); 4148a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall((*ts->monitor[i])(ts, step, ptime, u, ts->monitorcontext[i])); 429566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(u)); 433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 44d0c080abSJoseph Pusztay } 45d0c080abSJoseph Pusztay 46d0c080abSJoseph Pusztay /*@C 47d0c080abSJoseph Pusztay TSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 48d0c080abSJoseph Pusztay 49c3339decSBarry Smith Collective 50d0c080abSJoseph Pusztay 51d0c080abSJoseph Pusztay Input Parameters: 52bcf0153eSBarry Smith + ts - `TS` object you wish to monitor 53d0c080abSJoseph Pusztay . name - the monitor type one is seeking 54d0c080abSJoseph Pusztay . help - message indicating what monitoring is done 55d0c080abSJoseph Pusztay . manual - manual page for the monitor 56d0c080abSJoseph Pusztay . monitor - the monitor function 57bcf0153eSBarry Smith - 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 58d0c080abSJoseph Pusztay 59d0c080abSJoseph Pusztay Level: developer 60d0c080abSJoseph Pusztay 61*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 62db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 63db781477SPatrick Sanan `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, 64db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 65c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 66db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 67db781477SPatrick Sanan `PetscOptionsFList()`, `PetscOptionsEList()` 68d0c080abSJoseph Pusztay @*/ 69d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSetFromOptions(TS ts, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(TS, PetscInt, PetscReal, Vec, PetscViewerAndFormat *), PetscErrorCode (*monitorsetup)(TS, PetscViewerAndFormat *)) 70d71ae5a4SJacob Faibussowitsch { 71d0c080abSJoseph Pusztay PetscViewer viewer; 72d0c080abSJoseph Pusztay PetscViewerFormat format; 73d0c080abSJoseph Pusztay PetscBool flg; 74d0c080abSJoseph Pusztay 75d0c080abSJoseph Pusztay PetscFunctionBegin; 769566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts), ((PetscObject)ts)->options, ((PetscObject)ts)->prefix, name, &viewer, &format, &flg)); 77d0c080abSJoseph Pusztay if (flg) { 78d0c080abSJoseph Pusztay PetscViewerAndFormat *vf; 799812b6beSJed Brown char interval_key[1024]; 809566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 819812b6beSJed Brown PetscCall(PetscSNPrintf(interval_key, sizeof interval_key, "%s_interval", name)); 829812b6beSJed Brown PetscCall(PetscOptionsGetInt(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, interval_key, &vf->view_interval, NULL)); 839566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)viewer)); 841baa6e33SBarry Smith if (monitorsetup) PetscCall((*monitorsetup)(ts, vf)); 859566063dSJacob Faibussowitsch PetscCall(TSMonitorSet(ts, (PetscErrorCode(*)(TS, PetscInt, PetscReal, Vec, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy)); 86d0c080abSJoseph Pusztay } 873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 88d0c080abSJoseph Pusztay } 89d0c080abSJoseph Pusztay 90d0c080abSJoseph Pusztay /*@C 91d0c080abSJoseph Pusztay TSMonitorSet - Sets an ADDITIONAL function that is to be used at every 92d0c080abSJoseph Pusztay timestep to display the iteration's progress. 93d0c080abSJoseph Pusztay 94c3339decSBarry Smith Logically Collective 95d0c080abSJoseph Pusztay 96d0c080abSJoseph Pusztay Input Parameters: 97bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` 98d0c080abSJoseph Pusztay . monitor - monitoring routine 99195e9b02SBarry Smith . mctx - [optional] user-defined context for private data for the monitor routine (use `NULL` if no context is desired) 100195e9b02SBarry Smith - monitordestroy - [optional] routine that frees monitor context (may be `NULL`) 101d0c080abSJoseph Pusztay 10220f4b53cSBarry Smith Calling sequence of `monitor`: 103d0c080abSJoseph Pusztay $ PetscErrorCode monitor(TS ts, PetscInt steps, PetscReal time, Vec u, void *mctx) 10420f4b53cSBarry Smith + ts - the `TS` context 105d0c080abSJoseph Pusztay . 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) 106d0c080abSJoseph Pusztay . time - current time 107d0c080abSJoseph Pusztay . u - current iterate 108d0c080abSJoseph Pusztay - mctx - [optional] monitoring context 109d0c080abSJoseph Pusztay 110bcf0153eSBarry Smith Level: intermediate 111bcf0153eSBarry Smith 112bcf0153eSBarry Smith Note: 113195e9b02SBarry Smith This routine adds an additional monitor to the list of monitors that already has been loaded. 114d0c080abSJoseph Pusztay 115bcf0153eSBarry Smith Fortran Note: 116bcf0153eSBarry Smith Only a single monitor function can be set for each `TS` object 117d0c080abSJoseph Pusztay 118*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorDefault()`, `TSMonitorCancel()`, `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`, `TSMonitorDrawSolution()`, 1193a61192cSBarry Smith `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`, 1203a61192cSBarry Smith `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()` 121d0c080abSJoseph Pusztay @*/ 122d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSet(TS ts, PetscErrorCode (*monitor)(TS, PetscInt, PetscReal, Vec, void *), void *mctx, PetscErrorCode (*mdestroy)(void **)) 123d71ae5a4SJacob Faibussowitsch { 124d0c080abSJoseph Pusztay PetscInt i; 125d0c080abSJoseph Pusztay PetscBool identical; 126d0c080abSJoseph Pusztay 127d0c080abSJoseph Pusztay PetscFunctionBegin; 128d0c080abSJoseph Pusztay PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 129d0c080abSJoseph Pusztay for (i = 0; i < ts->numbermonitors; i++) { 1309566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))monitor, mctx, mdestroy, (PetscErrorCode(*)(void))ts->monitor[i], ts->monitorcontext[i], ts->monitordestroy[i], &identical)); 1313ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 132d0c080abSJoseph Pusztay } 1333c633725SBarry Smith PetscCheck(ts->numbermonitors < MAXTSMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 134d0c080abSJoseph Pusztay ts->monitor[ts->numbermonitors] = monitor; 135d0c080abSJoseph Pusztay ts->monitordestroy[ts->numbermonitors] = mdestroy; 136d0c080abSJoseph Pusztay ts->monitorcontext[ts->numbermonitors++] = (void *)mctx; 1373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 138d0c080abSJoseph Pusztay } 139d0c080abSJoseph Pusztay 140d0c080abSJoseph Pusztay /*@C 141d0c080abSJoseph Pusztay TSMonitorCancel - Clears all the monitors that have been set on a time-step object. 142d0c080abSJoseph Pusztay 143c3339decSBarry Smith Logically Collective 144d0c080abSJoseph Pusztay 1452fe279fdSBarry Smith Input Parameter: 146bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()` 147d0c080abSJoseph Pusztay 148d0c080abSJoseph Pusztay Level: intermediate 149d0c080abSJoseph Pusztay 150bcf0153eSBarry Smith Note: 151bcf0153eSBarry Smith There is no way to remove a single, specific monitor. 152bcf0153eSBarry Smith 153*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorDefault()`, `TSMonitorSet()` 154d0c080abSJoseph Pusztay @*/ 155d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorCancel(TS ts) 156d71ae5a4SJacob Faibussowitsch { 157d0c080abSJoseph Pusztay PetscInt i; 158d0c080abSJoseph Pusztay 159d0c080abSJoseph Pusztay PetscFunctionBegin; 160d0c080abSJoseph Pusztay PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 161d0c080abSJoseph Pusztay for (i = 0; i < ts->numbermonitors; i++) { 16248a46eb9SPierre Jolivet if (ts->monitordestroy[i]) PetscCall((*ts->monitordestroy[i])(&ts->monitorcontext[i])); 163d0c080abSJoseph Pusztay } 164d0c080abSJoseph Pusztay ts->numbermonitors = 0; 1653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 166d0c080abSJoseph Pusztay } 167d0c080abSJoseph Pusztay 168d0c080abSJoseph Pusztay /*@C 169195e9b02SBarry Smith TSMonitorDefault - The default monitor, prints the timestep and time for each step 170d0c080abSJoseph Pusztay 171bcf0153eSBarry Smith Options Database Key: 1723a61192cSBarry Smith . -ts_monitor - monitors the time integration 1733a61192cSBarry Smith 174d0c080abSJoseph Pusztay Level: intermediate 175d0c080abSJoseph Pusztay 176bcf0153eSBarry Smith Notes: 177bcf0153eSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 178bcf0153eSBarry Smith to be used during the `TS` integration. 179bcf0153eSBarry Smith 180*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorSet()`, `TSDMSwarmMonitorMoments()`, `TSMonitorExtreme()`, `TSMonitorDrawSolution()`, 1813a61192cSBarry Smith `TSMonitorDrawSolutionPhase()`, `TSMonitorDrawSolutionFunction()`, `TSMonitorDrawError()`, `TSMonitorSolution()`, `TSMonitorSolutionVTK()`, 1823a61192cSBarry Smith `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorSPSwarmSolution()`, `TSMonitorError()`, `TSMonitorEnvelope()`, `TSDMSwarmMonitorMoments()` 183d0c080abSJoseph Pusztay @*/ 184d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDefault(TS ts, PetscInt step, PetscReal ptime, Vec v, PetscViewerAndFormat *vf) 185d71ae5a4SJacob Faibussowitsch { 186d0c080abSJoseph Pusztay PetscViewer viewer = vf->viewer; 187d0c080abSJoseph Pusztay PetscBool iascii, ibinary; 188d0c080abSJoseph Pusztay 189d0c080abSJoseph Pusztay PetscFunctionBegin; 190064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 5); 1919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 1929566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &ibinary)); 1939566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 194d0c080abSJoseph Pusztay if (iascii) { 1959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)ts)->tablevel)); 196d0c080abSJoseph Pusztay if (step == -1) { /* this indicates it is an interpolated solution */ 19763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Interpolated solution at time %g between steps %" PetscInt_FMT " and %" PetscInt_FMT "\n", (double)ptime, ts->steps - 1, ts->steps)); 198d0c080abSJoseph Pusztay } else { 19963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " TS dt %g time %g%s", step, (double)ts->time_step, (double)ptime, ts->steprollback ? " (r)\n" : "\n")); 200d0c080abSJoseph Pusztay } 2019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)ts)->tablevel)); 202d0c080abSJoseph Pusztay } else if (ibinary) { 203d0c080abSJoseph Pusztay PetscMPIInt rank; 2049566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank)); 205c5853193SPierre Jolivet if (rank == 0) { 206d0c080abSJoseph Pusztay PetscBool skipHeader; 207d0c080abSJoseph Pusztay PetscInt classid = REAL_FILE_CLASSID; 208d0c080abSJoseph Pusztay 2099566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 21048a46eb9SPierre Jolivet if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT)); 2119566063dSJacob Faibussowitsch PetscCall(PetscRealView(1, &ptime, viewer)); 212d0c080abSJoseph Pusztay } else { 2139566063dSJacob Faibussowitsch PetscCall(PetscRealView(0, &ptime, viewer)); 214d0c080abSJoseph Pusztay } 215d0c080abSJoseph Pusztay } 2169566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 2173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 218d0c080abSJoseph Pusztay } 219d0c080abSJoseph Pusztay 220d0c080abSJoseph Pusztay /*@C 221d0c080abSJoseph Pusztay TSMonitorExtreme - Prints the extreme values of the solution at each timestep 222d0c080abSJoseph Pusztay 223bcf0153eSBarry Smith Level: intermediate 224bcf0153eSBarry Smith 225195e9b02SBarry Smith Note: 2263a61192cSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 227195e9b02SBarry Smith to be used during the `TS` integration. 2283a61192cSBarry Smith 229*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()` 230d0c080abSJoseph Pusztay @*/ 231d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorExtreme(TS ts, PetscInt step, PetscReal ptime, Vec v, PetscViewerAndFormat *vf) 232d71ae5a4SJacob Faibussowitsch { 233d0c080abSJoseph Pusztay PetscViewer viewer = vf->viewer; 234d0c080abSJoseph Pusztay PetscBool iascii; 235d0c080abSJoseph Pusztay PetscReal max, min; 236d0c080abSJoseph Pusztay 237d0c080abSJoseph Pusztay PetscFunctionBegin; 238064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 5); 2399566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 2409566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, vf->format)); 241d0c080abSJoseph Pusztay if (iascii) { 2429566063dSJacob Faibussowitsch PetscCall(VecMax(v, NULL, &max)); 2439566063dSJacob Faibussowitsch PetscCall(VecMin(v, NULL, &min)); 2449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)ts)->tablevel)); 24563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " 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)); 2469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)ts)->tablevel)); 247d0c080abSJoseph Pusztay } 2489566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 2493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 250d0c080abSJoseph Pusztay } 251d0c080abSJoseph Pusztay 252d0c080abSJoseph Pusztay /*@C 253bcf0153eSBarry Smith TSMonitorLGCtxCreate - Creates a `TSMonitorLGCtx` context for use with 254bcf0153eSBarry Smith `TS` to monitor the solution process graphically in various ways 255d0c080abSJoseph Pusztay 256c3339decSBarry Smith Collective 257d0c080abSJoseph Pusztay 258d0c080abSJoseph Pusztay Input Parameters: 259195e9b02SBarry Smith + host - the X display to open, or `NULL` for the local machine 260d0c080abSJoseph Pusztay . label - the title to put in the title bar 261d0c080abSJoseph Pusztay . x, y - the screen coordinates of the upper left coordinate of the window 262d0c080abSJoseph Pusztay . m, n - the screen width and height in pixels 263d0c080abSJoseph Pusztay - howoften - if positive then determines the frequency of the plotting, if -1 then only at the final time 264d0c080abSJoseph Pusztay 265d0c080abSJoseph Pusztay Output Parameter: 266d0c080abSJoseph Pusztay . ctx - the context 267d0c080abSJoseph Pusztay 268bcf0153eSBarry Smith Options Database Keys: 269d0c080abSJoseph Pusztay + -ts_monitor_lg_timestep - automatically sets line graph monitor 270d0c080abSJoseph Pusztay + -ts_monitor_lg_timestep_log - automatically sets line graph monitor 271bcf0153eSBarry Smith . -ts_monitor_lg_solution - monitor the solution (or certain values of the solution by calling `TSMonitorLGSetDisplayVariables()` or `TSMonitorLGCtxSetDisplayVariables()`) 272d0c080abSJoseph Pusztay . -ts_monitor_lg_error - monitor the error 273bcf0153eSBarry Smith . -ts_monitor_lg_ksp_iterations - monitor the number of `KSP` iterations needed for each timestep 274bcf0153eSBarry Smith . -ts_monitor_lg_snes_iterations - monitor the number of `SNES` iterations needed for each timestep 275d0c080abSJoseph Pusztay - -lg_use_markers <true,false> - mark the data points (at each time step) on the plot; default is true 276d0c080abSJoseph Pusztay 277d0c080abSJoseph Pusztay Level: intermediate 278d0c080abSJoseph Pusztay 279bcf0153eSBarry Smith Notes: 280bcf0153eSBarry Smith Pass the context and `TSMonitorLGCtxDestroy()` to `TSMonitorSet()` to have the context destroyed when no longer needed. 281bcf0153eSBarry Smith 282bcf0153eSBarry Smith One can provide a function that transforms the solution before plotting it with `TSMonitorLGCtxSetTransform()` or `TSMonitorLGSetTransform()` 283bcf0153eSBarry Smith 284bcf0153eSBarry Smith Many of the functions that control the monitoring have two forms: TSMonitorLGSet/GetXXXX() and TSMonitorLGCtxSet/GetXXXX() the first take a `TS` object as the 285bcf0153eSBarry Smith 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 286bcf0153eSBarry Smith as the first argument. 287bcf0153eSBarry Smith 288bcf0153eSBarry Smith One can control the names displayed for each solution or error variable with `TSMonitorLGCtxSetVariableNames()` or `TSMonitorLGSetVariableNames()` 289bcf0153eSBarry Smith 290*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()`, `TSMonitorDefault()`, `VecView()`, 291db781477SPatrick Sanan `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`, 292db781477SPatrick Sanan `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`, 293db781477SPatrick Sanan `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`, 294db781477SPatrick Sanan `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()` 295d0c080abSJoseph Pusztay @*/ 296d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorLGCtx *ctx) 297d71ae5a4SJacob Faibussowitsch { 298d0c080abSJoseph Pusztay PetscDraw draw; 299d0c080abSJoseph Pusztay 300d0c080abSJoseph Pusztay PetscFunctionBegin; 3019566063dSJacob Faibussowitsch PetscCall(PetscNew(ctx)); 3029566063dSJacob Faibussowitsch PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw)); 3039566063dSJacob Faibussowitsch PetscCall(PetscDrawSetFromOptions(draw)); 3049566063dSJacob Faibussowitsch PetscCall(PetscDrawLGCreate(draw, 1, &(*ctx)->lg)); 3059566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg)); 3069566063dSJacob Faibussowitsch PetscCall(PetscDrawDestroy(&draw)); 307d0c080abSJoseph Pusztay (*ctx)->howoften = howoften; 3083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 309d0c080abSJoseph Pusztay } 310d0c080abSJoseph Pusztay 311d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGTimeStep(TS ts, PetscInt step, PetscReal ptime, Vec v, void *monctx) 312d71ae5a4SJacob Faibussowitsch { 313d0c080abSJoseph Pusztay TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx; 314d0c080abSJoseph Pusztay PetscReal x = ptime, y; 315d0c080abSJoseph Pusztay 316d0c080abSJoseph Pusztay PetscFunctionBegin; 3173ba16761SJacob Faibussowitsch if (step < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates an interpolated solution */ 318d0c080abSJoseph Pusztay if (!step) { 319d0c080abSJoseph Pusztay PetscDrawAxis axis; 320d0c080abSJoseph Pusztay const char *ylabel = ctx->semilogy ? "Log Time Step" : "Time Step"; 3219566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis)); 3229566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetLabels(axis, "Timestep as function of time", "Time", ylabel)); 3239566063dSJacob Faibussowitsch PetscCall(PetscDrawLGReset(ctx->lg)); 324d0c080abSJoseph Pusztay } 3259566063dSJacob Faibussowitsch PetscCall(TSGetTimeStep(ts, &y)); 326d0c080abSJoseph Pusztay if (ctx->semilogy) y = PetscLog10Real(y); 3279566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y)); 328d0c080abSJoseph Pusztay if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 3299566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(ctx->lg)); 3309566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(ctx->lg)); 331d0c080abSJoseph Pusztay } 3323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 333d0c080abSJoseph Pusztay } 334d0c080abSJoseph Pusztay 335d0c080abSJoseph Pusztay /*@C 336195e9b02SBarry Smith TSMonitorLGCtxDestroy - Destroys a line graph context that was created with `TSMonitorLGCtxCreate()`. 337d0c080abSJoseph Pusztay 338c3339decSBarry Smith Collective 339d0c080abSJoseph Pusztay 340d0c080abSJoseph Pusztay Input Parameter: 341d0c080abSJoseph Pusztay . ctx - the monitor context 342d0c080abSJoseph Pusztay 343d0c080abSJoseph Pusztay Level: intermediate 344d0c080abSJoseph Pusztay 345bcf0153eSBarry Smith Note: 346bcf0153eSBarry Smith Pass to `TSMonitorSet()` along with the context and `TSMonitorLGTimeStep()` 347bcf0153eSBarry Smith 348*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep();` 349d0c080abSJoseph Pusztay @*/ 350d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxDestroy(TSMonitorLGCtx *ctx) 351d71ae5a4SJacob Faibussowitsch { 352d0c080abSJoseph Pusztay PetscFunctionBegin; 35348a46eb9SPierre Jolivet if ((*ctx)->transformdestroy) PetscCall(((*ctx)->transformdestroy)((*ctx)->transformctx)); 3549566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDestroy(&(*ctx)->lg)); 3559566063dSJacob Faibussowitsch PetscCall(PetscStrArrayDestroy(&(*ctx)->names)); 3569566063dSJacob Faibussowitsch PetscCall(PetscStrArrayDestroy(&(*ctx)->displaynames)); 3579566063dSJacob Faibussowitsch PetscCall(PetscFree((*ctx)->displayvariables)); 3589566063dSJacob Faibussowitsch PetscCall(PetscFree((*ctx)->displayvalues)); 3599566063dSJacob Faibussowitsch PetscCall(PetscFree(*ctx)); 3603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 361d0c080abSJoseph Pusztay } 362d0c080abSJoseph Pusztay 363d7462660SMatthew Knepley /* Creates a TSMonitorSPCtx for use with DMSwarm particle visualizations */ 36460e16b1bSMatthew G. Knepley PetscErrorCode TSMonitorSPCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, PetscInt retain, PetscBool phase, PetscBool multispecies, TSMonitorSPCtx *ctx) 365d71ae5a4SJacob Faibussowitsch { 366d0c080abSJoseph Pusztay PetscDraw draw; 367d0c080abSJoseph Pusztay 368d0c080abSJoseph Pusztay PetscFunctionBegin; 3699566063dSJacob Faibussowitsch PetscCall(PetscNew(ctx)); 3709566063dSJacob Faibussowitsch PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw)); 3719566063dSJacob Faibussowitsch PetscCall(PetscDrawSetFromOptions(draw)); 3729566063dSJacob Faibussowitsch PetscCall(PetscDrawSPCreate(draw, 1, &(*ctx)->sp)); 3739566063dSJacob Faibussowitsch PetscCall(PetscDrawDestroy(&draw)); 374d0c080abSJoseph Pusztay (*ctx)->howoften = howoften; 375d7462660SMatthew Knepley (*ctx)->retain = retain; 376d7462660SMatthew Knepley (*ctx)->phase = phase; 37760e16b1bSMatthew G. Knepley (*ctx)->multispecies = multispecies; 3783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 379d0c080abSJoseph Pusztay } 380d0c080abSJoseph Pusztay 38160e16b1bSMatthew G. Knepley /* Destroys a TSMonitorSPCtx that was created with TSMonitorSPCtxCreate */ 382d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSPCtxDestroy(TSMonitorSPCtx *ctx) 383d71ae5a4SJacob Faibussowitsch { 384d0c080abSJoseph Pusztay PetscFunctionBegin; 385d0c080abSJoseph Pusztay 3869566063dSJacob Faibussowitsch PetscCall(PetscDrawSPDestroy(&(*ctx)->sp)); 3879566063dSJacob Faibussowitsch PetscCall(PetscFree(*ctx)); 38860e16b1bSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 38960e16b1bSMatthew G. Knepley } 390d0c080abSJoseph Pusztay 39160e16b1bSMatthew G. Knepley /* Creates a TSMonitorHGCtx for use with DMSwarm particle visualizations */ 39260e16b1bSMatthew G. Knepley PetscErrorCode TSMonitorHGCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, PetscInt Ns, PetscInt Nb, PetscBool velocity, TSMonitorHGCtx *ctx) 39360e16b1bSMatthew G. Knepley { 39460e16b1bSMatthew G. Knepley PetscDraw draw; 39560e16b1bSMatthew G. Knepley PetscInt s; 39660e16b1bSMatthew G. Knepley 39760e16b1bSMatthew G. Knepley PetscFunctionBegin; 39860e16b1bSMatthew G. Knepley PetscCall(PetscNew(ctx)); 39960e16b1bSMatthew G. Knepley PetscCall(PetscMalloc1(Ns, &(*ctx)->hg)); 40060e16b1bSMatthew G. Knepley for (s = 0; s < Ns; ++s) { 40160e16b1bSMatthew G. Knepley PetscCall(PetscDrawCreate(comm, host, label, x + s * m, y, m, n, &draw)); 40260e16b1bSMatthew G. Knepley PetscCall(PetscDrawSetFromOptions(draw)); 40360e16b1bSMatthew G. Knepley PetscCall(PetscDrawHGCreate(draw, Nb, &(*ctx)->hg[s])); 40460e16b1bSMatthew G. Knepley PetscCall(PetscDrawHGCalcStats((*ctx)->hg[s], PETSC_TRUE)); 40560e16b1bSMatthew G. Knepley PetscCall(PetscDrawDestroy(&draw)); 40660e16b1bSMatthew G. Knepley } 40760e16b1bSMatthew G. Knepley (*ctx)->howoften = howoften; 40860e16b1bSMatthew G. Knepley (*ctx)->Ns = Ns; 40960e16b1bSMatthew G. Knepley (*ctx)->velocity = velocity; 41060e16b1bSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 41160e16b1bSMatthew G. Knepley } 41260e16b1bSMatthew G. Knepley 41360e16b1bSMatthew G. Knepley /* Destroys a TSMonitorHGCtx that was created with TSMonitorHGCtxCreate */ 41460e16b1bSMatthew G. Knepley PetscErrorCode TSMonitorHGCtxDestroy(TSMonitorHGCtx *ctx) 41560e16b1bSMatthew G. Knepley { 41660e16b1bSMatthew G. Knepley PetscInt s; 41760e16b1bSMatthew G. Knepley 41860e16b1bSMatthew G. Knepley PetscFunctionBegin; 41960e16b1bSMatthew G. Knepley for (s = 0; s < (*ctx)->Ns; ++s) PetscCall(PetscDrawHGDestroy(&(*ctx)->hg[s])); 42060e16b1bSMatthew G. Knepley PetscCall(PetscFree((*ctx)->hg)); 42160e16b1bSMatthew G. Knepley PetscCall(PetscFree(*ctx)); 4223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 423d0c080abSJoseph Pusztay } 424d0c080abSJoseph Pusztay 425d0c080abSJoseph Pusztay /*@C 426bcf0153eSBarry Smith TSMonitorDrawSolution - Monitors progress of the `TS` solvers by calling 427bcf0153eSBarry Smith `VecView()` for the solution at each timestep 428d0c080abSJoseph Pusztay 429c3339decSBarry Smith Collective 430d0c080abSJoseph Pusztay 431d0c080abSJoseph Pusztay Input Parameters: 432bcf0153eSBarry Smith + ts - the `TS` context 433d0c080abSJoseph Pusztay . step - current time-step 434d0c080abSJoseph Pusztay . ptime - current time 435195e9b02SBarry Smith - dummy - either a viewer or `NULL` 436d0c080abSJoseph Pusztay 437bcf0153eSBarry Smith Options Database Keys: 438bcf0153eSBarry Smith + -ts_monitor_draw_solution - draw the solution at each time-step 439bcf0153eSBarry Smith - -ts_monitor_draw_solution_initial - show initial solution as well as current solution 440bcf0153eSBarry Smith 441bcf0153eSBarry Smith Level: intermediate 442d0c080abSJoseph Pusztay 443d0c080abSJoseph Pusztay Notes: 444195e9b02SBarry Smith The initial solution and current solution are not displayed with a common axis scaling so generally the option `-ts_monitor_draw_solution_initial` 445d0c080abSJoseph Pusztay will look bad 446d0c080abSJoseph Pusztay 447bcf0153eSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, as well as the context created with 448bcf0153eSBarry Smith `TSMonitorDrawCtxCreate()` and the function `TSMonitorDrawCtxDestroy()` to cause the monitor to be used during the `TS` integration. 4493a61192cSBarry Smith 450*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawCtxCreate()`, `TSMonitorDrawCtxDestroy()` 451d0c080abSJoseph Pusztay @*/ 452d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy) 453d71ae5a4SJacob Faibussowitsch { 454d0c080abSJoseph Pusztay TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 455d0c080abSJoseph Pusztay PetscDraw draw; 456d0c080abSJoseph Pusztay 457d0c080abSJoseph Pusztay PetscFunctionBegin; 458d0c080abSJoseph Pusztay if (!step && ictx->showinitial) { 45948a46eb9SPierre Jolivet if (!ictx->initialsolution) PetscCall(VecDuplicate(u, &ictx->initialsolution)); 4609566063dSJacob Faibussowitsch PetscCall(VecCopy(u, ictx->initialsolution)); 461d0c080abSJoseph Pusztay } 4623ba16761SJacob Faibussowitsch if (!(((ictx->howoften > 0) && (!(step % ictx->howoften))) || ((ictx->howoften == -1) && ts->reason))) PetscFunctionReturn(PETSC_SUCCESS); 463d0c080abSJoseph Pusztay 464d0c080abSJoseph Pusztay if (ictx->showinitial) { 465d0c080abSJoseph Pusztay PetscReal pause; 4669566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetPause(ictx->viewer, &pause)); 4679566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawSetPause(ictx->viewer, 0.0)); 4689566063dSJacob Faibussowitsch PetscCall(VecView(ictx->initialsolution, ictx->viewer)); 4699566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawSetPause(ictx->viewer, pause)); 4709566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawSetHold(ictx->viewer, PETSC_TRUE)); 471d0c080abSJoseph Pusztay } 4729566063dSJacob Faibussowitsch PetscCall(VecView(u, ictx->viewer)); 473d0c080abSJoseph Pusztay if (ictx->showtimestepandtime) { 474d0c080abSJoseph Pusztay PetscReal xl, yl, xr, yr, h; 475d0c080abSJoseph Pusztay char time[32]; 476d0c080abSJoseph Pusztay 4779566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(ictx->viewer, 0, &draw)); 4789566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(time, 32, "Timestep %d Time %g", (int)step, (double)ptime)); 4799566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 480d0c080abSJoseph Pusztay h = yl + .95 * (yr - yl); 4819566063dSJacob Faibussowitsch PetscCall(PetscDrawStringCentered(draw, .5 * (xl + xr), h, PETSC_DRAW_BLACK, time)); 4829566063dSJacob Faibussowitsch PetscCall(PetscDrawFlush(draw)); 483d0c080abSJoseph Pusztay } 484d0c080abSJoseph Pusztay 4851baa6e33SBarry Smith if (ictx->showinitial) PetscCall(PetscViewerDrawSetHold(ictx->viewer, PETSC_FALSE)); 4863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 487d0c080abSJoseph Pusztay } 488d0c080abSJoseph Pusztay 489d0c080abSJoseph Pusztay /*@C 490bcf0153eSBarry Smith TSMonitorDrawSolutionPhase - Monitors progress of the `TS` solvers by plotting the solution as a phase diagram 491d0c080abSJoseph Pusztay 492c3339decSBarry Smith Collective 493d0c080abSJoseph Pusztay 494d0c080abSJoseph Pusztay Input Parameters: 495bcf0153eSBarry Smith + ts - the `TS` context 496d0c080abSJoseph Pusztay . step - current time-step 497d0c080abSJoseph Pusztay . ptime - current time 498195e9b02SBarry Smith - dummy - either a viewer or `NULL` 499d0c080abSJoseph Pusztay 500d0c080abSJoseph Pusztay Level: intermediate 501d0c080abSJoseph Pusztay 502bcf0153eSBarry Smith Notes: 503bcf0153eSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 504bcf0153eSBarry Smith to be used during the `TS` integration. 505bcf0153eSBarry Smith 506*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()` 507d0c080abSJoseph Pusztay @*/ 508d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawSolutionPhase(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy) 509d71ae5a4SJacob Faibussowitsch { 510d0c080abSJoseph Pusztay TSMonitorDrawCtx ictx = (TSMonitorDrawCtx)dummy; 511d0c080abSJoseph Pusztay PetscDraw draw; 512d0c080abSJoseph Pusztay PetscDrawAxis axis; 513d0c080abSJoseph Pusztay PetscInt n; 514d0c080abSJoseph Pusztay PetscMPIInt size; 515d0c080abSJoseph Pusztay PetscReal U0, U1, xl, yl, xr, yr, h; 516d0c080abSJoseph Pusztay char time[32]; 517d0c080abSJoseph Pusztay const PetscScalar *U; 518d0c080abSJoseph Pusztay 519d0c080abSJoseph Pusztay PetscFunctionBegin; 5209566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ts), &size)); 5213c633725SBarry Smith PetscCheck(size == 1, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Only allowed for sequential runs"); 5229566063dSJacob Faibussowitsch PetscCall(VecGetSize(u, &n)); 5233c633725SBarry Smith PetscCheck(n == 2, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Only for ODEs with two unknowns"); 524d0c080abSJoseph Pusztay 5259566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(ictx->viewer, 0, &draw)); 5269566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawAxis(ictx->viewer, 0, &axis)); 5279566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisGetLimits(axis, &xl, &xr, &yl, &yr)); 528d0c080abSJoseph Pusztay if (!step) { 5299566063dSJacob Faibussowitsch PetscCall(PetscDrawClear(draw)); 5309566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisDraw(axis)); 531d0c080abSJoseph Pusztay } 532d0c080abSJoseph Pusztay 5339566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(u, &U)); 534d0c080abSJoseph Pusztay U0 = PetscRealPart(U[0]); 535d0c080abSJoseph Pusztay U1 = PetscRealPart(U[1]); 5369566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(u, &U)); 5373ba16761SJacob Faibussowitsch if ((U0 < xl) || (U1 < yl) || (U0 > xr) || (U1 > yr)) PetscFunctionReturn(PETSC_SUCCESS); 538d0c080abSJoseph Pusztay 539d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 5409566063dSJacob Faibussowitsch PetscCall(PetscDrawPoint(draw, U0, U1, PETSC_DRAW_BLACK)); 541d0c080abSJoseph Pusztay if (ictx->showtimestepandtime) { 5429566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 5439566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(time, 32, "Timestep %d Time %g", (int)step, (double)ptime)); 544d0c080abSJoseph Pusztay h = yl + .95 * (yr - yl); 5459566063dSJacob Faibussowitsch PetscCall(PetscDrawStringCentered(draw, .5 * (xl + xr), h, PETSC_DRAW_BLACK, time)); 546d0c080abSJoseph Pusztay } 547d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 5489566063dSJacob Faibussowitsch PetscCall(PetscDrawFlush(draw)); 5499566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 5509566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 5513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 552d0c080abSJoseph Pusztay } 553d0c080abSJoseph Pusztay 554d0c080abSJoseph Pusztay /*@C 555bcf0153eSBarry Smith TSMonitorDrawCtxDestroy - Destroys the monitor context for `TSMonitorDrawSolution()` 556d0c080abSJoseph Pusztay 557c3339decSBarry Smith Collective 558d0c080abSJoseph Pusztay 5592fe279fdSBarry Smith Input Parameter: 560d0c080abSJoseph Pusztay . ctx - the monitor context 561d0c080abSJoseph Pusztay 562d0c080abSJoseph Pusztay Level: intermediate 563d0c080abSJoseph Pusztay 564*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawSolution()`, `TSMonitorDrawError()`, `TSMonitorDrawCtx` 565d0c080abSJoseph Pusztay @*/ 566d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawCtxDestroy(TSMonitorDrawCtx *ictx) 567d71ae5a4SJacob Faibussowitsch { 568d0c080abSJoseph Pusztay PetscFunctionBegin; 5699566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&(*ictx)->viewer)); 5709566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(*ictx)->initialsolution)); 5719566063dSJacob Faibussowitsch PetscCall(PetscFree(*ictx)); 5723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 573d0c080abSJoseph Pusztay } 574d0c080abSJoseph Pusztay 575d0c080abSJoseph Pusztay /*@C 576bcf0153eSBarry Smith TSMonitorDrawCtxCreate - Creates the monitor context for `TSMonitorDrawCtx` 577d0c080abSJoseph Pusztay 578c3339decSBarry Smith Collective 579d0c080abSJoseph Pusztay 580d0c080abSJoseph Pusztay Input Parameter: 581d0c080abSJoseph Pusztay . ts - time-step context 582d0c080abSJoseph Pusztay 583d5b43468SJose E. Roman Output Parameter: 584d0c080abSJoseph Pusztay . ctx - the monitor context 585d0c080abSJoseph Pusztay 586bcf0153eSBarry Smith Options Database Keys: 587bcf0153eSBarry Smith + -ts_monitor_draw_solution - draw the solution at each time-step 588bcf0153eSBarry Smith - -ts_monitor_draw_solution_initial - show initial solution as well as current solution 589d0c080abSJoseph Pusztay 590d0c080abSJoseph Pusztay Level: intermediate 591d0c080abSJoseph Pusztay 592bcf0153eSBarry Smith Note: 593bcf0153eSBarry Smith The context created by this function, `PetscMonitorDrawSolution()`, and `TSMonitorDrawCtxDestroy()` should be passed together to `TSMonitorSet()`. 594bcf0153eSBarry Smith 595*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorDrawCtxDestroy()`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorDrawCtx`, `PetscMonitorDrawSolution()` 596d0c080abSJoseph Pusztay @*/ 597d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawCtxCreate(MPI_Comm comm, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorDrawCtx *ctx) 598d71ae5a4SJacob Faibussowitsch { 599d0c080abSJoseph Pusztay PetscFunctionBegin; 6009566063dSJacob Faibussowitsch PetscCall(PetscNew(ctx)); 6019566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(comm, host, label, x, y, m, n, &(*ctx)->viewer)); 6029566063dSJacob Faibussowitsch PetscCall(PetscViewerSetFromOptions((*ctx)->viewer)); 603d0c080abSJoseph Pusztay 604d0c080abSJoseph Pusztay (*ctx)->howoften = howoften; 605d0c080abSJoseph Pusztay (*ctx)->showinitial = PETSC_FALSE; 6069566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-ts_monitor_draw_solution_initial", &(*ctx)->showinitial, NULL)); 607d0c080abSJoseph Pusztay 608d0c080abSJoseph Pusztay (*ctx)->showtimestepandtime = PETSC_FALSE; 6099566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-ts_monitor_draw_solution_show_time", &(*ctx)->showtimestepandtime, NULL)); 6103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 611d0c080abSJoseph Pusztay } 612d0c080abSJoseph Pusztay 613d0c080abSJoseph Pusztay /*@C 614bcf0153eSBarry Smith TSMonitorDrawSolutionFunction - Monitors progress of the `TS` solvers by calling 615bcf0153eSBarry Smith `VecView()` for the solution provided by `TSSetSolutionFunction()` at each timestep 616d0c080abSJoseph Pusztay 617c3339decSBarry Smith Collective 618d0c080abSJoseph Pusztay 619d0c080abSJoseph Pusztay Input Parameters: 620bcf0153eSBarry Smith + ts - the `TS` context 621d0c080abSJoseph Pusztay . step - current time-step 622d0c080abSJoseph Pusztay . ptime - current time 623195e9b02SBarry Smith - dummy - either a viewer or `NULL` 624d0c080abSJoseph Pusztay 625bcf0153eSBarry Smith Options Database Key: 626bcf0153eSBarry Smith . -ts_monitor_draw_solution_function - Monitor error graphically, requires user to have provided `TSSetSolutionFunction()` 6273a61192cSBarry Smith 628d0c080abSJoseph Pusztay Level: intermediate 629d0c080abSJoseph Pusztay 630bcf0153eSBarry Smith Note: 631bcf0153eSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 632bcf0153eSBarry Smith to be used during the `TS` integration. 633bcf0153eSBarry Smith 634*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()` 635d0c080abSJoseph Pusztay @*/ 636d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawSolutionFunction(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy) 637d71ae5a4SJacob Faibussowitsch { 638d0c080abSJoseph Pusztay TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 639d0c080abSJoseph Pusztay PetscViewer viewer = ctx->viewer; 640d0c080abSJoseph Pusztay Vec work; 641d0c080abSJoseph Pusztay 642d0c080abSJoseph Pusztay PetscFunctionBegin; 6433ba16761SJacob Faibussowitsch if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(PETSC_SUCCESS); 6449566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &work)); 6459566063dSJacob Faibussowitsch PetscCall(TSComputeSolutionFunction(ts, ptime, work)); 6469566063dSJacob Faibussowitsch PetscCall(VecView(work, viewer)); 6479566063dSJacob Faibussowitsch PetscCall(VecDestroy(&work)); 6483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 649d0c080abSJoseph Pusztay } 650d0c080abSJoseph Pusztay 651d0c080abSJoseph Pusztay /*@C 652bcf0153eSBarry Smith TSMonitorDrawError - Monitors progress of the `TS` solvers by calling 653bcf0153eSBarry Smith `VecView()` for the error at each timestep 654d0c080abSJoseph Pusztay 655c3339decSBarry Smith Collective 656d0c080abSJoseph Pusztay 657d0c080abSJoseph Pusztay Input Parameters: 658bcf0153eSBarry Smith + ts - the `TS` context 659d0c080abSJoseph Pusztay . step - current time-step 660d0c080abSJoseph Pusztay . ptime - current time 661195e9b02SBarry Smith - dummy - either a viewer or `NULL` 662d0c080abSJoseph Pusztay 663bcf0153eSBarry Smith Options Database Key: 664bcf0153eSBarry Smith . -ts_monitor_draw_error - Monitor error graphically, requires user to have provided `TSSetSolutionFunction()` 6653a61192cSBarry Smith 666d0c080abSJoseph Pusztay Level: intermediate 667d0c080abSJoseph Pusztay 668bcf0153eSBarry Smith Notes: 669bcf0153eSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 670bcf0153eSBarry Smith to be used during the `TS` integration. 671bcf0153eSBarry Smith 672*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()` 673d0c080abSJoseph Pusztay @*/ 674d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorDrawError(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy) 675d71ae5a4SJacob Faibussowitsch { 676d0c080abSJoseph Pusztay TSMonitorDrawCtx ctx = (TSMonitorDrawCtx)dummy; 677d0c080abSJoseph Pusztay PetscViewer viewer = ctx->viewer; 678d0c080abSJoseph Pusztay Vec work; 679d0c080abSJoseph Pusztay 680d0c080abSJoseph Pusztay PetscFunctionBegin; 6813ba16761SJacob Faibussowitsch if (!(((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason))) PetscFunctionReturn(PETSC_SUCCESS); 6829566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &work)); 6839566063dSJacob Faibussowitsch PetscCall(TSComputeSolutionFunction(ts, ptime, work)); 6849566063dSJacob Faibussowitsch PetscCall(VecAXPY(work, -1.0, u)); 6859566063dSJacob Faibussowitsch PetscCall(VecView(work, viewer)); 6869566063dSJacob Faibussowitsch PetscCall(VecDestroy(&work)); 6873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 688d0c080abSJoseph Pusztay } 689d0c080abSJoseph Pusztay 690d0c080abSJoseph Pusztay /*@C 691195e9b02SBarry Smith 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 692d0c080abSJoseph Pusztay 693c3339decSBarry Smith Collective 694d0c080abSJoseph Pusztay 695d0c080abSJoseph Pusztay Input Parameters: 696bcf0153eSBarry Smith + ts - the `TS` context 697d0c080abSJoseph Pusztay . step - current time-step 698d0c080abSJoseph Pusztay . ptime - current time 699d0c080abSJoseph Pusztay . u - current state 700d0c080abSJoseph Pusztay - vf - viewer and its format 701d0c080abSJoseph Pusztay 702d0c080abSJoseph Pusztay Level: intermediate 703d0c080abSJoseph Pusztay 704bcf0153eSBarry Smith Notes: 705bcf0153eSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 706bcf0153eSBarry Smith to be used during the `TS` integration. 707bcf0153eSBarry Smith 708*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()` 709d0c080abSJoseph Pusztay @*/ 710d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, PetscViewerAndFormat *vf) 711d71ae5a4SJacob Faibussowitsch { 712d0c080abSJoseph Pusztay PetscFunctionBegin; 7133ba16761SJacob Faibussowitsch if (vf->view_interval > 0 && !ts->reason && step % vf->view_interval != 0) PetscFunctionReturn(PETSC_SUCCESS); 7149566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vf->viewer, vf->format)); 7159566063dSJacob Faibussowitsch PetscCall(VecView(u, vf->viewer)); 7169566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vf->viewer)); 7173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 718d0c080abSJoseph Pusztay } 719d0c080abSJoseph Pusztay 720d0c080abSJoseph Pusztay /*@C 721bcf0153eSBarry Smith TSMonitorSolutionVTK - Monitors progress of the `TS` solvers by `VecView()` for the solution at each timestep. 722d0c080abSJoseph Pusztay 723c3339decSBarry Smith Collective 724d0c080abSJoseph Pusztay 725d0c080abSJoseph Pusztay Input Parameters: 726bcf0153eSBarry Smith + ts - the `TS` context 727d0c080abSJoseph Pusztay . step - current time-step 728d0c080abSJoseph Pusztay . ptime - current time 729d0c080abSJoseph Pusztay . u - current state 73063a3b9bcSJacob Faibussowitsch - filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ") 731d0c080abSJoseph Pusztay 732d0c080abSJoseph Pusztay Level: intermediate 733d0c080abSJoseph Pusztay 734d0c080abSJoseph Pusztay Notes: 735d0c080abSJoseph Pusztay 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. 736d0c080abSJoseph Pusztay These are named according to the file name template. 737d0c080abSJoseph Pusztay 7383a61192cSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 739bcf0153eSBarry Smith to be used during the `TS` integration. 740d0c080abSJoseph Pusztay 741*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()` 742d0c080abSJoseph Pusztay @*/ 743d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSolutionVTK(TS ts, PetscInt step, PetscReal ptime, Vec u, void *filenametemplate) 744d71ae5a4SJacob Faibussowitsch { 745d0c080abSJoseph Pusztay char filename[PETSC_MAX_PATH_LEN]; 746d0c080abSJoseph Pusztay PetscViewer viewer; 747d0c080abSJoseph Pusztay 748d0c080abSJoseph Pusztay PetscFunctionBegin; 7493ba16761SJacob Faibussowitsch if (step < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */ 7509566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(filename, sizeof(filename), (const char *)filenametemplate, step)); 7519566063dSJacob Faibussowitsch PetscCall(PetscViewerVTKOpen(PetscObjectComm((PetscObject)ts), filename, FILE_MODE_WRITE, &viewer)); 7529566063dSJacob Faibussowitsch PetscCall(VecView(u, viewer)); 7539566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 7543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 755d0c080abSJoseph Pusztay } 756d0c080abSJoseph Pusztay 757d0c080abSJoseph Pusztay /*@C 758bcf0153eSBarry Smith TSMonitorSolutionVTKDestroy - Destroy filename template string created for use with `TSMonitorSolutionVTK()` 759d0c080abSJoseph Pusztay 760bcf0153eSBarry Smith Not Collective 761d0c080abSJoseph Pusztay 7622fe279fdSBarry Smith Input Parameter: 76363a3b9bcSJacob Faibussowitsch . filenametemplate - string containing a format specifier for the integer time step (e.g. %03" PetscInt_FMT ") 764d0c080abSJoseph Pusztay 765d0c080abSJoseph Pusztay Level: intermediate 766d0c080abSJoseph Pusztay 767d0c080abSJoseph Pusztay Note: 768bcf0153eSBarry Smith This function is normally passed to `TSMonitorSet()` along with `TSMonitorSolutionVTK()`. 769d0c080abSJoseph Pusztay 770*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorSet()`, `TSMonitorSolutionVTK()` 771d0c080abSJoseph Pusztay @*/ 772d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSolutionVTKDestroy(void *filenametemplate) 773d71ae5a4SJacob Faibussowitsch { 774d0c080abSJoseph Pusztay PetscFunctionBegin; 7759566063dSJacob Faibussowitsch PetscCall(PetscFree(*(char **)filenametemplate)); 7763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 777d0c080abSJoseph Pusztay } 778d0c080abSJoseph Pusztay 779d0c080abSJoseph Pusztay /*@C 780bcf0153eSBarry Smith TSMonitorLGSolution - Monitors progress of the `TS` solvers by plotting each component of the solution vector 781d0c080abSJoseph Pusztay in a time based line graph 782d0c080abSJoseph Pusztay 783c3339decSBarry Smith Collective 784d0c080abSJoseph Pusztay 785d0c080abSJoseph Pusztay Input Parameters: 786bcf0153eSBarry Smith + ts - the `TS` context 787d0c080abSJoseph Pusztay . step - current time-step 788d0c080abSJoseph Pusztay . ptime - current time 789d0c080abSJoseph Pusztay . u - current solution 790bcf0153eSBarry Smith - dctx - the `TSMonitorLGCtx` object that contains all the options for the monitoring, this is created with `TSMonitorLGCtxCreate()` 791d0c080abSJoseph Pusztay 792bcf0153eSBarry Smith Options Database Key: 79367b8a455SSatish Balay . -ts_monitor_lg_solution_variables - enable monitor of lg solution variables 794d0c080abSJoseph Pusztay 795d0c080abSJoseph Pusztay Level: intermediate 796d0c080abSJoseph Pusztay 797d0c080abSJoseph Pusztay Notes: 798d0c080abSJoseph Pusztay Each process in a parallel run displays its component solutions in a separate window 799d0c080abSJoseph Pusztay 8003a61192cSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 801bcf0153eSBarry Smith to be used during the `TS` integration. 8023a61192cSBarry Smith 803*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGCtxCreate()`, `TSMonitorLGCtxSetVariableNames()`, `TSMonitorLGCtxGetVariableNames()`, 804db781477SPatrick Sanan `TSMonitorLGSetVariableNames()`, `TSMonitorLGGetVariableNames()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetDisplayVariables()`, 805db781477SPatrick Sanan `TSMonitorLGCtxSetTransform()`, `TSMonitorLGSetTransform()`, `TSMonitorLGError()`, `TSMonitorLGSNESIterations()`, `TSMonitorLGKSPIterations()`, 806db781477SPatrick Sanan `TSMonitorEnvelopeCtxCreate()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxDestroy()`, `TSMonitorEnvelop()` 807d0c080abSJoseph Pusztay @*/ 808d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx) 809d71ae5a4SJacob Faibussowitsch { 810d0c080abSJoseph Pusztay TSMonitorLGCtx ctx = (TSMonitorLGCtx)dctx; 811d0c080abSJoseph Pusztay const PetscScalar *yy; 812d0c080abSJoseph Pusztay Vec v; 813d0c080abSJoseph Pusztay 814d0c080abSJoseph Pusztay PetscFunctionBegin; 8153ba16761SJacob Faibussowitsch if (step < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */ 816d0c080abSJoseph Pusztay if (!step) { 817d0c080abSJoseph Pusztay PetscDrawAxis axis; 818d0c080abSJoseph Pusztay PetscInt dim; 8199566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis)); 8209566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetLabels(axis, "Solution as function of time", "Time", "Solution")); 821d0c080abSJoseph Pusztay if (!ctx->names) { 822d0c080abSJoseph Pusztay PetscBool flg; 823d0c080abSJoseph Pusztay /* user provides names of variables to plot but no names has been set so assume names are integer values */ 8249566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_monitor_lg_solution_variables", &flg)); 825d0c080abSJoseph Pusztay if (flg) { 826d0c080abSJoseph Pusztay PetscInt i, n; 827d0c080abSJoseph Pusztay char **names; 8289566063dSJacob Faibussowitsch PetscCall(VecGetSize(u, &n)); 8299566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n + 1, &names)); 830d0c080abSJoseph Pusztay for (i = 0; i < n; i++) { 8319566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(5, &names[i])); 83263a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(names[i], 5, "%" PetscInt_FMT, i)); 833d0c080abSJoseph Pusztay } 834d0c080abSJoseph Pusztay names[n] = NULL; 835d0c080abSJoseph Pusztay ctx->names = names; 836d0c080abSJoseph Pusztay } 837d0c080abSJoseph Pusztay } 838d0c080abSJoseph Pusztay if (ctx->names && !ctx->displaynames) { 839d0c080abSJoseph Pusztay char **displaynames; 840d0c080abSJoseph Pusztay PetscBool flg; 8419566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(u, &dim)); 8429566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(dim + 1, &displaynames)); 8439566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetStringArray(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_monitor_lg_solution_variables", displaynames, &dim, &flg)); 8441baa6e33SBarry Smith if (flg) PetscCall(TSMonitorLGCtxSetDisplayVariables(ctx, (const char *const *)displaynames)); 8459566063dSJacob Faibussowitsch PetscCall(PetscStrArrayDestroy(&displaynames)); 846d0c080abSJoseph Pusztay } 847d0c080abSJoseph Pusztay if (ctx->displaynames) { 8489566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSetDimension(ctx->lg, ctx->ndisplayvariables)); 8499566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSetLegend(ctx->lg, (const char *const *)ctx->displaynames)); 850d0c080abSJoseph Pusztay } else if (ctx->names) { 8519566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(u, &dim)); 8529566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSetDimension(ctx->lg, dim)); 8539566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSetLegend(ctx->lg, (const char *const *)ctx->names)); 854d0c080abSJoseph Pusztay } else { 8559566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(u, &dim)); 8569566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSetDimension(ctx->lg, dim)); 857d0c080abSJoseph Pusztay } 8589566063dSJacob Faibussowitsch PetscCall(PetscDrawLGReset(ctx->lg)); 859d0c080abSJoseph Pusztay } 860d0c080abSJoseph Pusztay 861d0c080abSJoseph Pusztay if (!ctx->transform) v = u; 8629566063dSJacob Faibussowitsch else PetscCall((*ctx->transform)(ctx->transformctx, u, &v)); 8639566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(v, &yy)); 864d0c080abSJoseph Pusztay if (ctx->displaynames) { 865d0c080abSJoseph Pusztay PetscInt i; 8669371c9d4SSatish Balay for (i = 0; i < ctx->ndisplayvariables; i++) ctx->displayvalues[i] = PetscRealPart(yy[ctx->displayvariables[i]]); 8679566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, ctx->displayvalues)); 868d0c080abSJoseph Pusztay } else { 869d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX) 870d0c080abSJoseph Pusztay PetscInt i, n; 871d0c080abSJoseph Pusztay PetscReal *yreal; 8729566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &n)); 8739566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &yreal)); 874d0c080abSJoseph Pusztay for (i = 0; i < n; i++) yreal[i] = PetscRealPart(yy[i]); 8759566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yreal)); 8769566063dSJacob Faibussowitsch PetscCall(PetscFree(yreal)); 877d0c080abSJoseph Pusztay #else 8789566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yy)); 879d0c080abSJoseph Pusztay #endif 880d0c080abSJoseph Pusztay } 8819566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(v, &yy)); 8829566063dSJacob Faibussowitsch if (ctx->transform) PetscCall(VecDestroy(&v)); 883d0c080abSJoseph Pusztay 884d0c080abSJoseph Pusztay if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 8859566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(ctx->lg)); 8869566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(ctx->lg)); 887d0c080abSJoseph Pusztay } 8883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 889d0c080abSJoseph Pusztay } 890d0c080abSJoseph Pusztay 891d0c080abSJoseph Pusztay /*@C 892d0c080abSJoseph Pusztay TSMonitorLGSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 893d0c080abSJoseph Pusztay 894c3339decSBarry Smith Collective 895d0c080abSJoseph Pusztay 896d0c080abSJoseph Pusztay Input Parameters: 897bcf0153eSBarry Smith + ts - the `TS` context 898195e9b02SBarry Smith - names - the names of the components, final string must be `NULL` 899d0c080abSJoseph Pusztay 900d0c080abSJoseph Pusztay Level: intermediate 901d0c080abSJoseph Pusztay 902d0c080abSJoseph Pusztay Notes: 903bcf0153eSBarry Smith If the `TS` object does not have a `TSMonitorLGCtx` associated with it then this function is ignored 904d0c080abSJoseph Pusztay 905*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGCtxSetVariableNames()` 906d0c080abSJoseph Pusztay @*/ 907d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSetVariableNames(TS ts, const char *const *names) 908d71ae5a4SJacob Faibussowitsch { 909d0c080abSJoseph Pusztay PetscInt i; 910d0c080abSJoseph Pusztay 911d0c080abSJoseph Pusztay PetscFunctionBegin; 912d0c080abSJoseph Pusztay for (i = 0; i < ts->numbermonitors; i++) { 913d0c080abSJoseph Pusztay if (ts->monitor[i] == TSMonitorLGSolution) { 9149566063dSJacob Faibussowitsch PetscCall(TSMonitorLGCtxSetVariableNames((TSMonitorLGCtx)ts->monitorcontext[i], names)); 915d0c080abSJoseph Pusztay break; 916d0c080abSJoseph Pusztay } 917d0c080abSJoseph Pusztay } 9183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 919d0c080abSJoseph Pusztay } 920d0c080abSJoseph Pusztay 921d0c080abSJoseph Pusztay /*@C 922d0c080abSJoseph Pusztay TSMonitorLGCtxSetVariableNames - Sets the name of each component in the solution vector so that it may be displayed in the plot 923d0c080abSJoseph Pusztay 924c3339decSBarry Smith Collective 925d0c080abSJoseph Pusztay 926d0c080abSJoseph Pusztay Input Parameters: 927bcf0153eSBarry Smith + ts - the `TS` context 928195e9b02SBarry Smith - names - the names of the components, final string must be `NULL` 929d0c080abSJoseph Pusztay 930d0c080abSJoseph Pusztay Level: intermediate 931d0c080abSJoseph Pusztay 932*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()`, `TSMonitorLGSetVariableNames()` 933d0c080abSJoseph Pusztay @*/ 934d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxSetVariableNames(TSMonitorLGCtx ctx, const char *const *names) 935d71ae5a4SJacob Faibussowitsch { 936d0c080abSJoseph Pusztay PetscFunctionBegin; 9379566063dSJacob Faibussowitsch PetscCall(PetscStrArrayDestroy(&ctx->names)); 9389566063dSJacob Faibussowitsch PetscCall(PetscStrArrayallocpy(names, &ctx->names)); 9393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 940d0c080abSJoseph Pusztay } 941d0c080abSJoseph Pusztay 942d0c080abSJoseph Pusztay /*@C 943d0c080abSJoseph Pusztay TSMonitorLGGetVariableNames - Gets the name of each component in the solution vector so that it may be displayed in the plot 944d0c080abSJoseph Pusztay 945c3339decSBarry Smith Collective 946d0c080abSJoseph Pusztay 947d0c080abSJoseph Pusztay Input Parameter: 948bcf0153eSBarry Smith . ts - the `TS` context 949d0c080abSJoseph Pusztay 950d0c080abSJoseph Pusztay Output Parameter: 951195e9b02SBarry Smith . names - the names of the components, final string must be `NULL` 952d0c080abSJoseph Pusztay 953d0c080abSJoseph Pusztay Level: intermediate 954d0c080abSJoseph Pusztay 955bcf0153eSBarry Smith Note: 956bcf0153eSBarry Smith If the `TS` object does not have a `TSMonitorLGCtx` associated with it then this function is ignored 957d0c080abSJoseph Pusztay 958*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()` 959d0c080abSJoseph Pusztay @*/ 960d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGGetVariableNames(TS ts, const char *const **names) 961d71ae5a4SJacob Faibussowitsch { 962d0c080abSJoseph Pusztay PetscInt i; 963d0c080abSJoseph Pusztay 964d0c080abSJoseph Pusztay PetscFunctionBegin; 965d0c080abSJoseph Pusztay *names = NULL; 966d0c080abSJoseph Pusztay for (i = 0; i < ts->numbermonitors; i++) { 967d0c080abSJoseph Pusztay if (ts->monitor[i] == TSMonitorLGSolution) { 968d0c080abSJoseph Pusztay TSMonitorLGCtx ctx = (TSMonitorLGCtx)ts->monitorcontext[i]; 969d0c080abSJoseph Pusztay *names = (const char *const *)ctx->names; 970d0c080abSJoseph Pusztay break; 971d0c080abSJoseph Pusztay } 972d0c080abSJoseph Pusztay } 9733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 974d0c080abSJoseph Pusztay } 975d0c080abSJoseph Pusztay 976d0c080abSJoseph Pusztay /*@C 977d0c080abSJoseph Pusztay TSMonitorLGCtxSetDisplayVariables - Sets the variables that are to be display in the monitor 978d0c080abSJoseph Pusztay 979c3339decSBarry Smith Collective 980d0c080abSJoseph Pusztay 981d0c080abSJoseph Pusztay Input Parameters: 982bcf0153eSBarry Smith + ctx - the `TSMonitorLG` context 983195e9b02SBarry Smith - displaynames - the names of the components, final string must be `NULL` 984d0c080abSJoseph Pusztay 985d0c080abSJoseph Pusztay Level: intermediate 986d0c080abSJoseph Pusztay 987*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()` 988d0c080abSJoseph Pusztay @*/ 989d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxSetDisplayVariables(TSMonitorLGCtx ctx, const char *const *displaynames) 990d71ae5a4SJacob Faibussowitsch { 991d0c080abSJoseph Pusztay PetscInt j = 0, k; 992d0c080abSJoseph Pusztay 993d0c080abSJoseph Pusztay PetscFunctionBegin; 9943ba16761SJacob Faibussowitsch if (!ctx->names) PetscFunctionReturn(PETSC_SUCCESS); 9959566063dSJacob Faibussowitsch PetscCall(PetscStrArrayDestroy(&ctx->displaynames)); 9969566063dSJacob Faibussowitsch PetscCall(PetscStrArrayallocpy(displaynames, &ctx->displaynames)); 997d0c080abSJoseph Pusztay while (displaynames[j]) j++; 998d0c080abSJoseph Pusztay ctx->ndisplayvariables = j; 9999566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ctx->ndisplayvariables, &ctx->displayvariables)); 10009566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ctx->ndisplayvariables, &ctx->displayvalues)); 1001d0c080abSJoseph Pusztay j = 0; 1002d0c080abSJoseph Pusztay while (displaynames[j]) { 1003d0c080abSJoseph Pusztay k = 0; 1004d0c080abSJoseph Pusztay while (ctx->names[k]) { 1005d0c080abSJoseph Pusztay PetscBool flg; 10069566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(displaynames[j], ctx->names[k], &flg)); 1007d0c080abSJoseph Pusztay if (flg) { 1008d0c080abSJoseph Pusztay ctx->displayvariables[j] = k; 1009d0c080abSJoseph Pusztay break; 1010d0c080abSJoseph Pusztay } 1011d0c080abSJoseph Pusztay k++; 1012d0c080abSJoseph Pusztay } 1013d0c080abSJoseph Pusztay j++; 1014d0c080abSJoseph Pusztay } 10153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1016d0c080abSJoseph Pusztay } 1017d0c080abSJoseph Pusztay 1018d0c080abSJoseph Pusztay /*@C 1019d0c080abSJoseph Pusztay TSMonitorLGSetDisplayVariables - Sets the variables that are to be display in the monitor 1020d0c080abSJoseph Pusztay 1021c3339decSBarry Smith Collective 1022d0c080abSJoseph Pusztay 1023d0c080abSJoseph Pusztay Input Parameters: 1024bcf0153eSBarry Smith + ts - the `TS` context 1025195e9b02SBarry Smith - displaynames - the names of the components, final string must be `NULL` 1026d0c080abSJoseph Pusztay 1027d0c080abSJoseph Pusztay Level: intermediate 1028d0c080abSJoseph Pusztay 1029bcf0153eSBarry Smith Note: 1030bcf0153eSBarry Smith If the `TS` object does not have a `TSMonitorLGCtx` associated with it then this function is ignored 1031bcf0153eSBarry Smith 1032*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()` 1033d0c080abSJoseph Pusztay @*/ 1034d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSetDisplayVariables(TS ts, const char *const *displaynames) 1035d71ae5a4SJacob Faibussowitsch { 1036d0c080abSJoseph Pusztay PetscInt i; 1037d0c080abSJoseph Pusztay 1038d0c080abSJoseph Pusztay PetscFunctionBegin; 1039d0c080abSJoseph Pusztay for (i = 0; i < ts->numbermonitors; i++) { 1040d0c080abSJoseph Pusztay if (ts->monitor[i] == TSMonitorLGSolution) { 10419566063dSJacob Faibussowitsch PetscCall(TSMonitorLGCtxSetDisplayVariables((TSMonitorLGCtx)ts->monitorcontext[i], displaynames)); 1042d0c080abSJoseph Pusztay break; 1043d0c080abSJoseph Pusztay } 1044d0c080abSJoseph Pusztay } 10453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1046d0c080abSJoseph Pusztay } 1047d0c080abSJoseph Pusztay 1048d0c080abSJoseph Pusztay /*@C 1049d0c080abSJoseph Pusztay TSMonitorLGSetTransform - Solution vector will be transformed by provided function before being displayed 1050d0c080abSJoseph Pusztay 1051c3339decSBarry Smith Collective 1052d0c080abSJoseph Pusztay 1053d0c080abSJoseph Pusztay Input Parameters: 1054bcf0153eSBarry Smith + ts - the `TS` context 1055d0c080abSJoseph Pusztay . transform - the transform function 1056d0c080abSJoseph Pusztay . destroy - function to destroy the optional context 1057d0c080abSJoseph Pusztay - ctx - optional context used by transform function 1058d0c080abSJoseph Pusztay 1059d0c080abSJoseph Pusztay Level: intermediate 1060d0c080abSJoseph Pusztay 1061bcf0153eSBarry Smith Note: 1062bcf0153eSBarry Smith If the `TS` object does not have a `TSMonitorLGCtx` associated with it then this function is ignored 1063bcf0153eSBarry Smith 1064*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGCtxSetTransform()` 1065d0c080abSJoseph Pusztay @*/ 1066d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSetTransform(TS ts, PetscErrorCode (*transform)(void *, Vec, Vec *), PetscErrorCode (*destroy)(void *), void *tctx) 1067d71ae5a4SJacob Faibussowitsch { 1068d0c080abSJoseph Pusztay PetscInt i; 1069d0c080abSJoseph Pusztay 1070d0c080abSJoseph Pusztay PetscFunctionBegin; 1071d0c080abSJoseph Pusztay for (i = 0; i < ts->numbermonitors; i++) { 107248a46eb9SPierre Jolivet if (ts->monitor[i] == TSMonitorLGSolution) PetscCall(TSMonitorLGCtxSetTransform((TSMonitorLGCtx)ts->monitorcontext[i], transform, destroy, tctx)); 1073d0c080abSJoseph Pusztay } 10743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1075d0c080abSJoseph Pusztay } 1076d0c080abSJoseph Pusztay 1077d0c080abSJoseph Pusztay /*@C 1078d0c080abSJoseph Pusztay TSMonitorLGCtxSetTransform - Solution vector will be transformed by provided function before being displayed 1079d0c080abSJoseph Pusztay 1080c3339decSBarry Smith Collective 1081d0c080abSJoseph Pusztay 1082d0c080abSJoseph Pusztay Input Parameters: 1083bcf0153eSBarry Smith + ts - the `TS` context 1084d0c080abSJoseph Pusztay . transform - the transform function 1085d0c080abSJoseph Pusztay . destroy - function to destroy the optional context 1086d0c080abSJoseph Pusztay - ctx - optional context used by transform function 1087d0c080abSJoseph Pusztay 1088d0c080abSJoseph Pusztay Level: intermediate 1089d0c080abSJoseph Pusztay 1090*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetVariableNames()`, `TSMonitorLGSetTransform()` 1091d0c080abSJoseph Pusztay @*/ 1092d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGCtxSetTransform(TSMonitorLGCtx ctx, PetscErrorCode (*transform)(void *, Vec, Vec *), PetscErrorCode (*destroy)(void *), void *tctx) 1093d71ae5a4SJacob Faibussowitsch { 1094d0c080abSJoseph Pusztay PetscFunctionBegin; 1095d0c080abSJoseph Pusztay ctx->transform = transform; 1096d0c080abSJoseph Pusztay ctx->transformdestroy = destroy; 1097d0c080abSJoseph Pusztay ctx->transformctx = tctx; 10983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1099d0c080abSJoseph Pusztay } 1100d0c080abSJoseph Pusztay 1101d0c080abSJoseph Pusztay /*@C 1102bcf0153eSBarry Smith TSMonitorLGError - Monitors progress of the `TS` solvers by plotting each component of the error 1103d0c080abSJoseph Pusztay in a time based line graph 1104d0c080abSJoseph Pusztay 1105c3339decSBarry Smith Collective 1106d0c080abSJoseph Pusztay 1107d0c080abSJoseph Pusztay Input Parameters: 1108bcf0153eSBarry Smith + ts - the `TS` context 1109d0c080abSJoseph Pusztay . step - current time-step 1110d0c080abSJoseph Pusztay . ptime - current time 1111d0c080abSJoseph Pusztay . u - current solution 1112bcf0153eSBarry Smith - dctx - `TSMonitorLGCtx` object created with `TSMonitorLGCtxCreate()` 1113d0c080abSJoseph Pusztay 1114bcf0153eSBarry Smith Options Database Key: 11153a61192cSBarry Smith . -ts_monitor_lg_error - create a graphical monitor of error history 11163a61192cSBarry Smith 1117d0c080abSJoseph Pusztay Level: intermediate 1118d0c080abSJoseph Pusztay 1119d0c080abSJoseph Pusztay Notes: 1120d0c080abSJoseph Pusztay Each process in a parallel run displays its component errors in a separate window 1121d0c080abSJoseph Pusztay 1122bcf0153eSBarry Smith The user must provide the solution using `TSSetSolutionFunction()` to use this monitor. 1123d0c080abSJoseph Pusztay 11243a61192cSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 11253a61192cSBarry Smith to be used during the TS integration. 1126d0c080abSJoseph Pusztay 1127*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()` 1128d0c080abSJoseph Pusztay @*/ 1129d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGError(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dummy) 1130d71ae5a4SJacob Faibussowitsch { 1131d0c080abSJoseph Pusztay TSMonitorLGCtx ctx = (TSMonitorLGCtx)dummy; 1132d0c080abSJoseph Pusztay const PetscScalar *yy; 1133d0c080abSJoseph Pusztay Vec y; 1134d0c080abSJoseph Pusztay 1135d0c080abSJoseph Pusztay PetscFunctionBegin; 1136d0c080abSJoseph Pusztay if (!step) { 1137d0c080abSJoseph Pusztay PetscDrawAxis axis; 1138d0c080abSJoseph Pusztay PetscInt dim; 11399566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis)); 11409566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetLabels(axis, "Error in solution as function of time", "Time", "Error")); 11419566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(u, &dim)); 11429566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSetDimension(ctx->lg, dim)); 11439566063dSJacob Faibussowitsch PetscCall(PetscDrawLGReset(ctx->lg)); 1144d0c080abSJoseph Pusztay } 11459566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &y)); 11469566063dSJacob Faibussowitsch PetscCall(TSComputeSolutionFunction(ts, ptime, y)); 11479566063dSJacob Faibussowitsch PetscCall(VecAXPY(y, -1.0, u)); 11489566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(y, &yy)); 1149d0c080abSJoseph Pusztay #if defined(PETSC_USE_COMPLEX) 1150d0c080abSJoseph Pusztay { 1151d0c080abSJoseph Pusztay PetscReal *yreal; 1152d0c080abSJoseph Pusztay PetscInt i, n; 11539566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(y, &n)); 11549566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &yreal)); 1155d0c080abSJoseph Pusztay for (i = 0; i < n; i++) yreal[i] = PetscRealPart(yy[i]); 11569566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yreal)); 11579566063dSJacob Faibussowitsch PetscCall(PetscFree(yreal)); 1158d0c080abSJoseph Pusztay } 1159d0c080abSJoseph Pusztay #else 11609566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddCommonPoint(ctx->lg, ptime, yy)); 1161d0c080abSJoseph Pusztay #endif 11629566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(y, &yy)); 11639566063dSJacob Faibussowitsch PetscCall(VecDestroy(&y)); 1164d0c080abSJoseph Pusztay if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 11659566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(ctx->lg)); 11669566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(ctx->lg)); 1167d0c080abSJoseph Pusztay } 11683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1169d0c080abSJoseph Pusztay } 1170d0c080abSJoseph Pusztay 1171d0c080abSJoseph Pusztay /*@C 1172bcf0153eSBarry Smith TSMonitorSPSwarmSolution - Graphically displays phase plots of `DMSWARM` particles on a scatter plot 1173d0c080abSJoseph Pusztay 1174d0c080abSJoseph Pusztay Input Parameters: 1175bcf0153eSBarry Smith + ts - the `TS` context 1176d0c080abSJoseph Pusztay . step - current time-step 1177d0c080abSJoseph Pusztay . ptime - current time 1178d0c080abSJoseph Pusztay . u - current solution 1179bcf0153eSBarry Smith - dctx - the `TSMonitorSPCtx` object that contains all the options for the monitoring, this is created with `TSMonitorSPCtxCreate()` 1180d0c080abSJoseph Pusztay 1181bcf0153eSBarry Smith Options Database Keys: 1182d7462660SMatthew Knepley + -ts_monitor_sp_swarm <n> - Monitor the solution every n steps, or -1 for plotting only the final solution 1183d7462660SMatthew Knepley . -ts_monitor_sp_swarm_retain <n> - Retain n old points so we can see the history, or -1 for all points 118420f4b53cSBarry Smith . -ts_monitor_sp_swarm_multi_species <bool> - Color each species differently 1185d7462660SMatthew Knepley - -ts_monitor_sp_swarm_phase <bool> - Plot in phase space, as opposed to coordinate space 1186d0c080abSJoseph Pusztay 1187d0c080abSJoseph Pusztay Level: intermediate 1188d0c080abSJoseph Pusztay 11893a61192cSBarry Smith Notes: 11903a61192cSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 1191bcf0153eSBarry Smith to be used during the `TS` integration. 11923a61192cSBarry Smith 1193*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitoSet()`, `DMSWARM`, `TSMonitorSPCtxCreate()` 1194d0c080abSJoseph Pusztay @*/ 1195d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorSPSwarmSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx) 1196d71ae5a4SJacob Faibussowitsch { 1197d0c080abSJoseph Pusztay TSMonitorSPCtx ctx = (TSMonitorSPCtx)dctx; 1198f98b2f00SMatthew G. Knepley PetscDraw draw; 1199d7462660SMatthew Knepley DM dm, cdm; 1200d0c080abSJoseph Pusztay const PetscScalar *yy; 120160e16b1bSMatthew G. Knepley PetscInt Np, p, dim = 2, *species; 120260e16b1bSMatthew G. Knepley PetscReal species_color; 1203d0c080abSJoseph Pusztay 1204d0c080abSJoseph Pusztay PetscFunctionBegin; 12053ba16761SJacob Faibussowitsch if (step < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */ 120660e16b1bSMatthew G. Knepley PetscCall(TSGetDM(ts, &dm)); 1207d0c080abSJoseph Pusztay if (!step) { 1208d0c080abSJoseph Pusztay PetscDrawAxis axis; 1209ab43fcacSJoe Pusztay PetscReal dmboxlower[2], dmboxupper[2]; 1210f98b2f00SMatthew G. Knepley 12119566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 12129566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 12133c633725SBarry Smith PetscCheck(dim == 2, PETSC_COMM_SELF, PETSC_ERR_SUP, "Monitor only supports two dimensional fields"); 12149566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(dm, &cdm)); 12159566063dSJacob Faibussowitsch PetscCall(DMGetBoundingBox(cdm, dmboxlower, dmboxupper)); 12169566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(u, &Np)); 1217d7462660SMatthew Knepley Np /= dim * 2; 12189566063dSJacob Faibussowitsch PetscCall(PetscDrawSPGetAxis(ctx->sp, &axis)); 12198c87cf4dSdanfinn if (ctx->phase) { 12209566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetLabels(axis, "Particles", "X", "V")); 122160e16b1bSMatthew G. Knepley PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], -10, 10)); 12228c87cf4dSdanfinn } else { 12239566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetLabels(axis, "Particles", "X", "Y")); 12249566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetLimits(axis, dmboxlower[0], dmboxupper[0], dmboxlower[1], dmboxupper[1])); 12258c87cf4dSdanfinn } 12269566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetHoldLimits(axis, PETSC_TRUE)); 12279566063dSJacob Faibussowitsch PetscCall(PetscDrawSPReset(ctx->sp)); 1228d0c080abSJoseph Pusztay } 122960e16b1bSMatthew G. Knepley if (ctx->multispecies) PetscCall(DMSwarmGetField(dm, "species", NULL, NULL, (void **)&species)); 12309566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(u, &Np)); 1231d7462660SMatthew Knepley Np /= dim * 2; 1232d0c080abSJoseph Pusztay if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 12339566063dSJacob Faibussowitsch PetscCall(PetscDrawSPGetDraw(ctx->sp, &draw)); 123448a46eb9SPierre Jolivet if ((ctx->retain == 0) || (ctx->retain > 0 && !(step % ctx->retain))) PetscCall(PetscDrawClear(draw)); 12359566063dSJacob Faibussowitsch PetscCall(PetscDrawFlush(draw)); 12369566063dSJacob Faibussowitsch PetscCall(PetscDrawSPReset(ctx->sp)); 1237f98b2f00SMatthew G. Knepley PetscCall(VecGetArrayRead(u, &yy)); 1238f98b2f00SMatthew G. Knepley for (p = 0; p < Np; ++p) { 1239f98b2f00SMatthew G. Knepley PetscReal x, y; 1240f98b2f00SMatthew G. Knepley 1241f98b2f00SMatthew G. Knepley if (ctx->phase) { 1242f98b2f00SMatthew G. Knepley x = PetscRealPart(yy[p * dim * 2]); 1243f98b2f00SMatthew G. Knepley y = PetscRealPart(yy[p * dim * 2 + dim]); 1244f98b2f00SMatthew G. Knepley } else { 1245f98b2f00SMatthew G. Knepley x = PetscRealPart(yy[p * dim * 2]); 1246f98b2f00SMatthew G. Knepley y = PetscRealPart(yy[p * dim * 2 + 1]); 1247f98b2f00SMatthew G. Knepley } 124860e16b1bSMatthew G. Knepley if (ctx->multispecies) { 124960e16b1bSMatthew G. Knepley species_color = species[p] + 2; 125060e16b1bSMatthew G. Knepley PetscCall(PetscDrawSPAddPointColorized(ctx->sp, &x, &y, &species_color)); 125160e16b1bSMatthew G. Knepley } else { 125260e16b1bSMatthew G. Knepley PetscCall(PetscDrawSPAddPoint(ctx->sp, &x, &y)); 125360e16b1bSMatthew G. Knepley } 1254f98b2f00SMatthew G. Knepley PetscCall(PetscDrawSPAddPoint(ctx->sp, &x, &y)); 1255f98b2f00SMatthew G. Knepley } 1256f98b2f00SMatthew G. Knepley PetscCall(VecRestoreArrayRead(u, &yy)); 12579566063dSJacob Faibussowitsch PetscCall(PetscDrawSPDraw(ctx->sp, PETSC_FALSE)); 12589566063dSJacob Faibussowitsch PetscCall(PetscDrawSPSave(ctx->sp)); 125960e16b1bSMatthew G. Knepley if (ctx->multispecies) PetscCall(DMSwarmRestoreField(dm, "species", NULL, NULL, (void **)&species)); 126060e16b1bSMatthew G. Knepley } 126160e16b1bSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 126260e16b1bSMatthew G. Knepley } 126360e16b1bSMatthew G. Knepley 126460e16b1bSMatthew G. Knepley /*@C 126520f4b53cSBarry Smith TSMonitorHGSwarmSolution - Graphically displays histograms of `DMSWARM` particles 126660e16b1bSMatthew G. Knepley 126760e16b1bSMatthew G. Knepley Input Parameters: 126820f4b53cSBarry Smith + ts - the `TS` context 126960e16b1bSMatthew G. Knepley . step - current time-step 127060e16b1bSMatthew G. Knepley . ptime - current time 127160e16b1bSMatthew G. Knepley . u - current solution 127220f4b53cSBarry Smith - dctx - the `TSMonitorSPCtx` object that contains all the options for the monitoring, this is created with `TSMonitorHGCtxCreate()` 127360e16b1bSMatthew G. Knepley 127420f4b53cSBarry Smith Options Database Keys: 127560e16b1bSMatthew G. Knepley + -ts_monitor_hg_swarm <n> - Monitor the solution every n steps, or -1 for plotting only the final solution 127660e16b1bSMatthew G. Knepley . -ts_monitor_hg_swarm_species <num> - Number of species to histogram 127760e16b1bSMatthew G. Knepley . -ts_monitor_hg_swarm_bins <num> - Number of histogram bins 127860e16b1bSMatthew G. Knepley - -ts_monitor_hg_swarm_velocity <bool> - Plot in velocity space, as opposed to coordinate space 127960e16b1bSMatthew G. Knepley 128060e16b1bSMatthew G. Knepley Level: intermediate 128160e16b1bSMatthew G. Knepley 128220f4b53cSBarry Smith Note: 128360e16b1bSMatthew G. Knepley This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 128460e16b1bSMatthew G. Knepley to be used during the `TS` integration. 128560e16b1bSMatthew G. Knepley 128660e16b1bSMatthew G. Knepley .seealso: `TSMonitoSet()` 128760e16b1bSMatthew G. Knepley @*/ 128860e16b1bSMatthew G. Knepley PetscErrorCode TSMonitorHGSwarmSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx) 128960e16b1bSMatthew G. Knepley { 129060e16b1bSMatthew G. Knepley TSMonitorHGCtx ctx = (TSMonitorHGCtx)dctx; 129160e16b1bSMatthew G. Knepley PetscDraw draw; 129260e16b1bSMatthew G. Knepley DM sw; 129360e16b1bSMatthew G. Knepley const PetscScalar *yy; 129460e16b1bSMatthew G. Knepley PetscInt *species; 129560e16b1bSMatthew G. Knepley PetscInt dim, d = 0, Np, p, Ns, s; 129660e16b1bSMatthew G. Knepley 129760e16b1bSMatthew G. Knepley PetscFunctionBegin; 129860e16b1bSMatthew G. Knepley if (step < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */ 129960e16b1bSMatthew G. Knepley PetscCall(TSGetDM(ts, &sw)); 130060e16b1bSMatthew G. Knepley PetscCall(DMGetDimension(sw, &dim)); 130160e16b1bSMatthew G. Knepley PetscCall(DMSwarmGetNumSpecies(sw, &Ns)); 130260e16b1bSMatthew G. Knepley Ns = PetscMin(Ns, ctx->Ns); 130360e16b1bSMatthew G. Knepley PetscCall(VecGetLocalSize(u, &Np)); 130460e16b1bSMatthew G. Knepley Np /= dim * 2; 130560e16b1bSMatthew G. Knepley if (!step) { 130660e16b1bSMatthew G. Knepley PetscDrawAxis axis; 130760e16b1bSMatthew G. Knepley char title[PETSC_MAX_PATH_LEN]; 130860e16b1bSMatthew G. Knepley 130960e16b1bSMatthew G. Knepley for (s = 0; s < Ns; ++s) { 131060e16b1bSMatthew G. Knepley PetscCall(PetscDrawHGGetAxis(ctx->hg[s], &axis)); 131160e16b1bSMatthew G. Knepley PetscCall(PetscSNPrintf(title, PETSC_MAX_PATH_LEN, "Species %" PetscInt_FMT, s)); 131260e16b1bSMatthew G. Knepley if (ctx->velocity) PetscCall(PetscDrawAxisSetLabels(axis, title, "V", "N")); 131360e16b1bSMatthew G. Knepley else PetscCall(PetscDrawAxisSetLabels(axis, title, "X", "N")); 131460e16b1bSMatthew G. Knepley } 131560e16b1bSMatthew G. Knepley } 131660e16b1bSMatthew G. Knepley if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && ts->reason)) { 131760e16b1bSMatthew G. Knepley PetscCall(DMSwarmGetField(sw, "species", NULL, NULL, (void **)&species)); 131860e16b1bSMatthew G. Knepley for (s = 0; s < Ns; ++s) { 131960e16b1bSMatthew G. Knepley PetscCall(PetscDrawHGReset(ctx->hg[s])); 132060e16b1bSMatthew G. Knepley PetscCall(PetscDrawHGGetDraw(ctx->hg[s], &draw)); 132160e16b1bSMatthew G. Knepley PetscCall(PetscDrawClear(draw)); 132260e16b1bSMatthew G. Knepley PetscCall(PetscDrawFlush(draw)); 132360e16b1bSMatthew G. Knepley } 132460e16b1bSMatthew G. Knepley PetscCall(VecGetArrayRead(u, &yy)); 132560e16b1bSMatthew G. Knepley for (p = 0; p < Np; ++p) { 132660e16b1bSMatthew G. Knepley const PetscInt s = species[p] < Ns ? species[p] : 0; 132760e16b1bSMatthew G. Knepley PetscReal v; 132860e16b1bSMatthew G. Knepley 132960e16b1bSMatthew G. Knepley if (ctx->velocity) v = PetscRealPart(yy[p * dim * 2 + d + dim]); 133060e16b1bSMatthew G. Knepley else v = PetscRealPart(yy[p * dim * 2 + d]); 133160e16b1bSMatthew G. Knepley PetscCall(PetscDrawHGAddValue(ctx->hg[s], v)); 133260e16b1bSMatthew G. Knepley } 133360e16b1bSMatthew G. Knepley PetscCall(VecRestoreArrayRead(u, &yy)); 133460e16b1bSMatthew G. Knepley for (s = 0; s < Ns; ++s) { 133560e16b1bSMatthew G. Knepley PetscCall(PetscDrawHGDraw(ctx->hg[s])); 133660e16b1bSMatthew G. Knepley PetscCall(PetscDrawHGSave(ctx->hg[s])); 133760e16b1bSMatthew G. Knepley } 133860e16b1bSMatthew G. Knepley PetscCall(DMSwarmRestoreField(sw, "species", NULL, NULL, (void **)&species)); 1339d0c080abSJoseph Pusztay } 13403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1341d0c080abSJoseph Pusztay } 1342d0c080abSJoseph Pusztay 1343d0c080abSJoseph Pusztay /*@C 1344bcf0153eSBarry Smith TSMonitorError - Monitors progress of the `TS` solvers by printing the 2 norm of the error at each timestep 1345d0c080abSJoseph Pusztay 1346c3339decSBarry Smith Collective 1347d0c080abSJoseph Pusztay 1348d0c080abSJoseph Pusztay Input Parameters: 1349bcf0153eSBarry Smith + ts - the `TS` context 1350d0c080abSJoseph Pusztay . step - current time-step 1351d0c080abSJoseph Pusztay . ptime - current time 1352d0c080abSJoseph Pusztay . u - current solution 1353d0c080abSJoseph Pusztay - dctx - unused context 1354d0c080abSJoseph Pusztay 1355bcf0153eSBarry Smith Options Database Key: 1356bcf0153eSBarry Smith . -ts_monitor_error - create a graphical monitor of error history 1357bcf0153eSBarry Smith 1358d0c080abSJoseph Pusztay Level: intermediate 1359d0c080abSJoseph Pusztay 13603a61192cSBarry Smith Notes: 13613a61192cSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 1362bcf0153eSBarry Smith to be used during the `TS` integration. 13633a61192cSBarry Smith 1364bcf0153eSBarry Smith The user must provide the solution using `TSSetSolutionFunction()` to use this monitor. 1365d0c080abSJoseph Pusztay 1366*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSSetSolutionFunction()` 1367d0c080abSJoseph Pusztay @*/ 1368d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorError(TS ts, PetscInt step, PetscReal ptime, Vec u, PetscViewerAndFormat *vf) 1369d71ae5a4SJacob Faibussowitsch { 137007eaae0cSMatthew G. Knepley DM dm; 137107eaae0cSMatthew G. Knepley PetscDS ds = NULL; 137207eaae0cSMatthew G. Knepley PetscInt Nf = -1, f; 1373d0c080abSJoseph Pusztay PetscBool flg; 1374d0c080abSJoseph Pusztay 1375d0c080abSJoseph Pusztay PetscFunctionBegin; 13769566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 13779566063dSJacob Faibussowitsch if (dm) PetscCall(DMGetDS(dm, &ds)); 13789566063dSJacob Faibussowitsch if (ds) PetscCall(PetscDSGetNumFields(ds, &Nf)); 137907eaae0cSMatthew G. Knepley if (Nf <= 0) { 138007eaae0cSMatthew G. Knepley Vec y; 138107eaae0cSMatthew G. Knepley PetscReal nrm; 138207eaae0cSMatthew G. Knepley 13839566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &y)); 13849566063dSJacob Faibussowitsch PetscCall(TSComputeSolutionFunction(ts, ptime, y)); 13859566063dSJacob Faibussowitsch PetscCall(VecAXPY(y, -1.0, u)); 13869566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERASCII, &flg)); 1387d0c080abSJoseph Pusztay if (flg) { 13889566063dSJacob Faibussowitsch PetscCall(VecNorm(y, NORM_2, &nrm)); 13899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vf->viewer, "2-norm of error %g\n", (double)nrm)); 1390d0c080abSJoseph Pusztay } 13919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERDRAW, &flg)); 13921baa6e33SBarry Smith if (flg) PetscCall(VecView(y, vf->viewer)); 13939566063dSJacob Faibussowitsch PetscCall(VecDestroy(&y)); 139407eaae0cSMatthew G. Knepley } else { 139507eaae0cSMatthew G. Knepley PetscErrorCode (**exactFuncs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx); 139607eaae0cSMatthew G. Knepley void **ctxs; 139707eaae0cSMatthew G. Knepley Vec v; 139807eaae0cSMatthew G. Knepley PetscReal ferrors[1]; 139907eaae0cSMatthew G. Knepley 14009566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exactFuncs, Nf, &ctxs)); 14019566063dSJacob Faibussowitsch for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(ds, f, &exactFuncs[f], &ctxs[f])); 14029566063dSJacob Faibussowitsch PetscCall(DMComputeL2FieldDiff(dm, ptime, exactFuncs, ctxs, u, ferrors)); 14039566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Timestep: %04d time = %-8.4g \t L_2 Error: [", (int)step, (double)ptime)); 140407eaae0cSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 14059566063dSJacob Faibussowitsch if (f > 0) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ", ")); 14069566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%2.3g", (double)ferrors[f])); 140707eaae0cSMatthew G. Knepley } 14089566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "]\n")); 140907eaae0cSMatthew G. Knepley 14109566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(u, NULL, "-sol_vec_view")); 141107eaae0cSMatthew G. Knepley 14129566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(NULL, NULL, "-exact_vec_view", &flg)); 141307eaae0cSMatthew G. Knepley if (flg) { 14149566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dm, &v)); 14159566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(dm, ptime, exactFuncs, ctxs, INSERT_ALL_VALUES, v)); 14169566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)v, "Exact Solution")); 14179566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(v, NULL, "-exact_vec_view")); 14189566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dm, &v)); 141907eaae0cSMatthew G. Knepley } 14209566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactFuncs, ctxs)); 142107eaae0cSMatthew G. Knepley } 14223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1423d0c080abSJoseph Pusztay } 1424d0c080abSJoseph Pusztay 1425d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGSNESIterations(TS ts, PetscInt n, PetscReal ptime, Vec v, void *monctx) 1426d71ae5a4SJacob Faibussowitsch { 1427d0c080abSJoseph Pusztay TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx; 1428d0c080abSJoseph Pusztay PetscReal x = ptime, y; 1429d0c080abSJoseph Pusztay PetscInt its; 1430d0c080abSJoseph Pusztay 1431d0c080abSJoseph Pusztay PetscFunctionBegin; 14323ba16761SJacob Faibussowitsch if (n < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */ 1433d0c080abSJoseph Pusztay if (!n) { 1434d0c080abSJoseph Pusztay PetscDrawAxis axis; 14359566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis)); 14369566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetLabels(axis, "Nonlinear iterations as function of time", "Time", "SNES Iterations")); 14379566063dSJacob Faibussowitsch PetscCall(PetscDrawLGReset(ctx->lg)); 1438d0c080abSJoseph Pusztay ctx->snes_its = 0; 1439d0c080abSJoseph Pusztay } 14409566063dSJacob Faibussowitsch PetscCall(TSGetSNESIterations(ts, &its)); 1441d0c080abSJoseph Pusztay y = its - ctx->snes_its; 14429566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y)); 1443d0c080abSJoseph Pusztay if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 14449566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(ctx->lg)); 14459566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(ctx->lg)); 1446d0c080abSJoseph Pusztay } 1447d0c080abSJoseph Pusztay ctx->snes_its = its; 14483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1449d0c080abSJoseph Pusztay } 1450d0c080abSJoseph Pusztay 1451d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorLGKSPIterations(TS ts, PetscInt n, PetscReal ptime, Vec v, void *monctx) 1452d71ae5a4SJacob Faibussowitsch { 1453d0c080abSJoseph Pusztay TSMonitorLGCtx ctx = (TSMonitorLGCtx)monctx; 1454d0c080abSJoseph Pusztay PetscReal x = ptime, y; 1455d0c080abSJoseph Pusztay PetscInt its; 1456d0c080abSJoseph Pusztay 1457d0c080abSJoseph Pusztay PetscFunctionBegin; 14583ba16761SJacob Faibussowitsch if (n < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */ 1459d0c080abSJoseph Pusztay if (!n) { 1460d0c080abSJoseph Pusztay PetscDrawAxis axis; 14619566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetAxis(ctx->lg, &axis)); 14629566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetLabels(axis, "Linear iterations as function of time", "Time", "KSP Iterations")); 14639566063dSJacob Faibussowitsch PetscCall(PetscDrawLGReset(ctx->lg)); 1464d0c080abSJoseph Pusztay ctx->ksp_its = 0; 1465d0c080abSJoseph Pusztay } 14669566063dSJacob Faibussowitsch PetscCall(TSGetKSPIterations(ts, &its)); 1467d0c080abSJoseph Pusztay y = its - ctx->ksp_its; 14689566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(ctx->lg, &x, &y)); 1469d0c080abSJoseph Pusztay if (((ctx->howoften > 0) && (!(n % ctx->howoften)) && (n > -1)) || ((ctx->howoften == -1) && (n == -1))) { 14709566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(ctx->lg)); 14719566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(ctx->lg)); 1472d0c080abSJoseph Pusztay } 1473d0c080abSJoseph Pusztay ctx->ksp_its = its; 14743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1475d0c080abSJoseph Pusztay } 1476d0c080abSJoseph Pusztay 1477d0c080abSJoseph Pusztay /*@C 1478bcf0153eSBarry Smith TSMonitorEnvelopeCtxCreate - Creates a context for use with `TSMonitorEnvelope()` 1479d0c080abSJoseph Pusztay 1480c3339decSBarry Smith Collective 1481d0c080abSJoseph Pusztay 14822fe279fdSBarry Smith Input Parameter: 1483bcf0153eSBarry Smith . ts - the `TS` solver object 1484d0c080abSJoseph Pusztay 1485d0c080abSJoseph Pusztay Output Parameter: 1486d0c080abSJoseph Pusztay . ctx - the context 1487d0c080abSJoseph Pusztay 1488d0c080abSJoseph Pusztay Level: intermediate 1489d0c080abSJoseph Pusztay 1490*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorLGTimeStep()`, `TSMonitorSet()`, `TSMonitorLGSolution()`, `TSMonitorLGError()` 1491d0c080abSJoseph Pusztay @*/ 1492d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelopeCtxCreate(TS ts, TSMonitorEnvelopeCtx *ctx) 1493d71ae5a4SJacob Faibussowitsch { 1494d0c080abSJoseph Pusztay PetscFunctionBegin; 14959566063dSJacob Faibussowitsch PetscCall(PetscNew(ctx)); 14963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1497d0c080abSJoseph Pusztay } 1498d0c080abSJoseph Pusztay 1499d0c080abSJoseph Pusztay /*@C 1500d0c080abSJoseph Pusztay TSMonitorEnvelope - Monitors the maximum and minimum value of each component of the solution 1501d0c080abSJoseph Pusztay 1502c3339decSBarry Smith Collective 1503d0c080abSJoseph Pusztay 1504d0c080abSJoseph Pusztay Input Parameters: 1505195e9b02SBarry Smith + ts - the `TS` context 1506d0c080abSJoseph Pusztay . step - current time-step 1507d0c080abSJoseph Pusztay . ptime - current time 1508d0c080abSJoseph Pusztay . u - current solution 1509d0c080abSJoseph Pusztay - dctx - the envelope context 1510d0c080abSJoseph Pusztay 1511bcf0153eSBarry Smith Options Database Key: 151267b8a455SSatish Balay . -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time 1513d0c080abSJoseph Pusztay 1514d0c080abSJoseph Pusztay Level: intermediate 1515d0c080abSJoseph Pusztay 1516d0c080abSJoseph Pusztay Notes: 1517bcf0153eSBarry Smith After a solve you can use `TSMonitorEnvelopeGetBounds()` to access the envelope 15183a61192cSBarry Smith 15193a61192cSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 1520bcf0153eSBarry Smith to be used during the `TS` integration. 1521d0c080abSJoseph Pusztay 1522*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorEnvelopeGetBounds()`, `TSMonitorEnvelopeCtxCreate()` 1523d0c080abSJoseph Pusztay @*/ 1524d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelope(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx) 1525d71ae5a4SJacob Faibussowitsch { 1526d0c080abSJoseph Pusztay TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)dctx; 1527d0c080abSJoseph Pusztay 1528d0c080abSJoseph Pusztay PetscFunctionBegin; 1529d0c080abSJoseph Pusztay if (!ctx->max) { 15309566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &ctx->max)); 15319566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &ctx->min)); 15329566063dSJacob Faibussowitsch PetscCall(VecCopy(u, ctx->max)); 15339566063dSJacob Faibussowitsch PetscCall(VecCopy(u, ctx->min)); 1534d0c080abSJoseph Pusztay } else { 15359566063dSJacob Faibussowitsch PetscCall(VecPointwiseMax(ctx->max, u, ctx->max)); 15369566063dSJacob Faibussowitsch PetscCall(VecPointwiseMin(ctx->min, u, ctx->min)); 1537d0c080abSJoseph Pusztay } 15383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1539d0c080abSJoseph Pusztay } 1540d0c080abSJoseph Pusztay 1541d0c080abSJoseph Pusztay /*@C 1542d0c080abSJoseph Pusztay TSMonitorEnvelopeGetBounds - Gets the bounds for the components of the solution 1543d0c080abSJoseph Pusztay 1544c3339decSBarry Smith Collective 1545d0c080abSJoseph Pusztay 1546d0c080abSJoseph Pusztay Input Parameter: 1547bcf0153eSBarry Smith . ts - the `TS` context 1548d0c080abSJoseph Pusztay 1549d8d19677SJose E. Roman Output Parameters: 1550d0c080abSJoseph Pusztay + max - the maximum values 1551d0c080abSJoseph Pusztay - min - the minimum values 1552d0c080abSJoseph Pusztay 1553195e9b02SBarry Smith Level: intermediate 1554195e9b02SBarry Smith 1555d0c080abSJoseph Pusztay Notes: 1556bcf0153eSBarry Smith If the `TS` does not have a `TSMonitorEnvelopeCtx` associated with it then this function is ignored 1557d0c080abSJoseph Pusztay 1558*1cc06b55SBarry Smith .seealso: [](ch_ts), `TSMonitorEnvelopeCtx`, `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `VecView()`, `TSMonitorLGSetDisplayVariables()` 1559d0c080abSJoseph Pusztay @*/ 1560d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelopeGetBounds(TS ts, Vec *max, Vec *min) 1561d71ae5a4SJacob Faibussowitsch { 1562d0c080abSJoseph Pusztay PetscInt i; 1563d0c080abSJoseph Pusztay 1564d0c080abSJoseph Pusztay PetscFunctionBegin; 1565d0c080abSJoseph Pusztay if (max) *max = NULL; 1566d0c080abSJoseph Pusztay if (min) *min = NULL; 1567d0c080abSJoseph Pusztay for (i = 0; i < ts->numbermonitors; i++) { 1568d0c080abSJoseph Pusztay if (ts->monitor[i] == TSMonitorEnvelope) { 1569d0c080abSJoseph Pusztay TSMonitorEnvelopeCtx ctx = (TSMonitorEnvelopeCtx)ts->monitorcontext[i]; 1570d0c080abSJoseph Pusztay if (max) *max = ctx->max; 1571d0c080abSJoseph Pusztay if (min) *min = ctx->min; 1572d0c080abSJoseph Pusztay break; 1573d0c080abSJoseph Pusztay } 1574d0c080abSJoseph Pusztay } 15753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1576d0c080abSJoseph Pusztay } 1577d0c080abSJoseph Pusztay 1578d0c080abSJoseph Pusztay /*@C 1579bcf0153eSBarry Smith TSMonitorEnvelopeCtxDestroy - Destroys a context that was created with `TSMonitorEnvelopeCtxCreate()`. 1580d0c080abSJoseph Pusztay 1581c3339decSBarry Smith Collective 1582d0c080abSJoseph Pusztay 1583d0c080abSJoseph Pusztay Input Parameter: 1584d0c080abSJoseph Pusztay . ctx - the monitor context 1585d0c080abSJoseph Pusztay 1586d0c080abSJoseph Pusztay Level: intermediate 1587d0c080abSJoseph Pusztay 1588*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorLGCtxCreate()`, `TSMonitorSet()`, `TSMonitorLGTimeStep()` 1589d0c080abSJoseph Pusztay @*/ 1590d71ae5a4SJacob Faibussowitsch PetscErrorCode TSMonitorEnvelopeCtxDestroy(TSMonitorEnvelopeCtx *ctx) 1591d71ae5a4SJacob Faibussowitsch { 1592d0c080abSJoseph Pusztay PetscFunctionBegin; 15939566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(*ctx)->min)); 15949566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(*ctx)->max)); 15959566063dSJacob Faibussowitsch PetscCall(PetscFree(*ctx)); 15963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1597d0c080abSJoseph Pusztay } 1598d0c080abSJoseph Pusztay 1599d0c080abSJoseph Pusztay /*@C 1600bcf0153eSBarry Smith TSDMSwarmMonitorMoments - Monitors the first three moments of a `DMSWARM` being evolved by the `TS` 1601d0c080abSJoseph Pusztay 160220f4b53cSBarry Smith Not Collective 1603d0c080abSJoseph Pusztay 1604d0c080abSJoseph Pusztay Input Parameters: 1605bcf0153eSBarry Smith + ts - the `TS` context 1606d0c080abSJoseph Pusztay . step - current timestep 1607d0c080abSJoseph Pusztay . t - current time 1608d0c080abSJoseph Pusztay . u - current solution 1609d0c080abSJoseph Pusztay - ctx - not used 1610d0c080abSJoseph Pusztay 1611bcf0153eSBarry Smith Options Database Key: 161267b8a455SSatish Balay . -ts_dmswarm_monitor_moments - Monitor moments of particle distribution 1613d0c080abSJoseph Pusztay 1614d0c080abSJoseph Pusztay Level: intermediate 1615d0c080abSJoseph Pusztay 1616d0c080abSJoseph Pusztay Notes: 1617bcf0153eSBarry Smith This requires a `DMSWARM` be attached to the `TS`. 1618d0c080abSJoseph Pusztay 16193a61192cSBarry Smith This is not called directly by users, rather one calls `TSMonitorSet()`, with this function as an argument, to cause the monitor 16203a61192cSBarry Smith to be used during the TS integration. 16213a61192cSBarry Smith 1622*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSMonitorSet()`, `TSMonitorDefault()`, `DMSWARM` 1623d0c080abSJoseph Pusztay @*/ 1624d71ae5a4SJacob Faibussowitsch PetscErrorCode TSDMSwarmMonitorMoments(TS ts, PetscInt step, PetscReal t, Vec U, PetscViewerAndFormat *vf) 1625d71ae5a4SJacob Faibussowitsch { 1626d0c080abSJoseph Pusztay DM sw; 1627d0c080abSJoseph Pusztay const PetscScalar *u; 1628d0c080abSJoseph Pusztay PetscReal m = 1.0, totE = 0., totMom[3] = {0., 0., 0.}; 1629d0c080abSJoseph Pusztay PetscInt dim, d, Np, p; 1630d0c080abSJoseph Pusztay MPI_Comm comm; 1631d0c080abSJoseph Pusztay 1632d0c080abSJoseph Pusztay PetscFunctionBeginUser; 16339566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &sw)); 16343ba16761SJacob Faibussowitsch if (!sw || step % ts->monitorFrequency != 0) PetscFunctionReturn(PETSC_SUCCESS); 16359566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)ts, &comm)); 16369566063dSJacob Faibussowitsch PetscCall(DMGetDimension(sw, &dim)); 16379566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(U, &Np)); 1638d0c080abSJoseph Pusztay Np /= dim; 16399566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(U, &u)); 1640d0c080abSJoseph Pusztay for (p = 0; p < Np; ++p) { 1641d0c080abSJoseph Pusztay for (d = 0; d < dim; ++d) { 1642d0c080abSJoseph Pusztay totE += PetscRealPart(u[p * dim + d] * u[p * dim + d]); 1643d0c080abSJoseph Pusztay totMom[d] += PetscRealPart(u[p * dim + d]); 1644d0c080abSJoseph Pusztay } 1645d0c080abSJoseph Pusztay } 16469566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(U, &u)); 1647d0c080abSJoseph Pusztay for (d = 0; d < dim; ++d) totMom[d] *= m; 1648d0c080abSJoseph Pusztay totE *= 0.5 * m; 164963a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(comm, "Step %4" PetscInt_FMT " Total Energy: %10.8lf", step, (double)totE)); 165063a3b9bcSJacob Faibussowitsch for (d = 0; d < dim; ++d) PetscCall(PetscPrintf(comm, " Total Momentum %c: %10.8lf", (char)('x' + d), (double)totMom[d])); 16519566063dSJacob Faibussowitsch PetscCall(PetscPrintf(comm, "\n")); 16523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1653d0c080abSJoseph Pusztay } 1654