1 2 #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I "petscviewer.h" I*/ 3 4 #define QUEUESTRINGSIZE 8192 5 6 #undef __FUNCT__ 7 #define __FUNCT__ "PetscViewerFileClose_ASCII" 8 static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer) 9 { 10 PetscErrorCode ierr; 11 PetscMPIInt rank; 12 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 13 int err; 14 15 PetscFunctionBegin; 16 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 17 if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) { 18 if (vascii->fd && vascii->closefile) { 19 err = fclose(vascii->fd); 20 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 21 } 22 if (vascii->storecompressed) { 23 char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN]; 24 FILE *fp; 25 ierr = PetscStrcpy(par,"gzip ");CHKERRQ(ierr); 26 ierr = PetscStrcat(par,vascii->filename);CHKERRQ(ierr); 27 #if defined(PETSC_HAVE_POPEN) 28 ierr = PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);CHKERRQ(ierr); 29 if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf); 30 ierr = PetscPClose(PETSC_COMM_SELF,fp,NULL);CHKERRQ(ierr); 31 #else 32 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine"); 33 #endif 34 } 35 } 36 ierr = PetscFree(vascii->filename);CHKERRQ(ierr); 37 PetscFunctionReturn(0); 38 } 39 40 /* ----------------------------------------------------------------------*/ 41 #undef __FUNCT__ 42 #define __FUNCT__ "PetscViewerDestroy_ASCII" 43 PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer) 44 { 45 PetscErrorCode ierr; 46 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 47 PetscViewerLink *vlink; 48 PetscBool flg; 49 50 PetscFunctionBegin; 51 if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton or subcomm PetscViewer"); 52 ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr); 53 ierr = PetscFree(vascii);CHKERRQ(ierr); 54 55 /* remove the viewer from the list in the MPI Communicator */ 56 if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) { 57 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr); 58 } 59 60 ierr = MPI_Attr_get(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr); 61 if (flg) { 62 if (vlink && vlink->viewer == viewer) { 63 ierr = MPI_Attr_put(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);CHKERRQ(ierr); 64 ierr = PetscFree(vlink);CHKERRQ(ierr); 65 } else { 66 while (vlink && vlink->next) { 67 if (vlink->next->viewer == viewer) { 68 PetscViewerLink *nv = vlink->next; 69 vlink->next = vlink->next->next; 70 ierr = PetscFree(nv);CHKERRQ(ierr); 71 } 72 vlink = vlink->next; 73 } 74 } 75 } 76 PetscFunctionReturn(0); 77 } 78 79 #undef __FUNCT__ 80 #define __FUNCT__ "PetscViewerDestroy_ASCII_Singleton" 81 PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer) 82 { 83 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 84 PetscErrorCode ierr; 85 86 PetscFunctionBegin; 87 ierr = PetscViewerRestoreSingleton(vascii->bviewer,&viewer);CHKERRQ(ierr); 88 PetscFunctionReturn(0); 89 } 90 91 #undef __FUNCT__ 92 #define __FUNCT__ "PetscViewerDestroy_ASCII_Subcomm" 93 PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer) 94 { 95 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 96 PetscErrorCode ierr; 97 98 PetscFunctionBegin; 99 ierr = PetscViewerRestoreSubcomm(vascii->bviewer,PetscObjectComm((PetscObject)viewer),&viewer);CHKERRQ(ierr); 100 PetscFunctionReturn(0); 101 } 102 103 #undef __FUNCT__ 104 #define __FUNCT__ "PetscViewerFlush_ASCII_Singleton_0" 105 PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer) 106 { 107 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 108 int err; 109 110 PetscFunctionBegin; 111 err = fflush(vascii->fd); 112 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 113 PetscFunctionReturn(0); 114 } 115 116 #undef __FUNCT__ 117 #define __FUNCT__ "PetscViewerFlush_ASCII" 118 PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer) 119 { 120 PetscMPIInt rank; 121 PetscErrorCode ierr; 122 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 123 int err; 124 125 PetscFunctionBegin; 126 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 127 /* fflush() fails on OSX for read-only descriptors */ 128 if (!rank && (vascii->mode != FILE_MODE_READ)) { 129 err = fflush(vascii->fd); 130 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed"); 131 } 132 133 if (vascii->allowsynchronized) { 134 /* Also flush anything printed with PetscViewerASCIISynchronizedPrintf() */ 135 ierr = PetscSynchronizedFlush(PetscObjectComm((PetscObject)viewer));CHKERRQ(ierr); 136 } 137 PetscFunctionReturn(0); 138 } 139 140 #undef __FUNCT__ 141 #define __FUNCT__ "PetscViewerASCIIGetPointer" 142 /*@C 143 PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer. 144 145 Not Collective 146 147 + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen() 148 - fd - file pointer 149 150 Level: intermediate 151 152 Fortran Note: 153 This routine is not supported in Fortran. 154 155 Concepts: PetscViewer^file pointer 156 Concepts: file pointer^getting from PetscViewer 157 158 .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(), 159 PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush() 160 @*/ 161 PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd) 162 { 163 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 164 165 PetscFunctionBegin; 166 *fd = vascii->fd; 167 PetscFunctionReturn(0); 168 } 169 170 #undef __FUNCT__ 171 #define __FUNCT__ "PetscViewerFileGetMode_ASCII" 172 PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode) 173 { 174 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 175 176 PetscFunctionBegin; 177 *mode = vascii->mode; 178 PetscFunctionReturn(0); 179 } 180 181 #undef __FUNCT__ 182 #define __FUNCT__ "PetscViewerFileSetMode_ASCII" 183 PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode) 184 { 185 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 186 187 PetscFunctionBegin; 188 vascii->mode = mode; 189 PetscFunctionReturn(0); 190 } 191 192 /* 193 If petsc_history is on, then all Petsc*Printf() results are saved 194 if the appropriate (usually .petschistory) file. 195 */ 196 extern FILE *petsc_history; 197 198 #undef __FUNCT__ 199 #define __FUNCT__ "PetscViewerASCIISetTab" 200 /*@ 201 PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times 202 203 Not Collective, but only first processor in set has any effect 204 205 Input Parameters: 206 + viewer - optained with PetscViewerASCIIOpen() 207 - tabs - number of tabs 208 209 Level: developer 210 211 Fortran Note: 212 This routine is not supported in Fortran. 213 214 Concepts: PetscViewerASCII^formating 215 Concepts: tab^setting 216 217 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(), 218 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 219 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab() 220 @*/ 221 PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs) 222 { 223 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 224 PetscBool iascii; 225 PetscErrorCode ierr; 226 227 PetscFunctionBegin; 228 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 229 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 230 if (iascii) ascii->tab = tabs; 231 PetscFunctionReturn(0); 232 } 233 234 #undef __FUNCT__ 235 #define __FUNCT__ "PetscViewerASCIIGetTab" 236 /*@ 237 PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer. 238 239 Not Collective, meaningful on first processor only. 240 241 Input Parameters: 242 . viewer - optained with PetscViewerASCIIOpen() 243 Output Parameters: 244 . tabs - number of tabs 245 246 Level: developer 247 248 Fortran Note: 249 This routine is not supported in Fortran. 250 251 Concepts: PetscViewerASCII^formating 252 Concepts: tab^retrieval 253 254 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(), 255 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 256 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab() 257 @*/ 258 PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs) 259 { 260 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 261 PetscBool iascii; 262 PetscErrorCode ierr; 263 264 PetscFunctionBegin; 265 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 266 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 267 if (iascii && tabs) *tabs = ascii->tab; 268 PetscFunctionReturn(0); 269 } 270 271 #undef __FUNCT__ 272 #define __FUNCT__ "PetscViewerASCIIAddTab" 273 /*@ 274 PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing 275 276 Not Collective, but only first processor in set has any effect 277 278 Input Parameters: 279 + viewer - optained with PetscViewerASCIIOpen() 280 - tabs - number of tabs 281 282 Level: developer 283 284 Fortran Note: 285 This routine is not supported in Fortran. 286 287 Concepts: PetscViewerASCII^formating 288 Concepts: tab^setting 289 290 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 291 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 292 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab() 293 @*/ 294 PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs) 295 { 296 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 297 PetscBool iascii; 298 PetscErrorCode ierr; 299 300 PetscFunctionBegin; 301 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 302 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 303 if (iascii) ascii->tab += tabs; 304 PetscFunctionReturn(0); 305 } 306 307 #undef __FUNCT__ 308 #define __FUNCT__ "PetscViewerASCIISubtractTab" 309 /*@ 310 PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing 311 312 Not Collective, but only first processor in set has any effect 313 314 Input Parameters: 315 + viewer - optained with PetscViewerASCIIOpen() 316 - tabs - number of tabs 317 318 Level: developer 319 320 Fortran Note: 321 This routine is not supported in Fortran. 322 323 Concepts: PetscViewerASCII^formating 324 Concepts: tab^setting 325 326 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 327 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 328 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab() 329 @*/ 330 PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs) 331 { 332 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 333 PetscBool iascii; 334 PetscErrorCode ierr; 335 336 PetscFunctionBegin; 337 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 338 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 339 if (iascii) ascii->tab -= tabs; 340 PetscFunctionReturn(0); 341 } 342 343 #undef __FUNCT__ 344 #define __FUNCT__ "PetscViewerASCIISynchronizedAllow" 345 /*@C 346 PetscViewerASCIISynchronizedAllow - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer 347 348 Collective on PetscViewer 349 350 Input Parameters: 351 + viewer - optained with PetscViewerASCIIOpen() 352 - allow - PETSC_TRUE to allow the synchronized printing 353 354 Level: intermediate 355 356 Concepts: PetscViewerASCII^formating 357 Concepts: tab^setting 358 359 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 360 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 361 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer() 362 @*/ 363 PetscErrorCode PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow) 364 { 365 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 366 PetscBool iascii; 367 PetscErrorCode ierr; 368 369 PetscFunctionBegin; 370 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 371 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 372 if (iascii) ascii->allowsynchronized = allow; 373 PetscFunctionReturn(0); 374 } 375 376 #undef __FUNCT__ 377 #define __FUNCT__ "PetscViewerASCIIPushTab" 378 /*@ 379 PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf() 380 lines are tabbed. 381 382 Not Collective, but only first processor in set has any effect 383 384 Input Parameters: 385 . viewer - optained with PetscViewerASCIIOpen() 386 387 Level: developer 388 389 Fortran Note: 390 This routine is not supported in Fortran. 391 392 Concepts: PetscViewerASCII^formating 393 Concepts: tab^setting 394 395 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 396 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 397 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer() 398 @*/ 399 PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer) 400 { 401 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 402 PetscBool iascii; 403 PetscErrorCode ierr; 404 405 PetscFunctionBegin; 406 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 407 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 408 if (iascii) ascii->tab++; 409 PetscFunctionReturn(0); 410 } 411 412 #undef __FUNCT__ 413 #define __FUNCT__ "PetscViewerASCIIPopTab" 414 /*@ 415 PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf() 416 lines are tabbed. 417 418 Not Collective, but only first processor in set has any effect 419 420 Input Parameters: 421 . viewer - optained with PetscViewerASCIIOpen() 422 423 Level: developer 424 425 Fortran Note: 426 This routine is not supported in Fortran. 427 428 Concepts: PetscViewerASCII^formating 429 Concepts: tab^setting 430 431 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 432 PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 433 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer() 434 @*/ 435 PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer) 436 { 437 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 438 PetscErrorCode ierr; 439 PetscBool iascii; 440 441 PetscFunctionBegin; 442 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 443 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 444 if (iascii) { 445 if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed"); 446 ascii->tab--; 447 } 448 PetscFunctionReturn(0); 449 } 450 451 #undef __FUNCT__ 452 #define __FUNCT__ "PetscViewerASCIIUseTabs" 453 /*@ 454 PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer 455 456 Not Collective, but only first processor in set has any effect 457 458 Input Parameters: 459 + viewer - optained with PetscViewerASCIIOpen() 460 - flg - PETSC_TRUE or PETSC_FALSE 461 462 Level: developer 463 464 Fortran Note: 465 This routine is not supported in Fortran. 466 467 Concepts: PetscViewerASCII^formating 468 Concepts: tab^setting 469 470 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 471 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(), 472 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer() 473 @*/ 474 PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg) 475 { 476 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 477 PetscBool iascii; 478 PetscErrorCode ierr; 479 480 PetscFunctionBegin; 481 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 482 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 483 if (iascii) { 484 if (flg) ascii->tab = ascii->tab_store; 485 else { 486 ascii->tab_store = ascii->tab; 487 ascii->tab = 0; 488 } 489 } 490 PetscFunctionReturn(0); 491 } 492 493 /* ----------------------------------------------------------------------- */ 494 495 #include <../src/sys/fileio/mprint.h> /* defines the queue datastructures and variables */ 496 497 #undef __FUNCT__ 498 #define __FUNCT__ "PetscViewerASCIIPrintf" 499 /*@C 500 PetscViewerASCIIPrintf - Prints to a file, only from the first 501 processor in the PetscViewer 502 503 Not Collective, but only first processor in set has any effect 504 505 Input Parameters: 506 + viewer - optained with PetscViewerASCIIOpen() 507 - format - the usual printf() format string 508 509 Level: developer 510 511 Fortran Note: 512 The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran. 513 That is, you can only pass a single character string from Fortran. 514 515 Concepts: PetscViewerASCII^printing 516 Concepts: printing^to file 517 Concepts: printf 518 519 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(), 520 PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), 521 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIISynchronizedAllow() 522 @*/ 523 PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...) 524 { 525 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 526 PetscMPIInt rank; 527 PetscInt tab; 528 PetscErrorCode ierr; 529 FILE *fd = ascii->fd; 530 PetscBool iascii; 531 int err; 532 533 PetscFunctionBegin; 534 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 535 PetscValidCharPointer(format,2); 536 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 537 if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer"); 538 539 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 540 if (!rank) { 541 va_list Argp; 542 if (ascii->bviewer) petsc_printfqueuefile = fd; 543 544 tab = ascii->tab; 545 while (tab--) { 546 ierr = PetscFPrintf(PETSC_COMM_SELF,fd," ");CHKERRQ(ierr); 547 } 548 549 va_start(Argp,format); 550 ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr); 551 err = fflush(fd); 552 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 553 if (petsc_history) { 554 va_start(Argp,format); 555 tab = ascii->tab; 556 while (tab--) { 557 ierr = PetscFPrintf(PETSC_COMM_SELF,fd," ");CHKERRQ(ierr); 558 } 559 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 560 err = fflush(petsc_history); 561 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 562 } 563 va_end(Argp); 564 } 565 PetscFunctionReturn(0); 566 } 567 568 #undef __FUNCT__ 569 #define __FUNCT__ "PetscViewerFileSetName" 570 /*@C 571 PetscViewerFileSetName - Sets the name of the file the PetscViewer uses. 572 573 Collective on PetscViewer 574 575 Input Parameters: 576 + viewer - the PetscViewer; either ASCII or binary 577 - name - the name of the file it should use 578 579 Level: advanced 580 581 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(), 582 PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 583 584 @*/ 585 PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[]) 586 { 587 PetscErrorCode ierr; 588 589 PetscFunctionBegin; 590 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 591 PetscValidCharPointer(name,2); 592 ierr = PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));CHKERRQ(ierr); 593 PetscFunctionReturn(0); 594 } 595 596 #undef __FUNCT__ 597 #define __FUNCT__ "PetscViewerFileGetName" 598 /*@C 599 PetscViewerFileGetName - Gets the name of the file the PetscViewer uses. 600 601 Not Collective 602 603 Input Parameter: 604 . viewer - the PetscViewer; either ASCII or binary 605 606 Output Parameter: 607 . name - the name of the file it is using 608 609 Level: advanced 610 611 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName() 612 613 @*/ 614 PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name) 615 { 616 PetscErrorCode ierr; 617 618 PetscFunctionBegin; 619 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 620 ierr = PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));CHKERRQ(ierr); 621 PetscFunctionReturn(0); 622 } 623 624 #undef __FUNCT__ 625 #define __FUNCT__ "PetscViewerFileGetName_ASCII" 626 PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name) 627 { 628 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 629 630 PetscFunctionBegin; 631 *name = vascii->filename; 632 PetscFunctionReturn(0); 633 } 634 635 #undef __FUNCT__ 636 #define __FUNCT__ "PetscViewerFileSetName_ASCII" 637 PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[]) 638 { 639 PetscErrorCode ierr; 640 size_t len; 641 char fname[PETSC_MAX_PATH_LEN],*gz; 642 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 643 PetscBool isstderr,isstdout; 644 PetscMPIInt rank; 645 646 PetscFunctionBegin; 647 ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr); 648 if (!name) PetscFunctionReturn(0); 649 ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr); 650 651 /* Is this file to be compressed */ 652 vascii->storecompressed = PETSC_FALSE; 653 654 ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr); 655 if (gz) { 656 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 657 if (len == 3) { 658 *gz = 0; 659 vascii->storecompressed = PETSC_TRUE; 660 } 661 } 662 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 663 if (!rank) { 664 ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr); 665 ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr); 666 /* empty filename means stdout */ 667 if (name[0] == 0) isstdout = PETSC_TRUE; 668 if (isstderr) vascii->fd = PETSC_STDERR; 669 else if (isstdout) vascii->fd = PETSC_STDOUT; 670 else { 671 672 673 ierr = PetscFixFilename(name,fname);CHKERRQ(ierr); 674 switch (vascii->mode) { 675 case FILE_MODE_READ: 676 vascii->fd = fopen(fname,"r"); 677 break; 678 case FILE_MODE_WRITE: 679 vascii->fd = fopen(fname,"w"); 680 break; 681 case FILE_MODE_APPEND: 682 vascii->fd = fopen(fname,"a"); 683 break; 684 case FILE_MODE_UPDATE: 685 vascii->fd = fopen(fname,"r+"); 686 if (!vascii->fd) vascii->fd = fopen(fname,"w+"); 687 break; 688 case FILE_MODE_APPEND_UPDATE: 689 /* I really want a file which is opened at the end for updating, 690 not a+, which opens at the beginning, but makes writes at the end. 691 */ 692 vascii->fd = fopen(fname,"r+"); 693 if (!vascii->fd) vascii->fd = fopen(fname,"w+"); 694 else { 695 ierr = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr); 696 } 697 break; 698 default: 699 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode); 700 } 701 if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname); 702 } 703 } 704 #if defined(PETSC_USE_LOG) 705 PetscLogObjectState((PetscObject)viewer,"File: %s",name); 706 #endif 707 PetscFunctionReturn(0); 708 } 709 710 #undef __FUNCT__ 711 #define __FUNCT__ "PetscViewerGetSingleton_ASCII" 712 PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer) 713 { 714 PetscMPIInt rank; 715 PetscErrorCode ierr; 716 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii; 717 const char *name; 718 719 PetscFunctionBegin; 720 if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored"); 721 ierr = PetscViewerCreate(PETSC_COMM_SELF,outviewer);CHKERRQ(ierr); 722 ierr = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr); 723 ovascii = (PetscViewer_ASCII*)(*outviewer)->data; 724 ovascii->fd = vascii->fd; 725 ovascii->tab = vascii->tab; 726 727 vascii->sviewer = *outviewer; 728 729 (*outviewer)->format = viewer->format; 730 731 ierr = PetscObjectGetName((PetscObject)viewer,&name);CHKERRQ(ierr); 732 ierr = PetscObjectSetName((PetscObject)(*outviewer),name);CHKERRQ(ierr); 733 734 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 735 ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer; 736 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton; 737 if (rank) (*outviewer)->ops->flush = 0; 738 else (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0; 739 PetscFunctionReturn(0); 740 } 741 742 #undef __FUNCT__ 743 #define __FUNCT__ "PetscViewerRestoreSingleton_ASCII" 744 PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer) 745 { 746 PetscErrorCode ierr; 747 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)(*outviewer)->data; 748 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 749 750 PetscFunctionBegin; 751 if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer"); 752 if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton"); 753 754 ascii->sviewer = 0; 755 vascii->fd = PETSC_STDOUT; 756 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII; 757 ierr = PetscViewerDestroy(outviewer);CHKERRQ(ierr); 758 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 759 PetscFunctionReturn(0); 760 } 761 762 #undef __FUNCT__ 763 #define __FUNCT__ "PetscViewerGetSubcomm_ASCII" 764 PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer) 765 { 766 PetscErrorCode ierr; 767 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii; 768 const char *name; 769 770 PetscFunctionBegin; 771 if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm viewer already obtained from PetscViewer and not restored"); 772 /* Note that we need to open vascii->filename for the subcomm: 773 we can't count on reusing viewer's fd since the root in comm and subcomm may differ. 774 Further, if the subcomm happens to be the same as comm, PetscViewerASCIIOpen() will 775 will return the current viewer, having increfed it. 776 */ 777 ierr = PetscViewerASCIIOpen(subcomm,vascii->filename, outviewer);CHKERRQ(ierr); 778 if (*outviewer == viewer) PetscFunctionReturn(0); 779 ovascii = (PetscViewer_ASCII*)(*outviewer)->data; 780 781 ovascii->tab = vascii->tab; 782 vascii->sviewer = *outviewer; 783 784 (*outviewer)->format = viewer->format; 785 786 ierr = PetscObjectGetName((PetscObject)viewer,&name);CHKERRQ(ierr); 787 ierr = PetscObjectSetName((PetscObject)(*outviewer),name);CHKERRQ(ierr); 788 789 ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer; 790 791 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Subcomm; 792 PetscFunctionReturn(0); 793 } 794 795 #undef __FUNCT__ 796 #define __FUNCT__ "PetscViewerRestoreSubcomm_ASCII" 797 PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer) 798 { 799 PetscErrorCode ierr; 800 PetscViewer_ASCII *oascii = (PetscViewer_ASCII*)(*outviewer)->data; 801 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 802 803 PetscFunctionBegin; 804 if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer"); 805 if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"The given PetscViewer did not generate this subcomm viewer"); 806 807 ascii->sviewer = 0; 808 oascii->fd = PETSC_STDOUT; 809 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII; 810 811 ierr = PetscViewerDestroy(outviewer);CHKERRQ(ierr); 812 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 813 PetscFunctionReturn(0); 814 } 815 816 #undef __FUNCT__ 817 #define __FUNCT__ "PetscViewerView_ASCII" 818 PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer) 819 { 820 PetscErrorCode ierr; 821 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data; 822 823 PetscFunctionBegin; 824 if (ascii->filename) { 825 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr); 826 } 827 PetscFunctionReturn(0); 828 } 829 830 #undef __FUNCT__ 831 #define __FUNCT__ "PetscViewerCreate_ASCII" 832 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer) 833 { 834 PetscViewer_ASCII *vascii; 835 PetscErrorCode ierr; 836 837 PetscFunctionBegin; 838 ierr = PetscNewLog(viewer,PetscViewer_ASCII,&vascii);CHKERRQ(ierr); 839 viewer->data = (void*)vascii; 840 841 viewer->ops->destroy = PetscViewerDestroy_ASCII; 842 viewer->ops->flush = PetscViewerFlush_ASCII; 843 viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII; 844 viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII; 845 viewer->ops->getsubcomm = PetscViewerGetSubcomm_ASCII; 846 viewer->ops->restoresubcomm = PetscViewerRestoreSubcomm_ASCII; 847 viewer->ops->view = PetscViewerView_ASCII; 848 849 /* defaults to stdout unless set with PetscViewerFileSetName() */ 850 vascii->fd = PETSC_STDOUT; 851 vascii->mode = FILE_MODE_WRITE; 852 vascii->bviewer = 0; 853 vascii->sviewer = 0; 854 vascii->tab = 0; 855 vascii->tab_store = 0; 856 vascii->filename = 0; 857 vascii->closefile = PETSC_TRUE; 858 859 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr); 860 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr); 861 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr); 862 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr); 863 PetscFunctionReturn(0); 864 } 865 866 867 #undef __FUNCT__ 868 #define __FUNCT__ "PetscViewerASCIISynchronizedPrintf" 869 /*@C 870 PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from 871 several processors. Output of the first processor is followed by that of the 872 second, etc. 873 874 Not Collective, must call collective PetscViewerFlush() to get the results out 875 876 Input Parameters: 877 + viewer - the ASCII PetscViewer 878 - format - the usual printf() format string 879 880 Level: intermediate 881 882 Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called. 883 884 Fortran Note: 885 Can only print a single character* string 886 887 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 888 PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(), 889 PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow() 890 891 @*/ 892 PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...) 893 { 894 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 895 PetscErrorCode ierr; 896 PetscMPIInt rank,size; 897 PetscInt tab = vascii->tab; 898 MPI_Comm comm; 899 FILE *fp; 900 PetscBool iascii; 901 int err; 902 903 PetscFunctionBegin; 904 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 905 PetscValidCharPointer(format,2); 906 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 907 if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer"); 908 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);CHKERRQ(ierr); 909 if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call"); 910 if (!viewer->ops->flush) PetscFunctionReturn(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */ 911 912 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 913 fp = vascii->fd; 914 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 915 916 /* First processor prints immediately to fp */ 917 if (!rank) { 918 va_list Argp; 919 920 while (tab--) { 921 ierr = PetscFPrintf(PETSC_COMM_SELF,fp," ");CHKERRQ(ierr); 922 } 923 924 va_start(Argp,format); 925 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 926 err = fflush(fp); 927 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 928 petsc_printfqueuefile = fp; 929 if (petsc_history) { 930 va_start(Argp,format); 931 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 932 err = fflush(petsc_history); 933 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 934 } 935 va_end(Argp); 936 } else { /* other processors add to local queue */ 937 char *string; 938 va_list Argp; 939 size_t fullLength; 940 PrintfQueue next; 941 942 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 943 if (petsc_printfqueue) { 944 petsc_printfqueue->next = next; 945 petsc_printfqueue = next; 946 } else { 947 petsc_printfqueuebase = petsc_printfqueue = next; 948 } 949 petsc_printfqueuelength++; 950 next->size = QUEUESTRINGSIZE; 951 ierr = PetscMalloc(next->size*sizeof(char), &next->string);CHKERRQ(ierr); 952 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 953 string = next->string; 954 tab *= 2; 955 while (tab--) { 956 *string++ = ' '; 957 } 958 va_start(Argp,format); 959 ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr); 960 va_end(Argp); 961 } 962 PetscFunctionReturn(0); 963 } 964 965 966