xref: /petsc/src/sys/fileio/mprint.c (revision c69effb2e05caa58810396c101d616d7ad9da0a7)
1e5c89e4eSSatish Balay /*
2da81f932SPierre Jolivet       Utilities routines to add simple ASCII IO capability.
3e5c89e4eSSatish Balay */
4c6db04a5SJed Brown #include <../src/sys/fileio/mprint.h>
579c0e996SJed Brown #include <errno.h>
6e5c89e4eSSatish Balay /*
7e5c89e4eSSatish Balay    If petsc_history is on, then all Petsc*Printf() results are saved
8e5c89e4eSSatish Balay    if the appropriate (usually .petschistory) file.
9e5c89e4eSSatish Balay */
1095c0884eSLisandro Dalcin PETSC_INTERN FILE *petsc_history;
11e5c89e4eSSatish Balay /*
12e5c89e4eSSatish Balay      Allows one to overwrite where standard out is sent. For example
135106ddf5SBarry Smith      PETSC_STDOUT = fopen("/dev/ttyXX","w") will cause all standard out
14e5c89e4eSSatish Balay      writes to go to terminal XX; assuming you have write permission there
15e5c89e4eSSatish Balay */
1602c9f0b5SLisandro Dalcin FILE *PETSC_STDOUT = NULL;
17ae9b4142SLisandro Dalcin /*
18ae9b4142SLisandro Dalcin      Allows one to overwrite where standard error is sent. For example
19ae9b4142SLisandro Dalcin      PETSC_STDERR = fopen("/dev/ttyXX","w") will cause all standard error
20ae9b4142SLisandro Dalcin      writes to go to terminal XX; assuming you have write permission there
21ae9b4142SLisandro Dalcin */
2202c9f0b5SLisandro Dalcin FILE *PETSC_STDERR = NULL;
23b13499bfSbcordonn 
24c9a19010SBarry Smith /*@C
25811af0c4SBarry Smith      PetscFormatConvertGetSize - Gets the length of a string needed to hold format converted with `PetscFormatConvert()`
26811af0c4SBarry Smith 
27058c9ee1SBarry Smith    No Fortran Support
28c9a19010SBarry Smith 
29d781fa04SBarry Smith    Input Parameter:
30d781fa04SBarry Smith .   format - the PETSc format string
31c9a19010SBarry Smith 
32d781fa04SBarry Smith    Output Parameter:
33d781fa04SBarry Smith .   size - the needed length of the new format
34c9a19010SBarry Smith 
35c9a19010SBarry Smith    Level: developer
36c9a19010SBarry Smith 
37db781477SPatrick Sanan .seealso: `PetscFormatConvert()`, `PetscVSNPrintf()`, `PetscVFPrintf()`
38c9a19010SBarry Smith @*/
39d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatConvertGetSize(const char *format, size_t *size)
40d71ae5a4SJacob Faibussowitsch {
413ca90d2dSJacob Faibussowitsch   size_t   sz = 0;
42d781fa04SBarry Smith   PetscInt i  = 0;
43d781fa04SBarry Smith 
44d781fa04SBarry Smith   PetscFunctionBegin;
453ca90d2dSJacob Faibussowitsch   PetscValidCharPointer(format, 1);
463ca90d2dSJacob Faibussowitsch   PetscValidPointer(size, 2);
47d781fa04SBarry Smith   while (format[i]) {
483ca90d2dSJacob Faibussowitsch     if (format[i] == '%') {
493ca90d2dSJacob Faibussowitsch       if (format[i + 1] == '%') {
503ca90d2dSJacob Faibussowitsch         i += 2;
513ca90d2dSJacob Faibussowitsch         sz += 2;
523ca90d2dSJacob Faibussowitsch         continue;
533ca90d2dSJacob Faibussowitsch       }
54d781fa04SBarry Smith       /* Find the letter */
559371c9d4SSatish Balay       while (format[i] && (format[i] <= '9')) {
569371c9d4SSatish Balay         ++i;
579371c9d4SSatish Balay         ++sz;
589371c9d4SSatish Balay       }
59d781fa04SBarry Smith       switch (format[i]) {
603ca90d2dSJacob Faibussowitsch #if PetscDefined(USE_64BIT_INDICES)
61d71ae5a4SJacob Faibussowitsch       case 'D':
62d71ae5a4SJacob Faibussowitsch         sz += 2;
63d71ae5a4SJacob Faibussowitsch         break;
64d781fa04SBarry Smith #endif
65d71ae5a4SJacob Faibussowitsch       case 'g':
66d71ae5a4SJacob Faibussowitsch         sz += 4;
67d71ae5a4SJacob Faibussowitsch       default:
68d71ae5a4SJacob Faibussowitsch         break;
69d781fa04SBarry Smith       }
70d781fa04SBarry Smith     }
713ca90d2dSJacob Faibussowitsch     ++i;
723ca90d2dSJacob Faibussowitsch     ++sz;
73d781fa04SBarry Smith   }
743ca90d2dSJacob Faibussowitsch   *size = sz + 1; /* space for NULL character */
753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
76d781fa04SBarry Smith }
77d781fa04SBarry Smith 
78d781fa04SBarry Smith /*@C
79058c9ee1SBarry Smith      PetscFormatConvert - converts %g to [|%g|] so that `PetscVSNPrintf()` can ensure all %g formatted numbers have a decimal point when printed. The
80058c9ee1SBarry Smith      decimal point is then used by the `petscdiff` script so that differences in floating point number output is ignored in the test harness.
81d781fa04SBarry Smith 
82058c9ee1SBarry Smith    No Fortran Support
83811af0c4SBarry Smith 
84d781fa04SBarry Smith    Input Parameters:
85d781fa04SBarry Smith +   format - the PETSc format string
86d781fa04SBarry Smith .   newformat - the location to put the new format
87811af0c4SBarry Smith -   size - the length of newformat, you can use `PetscFormatConvertGetSize()` to compute the needed size
88d781fa04SBarry Smith 
89d781fa04SBarry Smith    Level: developer
90d781fa04SBarry Smith 
91058c9ee1SBarry Smith     Note:
92058c9ee1SBarry Smith     Deprecated usage also converts the %D to %d for 32 bit PETSc indices and %lld for 64 bit PETSc indices. This feature is no
93058c9ee1SBarry Smith     longer used in PETSc code instead use %" PetscInt_FMT " in the format string
94058c9ee1SBarry Smith 
95db781477SPatrick Sanan .seealso: `PetscFormatConvertGetSize()`, `PetscVSNPrintf()`, `PetscVFPrintf()`
96d781fa04SBarry Smith @*/
97d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatConvert(const char *format, char *newformat)
98d71ae5a4SJacob Faibussowitsch {
99e5c89e4eSSatish Balay   PetscInt i = 0, j = 0;
100e5c89e4eSSatish Balay 
101eed5747fSBarry Smith   PetscFunctionBegin;
102d781fa04SBarry Smith   while (format[i]) {
1032a1ad9caSBarry Smith     if (format[i] == '%' && format[i + 1] == '%') {
1042a1ad9caSBarry Smith       newformat[j++] = format[i++];
1052a1ad9caSBarry Smith       newformat[j++] = format[i++];
1062a1ad9caSBarry Smith     } else if (format[i] == '%') {
1078627564fSBarry Smith       if (format[i + 1] == 'g') {
1088627564fSBarry Smith         newformat[j++] = '[';
1098627564fSBarry Smith         newformat[j++] = '|';
1108627564fSBarry Smith       }
1117bc47156SJose Roman       /* Find the letter */
1127bc47156SJose Roman       for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i];
1137bc47156SJose Roman       switch (format[i]) {
1147bc47156SJose Roman       case 'D':
1156de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES)
116e5c89e4eSSatish Balay         newformat[j++] = 'd';
117e5c89e4eSSatish Balay #else
118e5c89e4eSSatish Balay         newformat[j++] = 'l';
119e5c89e4eSSatish Balay         newformat[j++] = 'l';
120e5c89e4eSSatish Balay         newformat[j++] = 'd';
121e5c89e4eSSatish Balay #endif
1227bc47156SJose Roman         break;
1238627564fSBarry Smith       case 'g':
1248627564fSBarry Smith         newformat[j++] = format[i];
1258627564fSBarry Smith         if (format[i - 1] == '%') {
1268627564fSBarry Smith           newformat[j++] = '|';
1278627564fSBarry Smith           newformat[j++] = ']';
1288627564fSBarry Smith         }
1298627564fSBarry Smith         break;
130d71ae5a4SJacob Faibussowitsch       case 'G':
131d71ae5a4SJacob Faibussowitsch         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%G format is no longer supported, use %%g and cast the argument to double");
132d71ae5a4SJacob Faibussowitsch       case 'F':
133d71ae5a4SJacob Faibussowitsch         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%F format is no longer supported, use %%f and cast the argument to double");
134d71ae5a4SJacob Faibussowitsch       default:
135d71ae5a4SJacob Faibussowitsch         newformat[j++] = format[i];
136d71ae5a4SJacob Faibussowitsch         break;
1377bc47156SJose Roman       }
1387bc47156SJose Roman       i++;
139a297a907SKarl Rupp     } else newformat[j++] = format[i++];
140e5c89e4eSSatish Balay   }
141e5c89e4eSSatish Balay   newformat[j] = 0;
1423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
143e5c89e4eSSatish Balay }
144e5c89e4eSSatish Balay 
14514416c0eSBarry Smith #define PETSCDEFAULTBUFFERSIZE 8 * 1024
146d781fa04SBarry Smith 
147c9a19010SBarry Smith /*@C
1486026c97aSBarry Smith      PetscVSNPrintf - The PETSc version of `vsnprintf()`. Ensures that all `%g` formatted arguments' output contains the decimal point (which
149058c9ee1SBarry Smith      is used by the test harness)
150c9a19010SBarry Smith 
151c9a19010SBarry Smith    Input Parameters:
152c9a19010SBarry Smith +   str - location to put result
153c9a19010SBarry Smith .   len - the amount of space in str
154c9a19010SBarry Smith +   format - the PETSc format string
155c9a19010SBarry Smith -   fullLength - the amount of space in str actually used.
156c9a19010SBarry Smith 
157c9a19010SBarry Smith    Level: developer
158c9a19010SBarry Smith 
159058c9ee1SBarry Smith    Developer Note:
160058c9ee1SBarry Smith    This function may be called from an error handler, if an error occurs when it is called by the error handler than likely
161058c9ee1SBarry Smith    a recursion will occur resulting in a crash of the program.
162058c9ee1SBarry Smith 
1636026c97aSBarry Smith    If the length of the format string `format` is on the order of `PETSCDEFAULTBUFFERSIZE` (8 * 1024 bytes), this function will call `PetscMalloc()`
164058c9ee1SBarry Smith 
165058c9ee1SBarry Smith .seealso: `PetscFormatConvert()`, `PetscFormatConvertGetSize()`, `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscVPrintf()`
166c9a19010SBarry Smith @*/
167d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVSNPrintf(char *str, size_t len, const char *format, size_t *fullLength, va_list Argp)
168d71ae5a4SJacob Faibussowitsch {
169d781fa04SBarry Smith   char  *newformat = NULL;
17014416c0eSBarry Smith   char   formatbuf[PETSCDEFAULTBUFFERSIZE];
171d781fa04SBarry Smith   size_t newLength;
17214416c0eSBarry Smith   int    flen;
173e5c89e4eSSatish Balay 
174eed5747fSBarry Smith   PetscFunctionBegin;
1759566063dSJacob Faibussowitsch   PetscCall(PetscFormatConvertGetSize(format, &newLength));
17694217ebdSBarry Smith   if (newLength < sizeof(formatbuf)) {
177e2135aedSMatthew Knepley     newformat = formatbuf;
17894217ebdSBarry Smith     newLength = sizeof(formatbuf) - 1;
179e2135aedSMatthew Knepley   } else {
1809566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(newLength, &newformat));
181e2135aedSMatthew Knepley   }
1829566063dSJacob Faibussowitsch   PetscCall(PetscFormatConvert(format, newformat));
1837b9a2d1bSSatish Balay #if defined(PETSC_HAVE_VSNPRINTF)
184152b30f0SSatish Balay   flen = vsnprintf(str, len, newformat, Argp);
185e5c89e4eSSatish Balay #else
18689b07760SSatish Balay   #error "vsnprintf not found"
187e5c89e4eSSatish Balay #endif
18848a46eb9SPierre Jolivet   if (newLength > sizeof(formatbuf) - 1) PetscCall(PetscFree(newformat));
1898627564fSBarry Smith   {
1908627564fSBarry Smith     PetscBool foundedot;
1918627564fSBarry Smith     size_t    cnt = 0, ncnt = 0, leng;
1929566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(str, &leng));
19317ca8410SBarry Smith     if (leng > 4) {
1948627564fSBarry Smith       for (cnt = 0; cnt < leng - 4; cnt++) {
1958627564fSBarry Smith         if (str[cnt] == '[' && str[cnt + 1] == '|') {
196c540d043SBarry Smith           flen -= 4;
1979371c9d4SSatish Balay           cnt++;
1989371c9d4SSatish Balay           cnt++;
1998627564fSBarry Smith           foundedot = PETSC_FALSE;
2008627564fSBarry Smith           for (; cnt < leng - 1; cnt++) {
2018627564fSBarry Smith             if (str[cnt] == '|' && str[cnt + 1] == ']') {
2028627564fSBarry Smith               cnt++;
2038627564fSBarry Smith               if (!foundedot) str[ncnt++] = '.';
2048627564fSBarry Smith               ncnt--;
2058627564fSBarry Smith               break;
2068627564fSBarry Smith             } else {
2078627564fSBarry Smith               if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE;
2088627564fSBarry Smith               str[ncnt++] = str[cnt];
2098627564fSBarry Smith             }
2108627564fSBarry Smith           }
2118627564fSBarry Smith         } else {
2128627564fSBarry Smith           str[ncnt] = str[cnt];
2138627564fSBarry Smith         }
2148627564fSBarry Smith         ncnt++;
2158627564fSBarry Smith       }
2168627564fSBarry Smith       while (cnt < leng) {
2179371c9d4SSatish Balay         str[ncnt] = str[cnt];
2189371c9d4SSatish Balay         ncnt++;
2199371c9d4SSatish Balay         cnt++;
2208627564fSBarry Smith       }
2218627564fSBarry Smith       str[ncnt] = 0;
2228627564fSBarry Smith     }
2238627564fSBarry Smith   }
224748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT)
225e51f71cfSBarry Smith   /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */
226748e1b9dSBarry Smith   {
227748e1b9dSBarry Smith     size_t cnt = 0, ncnt = 0, leng;
2289566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(str, &leng));
229748e1b9dSBarry Smith     if (leng > 5) {
230748e1b9dSBarry Smith       for (cnt = 0; cnt < leng - 4; cnt++) {
231e51f71cfSBarry Smith         if (str[cnt] == 'e' && (str[cnt + 1] == '-' || str[cnt + 1] == '+') && str[cnt + 2] == '0' && str[cnt + 3] >= '0' && str[cnt + 3] <= '9' && str[cnt + 4] >= '0' && str[cnt + 4] <= '9') {
2329371c9d4SSatish Balay           str[ncnt] = str[cnt];
2339371c9d4SSatish Balay           ncnt++;
2349371c9d4SSatish Balay           cnt++;
2359371c9d4SSatish Balay           str[ncnt] = str[cnt];
2369371c9d4SSatish Balay           ncnt++;
2379371c9d4SSatish Balay           cnt++;
2389371c9d4SSatish Balay           cnt++;
239e51f71cfSBarry Smith           str[ncnt] = str[cnt];
240748e1b9dSBarry Smith         } else {
241748e1b9dSBarry Smith           str[ncnt] = str[cnt];
242748e1b9dSBarry Smith         }
243748e1b9dSBarry Smith         ncnt++;
244748e1b9dSBarry Smith       }
245748e1b9dSBarry Smith       while (cnt < leng) {
2469371c9d4SSatish Balay         str[ncnt] = str[cnt];
2479371c9d4SSatish Balay         ncnt++;
2489371c9d4SSatish Balay         cnt++;
249748e1b9dSBarry Smith       }
250748e1b9dSBarry Smith       str[ncnt] = 0;
251748e1b9dSBarry Smith     }
252748e1b9dSBarry Smith   }
253748e1b9dSBarry Smith #endif
254c540d043SBarry Smith   if (fullLength) *fullLength = 1 + (size_t)flen;
2553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
256e5c89e4eSSatish Balay }
257e5c89e4eSSatish Balay 
258c9a19010SBarry Smith /*@C
259*c69effb2SJacob Faibussowitsch   PetscFFlush - Flush a file stream
260*c69effb2SJacob Faibussowitsch 
261*c69effb2SJacob Faibussowitsch   Input Parameter:
262*c69effb2SJacob Faibussowitsch . fd - The file stream handle
263*c69effb2SJacob Faibussowitsch 
264*c69effb2SJacob Faibussowitsch   Level: intermediate
265*c69effb2SJacob Faibussowitsch 
266*c69effb2SJacob Faibussowitsch   Notes:
267*c69effb2SJacob Faibussowitsch   For output streams (and for update streams on which the last operation was output), writes
268*c69effb2SJacob Faibussowitsch   any unwritten data from the stream's buffer to the associated output device.
269*c69effb2SJacob Faibussowitsch 
270*c69effb2SJacob Faibussowitsch   For input streams (and for update streams on which the last operation was input), the
271*c69effb2SJacob Faibussowitsch   behavior is undefined.
272*c69effb2SJacob Faibussowitsch 
273*c69effb2SJacob Faibussowitsch   If `fd` is `NULL`, all open output streams are flushed, including ones not directly
274*c69effb2SJacob Faibussowitsch   accessible to the program.
275*c69effb2SJacob Faibussowitsch 
276*c69effb2SJacob Faibussowitsch .seealso: `PetscPrintf()`, `PetscFPrintf()`, `PetscVFPrintf()`, `PetscVSNPrintf()`
277*c69effb2SJacob Faibussowitsch @*/
278*c69effb2SJacob Faibussowitsch PetscErrorCode PetscFFlush(FILE *fd)
279*c69effb2SJacob Faibussowitsch {
280*c69effb2SJacob Faibussowitsch   int ret;
281*c69effb2SJacob Faibussowitsch 
282*c69effb2SJacob Faibussowitsch   PetscFunctionBegin;
283*c69effb2SJacob Faibussowitsch   if (fd) PetscValidPointer(fd, 1);
284*c69effb2SJacob Faibussowitsch   ret = fflush(fd);
285*c69effb2SJacob Faibussowitsch   // could also use PetscCallExternal() here, but since we can get additional error explanation
286*c69effb2SJacob Faibussowitsch   // from strerror() we opted for a manual check
287*c69effb2SJacob Faibussowitsch   PetscCheck(ret == 0, PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE, "Error in fflush(): error code %d (%s)", ret, strerror(errno));
288*c69effb2SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
289*c69effb2SJacob Faibussowitsch }
290*c69effb2SJacob Faibussowitsch 
291*c69effb2SJacob Faibussowitsch /*@C
292c9a19010SBarry Smith      PetscVFPrintf -  All PETSc standard out and error messages are sent through this function; so, in theory, this can
293e5c89e4eSSatish Balay         can be replaced with something that does not simply write to a file.
294e5c89e4eSSatish Balay 
295c9a19010SBarry Smith       To use, write your own function for example,
296058c9ee1SBarry Smith .vb
297058c9ee1SBarry Smith    PetscErrorCode mypetscvfprintf(FILE *fd, const char format[], va_list Argp)
298058c9ee1SBarry Smith    {
299058c9ee1SBarry Smith      PetscErrorCode ierr;
300058c9ee1SBarry Smith 
301058c9ee1SBarry Smith      PetscFunctionBegin;
302058c9ee1SBarry Smith       if (fd != stdout && fd != stderr) {  handle regular files
303058c9ee1SBarry Smith          CHKERR(PetscVFPrintfDefault(fd,format,Argp));
304058c9ee1SBarry Smith      } else {
305058c9ee1SBarry Smith         char   buff[BIG];
306058c9ee1SBarry Smith         size_t length;
307058c9ee1SBarry Smith         PetscCall(PetscVSNPrintf(buff,BIG,format,&length,Argp));
308058c9ee1SBarry Smith         now send buff to whatever stream or whatever you want
309058c9ee1SBarry Smith     }
310058c9ee1SBarry Smith     PetscFunctionReturn(PETSC_SUCCESS);
311058c9ee1SBarry Smith    }
312058c9ee1SBarry Smith .ve
313058c9ee1SBarry Smith    then before the call to `PetscInitialize()` do the assignment `PetscVFPrintf = mypetscvfprintf`;
314058c9ee1SBarry Smith 
315058c9ee1SBarry Smith   Level:  developer
316c9a19010SBarry Smith 
317811af0c4SBarry Smith    Note:
31895452b02SPatrick Sanan    For error messages this may be called by any process, for regular standard out it is
319e5c89e4eSSatish Balay    called only by process 0 of a given communicator
320e5c89e4eSSatish Balay 
321811af0c4SBarry Smith    Developer Note:
322058c9ee1SBarry Smith    This could be called by an error handler, if that happens then a recursion of the error handler may occur
323058c9ee1SBarry Smith    and a resulting crash
324c9a19010SBarry Smith 
325*c69effb2SJacob Faibussowitsch .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscFFlush()`
326c9a19010SBarry Smith @*/
327d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVFPrintfDefault(FILE *fd, const char *format, va_list Argp)
328d71ae5a4SJacob Faibussowitsch {
32914416c0eSBarry Smith   char   str[PETSCDEFAULTBUFFERSIZE];
33014416c0eSBarry Smith   char  *buff = str;
33114416c0eSBarry Smith   size_t fullLength;
3321531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY)
33314416c0eSBarry Smith   va_list Argpcopy;
3341531940fSBarry Smith #endif
3351179db26SBarry Smith 
336eed5747fSBarry Smith   PetscFunctionBegin;
3371531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY)
33814416c0eSBarry Smith   va_copy(Argpcopy, Argp);
3391531940fSBarry Smith #endif
3409566063dSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(str, sizeof(str), format, &fullLength, Argp));
34114416c0eSBarry Smith   if (fullLength > sizeof(str)) {
3429566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(fullLength, &buff));
3431531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY)
3449566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(buff, fullLength, format, NULL, Argpcopy));
3451531940fSBarry Smith #else
3461531940fSBarry Smith     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "C89 does not support va_copy() hence cannot print long strings with PETSc printing routines");
3471531940fSBarry Smith #endif
34814416c0eSBarry Smith   }
349*c69effb2SJacob Faibussowitsch   {
350*c69effb2SJacob Faibussowitsch     const int err = fprintf(fd, "%s", buff);
351*c69effb2SJacob Faibussowitsch     // cannot use PetscCallExternal() for fprintf since the return value is "number of
352*c69effb2SJacob Faibussowitsch     // characters transmitted to the output stream" on success
353*c69effb2SJacob Faibussowitsch     PetscCheck(err >= 0, PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE, "fprintf() returned error code %d", err);
354*c69effb2SJacob Faibussowitsch   }
355*c69effb2SJacob Faibussowitsch   PetscCall(PetscFFlush(fd));
35648a46eb9SPierre Jolivet   if (buff != str) PetscCall(PetscFree(buff));
3573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
358e5c89e4eSSatish Balay }
359e5c89e4eSSatish Balay 
3605b5bc046SBarry Smith /*@C
3615b5bc046SBarry Smith     PetscSNPrintf - Prints to a string of given length
3625b5bc046SBarry Smith 
3635b5bc046SBarry Smith     Not Collective
3645b5bc046SBarry Smith 
3655b5bc046SBarry Smith     Input Parameters:
3665b5bc046SBarry Smith +   str - the string to print to
367058c9ee1SBarry Smith .   len - the length of `str`
368058c9ee1SBarry Smith .   format - the usual `printf()` format string
36910699b91SBarry Smith -   ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument
3705b5bc046SBarry Smith 
3715b5bc046SBarry Smith    Level: intermediate
3725b5bc046SBarry Smith 
373db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`,
374*c69effb2SJacob Faibussowitsch           `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`,
375*c69effb2SJacob Faibussowitsch           `PetscVFPrintf()`, `PetscFFlush()`
3765b5bc046SBarry Smith @*/
377d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintf(char *str, size_t len, const char format[], ...)
378d71ae5a4SJacob Faibussowitsch {
379c9a19010SBarry Smith   size_t  fullLength;
3805b5bc046SBarry Smith   va_list Argp;
3815b5bc046SBarry Smith 
3825b5bc046SBarry Smith   PetscFunctionBegin;
3835b5bc046SBarry Smith   va_start(Argp, format);
3849566063dSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(str, len, format, &fullLength, Argp));
3853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3865b5bc046SBarry Smith }
3875b5bc046SBarry Smith 
388257d2499SJed Brown /*@C
389058c9ee1SBarry Smith     PetscSNPrintfCount - Prints to a string of given length, returns count of characters printed
390257d2499SJed Brown 
391257d2499SJed Brown     Not Collective
392257d2499SJed Brown 
393257d2499SJed Brown     Input Parameters:
394257d2499SJed Brown +   str - the string to print to
395058c9ee1SBarry Smith .   len - the length of `str`
396058c9ee1SBarry Smith .   format - the usual `printf()` format string
39710699b91SBarry Smith -   ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument
398257d2499SJed Brown 
399cb398dd3SBarry Smith     Output Parameter:
400058c9ee1SBarry Smith .   countused - number of characters printed
401cb398dd3SBarry Smith 
402257d2499SJed Brown    Level: intermediate
403257d2499SJed Brown 
404db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`,
405db781477SPatrick Sanan           `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscSNPrintf()`, `PetscVFPrintf()`
406257d2499SJed Brown @*/
407d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintfCount(char *str, size_t len, const char format[], size_t *countused, ...)
408d71ae5a4SJacob Faibussowitsch {
409257d2499SJed Brown   va_list Argp;
410257d2499SJed Brown 
411257d2499SJed Brown   PetscFunctionBegin;
412257d2499SJed Brown   va_start(Argp, countused);
4139566063dSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(str, len, format, countused, Argp));
4143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
415257d2499SJed Brown }
416257d2499SJed Brown 
417e5c89e4eSSatish Balay /* ----------------------------------------------------------------------- */
418e5c89e4eSSatish Balay 
41902c9f0b5SLisandro Dalcin PrintfQueue petsc_printfqueue = NULL, petsc_printfqueuebase = NULL;
420d30b0576SJed Brown int         petsc_printfqueuelength = 0;
421e5c89e4eSSatish Balay 
422e5c89e4eSSatish Balay /*@C
423e5c89e4eSSatish Balay     PetscSynchronizedPrintf - Prints synchronized output from several processors.
424e5c89e4eSSatish Balay     Output of the first processor is followed by that of the second, etc.
425e5c89e4eSSatish Balay 
426e5c89e4eSSatish Balay     Not Collective
427e5c89e4eSSatish Balay 
428e5c89e4eSSatish Balay     Input Parameters:
429058c9ee1SBarry Smith +   comm - the MPI communicator
4306026c97aSBarry Smith -   format - the usual `printf()` format string
431e5c89e4eSSatish Balay 
432e5c89e4eSSatish Balay    Level: intermediate
433e5c89e4eSSatish Balay 
434811af0c4SBarry Smith     Note:
435811af0c4SBarry Smith     REQUIRES a call to `PetscSynchronizedFlush()` by all the processes after the completion of the calls to `PetscSynchronizedPrintf()` for the information
436e5c89e4eSSatish Balay     from all the processors to be printed.
437e5c89e4eSSatish Balay 
438e5c89e4eSSatish Balay     Fortran Note:
439058c9ee1SBarry Smith     The call sequence is `PetscSynchronizedPrintf`(`MPI_Comm`, `character`(*), `PetscErrorCode` ierr).
440e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
441e5c89e4eSSatish Balay 
442db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`,
443*c69effb2SJacob Faibussowitsch           `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`,
444*c69effb2SJacob Faibussowitsch           `PetscFFlush()`
445e5c89e4eSSatish Balay @*/
446d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm, const char format[], ...)
447d71ae5a4SJacob Faibussowitsch {
448e5c89e4eSSatish Balay   PetscMPIInt rank;
449e5c89e4eSSatish Balay 
450e5c89e4eSSatish Balay   PetscFunctionBegin;
45108401ef6SPierre Jolivet   PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
4529566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
453e5c89e4eSSatish Balay 
454e5c89e4eSSatish Balay   /* First processor prints immediately to stdout */
455dd400576SPatrick Sanan   if (rank == 0) {
456e5c89e4eSSatish Balay     va_list Argp;
457e5c89e4eSSatish Balay     va_start(Argp, format);
4589566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(PETSC_STDOUT, format, Argp));
459e5c89e4eSSatish Balay     if (petsc_history) {
460cdc7d174SSatish Balay       va_start(Argp, format);
4619566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
462e5c89e4eSSatish Balay     }
463e5c89e4eSSatish Balay     va_end(Argp);
464e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
465e5c89e4eSSatish Balay     va_list     Argp;
466e5c89e4eSSatish Balay     PrintfQueue next;
46714416c0eSBarry Smith     size_t      fullLength = PETSCDEFAULTBUFFERSIZE;
468e5c89e4eSSatish Balay 
4699566063dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
470a297a907SKarl Rupp     if (petsc_printfqueue) {
471a297a907SKarl Rupp       petsc_printfqueue->next = next;
472a297a907SKarl Rupp       petsc_printfqueue       = next;
47302c9f0b5SLisandro Dalcin       petsc_printfqueue->next = NULL;
474a297a907SKarl Rupp     } else petsc_printfqueuebase = petsc_printfqueue = next;
475d30b0576SJed Brown     petsc_printfqueuelength++;
47694217ebdSBarry Smith     next->size   = 0;
47714416c0eSBarry Smith     next->string = NULL;
47894217ebdSBarry Smith     while (fullLength >= next->size) {
4792d609e63SMatthew Knepley       next->size = fullLength + 1;
4809566063dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
4819566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(next->size, &next->string));
482e5c89e4eSSatish Balay       va_start(Argp, format);
4839566063dSJacob Faibussowitsch       PetscCall(PetscArrayzero(next->string, next->size));
4849566063dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, Argp));
485e5c89e4eSSatish Balay       va_end(Argp);
486e5c89e4eSSatish Balay     }
4872d609e63SMatthew Knepley   }
4883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
489e5c89e4eSSatish Balay }
490e5c89e4eSSatish Balay 
491e5c89e4eSSatish Balay /*@C
492e5c89e4eSSatish Balay     PetscSynchronizedFPrintf - Prints synchronized output to the specified file from
493e5c89e4eSSatish Balay     several processors.  Output of the first processor is followed by that of the
494e5c89e4eSSatish Balay     second, etc.
495e5c89e4eSSatish Balay 
496e5c89e4eSSatish Balay     Not Collective
497e5c89e4eSSatish Balay 
498e5c89e4eSSatish Balay     Input Parameters:
499058c9ee1SBarry Smith +   comm - the MPI communicator
500e5c89e4eSSatish Balay .   fd - the file pointer
5016026c97aSBarry Smith -   format - the usual `printf()` format string
502e5c89e4eSSatish Balay 
503e5c89e4eSSatish Balay     Level: intermediate
504e5c89e4eSSatish Balay 
505811af0c4SBarry Smith     Note:
506811af0c4SBarry Smith     REQUIRES a intervening call to `PetscSynchronizedFlush()` for the information
507e5c89e4eSSatish Balay     from all the processors to be printed.
508e5c89e4eSSatish Balay 
509db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFPrintf()`,
510*c69effb2SJacob Faibussowitsch           `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
511*c69effb2SJacob Faibussowitsch           `PetscFFlush()`
512e5c89e4eSSatish Balay @*/
513d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm, FILE *fp, const char format[], ...)
514d71ae5a4SJacob Faibussowitsch {
515e5c89e4eSSatish Balay   PetscMPIInt rank;
516e5c89e4eSSatish Balay 
517e5c89e4eSSatish Balay   PetscFunctionBegin;
51808401ef6SPierre Jolivet   PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
5199566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
520e5c89e4eSSatish Balay 
521e5c89e4eSSatish Balay   /* First processor prints immediately to fp */
522dd400576SPatrick Sanan   if (rank == 0) {
523e5c89e4eSSatish Balay     va_list Argp;
524e5c89e4eSSatish Balay     va_start(Argp, format);
5259566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fp, format, Argp));
526cdc7d174SSatish Balay     if (petsc_history && (fp != petsc_history)) {
527cdc7d174SSatish Balay       va_start(Argp, format);
5289566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
529e5c89e4eSSatish Balay     }
530e5c89e4eSSatish Balay     va_end(Argp);
531e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
532e5c89e4eSSatish Balay     va_list     Argp;
533e5c89e4eSSatish Balay     PrintfQueue next;
53414416c0eSBarry Smith     size_t      fullLength = PETSCDEFAULTBUFFERSIZE;
53514416c0eSBarry Smith 
5369566063dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
537a297a907SKarl Rupp     if (petsc_printfqueue) {
538a297a907SKarl Rupp       petsc_printfqueue->next = next;
539a297a907SKarl Rupp       petsc_printfqueue       = next;
54002c9f0b5SLisandro Dalcin       petsc_printfqueue->next = NULL;
541a297a907SKarl Rupp     } else petsc_printfqueuebase = petsc_printfqueue = next;
542d30b0576SJed Brown     petsc_printfqueuelength++;
54394217ebdSBarry Smith     next->size   = 0;
54414416c0eSBarry Smith     next->string = NULL;
54594217ebdSBarry Smith     while (fullLength >= next->size) {
5462d609e63SMatthew Knepley       next->size = fullLength + 1;
5479566063dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
5489566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(next->size, &next->string));
549e5c89e4eSSatish Balay       va_start(Argp, format);
5509566063dSJacob Faibussowitsch       PetscCall(PetscArrayzero(next->string, next->size));
5519566063dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, Argp));
552e5c89e4eSSatish Balay       va_end(Argp);
553e5c89e4eSSatish Balay     }
5542d609e63SMatthew Knepley   }
5553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
556e5c89e4eSSatish Balay }
557e5c89e4eSSatish Balay 
5580ec8b6e3SBarry Smith /*@C
559e5c89e4eSSatish Balay     PetscSynchronizedFlush - Flushes to the screen output from all processors
560811af0c4SBarry Smith     involved in previous `PetscSynchronizedPrintf()`/`PetscSynchronizedFPrintf()` calls.
561e5c89e4eSSatish Balay 
562d083f849SBarry Smith     Collective
563e5c89e4eSSatish Balay 
564e5c89e4eSSatish Balay     Input Parameters:
565058c9ee1SBarry Smith +   comm - the MPI communicator
5660ec8b6e3SBarry Smith -   fd - the file pointer (valid on process 0 of the communicator)
567e5c89e4eSSatish Balay 
568e5c89e4eSSatish Balay     Level: intermediate
569e5c89e4eSSatish Balay 
570811af0c4SBarry Smith     Note:
571811af0c4SBarry Smith     If `PetscSynchronizedPrintf()` and/or `PetscSynchronizedFPrintf()` are called with
572811af0c4SBarry Smith     different MPI communicators there must be an intervening call to `PetscSynchronizedFlush()` between the calls with different MPI communicators.
573e5c89e4eSSatish Balay 
574811af0c4SBarry Smith     Fortran Note:
575811af0c4SBarry Smith     Pass `PETSC_STDOUT` if the flush is for standard out; otherwise pass a value obtained from `PetscFOpen()`
576e50bf69fSBarry Smith 
577db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscFPrintf()`, `PetscPrintf()`, `PetscViewerASCIIPrintf()`,
578db781477SPatrick Sanan           `PetscViewerASCIISynchronizedPrintf()`
5790087d953SMatthew G. Knepley @*/
580d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm, FILE *fd)
581d71ae5a4SJacob Faibussowitsch {
58229a5cbdcSMatthew G. Knepley   PetscMPIInt rank, size, tag, i, j, n = 0, dummy = 0;
5832d609e63SMatthew Knepley   char       *message;
584e5c89e4eSSatish Balay   MPI_Status  status;
585e5c89e4eSSatish Balay 
586e5c89e4eSSatish Balay   PetscFunctionBegin;
5879566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &comm, &tag));
5889566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
5899566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
590e5c89e4eSSatish Balay 
591e5c89e4eSSatish Balay   /* First processor waits for messages from all other processors */
592dd400576SPatrick Sanan   if (rank == 0) {
5930ec8b6e3SBarry Smith     if (!fd) fd = PETSC_STDOUT;
594e5c89e4eSSatish Balay     for (i = 1; i < size; i++) {
5959f73f8ecSBarry Smith       /* to prevent a flood of messages to process zero, request each message separately */
5969566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm));
5979566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status));
598e5c89e4eSSatish Balay       for (j = 0; j < n; j++) {
59929a5cbdcSMatthew G. Knepley         PetscMPIInt size = 0;
6002d609e63SMatthew Knepley 
6019566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status));
6029566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &message));
6039566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status));
6049566063dSJacob Faibussowitsch         PetscCall(PetscFPrintf(comm, fd, "%s", message));
6059566063dSJacob Faibussowitsch         PetscCall(PetscFree(message));
606e5c89e4eSSatish Balay       }
607e5c89e4eSSatish Balay     }
608e5c89e4eSSatish Balay   } else { /* other processors send queue to processor 0 */
609d30b0576SJed Brown     PrintfQueue next = petsc_printfqueuebase, previous;
610e5c89e4eSSatish Balay 
6119566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status));
6129566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Send(&petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm));
613d30b0576SJed Brown     for (i = 0; i < petsc_printfqueuelength; i++) {
6149566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm));
6159566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(next->string, next->size, MPI_CHAR, 0, tag, comm));
616e5c89e4eSSatish Balay       previous = next;
617e5c89e4eSSatish Balay       next     = next->next;
6189566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
6199566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
620e5c89e4eSSatish Balay     }
62102c9f0b5SLisandro Dalcin     petsc_printfqueue       = NULL;
622d30b0576SJed Brown     petsc_printfqueuelength = 0;
623e5c89e4eSSatish Balay   }
6249566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&comm));
6253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
626e5c89e4eSSatish Balay }
627e5c89e4eSSatish Balay 
628e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
629e5c89e4eSSatish Balay 
630e5c89e4eSSatish Balay /*@C
631e5c89e4eSSatish Balay     PetscFPrintf - Prints to a file, only from the first
632e5c89e4eSSatish Balay     processor in the communicator.
633e5c89e4eSSatish Balay 
634cf53795eSBarry Smith     Not Collective; No Fortran Support
635e5c89e4eSSatish Balay 
636e5c89e4eSSatish Balay     Input Parameters:
637058c9ee1SBarry Smith +   comm - the MPI communicator
638e5c89e4eSSatish Balay .   fd - the file pointer
6396026c97aSBarry Smith -   format - the usual `printf()` format string
640e5c89e4eSSatish Balay 
641e5c89e4eSSatish Balay     Level: intermediate
642e5c89e4eSSatish Balay 
643058c9ee1SBarry Smith     Developer Note:
644058c9ee1SBarry Smith     This maybe, and is, called from PETSc error handlers and `PetscMallocValidate()` hence it does not use `PetscCallMPI()` which
645058c9ee1SBarry Smith     could recursively restart the malloc validation.
646058c9ee1SBarry Smith 
647db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
648*c69effb2SJacob Faibussowitsch           `PetscViewerASCIISynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFFlush()`
649e5c89e4eSSatish Balay @*/
650d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFPrintf(MPI_Comm comm, FILE *fd, const char format[], ...)
651d71ae5a4SJacob Faibussowitsch {
652e5c89e4eSSatish Balay   PetscMPIInt rank;
653e5c89e4eSSatish Balay 
654e5c89e4eSSatish Balay   PetscFunctionBegin;
65508401ef6SPierre Jolivet   PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
6566026c97aSBarry Smith   PetscCheck(MPI_SUCCESS == MPI_Comm_rank(comm, &rank), comm, PETSC_ERR_MPI, "Error inside MPI_Comm_rank() in PetscFPrintf");
657dd400576SPatrick Sanan   if (rank == 0) {
658e5c89e4eSSatish Balay     va_list Argp;
659e5c89e4eSSatish Balay     va_start(Argp, format);
6609566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fd, format, Argp));
661cdc7d174SSatish Balay     if (petsc_history && (fd != petsc_history)) {
662cdc7d174SSatish Balay       va_start(Argp, format);
6639566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
664e5c89e4eSSatish Balay     }
665e5c89e4eSSatish Balay     va_end(Argp);
666e5c89e4eSSatish Balay   }
6673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
668e5c89e4eSSatish Balay }
669e5c89e4eSSatish Balay 
670e5c89e4eSSatish Balay /*@C
671e5c89e4eSSatish Balay     PetscPrintf - Prints to standard out, only from the first
672eed5747fSBarry Smith     processor in the communicator. Calls from other processes are ignored.
673e5c89e4eSSatish Balay 
674e5c89e4eSSatish Balay     Not Collective
675e5c89e4eSSatish Balay 
676e5c89e4eSSatish Balay     Input Parameters:
677e5c89e4eSSatish Balay +   comm - the communicator
678e5c89e4eSSatish Balay -   format - the usual printf() format string
679e5c89e4eSSatish Balay 
680e5c89e4eSSatish Balay     Level: intermediate
681e5c89e4eSSatish Balay 
682811af0c4SBarry Smith     Note:
683811af0c4SBarry Smith     Deprecated information: `PetscPrintf()` supports some format specifiers that are unique to PETSc.
684811af0c4SBarry Smith     See the manual page for `PetscFormatConvert()` for details.
685b2706f25SRichard Tran Mills 
686e5c89e4eSSatish Balay     Fortran Note:
687811af0c4SBarry Smith     The call sequence is `PetscPrintf`(MPI_Comm, character(*), `PetscErrorCode` ierr) from Fortran.
688e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
689e5c89e4eSSatish Balay 
690*c69effb2SJacob Faibussowitsch .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscFormatConvert()`, `PetscFFlush()`
691e5c89e4eSSatish Balay @*/
692d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPrintf(MPI_Comm comm, const char format[], ...)
693d71ae5a4SJacob Faibussowitsch {
694e5c89e4eSSatish Balay   PetscMPIInt rank;
695e5c89e4eSSatish Balay 
696e5c89e4eSSatish Balay   PetscFunctionBegin;
69708401ef6SPierre Jolivet   PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
6989566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
699dd400576SPatrick Sanan   if (rank == 0) {
700e5c89e4eSSatish Balay     va_list Argp;
701e5c89e4eSSatish Balay     va_start(Argp, format);
7029566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(PETSC_STDOUT, format, Argp));
703e5c89e4eSSatish Balay     if (petsc_history) {
704cdc7d174SSatish Balay       va_start(Argp, format);
7059566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
706e5c89e4eSSatish Balay     }
707e5c89e4eSSatish Balay     va_end(Argp);
708e5c89e4eSSatish Balay   }
7093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
710e5c89e4eSSatish Balay }
711e5c89e4eSSatish Balay 
712d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm, const char format[], ...)
713d71ae5a4SJacob Faibussowitsch {
714e5c89e4eSSatish Balay   PetscMPIInt rank;
715e5c89e4eSSatish Balay 
716e5c89e4eSSatish Balay   PetscFunctionBegin;
71708401ef6SPierre Jolivet   PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
7189566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
719dd400576SPatrick Sanan   if (rank == 0) {
720e5c89e4eSSatish Balay     va_list Argp;
721e5c89e4eSSatish Balay     va_start(Argp, format);
7229566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(PETSC_STDOUT, format, Argp));
723e5c89e4eSSatish Balay     if (petsc_history) {
724cdc7d174SSatish Balay       va_start(Argp, format);
7259566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
726e5c89e4eSSatish Balay     }
727e5c89e4eSSatish Balay     va_end(Argp);
728e5c89e4eSSatish Balay   }
7293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
730e5c89e4eSSatish Balay }
731e5c89e4eSSatish Balay 
732e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
733e5c89e4eSSatish Balay 
734e5c89e4eSSatish Balay /*@C
735e5c89e4eSSatish Balay     PetscSynchronizedFGets - Several processors all get the same line from a file.
736e5c89e4eSSatish Balay 
737d083f849SBarry Smith     Collective
738e5c89e4eSSatish Balay 
739e5c89e4eSSatish Balay     Input Parameters:
740e5c89e4eSSatish Balay +   comm - the communicator
741e5c89e4eSSatish Balay .   fd - the file pointer
742e5c89e4eSSatish Balay -   len - the length of the output buffer
743e5c89e4eSSatish Balay 
744e5c89e4eSSatish Balay     Output Parameter:
745e31d4fa4SJed Brown .   string - the line read from the file, at end of file string[0] == 0
746e5c89e4eSSatish Balay 
747e5c89e4eSSatish Balay     Level: intermediate
748e5c89e4eSSatish Balay 
749db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`,
750db781477SPatrick Sanan           `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()`
751e5c89e4eSSatish Balay @*/
752d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm, FILE *fp, size_t len, char string[])
753d71ae5a4SJacob Faibussowitsch {
754e5c89e4eSSatish Balay   PetscMPIInt rank;
755e5c89e4eSSatish Balay 
756e5c89e4eSSatish Balay   PetscFunctionBegin;
7579566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
758e5c89e4eSSatish Balay 
759dd400576SPatrick Sanan   if (rank == 0) {
760047b9c12SMatthew G Knepley     char *ptr = fgets(string, len, fp);
761047b9c12SMatthew G Knepley 
762047b9c12SMatthew G Knepley     if (!ptr) {
763e31d4fa4SJed Brown       string[0] = 0;
76408401ef6SPierre Jolivet       PetscCheck(feof(fp), PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno);
765047b9c12SMatthew G Knepley     }
766e5c89e4eSSatish Balay   }
7679566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(string, len, MPI_BYTE, 0, comm));
7683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
769e5c89e4eSSatish Balay }
770238ccf28SShri Abhyankar 
7718c74ee41SBarry Smith /*@C
7728c74ee41SBarry Smith      PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations
7738c74ee41SBarry Smith 
7748c74ee41SBarry Smith    Input Parameters:
7758c74ee41SBarry Smith .   format - the PETSc format string
7768c74ee41SBarry Smith 
7778c74ee41SBarry Smith  Level: developer
7788c74ee41SBarry Smith 
7798c74ee41SBarry Smith @*/
780d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatStrip(char *format)
781d71ae5a4SJacob Faibussowitsch {
7828c74ee41SBarry Smith   size_t loc1 = 0, loc2 = 0;
7838c74ee41SBarry Smith 
7848c74ee41SBarry Smith   PetscFunctionBegin;
7858c74ee41SBarry Smith   while (format[loc2]) {
7868c74ee41SBarry Smith     if (format[loc2] == '%') {
7878c74ee41SBarry Smith       format[loc1++] = format[loc2++];
7888c74ee41SBarry Smith       while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++;
7898c74ee41SBarry Smith     }
7908c74ee41SBarry Smith     format[loc1++] = format[loc2++];
7918c74ee41SBarry Smith   }
7923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7938c74ee41SBarry Smith }
7948c74ee41SBarry Smith 
795d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatRealArray(char buf[], size_t len, const char *fmt, PetscInt n, const PetscReal x[])
796d71ae5a4SJacob Faibussowitsch {
7971b5687a1SBarry Smith   PetscInt i;
7981b5687a1SBarry Smith   size_t   left, count;
7991b5687a1SBarry Smith   char    *p;
8001b5687a1SBarry Smith 
8011b5687a1SBarry Smith   PetscFunctionBegin;
8021b5687a1SBarry Smith   for (i = 0, p = buf, left = len; i < n; i++) {
8039566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintfCount(p, left, fmt, &count, (double)x[i]));
80408401ef6SPierre Jolivet     PetscCheck(count < left, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Insufficient space in buffer");
8051b5687a1SBarry Smith     left -= count;
8061b5687a1SBarry Smith     p += count - 1;
8071b5687a1SBarry Smith     *p++ = ' ';
8081b5687a1SBarry Smith   }
8091b5687a1SBarry Smith   p[i ? 0 : -1] = 0;
8103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8111b5687a1SBarry Smith }
812