1 #include <petscsys.h> 2 #include <petsc/private/viewerimpl.h> 3 4 struct _n_PetscViewers { 5 MPI_Comm comm; 6 PetscViewer *viewer; 7 int n; 8 }; 9 10 /*@C 11 PetscViewersDestroy - Destroys a set of `PetscViewer`s created with `PetscViewersCreate()`. 12 13 Collective 14 15 Input Parameter: 16 . v - the `PetscViewers` to be destroyed. 17 18 Level: intermediate 19 20 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerDestroy()`, `PetscViewers`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerCreate()`, `PetscViewerDrawOpen()`, `PetscViewersCreate()` 21 @*/ 22 PetscErrorCode PetscViewersDestroy(PetscViewers *v) 23 { 24 int i; 25 26 PetscFunctionBegin; 27 if (!*v) PetscFunctionReturn(PETSC_SUCCESS); 28 for (i = 0; i < (*v)->n; i++) PetscCall(PetscViewerDestroy(&(*v)->viewer[i])); 29 PetscCall(PetscFree((*v)->viewer)); 30 PetscCall(PetscFree(*v)); 31 PetscFunctionReturn(PETSC_SUCCESS); 32 } 33 34 /*@C 35 PetscViewersCreate - Creates a container to hold a set of `PetscViewer`'s. The container is essentially a sparse, growable in length array of `PetscViewer`s 36 37 Collective 38 39 Input Parameter: 40 . comm - the MPI communicator 41 42 Output Parameter: 43 . v - the collection of `PetscViewers` 44 45 Level: intermediate 46 47 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewers`, `PetscViewerCreate()`, `PetscViewersDestroy()` 48 @*/ 49 PetscErrorCode PetscViewersCreate(MPI_Comm comm, PetscViewers *v) 50 { 51 PetscFunctionBegin; 52 PetscAssertPointer(v, 2); 53 PetscCall(PetscNew(v)); 54 (*v)->n = 64; 55 (*v)->comm = comm; 56 57 PetscCall(PetscCalloc1(64, &(*v)->viewer)); 58 PetscFunctionReturn(PETSC_SUCCESS); 59 } 60 61 /*@C 62 PetscViewersGetViewer - Gets a `PetscViewer` from a `PetscViewers` collection 63 64 Collective if the viewer has not previously be obtained. 65 66 Input Parameters: 67 + viewers - object created with `PetscViewersCreate()` 68 - n - number of `PetscViewer` you want 69 70 Output Parameter: 71 . viewer - the `PetscViewer` 72 73 Level: intermediate 74 75 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewers`, `PetscViewersCreate()`, `PetscViewersDestroy()` 76 @*/ 77 PetscErrorCode PetscViewersGetViewer(PetscViewers viewers, PetscInt n, PetscViewer *viewer) 78 { 79 PetscFunctionBegin; 80 PetscAssertPointer(viewers, 1); 81 PetscAssertPointer(viewer, 3); 82 PetscCheck(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cannot access using a negative index - %" PetscInt_FMT, n); 83 if (n >= viewers->n) { 84 PetscViewer *v; 85 int newn = n + 64; /* add 64 new ones at a time */ 86 87 PetscCall(PetscCalloc1(newn, &v)); 88 PetscCall(PetscArraycpy(v, viewers->viewer, viewers->n)); 89 PetscCall(PetscFree(viewers->viewer)); 90 91 viewers->viewer = v; 92 } 93 if (!viewers->viewer[n]) PetscCall(PetscViewerCreate(viewers->comm, &viewers->viewer[n])); 94 *viewer = viewers->viewer[n]; 95 PetscFunctionReturn(PETSC_SUCCESS); 96 } 97 98 /*@C 99 PetscMonitorCompare - Checks if two monitors are identical; if they are then it destroys the new one 100 101 Not Collective 102 103 Input Parameters: 104 + nmon - The new monitor 105 . nmctx - The new monitor context, or `NULL` 106 . nmdestroy - The new monitor destroy function, or `NULL` 107 . mon - The old monitor 108 . mctx - The old monitor context, or `NULL` 109 - mdestroy - The old monitor destroy function, or `NULL` 110 111 Output Parameter: 112 . identical - `PETSC_TRUE` if the monitors are the same 113 114 Level: developer 115 116 .seealso: [](sec_viewers), `DMMonitorSetFromOptions()`, `KSPMonitorSetFromOptions()`, `SNESMonitorSetFromOptions()` 117 @*/ 118 PetscErrorCode PetscMonitorCompare(PetscErrorCode (*nmon)(void), void *nmctx, PetscErrorCode (*nmdestroy)(void **), PetscErrorCode (*mon)(void), void *mctx, PetscErrorCode (*mdestroy)(void **), PetscBool *identical) 119 { 120 PetscFunctionBegin; 121 PetscAssertPointer(identical, 7); 122 *identical = PETSC_FALSE; 123 if (nmon == mon && nmdestroy == mdestroy) { 124 if (nmctx == mctx) *identical = PETSC_TRUE; 125 else if (nmdestroy == (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy) { 126 PetscViewerAndFormat *old = (PetscViewerAndFormat *)mctx, *newo = (PetscViewerAndFormat *)nmctx; 127 if (old->viewer == newo->viewer && old->format == newo->format) *identical = PETSC_TRUE; 128 } 129 if (*identical) { 130 if (mdestroy) PetscCall((*mdestroy)(&nmctx)); 131 } 132 } 133 PetscFunctionReturn(PETSC_SUCCESS); 134 } 135