1 2 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/ 3 #include <petsc/private/hashtable.h> 4 #if defined(PETSC_HAVE_SAWS) 5 #include <petscviewersaws.h> 6 #endif 7 8 PetscFunctionList PetscViewerList = NULL; 9 10 PetscOptionsHelpPrinted PetscOptionsHelpPrintedSingleton = NULL; 11 KHASH_SET_INIT_STR(HTPrinted) 12 struct _n_PetscOptionsHelpPrinted{ 13 khash_t(HTPrinted) *printed; 14 PetscSegBuffer strings; 15 }; 16 17 PetscErrorCode PetscOptionsHelpPrintedDestroy(PetscOptionsHelpPrinted *hp) 18 { 19 PetscFunctionBegin; 20 if (!*hp) PetscFunctionReturn(0); 21 kh_destroy(HTPrinted,(*hp)->printed); 22 PetscCall(PetscSegBufferDestroy(&(*hp)->strings)); 23 PetscCall(PetscFree(*hp)); 24 PetscFunctionReturn(0); 25 } 26 27 /*@C 28 PetscOptionsHelpPrintedCreate - Creates an object used to manage tracking which help messages have 29 been printed so they will not be printed again. 30 31 Not collective 32 33 Level: developer 34 35 .seealso: `PetscOptionsHelpPrintedCheck()`, `PetscOptionsHelpPrintChecked()` 36 @*/ 37 PetscErrorCode PetscOptionsHelpPrintedCreate(PetscOptionsHelpPrinted *hp) 38 { 39 PetscFunctionBegin; 40 PetscCall(PetscNew(hp)); 41 (*hp)->printed = kh_init(HTPrinted); 42 PetscCall(PetscSegBufferCreate(sizeof(char),10000,&(*hp)->strings)); 43 PetscFunctionReturn(0); 44 } 45 46 /*@C 47 PetscOptionsHelpPrintedCheck - Checks if a particular pre, name pair has previous been entered (meaning the help message was printed) 48 49 Not collective 50 51 Input Parameters: 52 + hp - the object used to manage tracking what help messages have been printed 53 . pre - the prefix part of the string, many be NULL 54 - name - the string to look for (cannot be NULL) 55 56 Output Parameter: 57 . found - PETSC_TRUE if the string was already set 58 59 Level: intermediate 60 61 .seealso: `PetscOptionsHelpPrintedCreate()` 62 @*/ 63 PetscErrorCode PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrinted hp,const char *pre,const char* name,PetscBool *found) 64 { 65 size_t l1,l2; 66 #if !defined(PETSC_HAVE_THREADSAFETY) 67 char *both; 68 int newitem; 69 #endif 70 71 PetscFunctionBegin; 72 PetscCall(PetscStrlen(pre,&l1)); 73 PetscCall(PetscStrlen(name,&l2)); 74 if (l1+l2 == 0) { 75 *found = PETSC_FALSE; 76 PetscFunctionReturn(0); 77 } 78 #if !defined(PETSC_HAVE_THREADSAFETY) 79 PetscCall(PetscSegBufferGet(hp->strings,l1+l2+1,&both)); 80 PetscCall(PetscStrcpy(both,pre)); 81 PetscCall(PetscStrcat(both,name)); 82 kh_put(HTPrinted,hp->printed,both,&newitem); 83 if (!newitem) { 84 PetscCall(PetscSegBufferUnuse(hp->strings,l1+l2+1)); 85 } 86 *found = newitem ? PETSC_FALSE : PETSC_TRUE; 87 #else 88 *found = PETSC_FALSE; 89 #endif 90 PetscFunctionReturn(0); 91 } 92 93 static PetscBool noviewer = PETSC_FALSE; 94 static PetscBool noviewers[PETSCVIEWERGETVIEWEROFFPUSHESMAX]; 95 static PetscInt inoviewers = 0; 96 97 /*@ 98 PetscOptionsPushGetViewerOff - control whether PetscOptionsGetViewer returns a viewer. 99 100 Logically Collective 101 102 Input Parameter: 103 . flg - PETSC_TRUE to turn off viewer creation, PETSC_FALSE to turn it on. 104 105 Level: developer 106 107 Notes: 108 Calling XXXViewFromOptions in an inner loop can be very expensive. This can appear, for example, when using 109 many small subsolves. Call this function to control viewer creation in PetscOptionsGetViewer, thus removing the expensive XXXViewFromOptions calls. 110 111 .seealso: `PetscOptionsGetViewer()`, `PetscOptionsPopGetViewerOff()` 112 @*/ 113 PetscErrorCode PetscOptionsPushGetViewerOff(PetscBool flg) 114 { 115 PetscFunctionBegin; 116 PetscCheck(inoviewers < PETSCVIEWERGETVIEWEROFFPUSHESMAX,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptionsPushGetViewerOff(), perhaps you forgot PetscOptionsPopGetViewerOff()?"); 117 118 noviewers[inoviewers++] = noviewer; 119 noviewer = flg; 120 PetscFunctionReturn(0); 121 } 122 123 /*@ 124 PetscOptionsPopGetViewerOff - reset whether PetscOptionsGetViewer returns a viewer. 125 126 Logically Collective 127 128 Level: developer 129 130 Notes: 131 Calling XXXViewFromOptions in an inner loop can be very expensive. This can appear, for example, when using 132 many small subsolves. Call this function to control viewer creation in PetscOptionsGetViewer, thus removing the expensive XXXViewFromOptions calls. 133 134 .seealso: `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()` 135 @*/ 136 PetscErrorCode PetscOptionsPopGetViewerOff(void) 137 { 138 PetscFunctionBegin; 139 PetscCheck(inoviewers,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptionsPopGetViewerOff(), perhaps you forgot PetscOptionsPushGetViewerOff()?"); 140 noviewer = noviewers[--inoviewers]; 141 PetscFunctionReturn(0); 142 } 143 144 /*@ 145 PetscOptionsGetViewerOff - does PetscOptionsGetViewer return a viewer? 146 147 Logically Collective 148 149 Output Parameter: 150 . flg - whether viewers are returned. 151 152 Level: developer 153 154 Notes: 155 Calling XXXViewFromOptions in an inner loop can be very expensive. This can appear, for example, when using 156 many small subsolves. 157 158 .seealso: `PetscOptionsGetViewer()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()` 159 @*/ 160 PetscErrorCode PetscOptionsGetViewerOff(PetscBool *flg) 161 { 162 PetscFunctionBegin; 163 PetscValidBoolPointer(flg,1); 164 *flg = noviewer; 165 PetscFunctionReturn(0); 166 } 167 168 /*@C 169 PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user 170 171 Collective 172 173 Input Parameters: 174 + comm - the communicator to own the viewer 175 . options - options database, use NULL for default global database 176 . pre - the string to prepend to the name or NULL 177 - name - the option one is seeking 178 179 Output Parameters: 180 + viewer - the viewer, pass NULL if not needed 181 . format - the PetscViewerFormat requested by the user, pass NULL if not needed 182 - set - PETSC_TRUE if found, else PETSC_FALSE 183 184 Level: intermediate 185 186 Notes: 187 If no value is provided ascii:stdout is used 188 $ ascii[:[filename][:[format][:append]]] defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab, 189 for example ascii::ascii_info prints just the information about the object not all details 190 unless :append is given filename opens in write mode, overwriting what was already there 191 $ binary[:[filename][:[format][:append]]] defaults to the file binaryoutput 192 $ draw[:drawtype[:filename]] for example, draw:tikz, draw:tikz:figure.tex or draw:x 193 $ socket[:port] defaults to the standard output port 194 $ saws[:communicatorname] publishes object to the Scientific Application Webserver (SAWs) 195 196 Use PetscViewerDestroy() after using the viewer, otherwise a memory leak will occur 197 198 You can control whether calls to this function create a viewer (or return early with *set of PETSC_FALSE) with 199 PetscOptionsPushGetViewerOff. This is useful if calling many small subsolves, in which case XXXViewFromOptions can take 200 an appreciable fraction of the runtime. 201 202 If PETSc is configured with --with-viewfromoptions=0 this function always returns with *set of PETSC_FALSE 203 204 .seealso: `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 205 `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 206 `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, 207 `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 208 `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 209 `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 210 `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsPushGetViewerOff()`, `PetscOptionsPopGetViewerOff()`, 211 `PetscOptionsGetViewerOff()` 212 @*/ 213 PetscErrorCode PetscOptionsGetViewer(MPI_Comm comm,PetscOptions options,const char pre[],const char name[],PetscViewer *viewer,PetscViewerFormat *format,PetscBool *set) 214 { 215 const char *value; 216 PetscBool flag,hashelp; 217 218 PetscFunctionBegin; 219 PetscValidCharPointer(name,4); 220 221 if (viewer) *viewer = NULL; 222 if (format) *format = PETSC_VIEWER_DEFAULT; 223 if (set) *set = PETSC_FALSE; 224 PetscCall(PetscOptionsGetViewerOff(&flag)); 225 if (flag) PetscFunctionReturn(0); 226 227 PetscCall(PetscOptionsHasHelp(NULL,&hashelp)); 228 if (hashelp) { 229 PetscBool found; 230 231 if (!PetscOptionsHelpPrintedSingleton) { 232 PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton)); 233 } 234 PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton,pre,name,&found)); 235 if (!found && viewer) { 236 PetscCall((*PetscHelpPrintf)(comm,"----------------------------------------\nViewer (-%s%s) options:\n",pre ? pre : "",name+1)); 237 PetscCall((*PetscHelpPrintf)(comm," -%s%s ascii[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Prints object to stdout or ASCII file","PetscOptionsGetViewer")); 238 PetscCall((*PetscHelpPrintf)(comm," -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Saves object to a binary file","PetscOptionsGetViewer")); 239 PetscCall((*PetscHelpPrintf)(comm," -%s%s draw[:[drawtype][:filename|format]] %s (%s)\n",pre ? pre : "",name+1,"Draws object","PetscOptionsGetViewer")); 240 PetscCall((*PetscHelpPrintf)(comm," -%s%s socket[:port]: %s (%s)\n",pre ? pre : "",name+1,"Pushes object to a Unix socket","PetscOptionsGetViewer")); 241 PetscCall((*PetscHelpPrintf)(comm," -%s%s saws[:communicatorname]: %s (%s)\n",pre ? pre : "",name+1,"Publishes object to SAWs","PetscOptionsGetViewer")); 242 } 243 } 244 245 if (format) *format = PETSC_VIEWER_DEFAULT; 246 PetscCall(PetscOptionsFindPair(options,pre,name,&value,&flag)); 247 if (flag) { 248 if (set) *set = PETSC_TRUE; 249 if (!value) { 250 if (viewer) { 251 PetscCall(PetscViewerASCIIGetStdout(comm,viewer)); 252 PetscCall(PetscObjectReference((PetscObject)*viewer)); 253 } 254 } else { 255 char *loc0_vtype,*loc1_fname,*loc2_fmt = NULL,*loc3_fmode = NULL; 256 PetscInt cnt; 257 const char *viewers[] = {PETSCVIEWERASCII,PETSCVIEWERBINARY,PETSCVIEWERDRAW,PETSCVIEWERSOCKET,PETSCVIEWERMATLAB,PETSCVIEWERSAWS,PETSCVIEWERVTK,PETSCVIEWERHDF5,PETSCVIEWERGLVIS,PETSCVIEWEREXODUSII,NULL}; 258 259 PetscCall(PetscStrallocpy(value,&loc0_vtype)); 260 PetscCall(PetscStrchr(loc0_vtype,':',&loc1_fname)); 261 if (loc1_fname) { 262 *loc1_fname++ = 0; 263 PetscCall(PetscStrchr(loc1_fname,':',&loc2_fmt)); 264 } 265 if (loc2_fmt) { 266 *loc2_fmt++ = 0; 267 PetscCall(PetscStrchr(loc2_fmt,':',&loc3_fmode)); 268 } 269 if (loc3_fmode) *loc3_fmode++ = 0; 270 PetscCall(PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii",viewers,&cnt)); 271 PetscCheck(cnt <= (PetscInt) sizeof(viewers)-1,comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown viewer type: %s",loc0_vtype); 272 if (viewer) { 273 if (!loc1_fname) { 274 switch (cnt) { 275 case 0: 276 PetscCall(PetscViewerASCIIGetStdout(comm,viewer)); 277 break; 278 case 1: 279 if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) PetscCall(PETSC_ERR_PLIB); 280 break; 281 case 2: 282 if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) PetscCall(PETSC_ERR_PLIB); 283 break; 284 #if defined(PETSC_USE_SOCKET_VIEWER) 285 case 3: 286 if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) PetscCall(PETSC_ERR_PLIB); 287 break; 288 #endif 289 #if defined(PETSC_HAVE_MATLAB_ENGINE) 290 case 4: 291 if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) PetscCall(PETSC_ERR_PLIB); 292 break; 293 #endif 294 #if defined(PETSC_HAVE_SAWS) 295 case 5: 296 if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) PetscCall(PETSC_ERR_PLIB); 297 break; 298 #endif 299 #if defined(PETSC_HAVE_HDF5) 300 case 7: 301 if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) PetscCall(PETSC_ERR_PLIB); 302 break; 303 #endif 304 case 8: 305 if (!(*viewer = PETSC_VIEWER_GLVIS_(comm))) PetscCall(PETSC_ERR_PLIB); 306 break; 307 #if defined(PETSC_HAVE_EXODUSII) 308 case 9: 309 if (!(*viewer = PETSC_VIEWER_EXODUSII_(comm))) PetscCall(PETSC_ERR_PLIB); 310 break; 311 #endif 312 default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported viewer %s",loc0_vtype); 313 } 314 PetscCall(PetscObjectReference((PetscObject)*viewer)); 315 } else { 316 if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */ 317 PetscCall(PetscViewerASCIIGetStdout(comm,viewer)); 318 PetscCall(PetscObjectReference((PetscObject)*viewer)); 319 } else { 320 PetscFileMode fmode; 321 PetscCall(PetscViewerCreate(comm,viewer)); 322 PetscCall(PetscViewerSetType(*viewer,*loc0_vtype ? loc0_vtype : "ascii")); 323 fmode = FILE_MODE_WRITE; 324 if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */ 325 PetscCall(PetscEnumFind(PetscFileModes,loc3_fmode,(PetscEnum*)&fmode,&flag)); 326 PetscCheck(flag,comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown file mode: %s",loc3_fmode); 327 } 328 if (loc2_fmt) { 329 PetscBool tk,im; 330 PetscCall(PetscStrcmp(loc1_fname,"tikz",&tk)); 331 PetscCall(PetscStrcmp(loc1_fname,"image",&im)); 332 if (tk || im) { 333 PetscCall(PetscViewerDrawSetInfo(*viewer,NULL,loc2_fmt,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE)); 334 *loc2_fmt = 0; 335 } 336 } 337 PetscCall(PetscViewerFileSetMode(*viewer,flag?fmode:FILE_MODE_WRITE)); 338 PetscCall(PetscViewerFileSetName(*viewer,loc1_fname)); 339 if (*loc1_fname) PetscCall(PetscViewerDrawSetDrawType(*viewer,loc1_fname)); 340 PetscCall(PetscViewerSetFromOptions(*viewer)); 341 } 342 } 343 } 344 if (viewer) PetscCall(PetscViewerSetUp(*viewer)); 345 if (loc2_fmt && *loc2_fmt) { 346 PetscViewerFormat tfmt; 347 348 PetscCall(PetscEnumFind(PetscViewerFormats,loc2_fmt,(PetscEnum*)&tfmt,&flag)); 349 if (format) *format = tfmt; 350 PetscCheck(flag,PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer format %s",loc2_fmt); 351 } else if (viewer && (cnt == 6) && format) { /* Get format from VTK viewer */ 352 PetscCall(PetscViewerGetFormat(*viewer,format)); 353 } 354 PetscCall(PetscFree(loc0_vtype)); 355 } 356 } 357 PetscFunctionReturn(0); 358 } 359 360 /*@ 361 PetscViewerCreate - Creates a viewing context 362 363 Collective 364 365 Input Parameter: 366 . comm - MPI communicator 367 368 Output Parameter: 369 . inviewer - location to put the PetscViewer context 370 371 Level: advanced 372 373 .seealso: `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerType` 374 375 @*/ 376 PetscErrorCode PetscViewerCreate(MPI_Comm comm,PetscViewer *inviewer) 377 { 378 PetscViewer viewer; 379 380 PetscFunctionBegin; 381 *inviewer = NULL; 382 PetscCall(PetscViewerInitializePackage()); 383 PetscCall(PetscHeaderCreate(viewer,PETSC_VIEWER_CLASSID,"PetscViewer","PetscViewer","Viewer",comm,PetscViewerDestroy,PetscViewerView)); 384 *inviewer = viewer; 385 viewer->data = NULL; 386 PetscFunctionReturn(0); 387 } 388 389 /*@C 390 PetscViewerSetType - Builds PetscViewer for a particular implementation. 391 392 Collective on PetscViewer 393 394 Input Parameters: 395 + viewer - the PetscViewer context 396 - type - for example, PETSCVIEWERASCII 397 398 Options Database Command: 399 . -viewer_type <type> - Sets the type; use -help for a list 400 of available methods (for instance, ascii) 401 402 Level: advanced 403 404 Notes: 405 See "include/petscviewer.h" for available methods (for instance, 406 PETSCVIEWERSOCKET) 407 408 .seealso: `PetscViewerCreate()`, `PetscViewerGetType()`, `PetscViewerType`, `PetscViewerPushFormat()` 409 @*/ 410 PetscErrorCode PetscViewerSetType(PetscViewer viewer,PetscViewerType type) 411 { 412 PetscBool match; 413 PetscErrorCode (*r)(PetscViewer); 414 415 PetscFunctionBegin; 416 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 417 PetscValidCharPointer(type,2); 418 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,type,&match)); 419 if (match) PetscFunctionReturn(0); 420 421 /* cleanup any old type that may be there */ 422 if (viewer->data) { 423 PetscCall((*viewer->ops->destroy)(viewer)); 424 425 viewer->ops->destroy = NULL; 426 viewer->data = NULL; 427 } 428 PetscCall(PetscMemzero(viewer->ops,sizeof(struct _PetscViewerOps))); 429 430 PetscCall(PetscFunctionListFind(PetscViewerList,type,&r)); 431 PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscViewer type given: %s",type); 432 433 PetscCall(PetscObjectChangeTypeName((PetscObject)viewer,type)); 434 PetscCall((*r)(viewer)); 435 PetscFunctionReturn(0); 436 } 437 438 /*@C 439 PetscViewerRegister - Adds a viewer 440 441 Not Collective 442 443 Input Parameters: 444 + name_solver - name of a new user-defined viewer 445 - routine_create - routine to create method context 446 447 Level: developer 448 Notes: 449 PetscViewerRegister() may be called multiple times to add several user-defined viewers. 450 451 Sample usage: 452 .vb 453 PetscViewerRegister("my_viewer_type",MyViewerCreate); 454 .ve 455 456 Then, your solver can be chosen with the procedural interface via 457 $ PetscViewerSetType(viewer,"my_viewer_type") 458 or at runtime via the option 459 $ -viewer_type my_viewer_type 460 461 .seealso: `PetscViewerRegisterAll()` 462 @*/ 463 PetscErrorCode PetscViewerRegister(const char *sname,PetscErrorCode (*function)(PetscViewer)) 464 { 465 PetscFunctionBegin; 466 PetscCall(PetscViewerInitializePackage()); 467 PetscCall(PetscFunctionListAdd(&PetscViewerList,sname,function)); 468 PetscFunctionReturn(0); 469 } 470 471 /*@C 472 PetscViewerSetFromOptions - Sets the graphics type from the options database. 473 Defaults to a PETSc X windows graphics. 474 475 Collective on PetscViewer 476 477 Input Parameter: 478 . PetscViewer - the graphics context 479 480 Level: intermediate 481 482 Notes: 483 Must be called after PetscViewerCreate() before the PetscViewer is used. 484 485 .seealso: `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerType` 486 487 @*/ 488 PetscErrorCode PetscViewerSetFromOptions(PetscViewer viewer) 489 { 490 char vtype[256]; 491 PetscBool flg; 492 493 PetscFunctionBegin; 494 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 495 496 if (!PetscViewerList) { 497 PetscCall(PetscViewerRegisterAll()); 498 } 499 PetscObjectOptionsBegin((PetscObject)viewer); 500 PetscCall(PetscOptionsFList("-viewer_type","Type of PetscViewer","None",PetscViewerList,(char*)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII),vtype,256,&flg)); 501 if (flg) PetscCall(PetscViewerSetType(viewer,vtype)); 502 /* type has not been set? */ 503 if (!((PetscObject)viewer)->type_name) { 504 PetscCall(PetscViewerSetType(viewer,PETSCVIEWERASCII)); 505 } 506 if (viewer->ops->setfromoptions) PetscCall((*viewer->ops->setfromoptions)(PetscOptionsObject,viewer)); 507 508 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 509 PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)viewer)); 510 PetscCall(PetscViewerViewFromOptions(viewer,NULL,"-viewer_view")); 511 PetscOptionsEnd(); 512 PetscFunctionReturn(0); 513 } 514 515 PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer,PetscInt *mcnt,PetscInt *cnt) 516 { 517 PetscFunctionBegin; 518 PetscCall(PetscViewerBinaryGetFlowControl(viewer,mcnt)); 519 PetscCall(PetscViewerBinaryGetFlowControl(viewer,cnt)); 520 PetscFunctionReturn(0); 521 } 522 523 PetscErrorCode PetscViewerFlowControlStepMain(PetscViewer viewer,PetscInt i,PetscInt *mcnt,PetscInt cnt) 524 { 525 MPI_Comm comm; 526 527 PetscFunctionBegin; 528 PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm)); 529 if (i >= *mcnt) { 530 *mcnt += cnt; 531 PetscCallMPI(MPI_Bcast(mcnt,1,MPIU_INT,0,comm)); 532 } 533 PetscFunctionReturn(0); 534 } 535 536 PetscErrorCode PetscViewerFlowControlEndMain(PetscViewer viewer,PetscInt *mcnt) 537 { 538 MPI_Comm comm; 539 PetscFunctionBegin; 540 PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm)); 541 *mcnt = 0; 542 PetscCallMPI(MPI_Bcast(mcnt,1,MPIU_INT,0,comm)); 543 PetscFunctionReturn(0); 544 } 545 546 PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer,PetscMPIInt rank,PetscInt *mcnt) 547 { 548 MPI_Comm comm; 549 PetscFunctionBegin; 550 PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm)); 551 while (PETSC_TRUE) { 552 if (rank < *mcnt) break; 553 PetscCallMPI(MPI_Bcast(mcnt,1,MPIU_INT,0,comm)); 554 } 555 PetscFunctionReturn(0); 556 } 557 558 PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer,PetscInt *mcnt) 559 { 560 MPI_Comm comm; 561 PetscFunctionBegin; 562 PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm)); 563 while (PETSC_TRUE) { 564 PetscCallMPI(MPI_Bcast(mcnt,1,MPIU_INT,0,comm)); 565 if (!*mcnt) break; 566 } 567 PetscFunctionReturn(0); 568 } 569