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 */ 10e5c89e4eSSatish Balay extern 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 */ 16e5c89e4eSSatish Balay FILE *PETSC_STDOUT = 0; 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 */ 22ae9b4142SLisandro Dalcin FILE *PETSC_STDERR = 0; 23b13499bfSbcordonn 24354e5084SJose Roman /* 25354e5084SJose Roman Return the maximum expected new size of the format 26354e5084SJose Roman */ 27354e5084SJose Roman #define PETSC_MAX_LENGTH_FORMAT(l) (l+l/8) 28354e5084SJose Roman 29e5c89e4eSSatish Balay #undef __FUNCT__ 30e5c89e4eSSatish Balay #define __FUNCT__ "PetscFormatConvert" 31c9a19010SBarry Smith /*@C 32c9a19010SBarry Smith PetscFormatConvert - Takes a PETSc format string and converts it to a reqular C format string 33c9a19010SBarry Smith 34c9a19010SBarry Smith Input Parameters: 35c9a19010SBarry Smith + format - the PETSc format string 36c9a19010SBarry Smith . newformat - the location to put the standard C format string values 37c9a19010SBarry Smith - size - the length of newformat 38c9a19010SBarry Smith 39eed5747fSBarry Smith Note: this exists so we can have the same code when PetscInt is either int or long long and PetscScalar is either __float128, double, or float 40c9a19010SBarry Smith 41c9a19010SBarry Smith Level: developer 42c9a19010SBarry Smith 43c9a19010SBarry Smith @*/ 447087cfbeSBarry Smith PetscErrorCode PetscFormatConvert(const char *format,char *newformat,size_t size) 45e5c89e4eSSatish Balay { 46e5c89e4eSSatish Balay PetscInt i = 0,j = 0; 47e5c89e4eSSatish Balay 48eed5747fSBarry Smith PetscFunctionBegin; 497bc47156SJose Roman while (format[i] && j < (PetscInt)size-1) { 502a1ad9caSBarry Smith if (format[i] == '%' && format[i+1] == '%') { 512a1ad9caSBarry Smith newformat[j++] = format[i++]; 522a1ad9caSBarry Smith newformat[j++] = format[i++]; 532a1ad9caSBarry Smith } else if (format[i] == '%') { 548627564fSBarry Smith if (format[i+1] == 'g') { 558627564fSBarry Smith newformat[j++] = '['; 568627564fSBarry Smith newformat[j++] = '|'; 578627564fSBarry Smith } 587bc47156SJose Roman /* Find the letter */ 597bc47156SJose Roman for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i]; 607bc47156SJose Roman switch (format[i]) { 617bc47156SJose Roman case 'D': 626de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES) 63e5c89e4eSSatish Balay newformat[j++] = 'd'; 64e5c89e4eSSatish Balay #else 65e5c89e4eSSatish Balay newformat[j++] = 'l'; 66e5c89e4eSSatish Balay newformat[j++] = 'l'; 67e5c89e4eSSatish Balay newformat[j++] = 'd'; 68e5c89e4eSSatish Balay #endif 697bc47156SJose Roman break; 708627564fSBarry Smith case 'g': 718627564fSBarry Smith newformat[j++] = format[i]; 728627564fSBarry Smith if (format[i-1] == '%') { 738627564fSBarry Smith newformat[j++] = '|'; 748627564fSBarry Smith newformat[j++] = ']'; 758627564fSBarry Smith } 768627564fSBarry Smith break; 777bc47156SJose Roman case 'G': 78145505e7SDominic Meiser SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%G format is no longer supported, use %%g and cast the argument to double"); 797bc47156SJose Roman break; 80121a09c4SJose Roman case 'F': 81145505e7SDominic Meiser SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%F format is no longer supported, use %%f and cast the argument to double"); 82121a09c4SJose Roman break; 837bc47156SJose Roman default: 847bc47156SJose Roman newformat[j++] = format[i]; 857bc47156SJose Roman break; 867bc47156SJose Roman } 877bc47156SJose Roman i++; 88a297a907SKarl Rupp } else newformat[j++] = format[i++]; 89e5c89e4eSSatish Balay } 90e5c89e4eSSatish Balay newformat[j] = 0; 91eed5747fSBarry Smith PetscFunctionReturn(0); 92e5c89e4eSSatish Balay } 93e5c89e4eSSatish Balay 94e5c89e4eSSatish Balay #undef __FUNCT__ 95e5c89e4eSSatish Balay #define __FUNCT__ "PetscVSNPrintf" 96c9a19010SBarry Smith /*@C 97c9a19010SBarry Smith PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the 98c9a19010SBarry Smith function arguments into a string using the format statement. 99c9a19010SBarry Smith 100c9a19010SBarry Smith Input Parameters: 101c9a19010SBarry Smith + str - location to put result 102c9a19010SBarry Smith . len - the amount of space in str 103c9a19010SBarry Smith + format - the PETSc format string 104c9a19010SBarry Smith - fullLength - the amount of space in str actually used. 105c9a19010SBarry Smith 106eed5747fSBarry Smith Developer Notes: this function may be called from an error handler, if an error occurs when it is called by the error handler than likely 107eed5747fSBarry Smith a recursion will occur and possible crash. 108c9a19010SBarry Smith 109c9a19010SBarry Smith Level: developer 110c9a19010SBarry Smith 111c9a19010SBarry Smith @*/ 1127087cfbeSBarry Smith PetscErrorCode PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp) 113e5c89e4eSSatish Balay { 114e2135aedSMatthew Knepley char *newformat; 115e2135aedSMatthew Knepley char formatbuf[8*1024]; 1161a96acb8SJed Brown size_t oldLength,length; 1171a15ef5dSMatthew Knepley PetscErrorCode ierr; 118e5c89e4eSSatish Balay 119eed5747fSBarry Smith PetscFunctionBegin; 120e2135aedSMatthew Knepley ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr); 121e2135aedSMatthew Knepley if (oldLength < 8*1024) { 122e2135aedSMatthew Knepley newformat = formatbuf; 123354e5084SJose Roman oldLength = 8*1024-1; 124e2135aedSMatthew Knepley } else { 125354e5084SJose Roman oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength); 126785e854fSJed Brown ierr = PetscMalloc1(oldLength, &newformat);CHKERRQ(ierr); 127e2135aedSMatthew Knepley } 128e298bee8SBarry Smith ierr = PetscFormatConvert(format,newformat,oldLength);CHKERRQ(ierr); 1291a15ef5dSMatthew Knepley ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr); 1302d609e63SMatthew Knepley #if 0 131a297a907SKarl Rupp if (length > len) newformat[len] = '\0'; 1322d609e63SMatthew Knepley #endif 1335a058713SBarry Smith #if defined(PETSC_HAVE_VSNPRINTF_CHAR) 134748e1b9dSBarry Smith (void) vsnprintf(str,len,newformat,(char*)Argp); 13589b07760SSatish Balay #elif defined(PETSC_HAVE_VSNPRINTF) 136748e1b9dSBarry Smith (void) vsnprintf(str,len,newformat,Argp); 137141c0d65SSatish Balay #elif defined(PETSC_HAVE__VSNPRINTF) 138748e1b9dSBarry Smith (void) _vsnprintf(str,len,newformat,Argp); 139e5c89e4eSSatish Balay #else 14089b07760SSatish Balay #error "vsnprintf not found" 141e5c89e4eSSatish Balay #endif 142e2135aedSMatthew Knepley if (oldLength >= 8*1024) { 143e2135aedSMatthew Knepley ierr = PetscFree(newformat);CHKERRQ(ierr); 144e2135aedSMatthew Knepley } 1458627564fSBarry Smith { 1468627564fSBarry Smith PetscBool foundedot; 1478627564fSBarry Smith size_t cnt = 0,ncnt = 0,leng; 1488627564fSBarry Smith ierr = PetscStrlen(str,&leng);CHKERRQ(ierr); 14917ca8410SBarry Smith if (leng > 4) { 1508627564fSBarry Smith for (cnt=0; cnt<leng-4; cnt++) { 1518627564fSBarry Smith if (str[cnt] == '[' && str[cnt+1] == '|'){ 1528627564fSBarry Smith cnt++; cnt++; 1538627564fSBarry Smith foundedot = PETSC_FALSE; 1548627564fSBarry Smith for (; cnt<leng-1; cnt++) { 1558627564fSBarry Smith if (str[cnt] == '|' && str[cnt+1] == ']'){ 1568627564fSBarry Smith cnt++; 1578627564fSBarry Smith if (!foundedot) str[ncnt++] = '.'; 1588627564fSBarry Smith ncnt--; 1598627564fSBarry Smith break; 1608627564fSBarry Smith } else { 1618627564fSBarry Smith if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; 1628627564fSBarry Smith str[ncnt++] = str[cnt]; 1638627564fSBarry Smith } 1648627564fSBarry Smith } 1658627564fSBarry Smith } else { 1668627564fSBarry Smith str[ncnt] = str[cnt]; 1678627564fSBarry Smith } 1688627564fSBarry Smith ncnt++; 1698627564fSBarry Smith } 1708627564fSBarry Smith while (cnt < leng) { 1718627564fSBarry Smith str[ncnt] = str[cnt]; ncnt++; cnt++; 1728627564fSBarry Smith } 1738627564fSBarry Smith str[ncnt] = 0; 1748627564fSBarry Smith } 1758627564fSBarry Smith } 176748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) 177e51f71cfSBarry Smith /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ 178748e1b9dSBarry Smith { 179748e1b9dSBarry Smith size_t cnt = 0,ncnt = 0,leng; 180748e1b9dSBarry Smith ierr = PetscStrlen(str,&leng);CHKERRQ(ierr); 181748e1b9dSBarry Smith if (leng > 5) { 182748e1b9dSBarry Smith for (cnt=0; cnt<leng-4; cnt++) { 183e51f71cfSBarry 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') { 184748e1b9dSBarry Smith str[ncnt] = str[cnt]; ncnt++; cnt++; 185e51f71cfSBarry Smith str[ncnt] = str[cnt]; ncnt++; cnt++; cnt++; 186e51f71cfSBarry Smith str[ncnt] = str[cnt]; 187748e1b9dSBarry Smith } else { 188748e1b9dSBarry Smith str[ncnt] = str[cnt]; 189748e1b9dSBarry Smith } 190748e1b9dSBarry Smith ncnt++; 191748e1b9dSBarry Smith } 192748e1b9dSBarry Smith while (cnt < leng) { 193748e1b9dSBarry Smith str[ncnt] = str[cnt]; ncnt++; cnt++; 194748e1b9dSBarry Smith } 195748e1b9dSBarry Smith str[ncnt] = 0; 196748e1b9dSBarry Smith } 197748e1b9dSBarry Smith } 198748e1b9dSBarry Smith #endif 199748e1b9dSBarry Smith if (fullLength) { 200748e1b9dSBarry Smith ierr = PetscStrlen(str,fullLength);CHKERRQ(ierr); 201748e1b9dSBarry Smith } 202eed5747fSBarry Smith PetscFunctionReturn(0); 203e5c89e4eSSatish Balay } 204e5c89e4eSSatish Balay 205e5c89e4eSSatish Balay #undef __FUNCT__ 206c9a19010SBarry Smith #define __FUNCT__ "PetscVFPrintfDefault" 207c9a19010SBarry Smith /*@C 208c9a19010SBarry Smith PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can 209e5c89e4eSSatish Balay can be replaced with something that does not simply write to a file. 210e5c89e4eSSatish Balay 211c9a19010SBarry Smith To use, write your own function for example, 212c9a19010SBarry Smith $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp) 213c9a19010SBarry Smith ${ 214c9a19010SBarry Smith $ PetscErrorCode ierr; 215c9a19010SBarry Smith $ 216c9a19010SBarry Smith $ PetscFunctionBegin; 217c9a19010SBarry Smith $ if (fd != stdout && fd != stderr) { handle regular files 218c9a19010SBarry Smith $ ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERR(ierr); 219c9a19010SBarry Smith $ } else { 220c9a19010SBarry Smith $ char buff[BIG]; 221c9a19010SBarry Smith $ size_t length; 222c9a19010SBarry Smith $ ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr); 223c9a19010SBarry Smith $ now send buff to whatever stream or whatever you want 224c9a19010SBarry Smith $ } 225c9a19010SBarry Smith $ PetscFunctionReturn(0); 226c9a19010SBarry Smith $} 227c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment 228c9a19010SBarry Smith $ PetscVFPrintf = mypetscvfprintf; 229c9a19010SBarry Smith 230c9a19010SBarry Smith Notes: For error messages this may be called by any process, for regular standard out it is 231e5c89e4eSSatish Balay called only by process 0 of a given communicator 232e5c89e4eSSatish Balay 233eed5747fSBarry Smith Developer Notes: this could be called by an error handler, if that happens then a recursion of the error handler may occur 234eed5747fSBarry Smith and a crash 235c9a19010SBarry Smith 236c9a19010SBarry Smith Level: developer 237c9a19010SBarry Smith 238c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscErrorPrintf() 239c9a19010SBarry Smith 240c9a19010SBarry Smith @*/ 2417087cfbeSBarry Smith PetscErrorCode PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp) 242e5c89e4eSSatish Balay { 243748e1b9dSBarry Smith char str[8*1024]; 244eed5747fSBarry Smith PetscErrorCode ierr; 2451179db26SBarry Smith 246eed5747fSBarry Smith PetscFunctionBegin; 247748e1b9dSBarry Smith ierr = PetscVSNPrintf(str,sizeof(str),format,NULL,Argp);CHKERRQ(ierr); 248748e1b9dSBarry Smith fprintf(fd,"%s",str);CHKERRQ(ierr); 2495a058713SBarry Smith fflush(fd); 250eed5747fSBarry Smith PetscFunctionReturn(0); 251e5c89e4eSSatish Balay } 252e5c89e4eSSatish Balay 2535b5bc046SBarry Smith #undef __FUNCT__ 2545b5bc046SBarry Smith #define __FUNCT__ "PetscSNPrintf" 2555b5bc046SBarry Smith /*@C 2565b5bc046SBarry Smith PetscSNPrintf - Prints to a string of given length 2575b5bc046SBarry Smith 2585b5bc046SBarry Smith Not Collective 2595b5bc046SBarry Smith 2605b5bc046SBarry Smith Input Parameters: 2615b5bc046SBarry Smith + str - the string to print to 2625b5bc046SBarry Smith . len - the length of str 2635b5bc046SBarry Smith . format - the usual printf() format string 2645b5bc046SBarry Smith - any arguments 2655b5bc046SBarry Smith 2665b5bc046SBarry Smith Level: intermediate 2675b5bc046SBarry Smith 2685b5bc046SBarry Smith .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 2695b5bc046SBarry Smith PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 2705b5bc046SBarry Smith @*/ 2717087cfbeSBarry Smith PetscErrorCode PetscSNPrintf(char *str,size_t len,const char format[],...) 2725b5bc046SBarry Smith { 2735b5bc046SBarry Smith PetscErrorCode ierr; 274c9a19010SBarry Smith size_t fullLength; 2755b5bc046SBarry Smith va_list Argp; 2765b5bc046SBarry Smith 2775b5bc046SBarry Smith PetscFunctionBegin; 2785b5bc046SBarry Smith va_start(Argp,format); 2792d609e63SMatthew Knepley ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr); 2805b5bc046SBarry Smith PetscFunctionReturn(0); 2815b5bc046SBarry Smith } 2825b5bc046SBarry Smith 283257d2499SJed Brown #undef __FUNCT__ 284257d2499SJed Brown #define __FUNCT__ "PetscSNPrintfCount" 285257d2499SJed Brown /*@C 286257d2499SJed Brown PetscSNPrintfCount - Prints to a string of given length, returns count 287257d2499SJed Brown 288257d2499SJed Brown Not Collective 289257d2499SJed Brown 290257d2499SJed Brown Input Parameters: 291257d2499SJed Brown + str - the string to print to 292257d2499SJed Brown . len - the length of str 293257d2499SJed Brown . format - the usual printf() format string 294257d2499SJed Brown . countused - number of characters used 295257d2499SJed Brown - any arguments 296257d2499SJed Brown 297257d2499SJed Brown Level: intermediate 298257d2499SJed Brown 299257d2499SJed Brown .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 300257d2499SJed Brown PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscSNPrintf() 301257d2499SJed Brown @*/ 302257d2499SJed Brown PetscErrorCode PetscSNPrintfCount(char *str,size_t len,const char format[],size_t *countused,...) 303257d2499SJed Brown { 304257d2499SJed Brown PetscErrorCode ierr; 305257d2499SJed Brown va_list Argp; 306257d2499SJed Brown 307257d2499SJed Brown PetscFunctionBegin; 308257d2499SJed Brown va_start(Argp,countused); 309257d2499SJed Brown ierr = PetscVSNPrintf(str,len,format,countused,Argp);CHKERRQ(ierr); 310257d2499SJed Brown PetscFunctionReturn(0); 311257d2499SJed Brown } 312257d2499SJed Brown 313e5c89e4eSSatish Balay /* ----------------------------------------------------------------------- */ 314e5c89e4eSSatish Balay 315d30b0576SJed Brown PrintfQueue petsc_printfqueue = 0,petsc_printfqueuebase = 0; 316d30b0576SJed Brown int petsc_printfqueuelength = 0; 317e5c89e4eSSatish Balay 318e5c89e4eSSatish Balay #undef __FUNCT__ 319e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedPrintf" 320e5c89e4eSSatish Balay /*@C 321e5c89e4eSSatish Balay PetscSynchronizedPrintf - Prints synchronized output from several processors. 322e5c89e4eSSatish Balay Output of the first processor is followed by that of the second, etc. 323e5c89e4eSSatish Balay 324e5c89e4eSSatish Balay Not Collective 325e5c89e4eSSatish Balay 326e5c89e4eSSatish Balay Input Parameters: 327e5c89e4eSSatish Balay + comm - the communicator 328e5c89e4eSSatish Balay - format - the usual printf() format string 329e5c89e4eSSatish Balay 330e5c89e4eSSatish Balay Level: intermediate 331e5c89e4eSSatish Balay 332e5c89e4eSSatish Balay Notes: 3337889ec69SBarry Smith REQUIRES a call to PetscSynchronizedFlush() by all the processes after the completion of the calls to PetscSynchronizedPrintf() for the information 334e5c89e4eSSatish Balay from all the processors to be printed. 335e5c89e4eSSatish Balay 336e5c89e4eSSatish Balay Fortran Note: 337d60d70ccSBarry Smith The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 338e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 339e5c89e4eSSatish Balay 340e5c89e4eSSatish Balay .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), 341e5c89e4eSSatish Balay PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 342e5c89e4eSSatish Balay @*/ 3437087cfbeSBarry Smith PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...) 344e5c89e4eSSatish Balay { 345e5c89e4eSSatish Balay PetscErrorCode ierr; 346e5c89e4eSSatish Balay PetscMPIInt rank; 347e5c89e4eSSatish Balay 348e5c89e4eSSatish Balay PetscFunctionBegin; 3496180deefSBarry Smith if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 350e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 351e5c89e4eSSatish Balay 352e5c89e4eSSatish Balay /* First processor prints immediately to stdout */ 353e5c89e4eSSatish Balay if (!rank) { 354e5c89e4eSSatish Balay va_list Argp; 355e5c89e4eSSatish Balay va_start(Argp,format); 3561179db26SBarry Smith ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 357e5c89e4eSSatish Balay if (petsc_history) { 358cdc7d174SSatish Balay va_start(Argp,format); 3591179db26SBarry Smith ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 360e5c89e4eSSatish Balay } 361e5c89e4eSSatish Balay va_end(Argp); 362e5c89e4eSSatish Balay } else { /* other processors add to local queue */ 363e5c89e4eSSatish Balay va_list Argp; 364e5c89e4eSSatish Balay PrintfQueue next; 365c9a19010SBarry Smith size_t fullLength = 8191; 366e5c89e4eSSatish Balay 367b00a9115SJed Brown ierr = PetscNew(&next);CHKERRQ(ierr); 368a297a907SKarl Rupp if (petsc_printfqueue) { 369a297a907SKarl Rupp petsc_printfqueue->next = next; 370a297a907SKarl Rupp petsc_printfqueue = next; 371a297a907SKarl Rupp petsc_printfqueue->next = 0; 372a297a907SKarl Rupp } else petsc_printfqueuebase = petsc_printfqueue = next; 373d30b0576SJed Brown petsc_printfqueuelength++; 3742d609e63SMatthew Knepley next->size = -1; 3759ad23270SJed Brown while ((PetscInt)fullLength >= next->size) { 3762d609e63SMatthew Knepley next->size = fullLength+1; 377a297a907SKarl Rupp 378785e854fSJed Brown ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr); 379e5c89e4eSSatish Balay va_start(Argp,format); 3802d609e63SMatthew Knepley ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 3812d609e63SMatthew Knepley ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr); 382e5c89e4eSSatish Balay va_end(Argp); 383e5c89e4eSSatish Balay } 3842d609e63SMatthew Knepley } 385e5c89e4eSSatish Balay PetscFunctionReturn(0); 386e5c89e4eSSatish Balay } 387e5c89e4eSSatish Balay 388e5c89e4eSSatish Balay #undef __FUNCT__ 389e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFPrintf" 390e5c89e4eSSatish Balay /*@C 391e5c89e4eSSatish Balay PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 392e5c89e4eSSatish Balay several processors. Output of the first processor is followed by that of the 393e5c89e4eSSatish Balay second, etc. 394e5c89e4eSSatish Balay 395e5c89e4eSSatish Balay Not Collective 396e5c89e4eSSatish Balay 397e5c89e4eSSatish Balay Input Parameters: 398e5c89e4eSSatish Balay + comm - the communicator 399e5c89e4eSSatish Balay . fd - the file pointer 400e5c89e4eSSatish Balay - format - the usual printf() format string 401e5c89e4eSSatish Balay 402e5c89e4eSSatish Balay Level: intermediate 403e5c89e4eSSatish Balay 404e5c89e4eSSatish Balay Notes: 405e5c89e4eSSatish Balay REQUIRES a intervening call to PetscSynchronizedFlush() for the information 406e5c89e4eSSatish Balay from all the processors to be printed. 407e5c89e4eSSatish Balay 408e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 409e5c89e4eSSatish Balay PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 410e5c89e4eSSatish Balay 411e5c89e4eSSatish Balay @*/ 4127087cfbeSBarry Smith PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm,FILE *fp,const char format[],...) 413e5c89e4eSSatish Balay { 414e5c89e4eSSatish Balay PetscErrorCode ierr; 415e5c89e4eSSatish Balay PetscMPIInt rank; 416e5c89e4eSSatish Balay 417e5c89e4eSSatish Balay PetscFunctionBegin; 4186180deefSBarry Smith if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 419e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 420e5c89e4eSSatish Balay 421e5c89e4eSSatish Balay /* First processor prints immediately to fp */ 422e5c89e4eSSatish Balay if (!rank) { 423e5c89e4eSSatish Balay va_list Argp; 424e5c89e4eSSatish Balay va_start(Argp,format); 4251179db26SBarry Smith ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 426cdc7d174SSatish Balay if (petsc_history && (fp !=petsc_history)) { 427cdc7d174SSatish Balay va_start(Argp,format); 4281179db26SBarry Smith ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 429e5c89e4eSSatish Balay } 430e5c89e4eSSatish Balay va_end(Argp); 431e5c89e4eSSatish Balay } else { /* other processors add to local queue */ 432e5c89e4eSSatish Balay va_list Argp; 433e5c89e4eSSatish Balay PrintfQueue next; 434c9a19010SBarry Smith size_t fullLength = 8191; 435b00a9115SJed Brown ierr = PetscNew(&next);CHKERRQ(ierr); 436a297a907SKarl Rupp if (petsc_printfqueue) { 437a297a907SKarl Rupp petsc_printfqueue->next = next; 438a297a907SKarl Rupp petsc_printfqueue = next; 439a297a907SKarl Rupp petsc_printfqueue->next = 0; 440a297a907SKarl Rupp } else petsc_printfqueuebase = petsc_printfqueue = next; 441d30b0576SJed Brown petsc_printfqueuelength++; 4422d609e63SMatthew Knepley next->size = -1; 4439ad23270SJed Brown while ((PetscInt)fullLength >= next->size) { 4442d609e63SMatthew Knepley next->size = fullLength+1; 445785e854fSJed Brown ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr); 446e5c89e4eSSatish Balay va_start(Argp,format); 4472d609e63SMatthew Knepley ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 4482d609e63SMatthew Knepley ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr); 449e5c89e4eSSatish Balay va_end(Argp); 450e5c89e4eSSatish Balay } 4512d609e63SMatthew Knepley } 452e5c89e4eSSatish Balay PetscFunctionReturn(0); 453e5c89e4eSSatish Balay } 454e5c89e4eSSatish Balay 455e5c89e4eSSatish Balay #undef __FUNCT__ 456e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFlush" 4570ec8b6e3SBarry Smith /*@C 458e5c89e4eSSatish Balay PetscSynchronizedFlush - Flushes to the screen output from all processors 4597889ec69SBarry Smith involved in previous PetscSynchronizedPrintf()/PetscSynchronizedFPrintf() calls. 460e5c89e4eSSatish Balay 461e5c89e4eSSatish Balay Collective on MPI_Comm 462e5c89e4eSSatish Balay 463e5c89e4eSSatish Balay Input Parameters: 4640ec8b6e3SBarry Smith + comm - the communicator 4650ec8b6e3SBarry Smith - fd - the file pointer (valid on process 0 of the communicator) 466e5c89e4eSSatish Balay 467e5c89e4eSSatish Balay Level: intermediate 468e5c89e4eSSatish Balay 469e5c89e4eSSatish Balay Notes: 4707889ec69SBarry Smith If PetscSynchronizedPrintf() and/or PetscSynchronizedFPrintf() are called with 4717889ec69SBarry Smith different MPI communicators there must be an intervening call to PetscSynchronizedFlush() between the calls with different MPI communicators. 472e5c89e4eSSatish Balay 473*e50bf69fSBarry Smith From Fortran pass PETSC_STDOUT if the flush is for standard out; otherwise pass a value obtained from PetscFOpen() 474*e50bf69fSBarry Smith 475e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(), 476e5c89e4eSSatish Balay PetscViewerASCIISynchronizedPrintf() 4770087d953SMatthew G. Knepley @*/ 4780ec8b6e3SBarry Smith PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm,FILE *fd) 479e5c89e4eSSatish Balay { 480e5c89e4eSSatish Balay PetscErrorCode ierr; 48129a5cbdcSMatthew G. Knepley PetscMPIInt rank,size,tag,i,j,n = 0,dummy = 0; 4822d609e63SMatthew Knepley char *message; 483e5c89e4eSSatish Balay MPI_Status status; 484e5c89e4eSSatish Balay 485e5c89e4eSSatish Balay PetscFunctionBegin; 486e5c89e4eSSatish Balay ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr); 487e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 488e5c89e4eSSatish Balay ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 489e5c89e4eSSatish Balay 490e5c89e4eSSatish Balay /* First processor waits for messages from all other processors */ 491e5c89e4eSSatish Balay if (!rank) { 4920ec8b6e3SBarry Smith if (!fd) fd = PETSC_STDOUT; 493e5c89e4eSSatish Balay for (i=1; i<size; i++) { 4949f73f8ecSBarry Smith /* to prevent a flood of messages to process zero, request each message separately */ 4959f73f8ecSBarry Smith ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr); 496e5c89e4eSSatish Balay ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 497e5c89e4eSSatish Balay for (j=0; j<n; j++) { 49829a5cbdcSMatthew G. Knepley PetscMPIInt size = 0; 4992d609e63SMatthew Knepley 5002d609e63SMatthew Knepley ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 501785e854fSJed Brown ierr = PetscMalloc1(size, &message);CHKERRQ(ierr); 5022d609e63SMatthew Knepley ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr); 5033bf036e2SBarry Smith ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr); 5042d609e63SMatthew Knepley ierr = PetscFree(message);CHKERRQ(ierr); 505e5c89e4eSSatish Balay } 506e5c89e4eSSatish Balay } 507e5c89e4eSSatish Balay } else { /* other processors send queue to processor 0 */ 508d30b0576SJed Brown PrintfQueue next = petsc_printfqueuebase,previous; 509e5c89e4eSSatish Balay 510b3ef9d35SBarry Smith ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr); 511d30b0576SJed Brown ierr = MPI_Send(&petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 512d30b0576SJed Brown for (i=0; i<petsc_printfqueuelength; i++) { 5132d609e63SMatthew Knepley ierr = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 5142d609e63SMatthew Knepley ierr = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr); 515e5c89e4eSSatish Balay previous = next; 516e5c89e4eSSatish Balay next = next->next; 5172d609e63SMatthew Knepley ierr = PetscFree(previous->string);CHKERRQ(ierr); 518e5c89e4eSSatish Balay ierr = PetscFree(previous);CHKERRQ(ierr); 519e5c89e4eSSatish Balay } 520d30b0576SJed Brown petsc_printfqueue = 0; 521d30b0576SJed Brown petsc_printfqueuelength = 0; 522e5c89e4eSSatish Balay } 523e5c89e4eSSatish Balay ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 524e5c89e4eSSatish Balay PetscFunctionReturn(0); 525e5c89e4eSSatish Balay } 526e5c89e4eSSatish Balay 527e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/ 528e5c89e4eSSatish Balay 529e5c89e4eSSatish Balay #undef __FUNCT__ 530e5c89e4eSSatish Balay #define __FUNCT__ "PetscFPrintf" 531e5c89e4eSSatish Balay /*@C 532e5c89e4eSSatish Balay PetscFPrintf - Prints to a file, only from the first 533e5c89e4eSSatish Balay processor in the communicator. 534e5c89e4eSSatish Balay 535e5c89e4eSSatish Balay Not Collective 536e5c89e4eSSatish Balay 537e5c89e4eSSatish Balay Input Parameters: 538e5c89e4eSSatish Balay + comm - the communicator 539e5c89e4eSSatish Balay . fd - the file pointer 540e5c89e4eSSatish Balay - format - the usual printf() format string 541e5c89e4eSSatish Balay 542e5c89e4eSSatish Balay Level: intermediate 543e5c89e4eSSatish Balay 544e5c89e4eSSatish Balay Fortran Note: 545e5c89e4eSSatish Balay This routine is not supported in Fortran. 546e5c89e4eSSatish Balay 547e5c89e4eSSatish Balay Concepts: printing^in parallel 548e5c89e4eSSatish Balay Concepts: printf^in parallel 549e5c89e4eSSatish Balay 550e5c89e4eSSatish Balay .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 551e5c89e4eSSatish Balay PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush() 552e5c89e4eSSatish Balay @*/ 5537087cfbeSBarry Smith PetscErrorCode PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...) 554e5c89e4eSSatish Balay { 555e5c89e4eSSatish Balay PetscErrorCode ierr; 556e5c89e4eSSatish Balay PetscMPIInt rank; 557e5c89e4eSSatish Balay 558e5c89e4eSSatish Balay PetscFunctionBegin; 5596180deefSBarry Smith if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 560e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 561e5c89e4eSSatish Balay if (!rank) { 562e5c89e4eSSatish Balay va_list Argp; 563e5c89e4eSSatish Balay va_start(Argp,format); 5641179db26SBarry Smith ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr); 565cdc7d174SSatish Balay if (petsc_history && (fd !=petsc_history)) { 566cdc7d174SSatish Balay va_start(Argp,format); 5671179db26SBarry Smith ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 568e5c89e4eSSatish Balay } 569e5c89e4eSSatish Balay va_end(Argp); 570e5c89e4eSSatish Balay } 571e5c89e4eSSatish Balay PetscFunctionReturn(0); 572e5c89e4eSSatish Balay } 573e5c89e4eSSatish Balay 574e5c89e4eSSatish Balay #undef __FUNCT__ 575e5c89e4eSSatish Balay #define __FUNCT__ "PetscPrintf" 576e5c89e4eSSatish Balay /*@C 577e5c89e4eSSatish Balay PetscPrintf - Prints to standard out, only from the first 578eed5747fSBarry Smith processor in the communicator. Calls from other processes are ignored. 579e5c89e4eSSatish Balay 580e5c89e4eSSatish Balay Not Collective 581e5c89e4eSSatish Balay 582e5c89e4eSSatish Balay Input Parameters: 583e5c89e4eSSatish Balay + comm - the communicator 584e5c89e4eSSatish Balay - format - the usual printf() format string 585e5c89e4eSSatish Balay 586e5c89e4eSSatish Balay Level: intermediate 587e5c89e4eSSatish Balay 588e5c89e4eSSatish Balay Fortran Note: 589d60d70ccSBarry Smith The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 590e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 591e5c89e4eSSatish Balay 592e5c89e4eSSatish Balay Concepts: printing^in parallel 593e5c89e4eSSatish Balay Concepts: printf^in parallel 594e5c89e4eSSatish Balay 595e5c89e4eSSatish Balay .seealso: PetscFPrintf(), PetscSynchronizedPrintf() 596e5c89e4eSSatish Balay @*/ 5977087cfbeSBarry Smith PetscErrorCode PetscPrintf(MPI_Comm comm,const char format[],...) 598e5c89e4eSSatish Balay { 599e5c89e4eSSatish Balay PetscErrorCode ierr; 600e5c89e4eSSatish Balay PetscMPIInt rank; 601e5c89e4eSSatish Balay 602e5c89e4eSSatish Balay PetscFunctionBegin; 6036180deefSBarry Smith if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 604e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 605e5c89e4eSSatish Balay if (!rank) { 606e5c89e4eSSatish Balay va_list Argp; 607e5c89e4eSSatish Balay va_start(Argp,format); 608eed5747fSBarry Smith ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 609e5c89e4eSSatish Balay if (petsc_history) { 610cdc7d174SSatish Balay va_start(Argp,format); 611eed5747fSBarry Smith ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 612e5c89e4eSSatish Balay } 613e5c89e4eSSatish Balay va_end(Argp); 614e5c89e4eSSatish Balay } 615e5c89e4eSSatish Balay PetscFunctionReturn(0); 616e5c89e4eSSatish Balay } 617e5c89e4eSSatish Balay 618e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/ 619e5c89e4eSSatish Balay #undef __FUNCT__ 620e5c89e4eSSatish Balay #define __FUNCT__ "PetscHelpPrintfDefault" 621c9a19010SBarry Smith /*@C 622c9a19010SBarry Smith PetscHelpPrintf - All PETSc help messages are passing through this function. You can change how help messages are printed by 623c9a19010SBarry Smith replacinng it with something that does not simply write to a stdout. 624c9a19010SBarry Smith 625c9a19010SBarry Smith To use, write your own function for example, 626c9a19010SBarry Smith $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....) 627c9a19010SBarry Smith ${ 628c9a19010SBarry Smith $ PetscFunctionReturn(0); 629c9a19010SBarry Smith $} 630c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment 631c9a19010SBarry Smith $ PetscHelpPrintf = mypetschelpprintf; 632c9a19010SBarry Smith 633c9a19010SBarry Smith Note: the default routine used is called PetscHelpPrintfDefault(). 634c9a19010SBarry Smith 635c9a19010SBarry Smith Level: developer 636c9a19010SBarry Smith 637c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf() 638c9a19010SBarry Smith @*/ 6397087cfbeSBarry Smith PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...) 640e5c89e4eSSatish Balay { 641e5c89e4eSSatish Balay PetscErrorCode ierr; 642e5c89e4eSSatish Balay PetscMPIInt rank; 643e5c89e4eSSatish Balay 644e5c89e4eSSatish Balay PetscFunctionBegin; 6456180deefSBarry Smith if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 646e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 647e5c89e4eSSatish Balay if (!rank) { 648e5c89e4eSSatish Balay va_list Argp; 649e5c89e4eSSatish Balay va_start(Argp,format); 6501179db26SBarry Smith ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 651e5c89e4eSSatish Balay if (petsc_history) { 652cdc7d174SSatish Balay va_start(Argp,format); 6531179db26SBarry Smith ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 654e5c89e4eSSatish Balay } 655e5c89e4eSSatish Balay va_end(Argp); 656e5c89e4eSSatish Balay } 657e5c89e4eSSatish Balay PetscFunctionReturn(0); 658e5c89e4eSSatish Balay } 659e5c89e4eSSatish Balay 660e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/ 661e5c89e4eSSatish Balay 662e5c89e4eSSatish Balay 663e5c89e4eSSatish Balay #undef __FUNCT__ 664e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFGets" 665e5c89e4eSSatish Balay /*@C 666e5c89e4eSSatish Balay PetscSynchronizedFGets - Several processors all get the same line from a file. 667e5c89e4eSSatish Balay 668e5c89e4eSSatish Balay Collective on MPI_Comm 669e5c89e4eSSatish Balay 670e5c89e4eSSatish Balay Input Parameters: 671e5c89e4eSSatish Balay + comm - the communicator 672e5c89e4eSSatish Balay . fd - the file pointer 673e5c89e4eSSatish Balay - len - the length of the output buffer 674e5c89e4eSSatish Balay 675e5c89e4eSSatish Balay Output Parameter: 676e31d4fa4SJed Brown . string - the line read from the file, at end of file string[0] == 0 677e5c89e4eSSatish Balay 678e5c89e4eSSatish Balay Level: intermediate 679e5c89e4eSSatish Balay 680e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 681e5c89e4eSSatish Balay PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 682e5c89e4eSSatish Balay 683e5c89e4eSSatish Balay @*/ 6847087cfbeSBarry Smith PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm,FILE *fp,size_t len,char string[]) 685e5c89e4eSSatish Balay { 686e5c89e4eSSatish Balay PetscErrorCode ierr; 687e5c89e4eSSatish Balay PetscMPIInt rank; 688e5c89e4eSSatish Balay 689e5c89e4eSSatish Balay PetscFunctionBegin; 690e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 691e5c89e4eSSatish Balay 692e5c89e4eSSatish Balay if (!rank) { 693047b9c12SMatthew G Knepley char *ptr = fgets(string, len, fp); 694047b9c12SMatthew G Knepley 695047b9c12SMatthew G Knepley if (!ptr) { 696e31d4fa4SJed Brown string[0] = 0; 697e31d4fa4SJed Brown if (!feof(fp)) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno); 698047b9c12SMatthew G Knepley } 699e5c89e4eSSatish Balay } 700e5c89e4eSSatish Balay ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr); 701e5c89e4eSSatish Balay PetscFunctionReturn(0); 702e5c89e4eSSatish Balay } 703238ccf28SShri Abhyankar 704f1d7fe2eSBarry Smith #if defined(PETSC_HAVE_CLOSURES) 705f1d7fe2eSBarry Smith int (^SwiftClosure)(const char*) = 0; 706f1d7fe2eSBarry Smith 707f1d7fe2eSBarry Smith #undef __FUNCT__ 708f1d7fe2eSBarry Smith #define __FUNCT__ "PetscVFPrintfToString" 709f1d7fe2eSBarry Smith PetscErrorCode PetscVFPrintfToString(FILE *fd,const char format[],va_list Argp) 710f1d7fe2eSBarry Smith { 711f1d7fe2eSBarry Smith PetscErrorCode ierr; 712f1d7fe2eSBarry Smith 713f1d7fe2eSBarry Smith PetscFunctionBegin; 714f1d7fe2eSBarry Smith if (fd != stdout && fd != stderr) { /* handle regular files */ 715f1d7fe2eSBarry Smith ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr); 716f1d7fe2eSBarry Smith } else { 717f1d7fe2eSBarry Smith size_t len=8*1024,length; 718f1d7fe2eSBarry Smith char buf[len]; 719f1d7fe2eSBarry Smith 720f1d7fe2eSBarry Smith ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr); 721f1d7fe2eSBarry Smith ierr = SwiftClosure(buf);CHKERRQ(ierr); 722f1d7fe2eSBarry Smith } 723f1d7fe2eSBarry Smith PetscFunctionReturn(0); 724f1d7fe2eSBarry Smith } 725f1d7fe2eSBarry Smith 726f1d7fe2eSBarry Smith /* 727f1d7fe2eSBarry Smith Provide a Swift function that processes all the PETSc calls to PetscVFPrintf() 728f1d7fe2eSBarry Smith */ 729f1d7fe2eSBarry Smith PetscErrorCode PetscVFPrintfSetClosure(int (^closure)(const char*)) 730f1d7fe2eSBarry Smith { 731f1d7fe2eSBarry Smith PetscVFPrintf = PetscVFPrintfToString; 732f1d7fe2eSBarry Smith SwiftClosure = closure; 733f1d7fe2eSBarry Smith return 0; 734f1d7fe2eSBarry Smith } 735f1d7fe2eSBarry Smith #endif 736f1d7fe2eSBarry Smith 737238ccf28SShri Abhyankar #if defined(PETSC_HAVE_MATLAB_ENGINE) 738c6db04a5SJed Brown #include <mex.h> 739238ccf28SShri Abhyankar #undef __FUNCT__ 740238ccf28SShri Abhyankar #define __FUNCT__ "PetscVFPrintf_Matlab" 7417087cfbeSBarry Smith PetscErrorCode PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp) 742238ccf28SShri Abhyankar { 743238ccf28SShri Abhyankar PetscErrorCode ierr; 744238ccf28SShri Abhyankar 745238ccf28SShri Abhyankar PetscFunctionBegin; 746238ccf28SShri Abhyankar if (fd != stdout && fd != stderr) { /* handle regular files */ 747238ccf28SShri Abhyankar ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr); 748238ccf28SShri Abhyankar } else { 749238ccf28SShri Abhyankar size_t len=8*1024,length; 750238ccf28SShri Abhyankar char buf[len]; 751238ccf28SShri Abhyankar 752238ccf28SShri Abhyankar ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr); 753df413903SBarry Smith mexPrintf("%s",buf); 754238ccf28SShri Abhyankar } 755238ccf28SShri Abhyankar PetscFunctionReturn(0); 756238ccf28SShri Abhyankar } 757238ccf28SShri Abhyankar #endif 7586fc7ef2bSBarry Smith 7596fc7ef2bSBarry Smith #undef __FUNCT__ 7608c74ee41SBarry Smith #define __FUNCT__ "PetscFormatStrip" 7618c74ee41SBarry Smith /*@C 7628c74ee41SBarry Smith PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations 7638c74ee41SBarry Smith 7648c74ee41SBarry Smith Input Parameters: 7658c74ee41SBarry Smith . format - the PETSc format string 7668c74ee41SBarry Smith 7678c74ee41SBarry Smith Level: developer 7688c74ee41SBarry Smith 7698c74ee41SBarry Smith @*/ 7708c74ee41SBarry Smith PetscErrorCode PetscFormatStrip(char *format) 7718c74ee41SBarry Smith { 7728c74ee41SBarry Smith size_t loc1 = 0, loc2 = 0; 7738c74ee41SBarry Smith 7748c74ee41SBarry Smith PetscFunctionBegin; 7758c74ee41SBarry Smith while (format[loc2]) { 7768c74ee41SBarry Smith if (format[loc2] == '%') { 7778c74ee41SBarry Smith format[loc1++] = format[loc2++]; 7788c74ee41SBarry Smith while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++; 7798c74ee41SBarry Smith } 7808c74ee41SBarry Smith format[loc1++] = format[loc2++]; 7818c74ee41SBarry Smith } 7828c74ee41SBarry Smith PetscFunctionReturn(0); 7838c74ee41SBarry Smith } 7848c74ee41SBarry Smith 785