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