Actual source code: dmnetworkts.c

      1: #include <petsc/private/dmnetworkimpl.h>
      2: #include <petscts.h>
      3: #include <petscdraw.h>

      5: /*@C
      6:   TSMonitorLGCtxNetworkDestroy - Destroys  line graph contexts that where created with `TSMonitorLGCtxNetworkCreate()`.

      8:   Collective

     10:   Input Parameter:
     11: . ctx - the monitor context

     13:   Level: intermediate

     15: .seealso: [](ch_ts), `TS`, `TSMonitorLGCtxNetworkSolution()`
     16: @*/
     17: PetscErrorCode TSMonitorLGCtxNetworkDestroy(TSMonitorLGCtxNetwork *ctx)
     18: {
     19:   PetscInt i;

     21:   PetscFunctionBegin;
     22:   for (i = 0; i < (*ctx)->nlg; i++) PetscCall(PetscDrawLGDestroy(&(*ctx)->lg[i]));
     23:   PetscCall(PetscFree((*ctx)->lg));
     24:   PetscCall(PetscFree(*ctx));
     25:   PetscFunctionReturn(PETSC_SUCCESS);
     26: }

     28: PetscErrorCode TSMonitorLGCtxNetworkCreate(TS ts, const char host[], const char label[], int x, int y, int m, int n, PetscInt howoften, TSMonitorLGCtxNetwork *ctx)
     29: {
     30:   PetscDraw draw;
     31:   MPI_Comm  comm;
     32:   DM        dm;
     33:   PetscInt  i, Start, End, e, nvar;

     35:   PetscFunctionBegin;
     36:   PetscCall(TSGetDM(ts, &dm));
     37:   PetscCall(PetscObjectGetComm((PetscObject)ts, &comm));
     38:   PetscCall(PetscNew(ctx));
     39:   i = 0;
     40:   /* loop over edges counting number of line graphs needed */
     41:   PetscCall(DMNetworkGetEdgeRange(dm, &Start, &End));
     42:   for (e = Start; e < End; e++) {
     43:     PetscCall(DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar));
     44:     if (!nvar) continue;
     45:     i++;
     46:   }
     47:   /* loop over vertices */
     48:   PetscCall(DMNetworkGetVertexRange(dm, &Start, &End));
     49:   for (e = Start; e < End; e++) {
     50:     PetscCall(DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar));
     51:     if (!nvar) continue;
     52:     i++;
     53:   }
     54:   (*ctx)->nlg = i;
     55:   PetscCall(PetscMalloc1(i, &(*ctx)->lg));

     57:   i = 0;
     58:   /* loop over edges creating all needed line graphs*/
     59:   PetscCall(DMNetworkGetEdgeRange(dm, &Start, &End));
     60:   for (e = Start; e < End; e++) {
     61:     PetscCall(DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar));
     62:     if (!nvar) continue;
     63:     PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
     64:     PetscCall(PetscDrawSetFromOptions(draw));
     65:     PetscCall(PetscDrawLGCreate(draw, nvar, &(*ctx)->lg[i]));
     66:     PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg[i]));
     67:     PetscCall(PetscDrawDestroy(&draw));
     68:     i++;
     69:   }
     70:   /* loop over vertices */
     71:   PetscCall(DMNetworkGetVertexRange(dm, &Start, &End));
     72:   for (e = Start; e < End; e++) {
     73:     PetscCall(DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar));
     74:     if (!nvar) continue;
     75:     PetscCall(PetscDrawCreate(comm, host, label, x, y, m, n, &draw));
     76:     PetscCall(PetscDrawSetFromOptions(draw));
     77:     PetscCall(PetscDrawLGCreate(draw, nvar, &(*ctx)->lg[i]));
     78:     PetscCall(PetscDrawLGSetFromOptions((*ctx)->lg[i]));
     79:     PetscCall(PetscDrawDestroy(&draw));
     80:     i++;
     81:   }
     82:   PetscCall(PetscDrawDestroy(&draw));
     83:   (*ctx)->howoften = howoften;
     84:   PetscFunctionReturn(PETSC_SUCCESS);
     85: }

     87: /*@C
     88:   TSMonitorLGCtxNetworkSolution - Monitors progress of the `TS` solvers for a `DMNETWORK` solution with one window for each vertex and each edge

     90:   Collective

     92:   Input Parameters:
     93: + ts    - the `TS` context
     94: . step  - current time-step
     95: . ptime - current time
     96: . u     - current solution
     97: - dctx  - the `TSMonitorLGCtxNetwork` object that contains all the options for the monitoring, this is created with `TSMonitorLGCtxCreateNetwork()`

     99:   Options Database Key:
    100: . -ts_monitor_lg_solution_variables - monitor solution variables

    102:   Level: intermediate

    104:   Note:
    105:   Each process in a parallel run displays its component solutions in a separate graphics window

    107: .seealso: [](ch_ts), `TS`, `TSMonitorLGCtxNetworkDestroy()`
    108: @*/
    109: PetscErrorCode TSMonitorLGCtxNetworkSolution(TS ts, PetscInt step, PetscReal ptime, Vec u, void *dctx)
    110: {
    111:   TSMonitorLGCtxNetwork ctx = (TSMonitorLGCtxNetwork)dctx;
    112:   const PetscScalar    *xv;
    113:   PetscScalar          *yv;
    114:   PetscInt              i, v, Start, End, offset, nvar, e;
    115:   TSConvergedReason     reason;
    116:   DM                    dm;
    117:   Vec                   uv;

    119:   PetscFunctionBegin;
    120:   if (step < 0) PetscFunctionReturn(PETSC_SUCCESS); /* -1 indicates interpolated solution */
    121:   if (!step) {
    122:     PetscDrawAxis axis;

    124:     for (i = 0; i < ctx->nlg; i++) {
    125:       PetscCall(PetscDrawLGGetAxis(ctx->lg[i], &axis));
    126:       PetscCall(PetscDrawAxisSetLabels(axis, "Solution as function of time", "Time", "Solution"));
    127:       PetscCall(PetscDrawLGReset(ctx->lg[i]));
    128:     }
    129:   }

    131:   if (ctx->semilogy) {
    132:     PetscInt n, j;

    134:     PetscCall(VecDuplicate(u, &uv));
    135:     PetscCall(VecCopy(u, uv));
    136:     PetscCall(VecGetArray(uv, &yv));
    137:     PetscCall(VecGetLocalSize(uv, &n));
    138:     for (j = 0; j < n; j++) {
    139:       if (PetscRealPart(yv[j]) <= 0.0) yv[j] = -12;
    140:       else yv[j] = PetscLog10Real(PetscRealPart(yv[j]));
    141:     }
    142:     xv = yv;
    143:   } else {
    144:     PetscCall(VecGetArrayRead(u, &xv));
    145:   }
    146:   /* iterate over edges */
    147:   PetscCall(TSGetDM(ts, &dm));
    148:   i = 0;
    149:   PetscCall(DMNetworkGetEdgeRange(dm, &Start, &End));
    150:   for (e = Start; e < End; e++) {
    151:     PetscCall(DMNetworkGetComponent(dm, e, ALL_COMPONENTS, NULL, NULL, &nvar));
    152:     if (!nvar) continue;

    154:     PetscCall(DMNetworkGetLocalVecOffset(dm, e, ALL_COMPONENTS, &offset));
    155:     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg[i], ptime, (const PetscReal *)(xv + offset)));
    156:     i++;
    157:   }

    159:   /* iterate over vertices */
    160:   PetscCall(DMNetworkGetVertexRange(dm, &Start, &End));
    161:   for (v = Start; v < End; v++) {
    162:     PetscCall(DMNetworkGetComponent(dm, v, ALL_COMPONENTS, NULL, NULL, &nvar));
    163:     if (!nvar) continue;

    165:     PetscCall(DMNetworkGetLocalVecOffset(dm, v, ALL_COMPONENTS, &offset));
    166:     PetscCall(PetscDrawLGAddCommonPoint(ctx->lg[i], ptime, (const PetscReal *)(xv + offset)));
    167:     i++;
    168:   }
    169:   if (ctx->semilogy) {
    170:     PetscCall(VecRestoreArray(uv, &yv));
    171:     PetscCall(VecDestroy(&uv));
    172:   } else {
    173:     PetscCall(VecRestoreArrayRead(u, &xv));
    174:   }

    176:   PetscCall(TSGetConvergedReason(ts, &reason));
    177:   if (((ctx->howoften > 0) && (!(step % ctx->howoften))) || ((ctx->howoften == -1) && reason)) {
    178:     for (i = 0; i < ctx->nlg; i++) {
    179:       PetscCall(PetscDrawLGDraw(ctx->lg[i]));
    180:       PetscCall(PetscDrawLGSave(ctx->lg[i]));
    181:     }
    182:   }
    183:   PetscFunctionReturn(PETSC_SUCCESS);
    184: }