xref: /petsc/src/sys/objects/pinit.c (revision 74ed9c26ab880fdcd1d3cdbb5b1e39d1b833147d)
1 #define PETSC_DLL
2 /*
3    This file defines the initialization of PETSc, including PetscInitialize()
4 */
5 
6 #include "petsc.h"        /*I  "petsc.h"   I*/
7 #include "petscsys.h"
8 
9 #if defined(PETSC_USE_LOG)
10 EXTERN PetscErrorCode PetscLogBegin_Private(void);
11 #endif
12 extern PetscTruth PetscOpenMPWorker;
13 
14 /* -----------------------------------------------------------------------------------------*/
15 
16 extern FILE *petsc_history;
17 
18 EXTERN PetscErrorCode PetscInitialize_DynamicLibraries(void);
19 EXTERN PetscErrorCode PetscFinalize_DynamicLibraries(void);
20 EXTERN PetscErrorCode PetscFListDestroyAll(void);
21 EXTERN PetscErrorCode PetscSequentialPhaseBegin_Private(MPI_Comm,int);
22 EXTERN PetscErrorCode PetscSequentialPhaseEnd_Private(MPI_Comm,int);
23 EXTERN PetscErrorCode PetscLogCloseHistoryFile(FILE **);
24 EXTERN PetscErrorCode PetscOptionsHelpDestroyList(void);
25 
26 /* this is used by the _, __, and ___ macros (see include/petscerror.h) */
27 PetscErrorCode __gierr = 0;
28 
29 /* user may set this BEFORE calling PetscInitialize() */
30 MPI_Comm PETSC_COMM_WORLD = MPI_COMM_NULL;
31 
32 PetscMPIInt Petsc_Counter_keyval   = MPI_KEYVAL_INVALID;
33 PetscMPIInt Petsc_InnerComm_keyval = MPI_KEYVAL_INVALID;
34 PetscMPIInt Petsc_OuterComm_keyval = MPI_KEYVAL_INVALID;
35 
36 /*
37      Declare and set all the string names of the PETSc enums
38 */
39 const char *PetscTruths[]    = {"FALSE","TRUE","PetscTruth","PETSC_",0};
40 const char *PetscDataTypes[] = {"INT", "DOUBLE", "COMPLEX",
41                                 "LONG","SHORT",  "FLOAT",
42                                 "CHAR","LOGICAL","ENUM","TRUTH","LONGDOUBLE","PetscDataType","PETSC_",0};
43 
44 PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
45 PetscTruth PetscPreLoadingOn   = PETSC_FALSE;
46 
47 /*
48        Checks the options database for initializations related to the
49     PETSc components
50 */
51 #undef __FUNCT__
52 #define __FUNCT__ "PetscOptionsCheckInitial_Components"
53 PetscErrorCode PETSC_DLLEXPORT PetscOptionsCheckInitial_Components(void)
54 {
55   PetscTruth flg1;
56   PetscErrorCode ierr;
57 
58   PetscFunctionBegin;
59   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg1);CHKERRQ(ierr);
60   if (flg1) {
61 #if defined (PETSC_USE_LOG)
62     MPI_Comm   comm = PETSC_COMM_WORLD;
63     ierr = (*PetscHelpPrintf)(comm,"------Additional PETSc component options--------\n");CHKERRQ(ierr);
64     ierr = (*PetscHelpPrintf)(comm," -log_summary_exclude: <vec,mat,pc.ksp,snes>\n");CHKERRQ(ierr);
65     ierr = (*PetscHelpPrintf)(comm," -info_exclude: <null,vec,mat,pc,ksp,snes,ts>\n");CHKERRQ(ierr);
66     ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr);
67 #endif
68   }
69   PetscFunctionReturn(0);
70 }
71 
72 #undef __FUNCT__
73 #define __FUNCT__ "PetscInitializeNoArguments"
74 /*@C
75       PetscInitializeNoArguments - Calls PetscInitialize() from C/C++ without
76         the command line arguments.
77 
78    Collective
79 
80    Level: advanced
81 
82 .seealso: PetscInitialize(), PetscInitializeFortran()
83 @*/
84 PetscErrorCode PETSC_DLLEXPORT PetscInitializeNoArguments(void)
85 {
86   PetscErrorCode ierr;
87   int            argc = 0;
88   char           **args = 0;
89 
90   PetscFunctionBegin;
91   ierr = PetscInitialize(&argc,&args,PETSC_NULL,PETSC_NULL);
92   PetscFunctionReturn(ierr);
93 }
94 
95 #undef __FUNCT__
96 #define __FUNCT__ "PetscInitialized"
97 /*@
98       PetscInitialized - Determine whether PETSc is initialized.
99 
100 7   Level: beginner
101 
102 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
103 @*/
104 PetscErrorCode PETSC_DLLEXPORT PetscInitialized(PetscTruth *isInitialized)
105 {
106   PetscFunctionBegin;
107   PetscValidPointer(isInitialized, 1);
108   *isInitialized = PetscInitializeCalled;
109   PetscFunctionReturn(0);
110 }
111 
112 #undef __FUNCT__
113 #define __FUNCT__ "PetscFinalized"
114 /*@
115       PetscFinalized - Determine whether PetscFinalize() has been called yet
116 
117    Level: developer
118 
119 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
120 @*/
121 PetscErrorCode PETSC_DLLEXPORT PetscFinalized(PetscTruth *isFinalized)
122 {
123   PetscFunctionBegin;
124   PetscValidPointer(isFinalized, 1);
125   *isFinalized = PetscFinalizeCalled;
126   PetscFunctionReturn(0);
127 }
128 
129 EXTERN PetscErrorCode        PetscOptionsCheckInitial_Private(void);
130 extern PetscTruth PetscBeganMPI;
131 
132 /*
133        This function is the MPI reduction operation used to compute the sum of the
134    first half of the datatype and the max of the second half.
135 */
136 MPI_Op PetscMaxSum_Op = 0;
137 
138 EXTERN_C_BEGIN
139 #undef __FUNCT__
140 #define __FUNCT__ "PetscMaxSum_Local"
141 void PETSC_DLLEXPORT MPIAPI PetscMaxSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
142 {
143   PetscInt *xin = (PetscInt*)in,*xout = (PetscInt*)out,i,count = *cnt;
144 
145   PetscFunctionBegin;
146   if (*datatype != MPIU_2INT) {
147     (*PetscErrorPrintf)("Can only handle MPIU_2INT data types");
148     MPI_Abort(MPI_COMM_WORLD,1);
149   }
150 
151   for (i=0; i<count; i++) {
152     xout[2*i]    = PetscMax(xout[2*i],xin[2*i]);
153     xout[2*i+1] += xin[2*i+1];
154   }
155   PetscStackPop;
156   return;
157 }
158 EXTERN_C_END
159 
160 /*
161     Returns the max of the first entry owned by this processor and the
162 sum of the second entry.
163 
164     The reason nprocs[2*i] contains lengths nprocs[2*i+1] contains flag of 1 if length is nonzero
165 is so that the PetscMaxSum_Op() can set TWO values, if we passed in only nprocs[i] with lengths
166 there would be no place to store the both needed results.
167 */
168 #undef __FUNCT__
169 #define __FUNCT__ "PetscMaxSum"
170 PetscErrorCode PETSC_DLLEXPORT PetscMaxSum(MPI_Comm comm,const PetscInt nprocs[],PetscInt *max,PetscInt *sum)
171 {
172   PetscMPIInt    size,rank;
173   PetscInt       *work;
174   PetscErrorCode ierr;
175 
176   PetscFunctionBegin;
177   ierr   = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
178   ierr   = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
179   ierr   = PetscMalloc(2*size*sizeof(PetscInt),&work);CHKERRQ(ierr);
180   ierr   = MPI_Allreduce((void*)nprocs,work,size,MPIU_2INT,PetscMaxSum_Op,comm);CHKERRQ(ierr);
181   *max   = work[2*rank];
182   *sum   = work[2*rank+1];
183   ierr   = PetscFree(work);CHKERRQ(ierr);
184   PetscFunctionReturn(0);
185 }
186 
187 /* ----------------------------------------------------------------------------*/
188 MPI_Op PETSC_DLLEXPORT PetscADMax_Op = 0;
189 
190 EXTERN_C_BEGIN
191 #undef __FUNCT__
192 #define __FUNCT__ "PetscADMax_Local"
193 void PETSC_DLLEXPORT MPIAPI PetscADMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
194 {
195   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
196   PetscInt    i,count = *cnt;
197 
198   PetscFunctionBegin;
199   if (*datatype != MPIU_2SCALAR) {
200     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
201     MPI_Abort(MPI_COMM_WORLD,1);
202   }
203 
204   for (i=0; i<count; i++) {
205     if (PetscRealPart(xout[2*i]) < PetscRealPart(xin[2*i])) {
206       xout[2*i]   = xin[2*i];
207       xout[2*i+1] = xin[2*i+1];
208     }
209   }
210 
211   PetscStackPop;
212   return;
213 }
214 EXTERN_C_END
215 
216 MPI_Op PETSC_DLLEXPORT PetscADMin_Op = 0;
217 
218 EXTERN_C_BEGIN
219 #undef __FUNCT__
220 #define __FUNCT__ "PetscADMin_Local"
221 void PETSC_DLLEXPORT MPIAPI PetscADMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
222 {
223   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
224   PetscInt    i,count = *cnt;
225 
226   PetscFunctionBegin;
227   if (*datatype != MPIU_2SCALAR) {
228     (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types");
229     MPI_Abort(MPI_COMM_WORLD,1);
230   }
231 
232   for (i=0; i<count; i++) {
233     if (PetscRealPart(xout[2*i]) > PetscRealPart(xin[2*i])) {
234       xout[2*i]   = xin[2*i];
235       xout[2*i+1] = xin[2*i+1];
236     }
237   }
238 
239   PetscStackPop;
240   return;
241 }
242 EXTERN_C_END
243 /* ---------------------------------------------------------------------------------------*/
244 
245 #if defined(PETSC_USE_COMPLEX)
246 MPI_Op PetscSum_Op = 0;
247 
248 EXTERN_C_BEGIN
249 #undef __FUNCT__
250 #define __FUNCT__ "PetscSum_Local"
251 void PETSC_DLLEXPORT PetscSum_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
252 {
253   PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out;
254   PetscInt    i,count = *cnt;
255 
256   PetscFunctionBegin;
257   if (*datatype != MPIU_SCALAR) {
258     (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types");
259     MPI_Abort(MPI_COMM_WORLD,1);
260   }
261 
262   for (i=0; i<count; i++) {
263     xout[i] += xin[i];
264   }
265 
266   PetscStackPop;
267   return;
268 }
269 EXTERN_C_END
270 #endif
271 
272 EXTERN_C_BEGIN
273 #undef __FUNCT__
274 #define __FUNCT__ "Petsc_DelCounter"
275 /*
276    Private routine to delete internal tag/name counter storage when a communicator is freed.
277 
278    This is called by MPI, not by users.
279 
280    Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
281 
282 */
283 PetscMPIInt PETSC_DLLEXPORT MPIAPI Petsc_DelCounter(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state)
284 {
285   PetscErrorCode ierr;
286 
287   PetscFunctionBegin;
288   ierr = PetscInfo1(0,"Deleting counter data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
289   ierr = PetscFree(count_val);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
290   PetscFunctionReturn(MPI_SUCCESS);
291 }
292 EXTERN_C_END
293 
294 EXTERN_C_BEGIN
295 #undef __FUNCT__
296 #define __FUNCT__ "Petsc_DelComm"
297 /*
298   This does not actually free anything, it simply marks when a reference count to an internal MPI_Comm reaches zero and the
299   the external MPI_Comm drops its reference to the internal MPI_Comm
300 
301   This is called by MPI, not by users.
302 
303   Note: this is declared extern "C" because it is passed to MPI_Keyval_create()
304 
305 */
306 PetscMPIInt PETSC_DLLEXPORT MPIAPI Petsc_DelComm(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
307 {
308   PetscErrorCode ierr;
309 
310   PetscFunctionBegin;
311   ierr = PetscInfo1(0,"Deleting PETSc communicator imbedded in a user MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
312   /* actually don't delete anything because we cannot increase the reference count of the communicator anyways */
313   PetscFunctionReturn(MPI_SUCCESS);
314 }
315 EXTERN_C_END
316 
317 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
318 #if !defined(PETSC_WORDS_BIGENDIAN)
319 EXTERN_C_BEGIN
320 extern PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype,MPI_Aint*,void*);
321 extern PetscMPIInt PetscDataRep_read_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
322 extern PetscMPIInt PetscDataRep_write_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
323 EXTERN_C_END
324 #endif
325 #endif
326 
327 int  PetscGlobalArgc   = 0;
328 char **PetscGlobalArgs = 0;
329 
330 #undef __FUNCT__
331 #define __FUNCT__ "PetscGetArgs"
332 /*@C
333    PetscGetArgs - Allows you to access the raw command line arguments anywhere
334      after PetscInitialize() is called but before PetscFinalize().
335 
336    Not Collective
337 
338    Output Parameters:
339 +  argc - count of number of command line arguments
340 -  args - the command line arguments
341 
342    Level: intermediate
343 
344    Notes:
345       This is usually used to pass the command line arguments into other libraries
346    that are called internally deep in PETSc or the application.
347 
348    Concepts: command line arguments
349 
350 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArguments()
351 
352 @*/
353 PetscErrorCode PETSC_DLLEXPORT PetscGetArgs(int *argc,char ***args)
354 {
355   PetscFunctionBegin;
356   if (!PetscInitializeCalled && PetscFinalizeCalled) {
357     SETERRQ(PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
358   }
359   *argc = PetscGlobalArgc;
360   *args = PetscGlobalArgs;
361   PetscFunctionReturn(0);
362 }
363 
364 #undef __FUNCT__
365 #define __FUNCT__ "PetscGetArguments"
366 /*@C
367    PetscGetArguments - Allows you to access the  command line arguments anywhere
368      after PetscInitialize() is called but before PetscFinalize().
369 
370    Not Collective
371 
372    Output Parameters:
373 .  args - the command line arguments
374 
375    Level: intermediate
376 
377    Notes:
378       This does NOT start with the program name and IS null terminated (final arg is void)
379 
380    Concepts: command line arguments
381 
382 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscFreeArguments()
383 
384 @*/
385 PetscErrorCode PETSC_DLLEXPORT PetscGetArguments(char ***args)
386 {
387   PetscInt       i,argc = PetscGlobalArgc;
388   PetscErrorCode ierr;
389 
390   PetscFunctionBegin;
391   if (!PetscInitializeCalled && PetscFinalizeCalled) {
392     SETERRQ(PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()");
393   }
394   if (!argc) {*args = 0; PetscFunctionReturn(0);}
395   ierr = PetscMalloc(argc*sizeof(char*),args);CHKERRQ(ierr);
396   for (i=0; i<argc-1; i++) {
397     ierr = PetscStrallocpy(PetscGlobalArgs[i+1],&(*args)[i]);CHKERRQ(ierr);
398   }
399   (*args)[argc-1] = 0;
400   PetscFunctionReturn(0);
401 }
402 
403 #undef __FUNCT__
404 #define __FUNCT__ "PetscFreeArguments"
405 /*@C
406    PetscFreeArguments - Frees the memory obtained with PetscGetArguments()
407 
408    Not Collective
409 
410    Output Parameters:
411 .  args - the command line arguments
412 
413    Level: intermediate
414 
415    Concepts: command line arguments
416 
417 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscGetArguments()
418 
419 @*/
420 PetscErrorCode PETSC_DLLEXPORT PetscFreeArguments(char **args)
421 {
422   PetscInt       i = 0;
423   PetscErrorCode ierr;
424 
425   PetscFunctionBegin;
426   if (!args) {PetscFunctionReturn(0);}
427   while (args[i]) {
428     ierr = PetscFree(args[i]);CHKERRQ(ierr);
429     i++;
430   }
431   ierr = PetscFree(args);CHKERRQ(ierr);
432   PetscFunctionReturn(0);
433 }
434 
435 #undef __FUNCT__
436 #define __FUNCT__ "PetscInitialize"
437 /*@C
438    PetscInitialize - Initializes the PETSc database and MPI.
439    PetscInitialize() calls MPI_Init() if that has yet to be called,
440    so this routine should always be called near the beginning of
441    your program -- usually the very first line!
442 
443    Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set
444 
445    Input Parameters:
446 +  argc - count of number of command line arguments
447 .  args - the command line arguments
448 .  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL to not check for
449           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
450 -  help - [optional] Help message to print, use PETSC_NULL for no message
451 
452    If you wish PETSc code to run ONLY on a subcommunicator of MPI_COMM_WORLD, create that
453    communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize(). Thus if you are running a
454    four process job and two processes will run PETSc and have PetscInitialize() and PetscFinalize() and two process will not,
455    then do this. If ALL processes in the job are using PetscInitialize() and PetscFinalize() then you don't need to do this, even
456    if different subcommunicators of the job are doing different things with PETSc.
457 
458    Options Database Keys:
459 +  -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger
460 .  -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected
461 .  -on_error_emacs <machinename> causes emacsclient to jump to error file
462 .  -on_error_abort calls abort() when error detected (no traceback)
463 .  -on_error_mpiabort calls MPI_abort() when error detected
464 .  -error_output_stderr prints error messages to stderr instead of the default stdout
465 .  -error_output_none does not print the error messages (but handles errors in the same way as if this was not called)
466 .  -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger
467 .  -debugger_pause [sleeptime] (in seconds) - Pauses debugger
468 .  -stop_for_debugger - Print message on how to attach debugger manually to
469                         process and wait (-debugger_pause) seconds for attachment
470 .  -malloc - Indicates use of PETSc error-checking malloc (on by default for debug version of libraries)
471 .  -malloc no - Indicates not to use error-checking malloc
472 .  -malloc_debug - check for memory corruption at EVERY malloc or free
473 .  -fp_trap - Stops on floating point exceptions (Note that on the
474               IBM RS6000 this slows code by at least a factor of 10.)
475 .  -no_signal_handler - Indicates not to trap error signals
476 .  -shared_tmp - indicates /tmp directory is shared by all processors
477 .  -not_shared_tmp - each processor has own /tmp
478 .  -tmp - alternative name of /tmp directory
479 .  -get_total_flops - returns total flops done by all processors
480 -  -memory_info - Print memory usage at end of run
481 
482    Options Database Keys for Profiling:
483    See the Profiling chapter of the users manual for details.
484 +  -log_trace [filename] - Print traces of all PETSc calls
485         to the screen (useful to determine where a program
486         hangs without running in the debugger).  See PetscLogTraceBegin().
487 .  -info <optional filename> - Prints verbose information to the screen
488 -  -info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages
489 
490    Environmental Variables:
491 +   PETSC_TMP - alternative tmp directory
492 .   PETSC_SHARED_TMP - tmp is shared by all processes
493 .   PETSC_NOT_SHARED_TMP - each process has its own private tmp
494 .   PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
495 -   PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to
496 
497 
498    Level: beginner
499 
500    Notes:
501    If for some reason you must call MPI_Init() separately, call
502    it before PetscInitialize().
503 
504    Fortran Version:
505    In Fortran this routine has the format
506 $       call PetscInitialize(file,ierr)
507 
508 +   ierr - error return code
509 -  file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL_CHARACTER to not check for
510           code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files
511 
512    Important Fortran Note:
513    In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a
514    null character string; you CANNOT just use PETSC_NULL as
515    in the C version.  See the users manual for details.
516 
517 
518    Concepts: initializing PETSc
519 
520 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs()
521 
522 @*/
523 PetscErrorCode PETSC_DLLEXPORT PetscInitialize(int *argc,char ***args,const char file[],const char help[])
524 {
525   PetscErrorCode ierr;
526   PetscMPIInt    flag, size;
527   PetscInt       nodesize;
528   PetscTruth     flg;
529   char           hostname[256];
530 
531   PetscFunctionBegin;
532   if (PetscInitializeCalled) PetscFunctionReturn(0);
533 
534   /* these must be initialized in a routine, not as a constant declaration*/
535   PETSC_STDOUT = stdout;
536   PETSC_STDERR = stderr;
537 
538   ierr = PetscOptionsCreate();CHKERRQ(ierr);
539 
540   /*
541      We initialize the program name here (before MPI_Init()) because MPICH has a bug in
542      it that it sets args[0] on all processors to be args[0] on the first processor.
543   */
544   if (argc && *argc) {
545     ierr = PetscSetProgramName(**args);CHKERRQ(ierr);
546   } else {
547     ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr);
548   }
549 
550   ierr = MPI_Initialized(&flag);CHKERRQ(ierr);
551   if (!flag) {
552     if (PETSC_COMM_WORLD != MPI_COMM_NULL) SETERRQ(PETSC_ERR_SUP,"You cannot set PETSC_COMM_WORLD if you have not initialized MPI first");
553     ierr          = MPI_Init(argc,args);CHKERRQ(ierr);
554     PetscBeganMPI = PETSC_TRUE;
555   }
556   if (argc && args) {
557     PetscGlobalArgc = *argc;
558     PetscGlobalArgs = *args;
559   }
560   PetscInitializeCalled = PETSC_TRUE;
561   PetscFinalizeCalled   = PETSC_FALSE;
562 
563   if (PETSC_COMM_WORLD == MPI_COMM_NULL) {
564     PETSC_COMM_WORLD = MPI_COMM_WORLD;
565   }
566 
567   /* Done after init due to a bug in MPICH-GM? */
568   ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr);
569 
570   ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr);
571   ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr);
572 
573 #if defined(PETSC_USE_COMPLEX)
574   /*
575      Initialized the global complex variable; this is because with
576      shared libraries the constructors for global variables
577      are not called; at least on IRIX.
578   */
579   {
580 #if defined(PETSC_CLANGUAGE_CXX)
581     PetscScalar ic(0.0,1.0);
582     PETSC_i = ic;
583 #else
584     PETSC_i = I;
585 #endif
586   }
587 
588   ierr = MPI_Type_contiguous(2,MPIU_REAL,&MPIU_COMPLEX);CHKERRQ(ierr);
589   ierr = MPI_Type_commit(&MPIU_COMPLEX);CHKERRQ(ierr);
590   ierr = MPI_Op_create(PetscSum_Local,1,&PetscSum_Op);CHKERRQ(ierr);
591 #endif
592 
593   /*
594      Create the PETSc MPI reduction operator that sums of the first
595      half of the entries and maxes the second half.
596   */
597   ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr);
598 
599   ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr);
600   ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr);
601   ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr);
602   ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr);
603 
604   ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr);
605   ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr);
606 
607   /*
608      Attributes to be set on PETSc communicators
609   */
610   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr);
611   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr);
612   ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr);
613 
614   /*
615      Build the options database
616   */
617   ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr);
618 
619 
620   /*
621      Print main application help message
622   */
623   ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
624   if (help && flg) {
625     ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr);
626   }
627   ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr);
628 
629   /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */
630 #if defined(PETSC_USE_LOG)
631   ierr = PetscLogBegin_Private();CHKERRQ(ierr);
632 #endif
633 
634   /*
635      Load the dynamic libraries (on machines that support them), this registers all
636      the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
637   */
638   ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr);
639 
640   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
641   ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr);
642   ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr);
643   ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr);
644 
645   ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr);
646   /* Check the options database for options related to the options database itself */
647   ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr);
648 
649 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
650   /*
651       Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
652 
653       Currently not used because it is not supported by MPICH.
654   */
655 #if !defined(PETSC_WORDS_BIGENDIAN)
656   ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr);
657 #endif
658 #endif
659 
660   ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_spawn_size",&nodesize,&flg);CHKERRQ(ierr);
661   if (flg) {
662 #if defined(PETSC_HAVE_MPI_COMM_SPAWN)
663     ierr = PetscOpenMPSpawn((PetscMPIInt) nodesize);CHKERRQ(ierr);
664 #else
665     SETERRQ(PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -openmp_merge_size instead");
666 #endif
667   } else {
668     ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_merge_size",&nodesize,&flg);CHKERRQ(ierr);
669     if (flg) {
670       ierr = PetscOpenMPMerge((PetscMPIInt) nodesize);CHKERRQ(ierr);
671     }
672   }
673   flg  = PETSC_FALSE;
674   ierr = PetscOptionsGetTruth(PETSC_NULL,"-python",&flg,PETSC_NULL);CHKERRQ(ierr);
675   if (flg) {ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
676 
677   PetscFunctionReturn(ierr);
678 }
679 
680 
681 #undef __FUNCT__
682 #define __FUNCT__ "PetscFinalize"
683 /*@C
684    PetscFinalize - Checks for options to be called at the conclusion
685    of the program. MPI_Finalize() is called only if the user had not
686    called MPI_Init() before calling PetscInitialize().
687 
688    Collective on PETSC_COMM_WORLD
689 
690    Options Database Keys:
691 +  -options_table - Calls PetscOptionsPrint()
692 .  -options_left - Prints unused options that remain in the database
693 .  -options_left no - Does not print unused options that remain in the database
694 .  -mpidump - Calls PetscMPIDump()
695 .  -malloc_dump - Calls PetscMallocDump()
696 .  -malloc_info - Prints total memory usage
697 -  -malloc_log - Prints summary of memory usage
698 
699    Options Database Keys for Profiling:
700    See the Profiling chapter of the users manual for details.
701 +  -log_summary [filename] - Prints summary of flop and timing
702         information to screen. If the filename is specified the
703         summary is written to the file. (for code compiled with
704         PETSC_USE_LOG).  See PetscLogPrintSummary().
705 .  -log_all [filename] - Logs extensive profiling information
706         (for code compiled with PETSC_USE_LOG). See PetscLogDump().
707 .  -log [filename] - Logs basic profiline information (for
708         code compiled with PETSC_USE_LOG).  See PetscLogDump().
709 .  -log_sync - Log the synchronization in scatters, inner products
710         and norms
711 -  -log_mpe [filename] - Creates a logfile viewable by the
712       utility Upshot/Nupshot (in MPICH distribution)
713 
714    Level: beginner
715 
716    Note:
717    See PetscInitialize() for more general runtime options.
718 
719 .seealso: PetscInitialize(), PetscOptionsPrint(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
720 @*/
721 PetscErrorCode PETSC_DLLEXPORT PetscFinalize(void)
722 {
723   PetscErrorCode ierr;
724   PetscMPIInt    rank;
725   int            nopt;
726   PetscTruth     flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
727   extern FILE   *PETSC_ZOPEFD;
728 
729   PetscFunctionBegin;
730 
731   if (!PetscInitializeCalled) {
732     (*PetscErrorPrintf)("PetscInitialize() must be called before PetscFinalize()\n");
733     PetscFunctionReturn(0);
734   }
735   ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");
736 
737   ierr = PetscOpenMPFinalize();CHKERRQ(ierr);
738 
739   ierr = PetscOptionsGetTruth(PETSC_NULL,"-python",&flg1,PETSC_NULL);CHKERRQ(ierr);
740   if (flg1) {ierr = PetscPythonFinalize();CHKERRQ(ierr);}
741 
742   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
743   ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
744   if (!flg2) {
745     flg2 = PETSC_FALSE;
746     ierr = PetscOptionsGetTruth(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr);
747   }
748   if (flg2) {
749     ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr);
750   }
751 
752   /*
753      Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
754   */
755   ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr);
756 
757   /*
758        Free all the registered create functions, such as KSPList, VecList, SNESList, etc
759   */
760   ierr = PetscFListDestroyAll();CHKERRQ(ierr);
761 
762   /*
763      Destroy any packages that registered a finalize
764   */
765   ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr);
766 
767   /*
768      Destroy all the function registration lists created
769   */
770   ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr);
771 
772 #if defined(PETSC_USE_LOG)
773   flg1 = PETSC_FALSE;
774   ierr = PetscOptionsGetTruth(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr);
775   if (flg1) {
776     PetscLogDouble flops = 0;
777     ierr = MPI_Reduce(&_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
778     ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr);
779   }
780 #endif
781 
782   ierr = PetscOptionsHelpDestroyList();CHKERRQ(ierr);
783 
784 #if defined(PETSC_USE_DEBUG)
785   if (PetscStackActive) {
786     ierr = PetscStackDestroy();CHKERRQ(ierr);
787   }
788 #endif
789 
790 #if defined(PETSC_USE_LOG)
791   {
792     char mname[PETSC_MAX_PATH_LEN];
793 #if defined(PETSC_HAVE_MPE)
794     mname[0] = 0;
795     ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
796     if (flg1){
797       if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);}
798       else          {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);}
799     }
800 #endif
801     mname[0] = 0;
802     ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
803     if (flg1) {
804       if (mname[0])  {ierr = PetscLogPrintSummary(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
805       else           {ierr = PetscLogPrintSummary(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
806     }
807 
808     ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
809     if (flg1) {
810       if (mname[0])  {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);}
811       else           {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);}
812     }
813 
814     mname[0] = 0;
815     ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);
816     ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr);
817     if (flg1 || flg2){
818       if (mname[0]) PetscLogDump(mname);
819       else          PetscLogDump(0);
820     }
821     ierr = PetscLogDestroy();CHKERRQ(ierr);
822   }
823 #endif
824   flg1 = PETSC_FALSE;
825   ierr = PetscOptionsGetTruth(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr);
826   if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);}
827   flg1 = PETSC_FALSE;
828   ierr = PetscOptionsGetTruth(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr);
829   if (flg1) {
830     ierr = PetscMPIDump(stdout);CHKERRQ(ierr);
831   }
832   flg1 = PETSC_FALSE;
833   flg2 = PETSC_FALSE;
834   ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_dump",&flg1,PETSC_NULL);CHKERRQ(ierr);
835   ierr = PetscOptionsGetTruth(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr);
836   if (flg2) {
837     if (!rank) {ierr = PetscOptionsPrint(stdout);CHKERRQ(ierr);}
838   }
839 
840   /* to prevent PETSc -options_left from warning */
841   ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr)
842   ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr)
843 
844   if (!PetscOpenMPWorker) { /* worker processes skip this because they do not usually process options */
845     flg3 = PETSC_FALSE; /* default value is required */
846     ierr = PetscOptionsGetTruth(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr);
847     ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr);
848     if (flg3) {
849       if (!flg2) { /* have not yet printed the options */
850 	ierr = PetscOptionsPrint(stdout);CHKERRQ(ierr);
851       }
852       if (!nopt) {
853 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr);
854       } else if (nopt == 1) {
855 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr);
856       } else {
857 	ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %d unused database options. They are:\n",nopt);CHKERRQ(ierr);
858       }
859     }
860 #if defined(PETSC_USE_DEBUG)
861     if (nopt && !flg3 && !flg1) {
862       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr);
863       ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr);
864       ierr = PetscOptionsLeft();CHKERRQ(ierr);
865     } else if (nopt && flg3) {
866 #else
867     if (nopt && flg3) {
868 #endif
869       ierr = PetscOptionsLeft();CHKERRQ(ierr);
870     }
871   }
872 
873   flg1 = PETSC_FALSE;
874   ierr = PetscOptionsGetTruth(PETSC_NULL,"-log_history",&flg1,PETSC_NULL);CHKERRQ(ierr);
875   if (flg1) {
876     ierr = PetscLogCloseHistoryFile(&petsc_history);CHKERRQ(ierr);
877     petsc_history = 0;
878   }
879 
880   ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr);
881 
882   flg1 = PETSC_FALSE;
883   flg3 = PETSC_FALSE;
884   ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_dump",&flg1,PETSC_NULL);CHKERRQ(ierr);
885   ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_log",&flg3,PETSC_NULL);CHKERRQ(ierr);
886   if (flg1) {
887     char fname[PETSC_MAX_PATH_LEN];
888     FILE *fd;
889     int  err;
890 
891     fname[0] = 0;
892     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr);
893     if (flg1 && fname[0]) {
894       char sname[PETSC_MAX_PATH_LEN];
895 
896       sprintf(sname,"%s_%d",fname,rank);
897       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
898       ierr = PetscMallocDump(fd);CHKERRQ(ierr);
899       err = fclose(fd);
900       if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
901     } else {
902       MPI_Comm local_comm;
903 
904       ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr);
905       ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr);
906         ierr = PetscMallocDump(stdout);CHKERRQ(ierr);
907       ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr);
908       ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr);
909     }
910   }
911   if (flg3) {
912     char fname[PETSC_MAX_PATH_LEN];
913     FILE *fd;
914 
915     fname[0] = 0;
916     ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr);
917     if (flg1 && fname[0]) {
918       char sname[PETSC_MAX_PATH_LEN];
919       int  err;
920 
921       sprintf(sname,"%s_%d",fname,rank);
922       fd   = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname);
923       ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr);
924       err = fclose(fd);
925       if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
926     } else {
927       ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr);
928     }
929   }
930   /* Can be destroyed only after all the options are used */
931   ierr = PetscOptionsDestroy();CHKERRQ(ierr);
932 
933   PetscGlobalArgc = 0;
934   PetscGlobalArgs = 0;
935 
936 #if defined(PETSC_USE_COMPLEX)
937   ierr = MPI_Op_free(&PetscSum_Op);CHKERRQ(ierr);
938   ierr = MPI_Type_free(&MPIU_COMPLEX);CHKERRQ(ierr);
939 #endif
940   ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr);
941   ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr);
942   ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr);
943   ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr);
944   ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr);
945 
946   ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr);
947   ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr);
948   ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr);
949 
950   ierr = PetscInfo(0,"PETSc successfully ended!\n");CHKERRQ(ierr);
951   if (PetscBeganMPI) {
952 #if defined(PETSC_HAVE_MPI_FINALIZED)
953     PetscMPIInt flag;
954     ierr = MPI_Finalized(&flag);CHKERRQ(ierr);
955     if (flag) SETERRQ(PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()");
956 #endif
957     ierr = MPI_Finalize();CHKERRQ(ierr);
958   }
959 
960   if(PETSC_ZOPEFD != NULL){
961     if (PETSC_ZOPEFD != PETSC_STDOUT) fprintf(PETSC_ZOPEFD, "<<<end>>>");
962     else fprintf(PETSC_STDOUT, "<<<end>>>");}
963 
964 /*
965 
966      Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
967    the communicator has some outstanding requests on it. Specifically if the
968    flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
969    src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
970    is never freed as it should be. Thus one may obtain messages of the form
971    [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
972    memory was not freed.
973 
974 */
975   ierr = PetscMallocClear();CHKERRQ(ierr);
976   PetscInitializeCalled = PETSC_FALSE;
977   PetscFinalizeCalled   = PETSC_TRUE;
978   PetscFunctionReturn(ierr);
979 }
980 
981 /*
982      These may be used in code that ADIC is to be used on
983 */
984 
985 #undef __FUNCT__
986 #define __FUNCT__ "PetscGlobalMax"
987 /*@
988       PetscGlobalMax - Computes the maximum value over several processors
989 
990      Collective on MPI_Comm
991 
992    Input Parameters:
993 +   local - the local value
994 -   comm - the processors that find the maximum
995 
996    Output Parameter:
997 .   result - the maximum value
998 
999    Level: intermediate
1000 
1001    Notes:
1002      These functions are to be used inside user functions that are to be processed with
1003    ADIC. PETSc will automatically provide differentiated versions of these functions
1004 
1005 .seealso: PetscGlobalMin(), PetscGlobalSum()
1006 @*/
1007 PetscErrorCode PETSC_DLLEXPORT PetscGlobalMax(PetscReal* local,PetscReal* result,MPI_Comm comm)
1008 {
1009   return MPI_Allreduce(local,result,1,MPIU_REAL,MPI_MAX,comm);
1010 }
1011 
1012 #undef __FUNCT__
1013 #define __FUNCT__ "PetscGlobalMin"
1014 /*@
1015       PetscGlobalMin - Computes the minimum value over several processors
1016 
1017      Collective on MPI_Comm
1018 
1019    Input Parameters:
1020 +   local - the local value
1021 -   comm - the processors that find the minimum
1022 
1023    Output Parameter:
1024 .   result - the minimum value
1025 
1026    Level: intermediate
1027 
1028    Notes:
1029      These functions are to be used inside user functions that are to be processed with
1030    ADIC. PETSc will automatically provide differentiated versions of these functions
1031 
1032 .seealso: PetscGlobalMax(), PetscGlobalSum()
1033 @*/
1034 PetscErrorCode PETSC_DLLEXPORT PetscGlobalMin(PetscReal* local,PetscReal* result,MPI_Comm comm)
1035 {
1036   return MPI_Allreduce(local,result,1,MPIU_REAL,MPI_MIN,comm);
1037 }
1038 
1039 #undef __FUNCT__
1040 #define __FUNCT__ "PetscGlobalSum"
1041 /*@
1042       PetscGlobalSum - Computes the sum over sever processors
1043 
1044      Collective on MPI_Comm
1045 
1046    Input Parameters:
1047 +   local - the local value
1048 -   comm - the processors that find the sum
1049 
1050    Output Parameter:
1051 .   result - the sum
1052 
1053    Level: intermediate
1054 
1055    Notes:
1056      These functions are to be used inside user functions that are to be processed with
1057    ADIC. PETSc will automatically provide differentiated versions of these functions
1058 
1059 .seealso: PetscGlobalMin(), PetscGlobalMax()
1060 @*/
1061 PetscErrorCode PETSC_DLLEXPORT PetscGlobalSum(PetscScalar* local,PetscScalar* result,MPI_Comm comm)
1062 {
1063   return MPI_Allreduce(local,result,1,MPIU_SCALAR,PetscSum_Op,comm);
1064 }
1065 
1066 
1067