1 #define PETSC_DLL 2 /* 3 Utilites routines to add simple ASCII IO capability. 4 */ 5 #include "../src/sys/fileio/mprint.h" 6 /* 7 If petsc_history is on, then all Petsc*Printf() results are saved 8 if the appropriate (usually .petschistory) file. 9 */ 10 extern FILE *petsc_history; 11 /* 12 Allows one to overwrite where standard out is sent. For example 13 PETSC_STDOUT = fopen("/dev/ttyXX","w") will cause all standard out 14 writes to go to terminal XX; assuming you have write permission there 15 */ 16 FILE *PETSC_STDOUT = 0; 17 /* 18 Allows one to overwrite where standard error is sent. For example 19 PETSC_STDERR = fopen("/dev/ttyXX","w") will cause all standard error 20 writes to go to terminal XX; assuming you have write permission there 21 */ 22 FILE *PETSC_STDERR = 0; 23 /* 24 Used to output to Zope 25 */ 26 FILE *PETSC_ZOPEFD = 0; 27 28 #undef __FUNCT__ 29 #define __FUNCT__ "PetscFormatConvert" 30 /*@C 31 PetscFormatConvert - Takes a PETSc format string and converts it to a reqular C format string 32 33 Input Parameters: 34 + format - the PETSc format string 35 . newformat - the location to put the standard C format string values 36 - size - the length of newformat 37 38 Note: this exists so we can have the same code when PetscInt is either int or long long and PetscScalar is either double or float 39 40 Level: developer 41 42 @*/ 43 PetscErrorCode PETSCSYS_DLLEXPORT PetscFormatConvert(const char *format,char *newformat,size_t size) 44 { 45 PetscInt i = 0,j = 0; 46 47 while (format[i] && i < size-1) { 48 if (format[i] == '%' && format[i+1] == 'D') { 49 newformat[j++] = '%'; 50 #if !defined(PETSC_USE_64BIT_INDICES) 51 newformat[j++] = 'd'; 52 #else 53 newformat[j++] = 'l'; 54 newformat[j++] = 'l'; 55 newformat[j++] = 'd'; 56 #endif 57 i += 2; 58 } else if (format[i] == '%' && format[i+1] >= '1' && format[i+1] <= '9' && format[i+2] == 'D') { 59 newformat[j++] = '%'; 60 newformat[j++] = format[i+1]; 61 #if !defined(PETSC_USE_64BIT_INDICES) 62 newformat[j++] = 'd'; 63 #else 64 newformat[j++] = 'l'; 65 newformat[j++] = 'l'; 66 newformat[j++] = 'd'; 67 #endif 68 i += 3; 69 } else if (format[i] == '%' && format[i+1] == 'G') { 70 newformat[j++] = '%'; 71 #if defined(PETSC_USE_SCALAR_INT) 72 newformat[j++] = 'd'; 73 #elif !defined(PETSC_USE_SCALAR_LONG_DOUBLE) 74 newformat[j++] = 'g'; 75 #else 76 newformat[j++] = 'L'; 77 newformat[j++] = 'g'; 78 #endif 79 i += 2; 80 }else { 81 newformat[j++] = format[i++]; 82 } 83 } 84 newformat[j] = 0; 85 return 0; 86 } 87 88 #undef __FUNCT__ 89 #define __FUNCT__ "PetscVSNPrintf" 90 /*@C 91 PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the 92 function arguments into a string using the format statement. 93 94 Input Parameters: 95 + str - location to put result 96 . len - the amount of space in str 97 + format - the PETSc format string 98 - fullLength - the amount of space in str actually used. 99 100 Note: No error handling because may be called by error handler 101 102 Level: developer 103 104 @*/ 105 PetscErrorCode PETSCSYS_DLLEXPORT PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp) 106 { 107 /* no malloc since may be called by error handler */ 108 char *newformat; 109 char formatbuf[8*1024]; 110 size_t oldLength,length; 111 PetscErrorCode ierr; 112 113 ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr); 114 if (oldLength < 8*1024) { 115 newformat = formatbuf; 116 } else { 117 ierr = PetscMalloc((oldLength+1) * sizeof(char), &newformat);CHKERRQ(ierr); 118 } 119 PetscFormatConvert(format,newformat,oldLength+1); 120 ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr); 121 #if 0 122 if (length > len) { 123 newformat[len] = '\0'; 124 } 125 #endif 126 #if defined(PETSC_HAVE_VSNPRINTF_CHAR) 127 *fullLength = vsnprintf(str,len,newformat,(char *)Argp); 128 #elif defined(PETSC_HAVE_VSNPRINTF) 129 *fullLength = vsnprintf(str,len,newformat,Argp); 130 #elif defined(PETSC_HAVE__VSNPRINTF) 131 *fullLength = _vsnprintf(str,len,newformat,Argp); 132 #else 133 #error "vsnprintf not found" 134 #endif 135 if (oldLength >= 8*1024) { 136 ierr = PetscFree(newformat);CHKERRQ(ierr); 137 } 138 return 0; 139 } 140 141 #undef __FUNCT__ 142 #define __FUNCT__ "PetscZopeLog" 143 PetscErrorCode PETSCSYS_DLLEXPORT PetscZopeLog(const char *format,va_list Argp) 144 { 145 /* no malloc since may be called by error handler */ 146 char newformat[8*1024]; 147 char log[8*1024]; 148 char logstart[] = " <<<log>>>"; 149 size_t len,formatlen; 150 151 PetscFormatConvert(format,newformat,8*1024); 152 PetscStrlen(logstart, &len); 153 PetscMemcpy(log, logstart, len); 154 PetscStrlen(newformat, &formatlen); 155 PetscMemcpy(&(log[len]), newformat, formatlen); 156 if (PETSC_ZOPEFD){ 157 #if defined(PETSC_HAVE_VFPRINTF_CHAR) 158 vfprintf(PETSC_ZOPEFD,log,(char *)Argp); 159 #else 160 vfprintf(PETSC_ZOPEFD,log,Argp); 161 #endif 162 fflush(PETSC_ZOPEFD); 163 } 164 return 0; 165 } 166 167 #undef __FUNCT__ 168 #define __FUNCT__ "PetscVFPrintfDefault" 169 /*@C 170 PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can 171 can be replaced with something that does not simply write to a file. 172 173 To use, write your own function for example, 174 $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp) 175 ${ 176 $ PetscErrorCode ierr; 177 $ 178 $ PetscFunctionBegin; 179 $ if (fd != stdout && fd != stderr) { handle regular files 180 $ ierr = PetscVFPrintfDefault(fd,format,Argp); CHKERR(ierr); 181 $ } else { 182 $ char buff[BIG]; 183 $ size_t length; 184 $ ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr); 185 $ now send buff to whatever stream or whatever you want 186 $ } 187 $ PetscFunctionReturn(0); 188 $} 189 then before the call to PetscInitialize() do the assignment 190 $ PetscVFPrintf = mypetscvfprintf; 191 192 Notes: For error messages this may be called by any process, for regular standard out it is 193 called only by process 0 of a given communicator 194 195 No error handling because may be called by error handler 196 197 Level: developer 198 199 .seealso: PetscVSNPrintf(), PetscErrorPrintf() 200 201 @*/ 202 PetscErrorCode PETSCSYS_DLLEXPORT PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp) 203 { 204 /* no malloc since may be called by error handler (assume no long messages in errors) */ 205 char *newformat; 206 char formatbuf[8*1024]; 207 size_t oldLength; 208 209 PetscStrlen(format, &oldLength); 210 if (oldLength < 8*1024) { 211 newformat = formatbuf; 212 } else { 213 (void)PetscMalloc((oldLength+1) * sizeof(char), &newformat); 214 } 215 PetscFormatConvert(format,newformat,oldLength+1); 216 if (PETSC_ZOPEFD && PETSC_ZOPEFD != PETSC_STDOUT){ 217 va_list s; 218 #if defined(PETSC_HAVE_VA_COPY) 219 va_copy(s, Argp); 220 #elif defined(PETSC_HAVE___VA_COPY) 221 __va_copy(s, Argp); 222 #else 223 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Zope not supported due to missing va_copy()"); 224 #endif 225 226 #if defined(PETSC_HAVE_VA_COPY) || defined(PETSC_HAVE___VA_COPY) 227 #if defined(PETSC_HAVE_VFPRINTF_CHAR) 228 vfprintf(PETSC_ZOPEFD,newformat,(char *)s); 229 #else 230 vfprintf(PETSC_ZOPEFD,newformat,s); 231 #endif 232 fflush(PETSC_ZOPEFD); 233 #endif 234 } 235 236 #if defined(PETSC_HAVE_VFPRINTF_CHAR) 237 vfprintf(fd,newformat,(char *)Argp); 238 #else 239 vfprintf(fd,newformat,Argp); 240 #endif 241 fflush(fd); 242 if (oldLength >= 8*1024) { 243 if (PetscFree(newformat)) {}; 244 } 245 return 0; 246 } 247 248 #undef __FUNCT__ 249 #define __FUNCT__ "PetscSNPrintf" 250 /*@C 251 PetscSNPrintf - Prints to a string of given length 252 253 Not Collective 254 255 Input Parameters: 256 + str - the string to print to 257 . len - the length of str 258 . format - the usual printf() format string 259 - any arguments 260 261 Level: intermediate 262 263 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 264 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 265 @*/ 266 PetscErrorCode PETSCSYS_DLLEXPORT PetscSNPrintf(char *str,size_t len,const char format[],...) 267 { 268 PetscErrorCode ierr; 269 size_t fullLength; 270 va_list Argp; 271 272 PetscFunctionBegin; 273 va_start(Argp,format); 274 ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr); 275 PetscFunctionReturn(0); 276 } 277 278 /* ----------------------------------------------------------------------- */ 279 280 PrintfQueue queue = 0,queuebase = 0; 281 int queuelength = 0; 282 FILE *queuefile = PETSC_NULL; 283 284 #undef __FUNCT__ 285 #define __FUNCT__ "PetscSynchronizedPrintf" 286 /*@C 287 PetscSynchronizedPrintf - Prints synchronized output from several processors. 288 Output of the first processor is followed by that of the second, etc. 289 290 Not Collective 291 292 Input Parameters: 293 + comm - the communicator 294 - format - the usual printf() format string 295 296 Level: intermediate 297 298 Notes: 299 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 300 from all the processors to be printed. 301 302 Fortran Note: 303 The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 304 That is, you can only pass a single character string from Fortran. 305 306 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), 307 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 308 @*/ 309 PetscErrorCode PETSCSYS_DLLEXPORT PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...) 310 { 311 PetscErrorCode ierr; 312 PetscMPIInt rank; 313 314 PetscFunctionBegin; 315 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 316 317 /* First processor prints immediately to stdout */ 318 if (!rank) { 319 va_list Argp; 320 va_start(Argp,format); 321 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 322 if (petsc_history) { 323 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 324 } 325 va_end(Argp); 326 } else { /* other processors add to local queue */ 327 va_list Argp; 328 PrintfQueue next; 329 size_t fullLength = 8191; 330 331 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 332 if (queue) {queue->next = next; queue = next; queue->next = 0;} 333 else {queuebase = queue = next;} 334 queuelength++; 335 next->size = -1; 336 while(fullLength >= next->size) { 337 next->size = fullLength+1; 338 ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr); 339 va_start(Argp,format); 340 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 341 ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr); 342 va_end(Argp); 343 } 344 } 345 346 PetscFunctionReturn(0); 347 } 348 349 #undef __FUNCT__ 350 #define __FUNCT__ "PetscSynchronizedFPrintf" 351 /*@C 352 PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 353 several processors. Output of the first processor is followed by that of the 354 second, etc. 355 356 Not Collective 357 358 Input Parameters: 359 + comm - the communicator 360 . fd - the file pointer 361 - format - the usual printf() format string 362 363 Level: intermediate 364 365 Notes: 366 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 367 from all the processors to be printed. 368 369 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 370 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 371 372 @*/ 373 PetscErrorCode PETSCSYS_DLLEXPORT PetscSynchronizedFPrintf(MPI_Comm comm,FILE* fp,const char format[],...) 374 { 375 PetscErrorCode ierr; 376 PetscMPIInt rank; 377 378 PetscFunctionBegin; 379 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 380 381 /* First processor prints immediately to fp */ 382 if (!rank) { 383 va_list Argp; 384 va_start(Argp,format); 385 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 386 queuefile = fp; 387 if (petsc_history) { 388 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 389 } 390 va_end(Argp); 391 } else { /* other processors add to local queue */ 392 va_list Argp; 393 PrintfQueue next; 394 size_t fullLength = 8191; 395 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 396 if (queue) {queue->next = next; queue = next; queue->next = 0;} 397 else {queuebase = queue = next;} 398 queuelength++; 399 next->size = -1; 400 while(fullLength >= next->size) { 401 next->size = fullLength+1; 402 ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr); 403 va_start(Argp,format); 404 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 405 ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr); 406 va_end(Argp); 407 } 408 } 409 PetscFunctionReturn(0); 410 } 411 412 #undef __FUNCT__ 413 #define __FUNCT__ "PetscSynchronizedFlush" 414 /*@ 415 PetscSynchronizedFlush - Flushes to the screen output from all processors 416 involved in previous PetscSynchronizedPrintf() calls. 417 418 Collective on MPI_Comm 419 420 Input Parameters: 421 . comm - the communicator 422 423 Level: intermediate 424 425 Notes: 426 Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with 427 different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush(). 428 429 .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(), 430 PetscViewerASCIISynchronizedPrintf() 431 @*/ 432 PetscErrorCode PETSCSYS_DLLEXPORT PetscSynchronizedFlush(MPI_Comm comm) 433 { 434 PetscErrorCode ierr; 435 PetscMPIInt rank,size,tag,i,j,n,dummy = 0; 436 char *message; 437 MPI_Status status; 438 FILE *fd; 439 440 PetscFunctionBegin; 441 ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr); 442 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 443 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 444 445 /* First processor waits for messages from all other processors */ 446 if (!rank) { 447 if (queuefile) { 448 fd = queuefile; 449 } else { 450 fd = PETSC_STDOUT; 451 } 452 for (i=1; i<size; i++) { 453 /* to prevent a flood of messages to process zero, request each message separately */ 454 ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr); 455 ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 456 for (j=0; j<n; j++) { 457 PetscMPIInt size; 458 459 ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 460 ierr = PetscMalloc(size * sizeof(char), &message);CHKERRQ(ierr); 461 ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr); 462 ierr = PetscFPrintf(comm,fd,"%s",message); 463 ierr = PetscFree(message);CHKERRQ(ierr); 464 } 465 } 466 queuefile = PETSC_NULL; 467 } else { /* other processors send queue to processor 0 */ 468 PrintfQueue next = queuebase,previous; 469 470 ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr); 471 ierr = MPI_Send(&queuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 472 for (i=0; i<queuelength; i++) { 473 ierr = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 474 ierr = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr); 475 previous = next; 476 next = next->next; 477 ierr = PetscFree(previous->string);CHKERRQ(ierr); 478 ierr = PetscFree(previous);CHKERRQ(ierr); 479 } 480 queue = 0; 481 queuelength = 0; 482 } 483 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 484 PetscFunctionReturn(0); 485 } 486 487 /* ---------------------------------------------------------------------------------------*/ 488 489 #undef __FUNCT__ 490 #define __FUNCT__ "PetscFPrintf" 491 /*@C 492 PetscFPrintf - Prints to a file, only from the first 493 processor in the communicator. 494 495 Not Collective 496 497 Input Parameters: 498 + comm - the communicator 499 . fd - the file pointer 500 - format - the usual printf() format string 501 502 Level: intermediate 503 504 Fortran Note: 505 This routine is not supported in Fortran. 506 507 Concepts: printing^in parallel 508 Concepts: printf^in parallel 509 510 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 511 PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush() 512 @*/ 513 PetscErrorCode PETSCSYS_DLLEXPORT PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...) 514 { 515 PetscErrorCode ierr; 516 PetscMPIInt rank; 517 518 PetscFunctionBegin; 519 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 520 if (!rank) { 521 va_list Argp; 522 va_start(Argp,format); 523 ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr); 524 if (petsc_history) { 525 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 526 } 527 va_end(Argp); 528 } 529 PetscFunctionReturn(0); 530 } 531 532 #undef __FUNCT__ 533 #define __FUNCT__ "PetscPrintf" 534 /*@C 535 PetscPrintf - Prints to standard out, only from the first 536 processor in the communicator. 537 538 Not Collective 539 540 Input Parameters: 541 + comm - the communicator 542 - format - the usual printf() format string 543 544 Level: intermediate 545 546 Fortran Note: 547 The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 548 That is, you can only pass a single character string from Fortran. 549 550 Notes: %A is replace with %g unless the value is < 1.e-12 when it is 551 replaced with < 1.e-12 552 553 Concepts: printing^in parallel 554 Concepts: printf^in parallel 555 556 .seealso: PetscFPrintf(), PetscSynchronizedPrintf() 557 @*/ 558 PetscErrorCode PETSCSYS_DLLEXPORT PetscPrintf(MPI_Comm comm,const char format[],...) 559 { 560 PetscErrorCode ierr; 561 PetscMPIInt rank; 562 size_t len; 563 char *nformat,*sub1,*sub2; 564 PetscReal value; 565 566 PetscFunctionBegin; 567 if (!comm) comm = PETSC_COMM_WORLD; 568 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 569 if (!rank) { 570 va_list Argp; 571 va_start(Argp,format); 572 573 ierr = PetscStrstr(format,"%A",&sub1);CHKERRQ(ierr); 574 if (sub1) { 575 ierr = PetscStrstr(format,"%",&sub2);CHKERRQ(ierr); 576 if (sub1 != sub2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"%%A format must be first in format string"); 577 ierr = PetscStrlen(format,&len);CHKERRQ(ierr); 578 ierr = PetscMalloc((len+16)*sizeof(char),&nformat);CHKERRQ(ierr); 579 ierr = PetscStrcpy(nformat,format);CHKERRQ(ierr); 580 ierr = PetscStrstr(nformat,"%",&sub2);CHKERRQ(ierr); 581 sub2[0] = 0; 582 value = (double)va_arg(Argp,double); 583 if (PetscAbsReal(value) < 1.e-12) { 584 ierr = PetscStrcat(nformat,"< 1.e-12");CHKERRQ(ierr); 585 } else { 586 ierr = PetscStrcat(nformat,"%g");CHKERRQ(ierr); 587 va_end(Argp); 588 va_start(Argp,format); 589 } 590 ierr = PetscStrcat(nformat,sub1+2);CHKERRQ(ierr); 591 } else { 592 nformat = (char*)format; 593 } 594 ierr = (*PetscVFPrintf)(PETSC_STDOUT,nformat,Argp);CHKERRQ(ierr); 595 if (petsc_history) { 596 ierr = (*PetscVFPrintf)(petsc_history,nformat,Argp);CHKERRQ(ierr); 597 } 598 va_end(Argp); 599 if (sub1) {ierr = PetscFree(nformat);CHKERRQ(ierr);} 600 } 601 PetscFunctionReturn(0); 602 } 603 604 /* ---------------------------------------------------------------------------------------*/ 605 #undef __FUNCT__ 606 #define __FUNCT__ "PetscHelpPrintfDefault" 607 /*@C 608 PetscHelpPrintf - All PETSc help messages are passing through this function. You can change how help messages are printed by 609 replacinng it with something that does not simply write to a stdout. 610 611 To use, write your own function for example, 612 $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....) 613 ${ 614 $ PetscFunctionReturn(0); 615 $} 616 then before the call to PetscInitialize() do the assignment 617 $ PetscHelpPrintf = mypetschelpprintf; 618 619 Note: the default routine used is called PetscHelpPrintfDefault(). 620 621 Level: developer 622 623 .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf() 624 @*/ 625 PetscErrorCode PETSCSYS_DLLEXPORT PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...) 626 { 627 PetscErrorCode ierr; 628 PetscMPIInt rank; 629 630 PetscFunctionBegin; 631 if (!comm) comm = PETSC_COMM_WORLD; 632 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 633 if (!rank) { 634 va_list Argp; 635 va_start(Argp,format); 636 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 637 if (petsc_history) { 638 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 639 } 640 va_end(Argp); 641 } 642 PetscFunctionReturn(0); 643 } 644 645 /* ---------------------------------------------------------------------------------------*/ 646 647 648 #undef __FUNCT__ 649 #define __FUNCT__ "PetscSynchronizedFGets" 650 /*@C 651 PetscSynchronizedFGets - Several processors all get the same line from a file. 652 653 Collective on MPI_Comm 654 655 Input Parameters: 656 + comm - the communicator 657 . fd - the file pointer 658 - len - the length of the output buffer 659 660 Output Parameter: 661 . string - the line read from the file 662 663 Level: intermediate 664 665 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 666 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 667 668 @*/ 669 PetscErrorCode PETSCSYS_DLLEXPORT PetscSynchronizedFGets(MPI_Comm comm,FILE* fp,size_t len,char string[]) 670 { 671 PetscErrorCode ierr; 672 PetscMPIInt rank; 673 char *str; 674 675 PetscFunctionBegin; 676 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 677 678 if (!rank) { 679 str = fgets(string,len,fp); /* Not very useful error behavior, but what is desired behavior for attempt to read at EOF? */ 680 } 681 ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr); 682 PetscFunctionReturn(0); 683 } 684