1e5c89e4eSSatish Balay /* 2e5c89e4eSSatish Balay Utilites 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 27811af0c4SBarry Smith Deprecated 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 */ 75d781fa04SBarry Smith PetscFunctionReturn(0); 76d781fa04SBarry Smith } 77d781fa04SBarry Smith 78d781fa04SBarry Smith /*@C 79d781fa04SBarry Smith PetscFormatConvert - Takes a PETSc format string and converts the %D to %d for 32 bit PETSc indices and %lld for 64 bit PETSc indices. Also 80d781fa04SBarry Smith converts %g to [|%g|] so that PetscVSNPrintf() can easily insure all %g formatted numbers have a decimal point when printed. 81d781fa04SBarry Smith 82811af0c4SBarry Smith Deprecated 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 89811af0c4SBarry Smith Note: this exists so we can have the same code when `PetscInt` is either int or long long int 90d781fa04SBarry Smith 91d781fa04SBarry Smith Level: developer 92d781fa04SBarry Smith 93db781477SPatrick Sanan .seealso: `PetscFormatConvertGetSize()`, `PetscVSNPrintf()`, `PetscVFPrintf()` 94d781fa04SBarry Smith @*/ 95d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatConvert(const char *format, char *newformat) 96d71ae5a4SJacob Faibussowitsch { 97e5c89e4eSSatish Balay PetscInt i = 0, j = 0; 98e5c89e4eSSatish Balay 99eed5747fSBarry Smith PetscFunctionBegin; 100d781fa04SBarry Smith while (format[i]) { 1012a1ad9caSBarry Smith if (format[i] == '%' && format[i + 1] == '%') { 1022a1ad9caSBarry Smith newformat[j++] = format[i++]; 1032a1ad9caSBarry Smith newformat[j++] = format[i++]; 1042a1ad9caSBarry Smith } else if (format[i] == '%') { 1058627564fSBarry Smith if (format[i + 1] == 'g') { 1068627564fSBarry Smith newformat[j++] = '['; 1078627564fSBarry Smith newformat[j++] = '|'; 1088627564fSBarry Smith } 1097bc47156SJose Roman /* Find the letter */ 1107bc47156SJose Roman for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i]; 1117bc47156SJose Roman switch (format[i]) { 1127bc47156SJose Roman case 'D': 1136de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES) 114e5c89e4eSSatish Balay newformat[j++] = 'd'; 115e5c89e4eSSatish Balay #else 116e5c89e4eSSatish Balay newformat[j++] = 'l'; 117e5c89e4eSSatish Balay newformat[j++] = 'l'; 118e5c89e4eSSatish Balay newformat[j++] = 'd'; 119e5c89e4eSSatish Balay #endif 1207bc47156SJose Roman break; 1218627564fSBarry Smith case 'g': 1228627564fSBarry Smith newformat[j++] = format[i]; 1238627564fSBarry Smith if (format[i - 1] == '%') { 1248627564fSBarry Smith newformat[j++] = '|'; 1258627564fSBarry Smith newformat[j++] = ']'; 1268627564fSBarry Smith } 1278627564fSBarry Smith break; 128d71ae5a4SJacob Faibussowitsch case 'G': 129d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%G format is no longer supported, use %%g and cast the argument to double"); 130d71ae5a4SJacob Faibussowitsch case 'F': 131d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%F format is no longer supported, use %%f and cast the argument to double"); 132d71ae5a4SJacob Faibussowitsch default: 133d71ae5a4SJacob Faibussowitsch newformat[j++] = format[i]; 134d71ae5a4SJacob Faibussowitsch break; 1357bc47156SJose Roman } 1367bc47156SJose Roman i++; 137a297a907SKarl Rupp } else newformat[j++] = format[i++]; 138e5c89e4eSSatish Balay } 139e5c89e4eSSatish Balay newformat[j] = 0; 140eed5747fSBarry Smith PetscFunctionReturn(0); 141e5c89e4eSSatish Balay } 142e5c89e4eSSatish Balay 14314416c0eSBarry Smith #define PETSCDEFAULTBUFFERSIZE 8 * 1024 144d781fa04SBarry Smith 145c9a19010SBarry Smith /*@C 146c9a19010SBarry Smith PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the 147c9a19010SBarry Smith function arguments into a string using the format statement. 148c9a19010SBarry Smith 149c9a19010SBarry Smith Input Parameters: 150c9a19010SBarry Smith + str - location to put result 151c9a19010SBarry Smith . len - the amount of space in str 152c9a19010SBarry Smith + format - the PETSc format string 153c9a19010SBarry Smith - fullLength - the amount of space in str actually used. 154c9a19010SBarry Smith 155811af0c4SBarry Smith Developer Note: 15695452b02SPatrick Sanan this function may be called from an error handler, if an error occurs when it is called by the error handler than likely 157eed5747fSBarry Smith a recursion will occur and possible crash. 158c9a19010SBarry Smith 159c9a19010SBarry Smith Level: developer 160c9a19010SBarry Smith 161db781477SPatrick Sanan .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscVPrintf()` 162c9a19010SBarry Smith @*/ 163d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVSNPrintf(char *str, size_t len, const char *format, size_t *fullLength, va_list Argp) 164d71ae5a4SJacob Faibussowitsch { 165d781fa04SBarry Smith char *newformat = NULL; 16614416c0eSBarry Smith char formatbuf[PETSCDEFAULTBUFFERSIZE]; 167d781fa04SBarry Smith size_t newLength; 16814416c0eSBarry Smith int flen; 169e5c89e4eSSatish Balay 170eed5747fSBarry Smith PetscFunctionBegin; 1719566063dSJacob Faibussowitsch PetscCall(PetscFormatConvertGetSize(format, &newLength)); 17294217ebdSBarry Smith if (newLength < sizeof(formatbuf)) { 173e2135aedSMatthew Knepley newformat = formatbuf; 17494217ebdSBarry Smith newLength = sizeof(formatbuf) - 1; 175e2135aedSMatthew Knepley } else { 1769566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(newLength, &newformat)); 177e2135aedSMatthew Knepley } 1789566063dSJacob Faibussowitsch PetscCall(PetscFormatConvert(format, newformat)); 1797b9a2d1bSSatish Balay #if defined(PETSC_HAVE_VSNPRINTF) 180152b30f0SSatish Balay flen = vsnprintf(str, len, newformat, Argp); 181e5c89e4eSSatish Balay #else 18289b07760SSatish Balay #error "vsnprintf not found" 183e5c89e4eSSatish Balay #endif 18448a46eb9SPierre Jolivet if (newLength > sizeof(formatbuf) - 1) PetscCall(PetscFree(newformat)); 1858627564fSBarry Smith { 1868627564fSBarry Smith PetscBool foundedot; 1878627564fSBarry Smith size_t cnt = 0, ncnt = 0, leng; 1889566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 18917ca8410SBarry Smith if (leng > 4) { 1908627564fSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 1918627564fSBarry Smith if (str[cnt] == '[' && str[cnt + 1] == '|') { 192c540d043SBarry Smith flen -= 4; 1939371c9d4SSatish Balay cnt++; 1949371c9d4SSatish Balay cnt++; 1958627564fSBarry Smith foundedot = PETSC_FALSE; 1968627564fSBarry Smith for (; cnt < leng - 1; cnt++) { 1978627564fSBarry Smith if (str[cnt] == '|' && str[cnt + 1] == ']') { 1988627564fSBarry Smith cnt++; 1998627564fSBarry Smith if (!foundedot) str[ncnt++] = '.'; 2008627564fSBarry Smith ncnt--; 2018627564fSBarry Smith break; 2028627564fSBarry Smith } else { 2038627564fSBarry Smith if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; 2048627564fSBarry Smith str[ncnt++] = str[cnt]; 2058627564fSBarry Smith } 2068627564fSBarry Smith } 2078627564fSBarry Smith } else { 2088627564fSBarry Smith str[ncnt] = str[cnt]; 2098627564fSBarry Smith } 2108627564fSBarry Smith ncnt++; 2118627564fSBarry Smith } 2128627564fSBarry Smith while (cnt < leng) { 2139371c9d4SSatish Balay str[ncnt] = str[cnt]; 2149371c9d4SSatish Balay ncnt++; 2159371c9d4SSatish Balay cnt++; 2168627564fSBarry Smith } 2178627564fSBarry Smith str[ncnt] = 0; 2188627564fSBarry Smith } 2198627564fSBarry Smith } 220748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) 221e51f71cfSBarry Smith /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ 222748e1b9dSBarry Smith { 223748e1b9dSBarry Smith size_t cnt = 0, ncnt = 0, leng; 2249566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 225748e1b9dSBarry Smith if (leng > 5) { 226748e1b9dSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 227e51f71cfSBarry 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') { 2289371c9d4SSatish Balay str[ncnt] = str[cnt]; 2299371c9d4SSatish Balay ncnt++; 2309371c9d4SSatish Balay cnt++; 2319371c9d4SSatish Balay str[ncnt] = str[cnt]; 2329371c9d4SSatish Balay ncnt++; 2339371c9d4SSatish Balay cnt++; 2349371c9d4SSatish Balay cnt++; 235e51f71cfSBarry Smith str[ncnt] = str[cnt]; 236748e1b9dSBarry Smith } else { 237748e1b9dSBarry Smith str[ncnt] = str[cnt]; 238748e1b9dSBarry Smith } 239748e1b9dSBarry Smith ncnt++; 240748e1b9dSBarry Smith } 241748e1b9dSBarry Smith while (cnt < leng) { 2429371c9d4SSatish Balay str[ncnt] = str[cnt]; 2439371c9d4SSatish Balay ncnt++; 2449371c9d4SSatish Balay cnt++; 245748e1b9dSBarry Smith } 246748e1b9dSBarry Smith str[ncnt] = 0; 247748e1b9dSBarry Smith } 248748e1b9dSBarry Smith } 249748e1b9dSBarry Smith #endif 250c540d043SBarry Smith if (fullLength) *fullLength = 1 + (size_t)flen; 251eed5747fSBarry Smith PetscFunctionReturn(0); 252e5c89e4eSSatish Balay } 253e5c89e4eSSatish Balay 254c9a19010SBarry Smith /*@C 255c9a19010SBarry Smith PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can 256e5c89e4eSSatish Balay can be replaced with something that does not simply write to a file. 257e5c89e4eSSatish Balay 258c9a19010SBarry Smith To use, write your own function for example, 259c9a19010SBarry Smith $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp) 260c9a19010SBarry Smith ${ 261c9a19010SBarry Smith $ PetscErrorCode ierr; 262c9a19010SBarry Smith $ 263c9a19010SBarry Smith $ PetscFunctionBegin; 264c9a19010SBarry Smith $ if (fd != stdout && fd != stderr) { handle regular files 2655f80ce2aSJacob Faibussowitsch $ CHKERR(PetscVFPrintfDefault(fd,format,Argp)); 266c9a19010SBarry Smith $ } else { 267c9a19010SBarry Smith $ char buff[BIG]; 268c9a19010SBarry Smith $ size_t length; 2699566063dSJacob Faibussowitsch $ PetscCall(PetscVSNPrintf(buff,BIG,format,&length,Argp)); 270c9a19010SBarry Smith $ now send buff to whatever stream or whatever you want 271c9a19010SBarry Smith $ } 272c9a19010SBarry Smith $ PetscFunctionReturn(0); 273c9a19010SBarry Smith $} 274c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment 275c9a19010SBarry Smith $ PetscVFPrintf = mypetscvfprintf; 276c9a19010SBarry Smith 277811af0c4SBarry Smith Note: 27895452b02SPatrick Sanan For error messages this may be called by any process, for regular standard out it is 279e5c89e4eSSatish Balay called only by process 0 of a given communicator 280e5c89e4eSSatish Balay 281811af0c4SBarry Smith Developer Note: 28295452b02SPatrick Sanan this could be called by an error handler, if that happens then a recursion of the error handler may occur 283eed5747fSBarry Smith and a crash 284c9a19010SBarry Smith 285c9a19010SBarry Smith Level: developer 286c9a19010SBarry Smith 287db781477SPatrick Sanan .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()` 288c9a19010SBarry Smith @*/ 289d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVFPrintfDefault(FILE *fd, const char *format, va_list Argp) 290d71ae5a4SJacob Faibussowitsch { 29114416c0eSBarry Smith char str[PETSCDEFAULTBUFFERSIZE]; 29214416c0eSBarry Smith char *buff = str; 29314416c0eSBarry Smith size_t fullLength; 2941531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 29514416c0eSBarry Smith va_list Argpcopy; 2961531940fSBarry Smith #endif 2971179db26SBarry Smith 298eed5747fSBarry Smith PetscFunctionBegin; 2991531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 30014416c0eSBarry Smith va_copy(Argpcopy, Argp); 3011531940fSBarry Smith #endif 3029566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, sizeof(str), format, &fullLength, Argp)); 30314416c0eSBarry Smith if (fullLength > sizeof(str)) { 3049566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fullLength, &buff)); 3051531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 3069566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(buff, fullLength, format, NULL, Argpcopy)); 3071531940fSBarry Smith #else 3081531940fSBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "C89 does not support va_copy() hence cannot print long strings with PETSc printing routines"); 3091531940fSBarry Smith #endif 31014416c0eSBarry Smith } 3112f613bf5SBarry Smith fprintf(fd, "%s", buff); 3125a058713SBarry Smith fflush(fd); 31348a46eb9SPierre Jolivet if (buff != str) PetscCall(PetscFree(buff)); 314eed5747fSBarry Smith PetscFunctionReturn(0); 315e5c89e4eSSatish Balay } 316e5c89e4eSSatish Balay 3175b5bc046SBarry Smith /*@C 3185b5bc046SBarry Smith PetscSNPrintf - Prints to a string of given length 3195b5bc046SBarry Smith 3205b5bc046SBarry Smith Not Collective 3215b5bc046SBarry Smith 3225b5bc046SBarry Smith Input Parameters: 3235b5bc046SBarry Smith + str - the string to print to 3245b5bc046SBarry Smith . len - the length of str 3255b5bc046SBarry Smith . format - the usual printf() format string 32610699b91SBarry Smith - ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument 3275b5bc046SBarry Smith 3285b5bc046SBarry Smith Level: intermediate 3295b5bc046SBarry Smith 330db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 331db781477SPatrick Sanan `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscVFPrintf()` 3325b5bc046SBarry Smith @*/ 333d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintf(char *str, size_t len, const char format[], ...) 334d71ae5a4SJacob Faibussowitsch { 335c9a19010SBarry Smith size_t fullLength; 3365b5bc046SBarry Smith va_list Argp; 3375b5bc046SBarry Smith 3385b5bc046SBarry Smith PetscFunctionBegin; 3395b5bc046SBarry Smith va_start(Argp, format); 3409566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, &fullLength, Argp)); 3415b5bc046SBarry Smith PetscFunctionReturn(0); 3425b5bc046SBarry Smith } 3435b5bc046SBarry Smith 344257d2499SJed Brown /*@C 345257d2499SJed Brown PetscSNPrintfCount - Prints to a string of given length, returns count 346257d2499SJed Brown 347257d2499SJed Brown Not Collective 348257d2499SJed Brown 349257d2499SJed Brown Input Parameters: 350257d2499SJed Brown + str - the string to print to 351257d2499SJed Brown . len - the length of str 352257d2499SJed Brown . format - the usual printf() format string 35310699b91SBarry Smith - ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument 354257d2499SJed Brown 355cb398dd3SBarry Smith Output Parameter: 356cb398dd3SBarry Smith . countused - number of characters used 357cb398dd3SBarry Smith 358257d2499SJed Brown Level: intermediate 359257d2499SJed Brown 360db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 361db781477SPatrick Sanan `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscSNPrintf()`, `PetscVFPrintf()` 362257d2499SJed Brown @*/ 363d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintfCount(char *str, size_t len, const char format[], size_t *countused, ...) 364d71ae5a4SJacob Faibussowitsch { 365257d2499SJed Brown va_list Argp; 366257d2499SJed Brown 367257d2499SJed Brown PetscFunctionBegin; 368257d2499SJed Brown va_start(Argp, countused); 3699566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, countused, Argp)); 370257d2499SJed Brown PetscFunctionReturn(0); 371257d2499SJed Brown } 372257d2499SJed Brown 373e5c89e4eSSatish Balay /* ----------------------------------------------------------------------- */ 374e5c89e4eSSatish Balay 37502c9f0b5SLisandro Dalcin PrintfQueue petsc_printfqueue = NULL, petsc_printfqueuebase = NULL; 376d30b0576SJed Brown int petsc_printfqueuelength = 0; 377e5c89e4eSSatish Balay 378e5c89e4eSSatish Balay /*@C 379e5c89e4eSSatish Balay PetscSynchronizedPrintf - Prints synchronized output from several processors. 380e5c89e4eSSatish Balay Output of the first processor is followed by that of the second, etc. 381e5c89e4eSSatish Balay 382e5c89e4eSSatish Balay Not Collective 383e5c89e4eSSatish Balay 384e5c89e4eSSatish Balay Input Parameters: 385e5c89e4eSSatish Balay + comm - the communicator 386e5c89e4eSSatish Balay - format - the usual printf() format string 387e5c89e4eSSatish Balay 388e5c89e4eSSatish Balay Level: intermediate 389e5c89e4eSSatish Balay 390811af0c4SBarry Smith Note: 391811af0c4SBarry Smith REQUIRES a call to `PetscSynchronizedFlush()` by all the processes after the completion of the calls to `PetscSynchronizedPrintf()` for the information 392e5c89e4eSSatish Balay from all the processors to be printed. 393e5c89e4eSSatish Balay 394e5c89e4eSSatish Balay Fortran Note: 395811af0c4SBarry Smith The call sequence is `PetscSynchronizedPrintf`(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 396e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 397e5c89e4eSSatish Balay 398db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, 399db781477SPatrick Sanan `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()` 400e5c89e4eSSatish Balay @*/ 401d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm, const char format[], ...) 402d71ae5a4SJacob Faibussowitsch { 403e5c89e4eSSatish Balay PetscMPIInt rank; 404e5c89e4eSSatish Balay 405e5c89e4eSSatish Balay PetscFunctionBegin; 40608401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 4079566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 408e5c89e4eSSatish Balay 409e5c89e4eSSatish Balay /* First processor prints immediately to stdout */ 410dd400576SPatrick Sanan if (rank == 0) { 411e5c89e4eSSatish Balay va_list Argp; 412e5c89e4eSSatish Balay va_start(Argp, format); 4139566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(PETSC_STDOUT, format, Argp)); 414e5c89e4eSSatish Balay if (petsc_history) { 415cdc7d174SSatish Balay va_start(Argp, format); 4169566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, Argp)); 417e5c89e4eSSatish Balay } 418e5c89e4eSSatish Balay va_end(Argp); 419e5c89e4eSSatish Balay } else { /* other processors add to local queue */ 420e5c89e4eSSatish Balay va_list Argp; 421e5c89e4eSSatish Balay PrintfQueue next; 42214416c0eSBarry Smith size_t fullLength = PETSCDEFAULTBUFFERSIZE; 423e5c89e4eSSatish Balay 4249566063dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 425a297a907SKarl Rupp if (petsc_printfqueue) { 426a297a907SKarl Rupp petsc_printfqueue->next = next; 427a297a907SKarl Rupp petsc_printfqueue = next; 42802c9f0b5SLisandro Dalcin petsc_printfqueue->next = NULL; 429a297a907SKarl Rupp } else petsc_printfqueuebase = petsc_printfqueue = next; 430d30b0576SJed Brown petsc_printfqueuelength++; 43194217ebdSBarry Smith next->size = 0; 43214416c0eSBarry Smith next->string = NULL; 43394217ebdSBarry Smith while (fullLength >= next->size) { 4342d609e63SMatthew Knepley next->size = fullLength + 1; 4359566063dSJacob Faibussowitsch PetscCall(PetscFree(next->string)); 4369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(next->size, &next->string)); 437e5c89e4eSSatish Balay va_start(Argp, format); 4389566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string, next->size)); 4399566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, Argp)); 440e5c89e4eSSatish Balay va_end(Argp); 441e5c89e4eSSatish Balay } 4422d609e63SMatthew Knepley } 443e5c89e4eSSatish Balay PetscFunctionReturn(0); 444e5c89e4eSSatish Balay } 445e5c89e4eSSatish Balay 446e5c89e4eSSatish Balay /*@C 447e5c89e4eSSatish Balay PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 448e5c89e4eSSatish Balay several processors. Output of the first processor is followed by that of the 449e5c89e4eSSatish Balay second, etc. 450e5c89e4eSSatish Balay 451e5c89e4eSSatish Balay Not Collective 452e5c89e4eSSatish Balay 453e5c89e4eSSatish Balay Input Parameters: 454e5c89e4eSSatish Balay + comm - the communicator 455e5c89e4eSSatish Balay . fd - the file pointer 456e5c89e4eSSatish Balay - format - the usual printf() format string 457e5c89e4eSSatish Balay 458e5c89e4eSSatish Balay Level: intermediate 459e5c89e4eSSatish Balay 460811af0c4SBarry Smith Note: 461811af0c4SBarry Smith REQUIRES a intervening call to `PetscSynchronizedFlush()` for the information 462e5c89e4eSSatish Balay from all the processors to be printed. 463e5c89e4eSSatish Balay 464db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFPrintf()`, 465db781477SPatrick Sanan `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()` 466e5c89e4eSSatish Balay @*/ 467d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm, FILE *fp, const char format[], ...) 468d71ae5a4SJacob Faibussowitsch { 469e5c89e4eSSatish Balay PetscMPIInt rank; 470e5c89e4eSSatish Balay 471e5c89e4eSSatish Balay PetscFunctionBegin; 47208401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 4739566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 474e5c89e4eSSatish Balay 475e5c89e4eSSatish Balay /* First processor prints immediately to fp */ 476dd400576SPatrick Sanan if (rank == 0) { 477e5c89e4eSSatish Balay va_list Argp; 478e5c89e4eSSatish Balay va_start(Argp, format); 4799566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(fp, format, Argp)); 480cdc7d174SSatish Balay if (petsc_history && (fp != petsc_history)) { 481cdc7d174SSatish Balay va_start(Argp, format); 4829566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, Argp)); 483e5c89e4eSSatish Balay } 484e5c89e4eSSatish Balay va_end(Argp); 485e5c89e4eSSatish Balay } else { /* other processors add to local queue */ 486e5c89e4eSSatish Balay va_list Argp; 487e5c89e4eSSatish Balay PrintfQueue next; 48814416c0eSBarry Smith size_t fullLength = PETSCDEFAULTBUFFERSIZE; 48914416c0eSBarry Smith 4909566063dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 491a297a907SKarl Rupp if (petsc_printfqueue) { 492a297a907SKarl Rupp petsc_printfqueue->next = next; 493a297a907SKarl Rupp petsc_printfqueue = next; 49402c9f0b5SLisandro Dalcin petsc_printfqueue->next = NULL; 495a297a907SKarl Rupp } else petsc_printfqueuebase = petsc_printfqueue = next; 496d30b0576SJed Brown petsc_printfqueuelength++; 49794217ebdSBarry Smith next->size = 0; 49814416c0eSBarry Smith next->string = NULL; 49994217ebdSBarry Smith while (fullLength >= next->size) { 5002d609e63SMatthew Knepley next->size = fullLength + 1; 5019566063dSJacob Faibussowitsch PetscCall(PetscFree(next->string)); 5029566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(next->size, &next->string)); 503e5c89e4eSSatish Balay va_start(Argp, format); 5049566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string, next->size)); 5059566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, Argp)); 506e5c89e4eSSatish Balay va_end(Argp); 507e5c89e4eSSatish Balay } 5082d609e63SMatthew Knepley } 509e5c89e4eSSatish Balay PetscFunctionReturn(0); 510e5c89e4eSSatish Balay } 511e5c89e4eSSatish Balay 5120ec8b6e3SBarry Smith /*@C 513e5c89e4eSSatish Balay PetscSynchronizedFlush - Flushes to the screen output from all processors 514811af0c4SBarry Smith involved in previous `PetscSynchronizedPrintf()`/`PetscSynchronizedFPrintf()` calls. 515e5c89e4eSSatish Balay 516d083f849SBarry Smith Collective 517e5c89e4eSSatish Balay 518e5c89e4eSSatish Balay Input Parameters: 5190ec8b6e3SBarry Smith + comm - the communicator 5200ec8b6e3SBarry Smith - fd - the file pointer (valid on process 0 of the communicator) 521e5c89e4eSSatish Balay 522e5c89e4eSSatish Balay Level: intermediate 523e5c89e4eSSatish Balay 524811af0c4SBarry Smith Note: 525811af0c4SBarry Smith If `PetscSynchronizedPrintf()` and/or `PetscSynchronizedFPrintf()` are called with 526811af0c4SBarry Smith different MPI communicators there must be an intervening call to `PetscSynchronizedFlush()` between the calls with different MPI communicators. 527e5c89e4eSSatish Balay 528811af0c4SBarry Smith Fortran Note: 529811af0c4SBarry Smith Pass `PETSC_STDOUT` if the flush is for standard out; otherwise pass a value obtained from `PetscFOpen()` 530e50bf69fSBarry Smith 531db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscFPrintf()`, `PetscPrintf()`, `PetscViewerASCIIPrintf()`, 532db781477SPatrick Sanan `PetscViewerASCIISynchronizedPrintf()` 5330087d953SMatthew G. Knepley @*/ 534d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm, FILE *fd) 535d71ae5a4SJacob Faibussowitsch { 53629a5cbdcSMatthew G. Knepley PetscMPIInt rank, size, tag, i, j, n = 0, dummy = 0; 5372d609e63SMatthew Knepley char *message; 538e5c89e4eSSatish Balay MPI_Status status; 539e5c89e4eSSatish Balay 540e5c89e4eSSatish Balay PetscFunctionBegin; 5419566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(comm, &comm, &tag)); 5429566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5439566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 544e5c89e4eSSatish Balay 545e5c89e4eSSatish Balay /* First processor waits for messages from all other processors */ 546dd400576SPatrick Sanan if (rank == 0) { 5470ec8b6e3SBarry Smith if (!fd) fd = PETSC_STDOUT; 548e5c89e4eSSatish Balay for (i = 1; i < size; i++) { 5499f73f8ecSBarry Smith /* to prevent a flood of messages to process zero, request each message separately */ 5509566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm)); 5519566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status)); 552e5c89e4eSSatish Balay for (j = 0; j < n; j++) { 55329a5cbdcSMatthew G. Knepley PetscMPIInt size = 0; 5542d609e63SMatthew Knepley 5559566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status)); 5569566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &message)); 5579566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status)); 5589566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, "%s", message)); 5599566063dSJacob Faibussowitsch PetscCall(PetscFree(message)); 560e5c89e4eSSatish Balay } 561e5c89e4eSSatish Balay } 562e5c89e4eSSatish Balay } else { /* other processors send queue to processor 0 */ 563d30b0576SJed Brown PrintfQueue next = petsc_printfqueuebase, previous; 564e5c89e4eSSatish Balay 5659566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status)); 5669566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm)); 567d30b0576SJed Brown for (i = 0; i < petsc_printfqueuelength; i++) { 5689566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm)); 5699566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(next->string, next->size, MPI_CHAR, 0, tag, comm)); 570e5c89e4eSSatish Balay previous = next; 571e5c89e4eSSatish Balay next = next->next; 5729566063dSJacob Faibussowitsch PetscCall(PetscFree(previous->string)); 5739566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 574e5c89e4eSSatish Balay } 57502c9f0b5SLisandro Dalcin petsc_printfqueue = NULL; 576d30b0576SJed Brown petsc_printfqueuelength = 0; 577e5c89e4eSSatish Balay } 5789566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&comm)); 579e5c89e4eSSatish Balay PetscFunctionReturn(0); 580e5c89e4eSSatish Balay } 581e5c89e4eSSatish Balay 582e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/ 583e5c89e4eSSatish Balay 584e5c89e4eSSatish Balay /*@C 585e5c89e4eSSatish Balay PetscFPrintf - Prints to a file, only from the first 586e5c89e4eSSatish Balay processor in the communicator. 587e5c89e4eSSatish Balay 588*cf53795eSBarry Smith Not Collective; No Fortran Support 589e5c89e4eSSatish Balay 590e5c89e4eSSatish Balay Input Parameters: 591e5c89e4eSSatish Balay + comm - the communicator 592e5c89e4eSSatish Balay . fd - the file pointer 593e5c89e4eSSatish Balay - format - the usual printf() format string 594e5c89e4eSSatish Balay 595e5c89e4eSSatish Balay Level: intermediate 596e5c89e4eSSatish Balay 597db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 598db781477SPatrick Sanan `PetscViewerASCIISynchronizedPrintf()`, `PetscSynchronizedFlush()` 599e5c89e4eSSatish Balay @*/ 600d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFPrintf(MPI_Comm comm, FILE *fd, const char format[], ...) 601d71ae5a4SJacob Faibussowitsch { 602e5c89e4eSSatish Balay PetscMPIInt rank; 603e5c89e4eSSatish Balay 604e5c89e4eSSatish Balay PetscFunctionBegin; 60508401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 6069566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 607dd400576SPatrick Sanan if (rank == 0) { 608e5c89e4eSSatish Balay va_list Argp; 609e5c89e4eSSatish Balay va_start(Argp, format); 6109566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(fd, format, Argp)); 611cdc7d174SSatish Balay if (petsc_history && (fd != petsc_history)) { 612cdc7d174SSatish Balay va_start(Argp, format); 6139566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, Argp)); 614e5c89e4eSSatish Balay } 615e5c89e4eSSatish Balay va_end(Argp); 616e5c89e4eSSatish Balay } 617e5c89e4eSSatish Balay PetscFunctionReturn(0); 618e5c89e4eSSatish Balay } 619e5c89e4eSSatish Balay 620e5c89e4eSSatish Balay /*@C 621e5c89e4eSSatish Balay PetscPrintf - Prints to standard out, only from the first 622eed5747fSBarry Smith processor in the communicator. Calls from other processes are ignored. 623e5c89e4eSSatish Balay 624e5c89e4eSSatish Balay Not Collective 625e5c89e4eSSatish Balay 626e5c89e4eSSatish Balay Input Parameters: 627e5c89e4eSSatish Balay + comm - the communicator 628e5c89e4eSSatish Balay - format - the usual printf() format string 629e5c89e4eSSatish Balay 630e5c89e4eSSatish Balay Level: intermediate 631e5c89e4eSSatish Balay 632811af0c4SBarry Smith Note: 633811af0c4SBarry Smith Deprecated information: `PetscPrintf()` supports some format specifiers that are unique to PETSc. 634811af0c4SBarry Smith See the manual page for `PetscFormatConvert()` for details. 635b2706f25SRichard Tran Mills 636e5c89e4eSSatish Balay Fortran Note: 637811af0c4SBarry Smith The call sequence is `PetscPrintf`(MPI_Comm, character(*), `PetscErrorCode` ierr) from Fortran. 638e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 639e5c89e4eSSatish Balay 640db781477SPatrick Sanan .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscFormatConvert()` 641e5c89e4eSSatish Balay @*/ 642d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPrintf(MPI_Comm comm, const char format[], ...) 643d71ae5a4SJacob Faibussowitsch { 644e5c89e4eSSatish Balay PetscMPIInt rank; 645e5c89e4eSSatish Balay 646e5c89e4eSSatish Balay PetscFunctionBegin; 64708401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 6489566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 649dd400576SPatrick Sanan if (rank == 0) { 650e5c89e4eSSatish Balay va_list Argp; 651e5c89e4eSSatish Balay va_start(Argp, format); 6529566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(PETSC_STDOUT, format, Argp)); 653e5c89e4eSSatish Balay if (petsc_history) { 654cdc7d174SSatish Balay va_start(Argp, format); 6559566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, Argp)); 656e5c89e4eSSatish Balay } 657e5c89e4eSSatish Balay va_end(Argp); 658e5c89e4eSSatish Balay } 659e5c89e4eSSatish Balay PetscFunctionReturn(0); 660e5c89e4eSSatish Balay } 661e5c89e4eSSatish Balay 662d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm, const char format[], ...) 663d71ae5a4SJacob Faibussowitsch { 664e5c89e4eSSatish Balay PetscMPIInt rank; 665e5c89e4eSSatish Balay 666e5c89e4eSSatish Balay PetscFunctionBegin; 66708401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 6689566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 669dd400576SPatrick Sanan if (rank == 0) { 670e5c89e4eSSatish Balay va_list Argp; 671e5c89e4eSSatish Balay va_start(Argp, format); 6729566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(PETSC_STDOUT, format, Argp)); 673e5c89e4eSSatish Balay if (petsc_history) { 674cdc7d174SSatish Balay va_start(Argp, format); 6759566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, Argp)); 676e5c89e4eSSatish Balay } 677e5c89e4eSSatish Balay va_end(Argp); 678e5c89e4eSSatish Balay } 679e5c89e4eSSatish Balay PetscFunctionReturn(0); 680e5c89e4eSSatish Balay } 681e5c89e4eSSatish Balay 682e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/ 683e5c89e4eSSatish Balay 684e5c89e4eSSatish Balay /*@C 685e5c89e4eSSatish Balay PetscSynchronizedFGets - Several processors all get the same line from a file. 686e5c89e4eSSatish Balay 687d083f849SBarry Smith Collective 688e5c89e4eSSatish Balay 689e5c89e4eSSatish Balay Input Parameters: 690e5c89e4eSSatish Balay + comm - the communicator 691e5c89e4eSSatish Balay . fd - the file pointer 692e5c89e4eSSatish Balay - len - the length of the output buffer 693e5c89e4eSSatish Balay 694e5c89e4eSSatish Balay Output Parameter: 695e31d4fa4SJed Brown . string - the line read from the file, at end of file string[0] == 0 696e5c89e4eSSatish Balay 697e5c89e4eSSatish Balay Level: intermediate 698e5c89e4eSSatish Balay 699db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, 700db781477SPatrick Sanan `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()` 701e5c89e4eSSatish Balay @*/ 702d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm, FILE *fp, size_t len, char string[]) 703d71ae5a4SJacob Faibussowitsch { 704e5c89e4eSSatish Balay PetscMPIInt rank; 705e5c89e4eSSatish Balay 706e5c89e4eSSatish Balay PetscFunctionBegin; 7079566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 708e5c89e4eSSatish Balay 709dd400576SPatrick Sanan if (rank == 0) { 710047b9c12SMatthew G Knepley char *ptr = fgets(string, len, fp); 711047b9c12SMatthew G Knepley 712047b9c12SMatthew G Knepley if (!ptr) { 713e31d4fa4SJed Brown string[0] = 0; 71408401ef6SPierre Jolivet PetscCheck(feof(fp), PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno); 715047b9c12SMatthew G Knepley } 716e5c89e4eSSatish Balay } 7179566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(string, len, MPI_BYTE, 0, comm)); 718e5c89e4eSSatish Balay PetscFunctionReturn(0); 719e5c89e4eSSatish Balay } 720238ccf28SShri Abhyankar 7218c74ee41SBarry Smith /*@C 7228c74ee41SBarry Smith PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations 7238c74ee41SBarry Smith 7248c74ee41SBarry Smith Input Parameters: 7258c74ee41SBarry Smith . format - the PETSc format string 7268c74ee41SBarry Smith 7278c74ee41SBarry Smith Level: developer 7288c74ee41SBarry Smith 7298c74ee41SBarry Smith @*/ 730d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatStrip(char *format) 731d71ae5a4SJacob Faibussowitsch { 7328c74ee41SBarry Smith size_t loc1 = 0, loc2 = 0; 7338c74ee41SBarry Smith 7348c74ee41SBarry Smith PetscFunctionBegin; 7358c74ee41SBarry Smith while (format[loc2]) { 7368c74ee41SBarry Smith if (format[loc2] == '%') { 7378c74ee41SBarry Smith format[loc1++] = format[loc2++]; 7388c74ee41SBarry Smith while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++; 7398c74ee41SBarry Smith } 7408c74ee41SBarry Smith format[loc1++] = format[loc2++]; 7418c74ee41SBarry Smith } 7428c74ee41SBarry Smith PetscFunctionReturn(0); 7438c74ee41SBarry Smith } 7448c74ee41SBarry Smith 745d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatRealArray(char buf[], size_t len, const char *fmt, PetscInt n, const PetscReal x[]) 746d71ae5a4SJacob Faibussowitsch { 7471b5687a1SBarry Smith PetscInt i; 7481b5687a1SBarry Smith size_t left, count; 7491b5687a1SBarry Smith char *p; 7501b5687a1SBarry Smith 7511b5687a1SBarry Smith PetscFunctionBegin; 7521b5687a1SBarry Smith for (i = 0, p = buf, left = len; i < n; i++) { 7539566063dSJacob Faibussowitsch PetscCall(PetscSNPrintfCount(p, left, fmt, &count, (double)x[i])); 75408401ef6SPierre Jolivet PetscCheck(count < left, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Insufficient space in buffer"); 7551b5687a1SBarry Smith left -= count; 7561b5687a1SBarry Smith p += count - 1; 7571b5687a1SBarry Smith *p++ = ' '; 7581b5687a1SBarry Smith } 7591b5687a1SBarry Smith p[i ? 0 : -1] = 0; 7601b5687a1SBarry Smith PetscFunctionReturn(0); 7611b5687a1SBarry Smith } 762