xref: /petsc/src/sys/fileio/mprint.c (revision 9fb22e1a5a92dd4c1f6b11e8d40bcaba12a7ec6d)
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