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