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),vascii->fd);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 tab = ascii->tab; 543 while (tab--) { 544 ierr = PetscFPrintf(PETSC_COMM_SELF,fd," ");CHKERRQ(ierr); 545 } 546 547 va_start(Argp,format); 548 ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr); 549 err = fflush(fd); 550 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 551 if (petsc_history) { 552 va_start(Argp,format); 553 tab = ascii->tab; 554 while (tab--) { 555 ierr = PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");CHKERRQ(ierr); 556 } 557 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 558 err = fflush(petsc_history); 559 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 560 } 561 va_end(Argp); 562 } 563 PetscFunctionReturn(0); 564 } 565 566 #undef __FUNCT__ 567 #define __FUNCT__ "PetscViewerFileSetName" 568 /*@C 569 PetscViewerFileSetName - Sets the name of the file the PetscViewer uses. 570 571 Collective on PetscViewer 572 573 Input Parameters: 574 + viewer - the PetscViewer; either ASCII or binary 575 - name - the name of the file it should use 576 577 Level: advanced 578 579 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(), 580 PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 581 582 @*/ 583 PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[]) 584 { 585 PetscErrorCode ierr; 586 587 PetscFunctionBegin; 588 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 589 PetscValidCharPointer(name,2); 590 ierr = PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));CHKERRQ(ierr); 591 PetscFunctionReturn(0); 592 } 593 594 #undef __FUNCT__ 595 #define __FUNCT__ "PetscViewerFileGetName" 596 /*@C 597 PetscViewerFileGetName - Gets the name of the file the PetscViewer uses. 598 599 Not Collective 600 601 Input Parameter: 602 . viewer - the PetscViewer; either ASCII or binary 603 604 Output Parameter: 605 . name - the name of the file it is using 606 607 Level: advanced 608 609 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName() 610 611 @*/ 612 PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name) 613 { 614 PetscErrorCode ierr; 615 616 PetscFunctionBegin; 617 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 618 ierr = PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));CHKERRQ(ierr); 619 PetscFunctionReturn(0); 620 } 621 622 #undef __FUNCT__ 623 #define __FUNCT__ "PetscViewerFileGetName_ASCII" 624 PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name) 625 { 626 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 627 628 PetscFunctionBegin; 629 *name = vascii->filename; 630 PetscFunctionReturn(0); 631 } 632 633 #undef __FUNCT__ 634 #define __FUNCT__ "PetscViewerFileSetName_ASCII" 635 PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[]) 636 { 637 PetscErrorCode ierr; 638 size_t len; 639 char fname[PETSC_MAX_PATH_LEN],*gz; 640 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 641 PetscBool isstderr,isstdout; 642 PetscMPIInt rank; 643 644 PetscFunctionBegin; 645 ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr); 646 if (!name) PetscFunctionReturn(0); 647 ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr); 648 649 /* Is this file to be compressed */ 650 vascii->storecompressed = PETSC_FALSE; 651 652 ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr); 653 if (gz) { 654 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 655 if (len == 3) { 656 *gz = 0; 657 vascii->storecompressed = PETSC_TRUE; 658 } 659 } 660 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 661 if (!rank) { 662 ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr); 663 ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr); 664 /* empty filename means stdout */ 665 if (name[0] == 0) isstdout = PETSC_TRUE; 666 if (isstderr) vascii->fd = PETSC_STDERR; 667 else if (isstdout) vascii->fd = PETSC_STDOUT; 668 else { 669 670 671 ierr = PetscFixFilename(name,fname);CHKERRQ(ierr); 672 switch (vascii->mode) { 673 case FILE_MODE_READ: 674 vascii->fd = fopen(fname,"r"); 675 break; 676 case FILE_MODE_WRITE: 677 vascii->fd = fopen(fname,"w"); 678 break; 679 case FILE_MODE_APPEND: 680 vascii->fd = fopen(fname,"a"); 681 break; 682 case FILE_MODE_UPDATE: 683 vascii->fd = fopen(fname,"r+"); 684 if (!vascii->fd) vascii->fd = fopen(fname,"w+"); 685 break; 686 case FILE_MODE_APPEND_UPDATE: 687 /* I really want a file which is opened at the end for updating, 688 not a+, which opens at the beginning, but makes writes at the end. 689 */ 690 vascii->fd = fopen(fname,"r+"); 691 if (!vascii->fd) vascii->fd = fopen(fname,"w+"); 692 else { 693 ierr = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr); 694 } 695 break; 696 default: 697 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode); 698 } 699 if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname); 700 } 701 } 702 #if defined(PETSC_USE_LOG) 703 PetscLogObjectState((PetscObject)viewer,"File: %s",name); 704 #endif 705 PetscFunctionReturn(0); 706 } 707 708 #undef __FUNCT__ 709 #define __FUNCT__ "PetscViewerGetSingleton_ASCII" 710 PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer) 711 { 712 PetscMPIInt rank; 713 PetscErrorCode ierr; 714 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii; 715 const char *name; 716 717 PetscFunctionBegin; 718 if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored"); 719 ierr = PetscViewerCreate(PETSC_COMM_SELF,outviewer);CHKERRQ(ierr); 720 ierr = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr); 721 ovascii = (PetscViewer_ASCII*)(*outviewer)->data; 722 ovascii->fd = vascii->fd; 723 ovascii->tab = vascii->tab; 724 725 vascii->sviewer = *outviewer; 726 727 (*outviewer)->format = viewer->format; 728 729 ierr = PetscObjectGetName((PetscObject)viewer,&name);CHKERRQ(ierr); 730 ierr = PetscObjectSetName((PetscObject)(*outviewer),name);CHKERRQ(ierr); 731 732 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 733 ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer; 734 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton; 735 if (rank) (*outviewer)->ops->flush = 0; 736 else (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0; 737 PetscFunctionReturn(0); 738 } 739 740 #undef __FUNCT__ 741 #define __FUNCT__ "PetscViewerRestoreSingleton_ASCII" 742 PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer) 743 { 744 PetscErrorCode ierr; 745 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)(*outviewer)->data; 746 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 747 748 PetscFunctionBegin; 749 if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer"); 750 if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton"); 751 752 ascii->sviewer = 0; 753 vascii->fd = PETSC_STDOUT; 754 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII; 755 ierr = PetscViewerDestroy(outviewer);CHKERRQ(ierr); 756 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 757 PetscFunctionReturn(0); 758 } 759 760 #undef __FUNCT__ 761 #define __FUNCT__ "PetscViewerGetSubcomm_ASCII" 762 PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer) 763 { 764 PetscErrorCode ierr; 765 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii; 766 const char *name; 767 768 PetscFunctionBegin; 769 if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm viewer already obtained from PetscViewer and not restored"); 770 /* Note that we need to open vascii->filename for the subcomm: 771 we can't count on reusing viewer's fd since the root in comm and subcomm may differ. 772 Further, if the subcomm happens to be the same as comm, PetscViewerASCIIOpen() will 773 will return the current viewer, having increfed it. 774 */ 775 ierr = PetscViewerASCIIOpen(subcomm,vascii->filename, outviewer);CHKERRQ(ierr); 776 if (*outviewer == viewer) PetscFunctionReturn(0); 777 ovascii = (PetscViewer_ASCII*)(*outviewer)->data; 778 779 ovascii->tab = vascii->tab; 780 vascii->sviewer = *outviewer; 781 782 (*outviewer)->format = viewer->format; 783 784 ierr = PetscObjectGetName((PetscObject)viewer,&name);CHKERRQ(ierr); 785 ierr = PetscObjectSetName((PetscObject)(*outviewer),name);CHKERRQ(ierr); 786 787 ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer; 788 789 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Subcomm; 790 PetscFunctionReturn(0); 791 } 792 793 #undef __FUNCT__ 794 #define __FUNCT__ "PetscViewerRestoreSubcomm_ASCII" 795 PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer) 796 { 797 PetscErrorCode ierr; 798 PetscViewer_ASCII *oascii = (PetscViewer_ASCII*)(*outviewer)->data; 799 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 800 801 PetscFunctionBegin; 802 if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer"); 803 if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"The given PetscViewer did not generate this subcomm viewer"); 804 805 ascii->sviewer = 0; 806 oascii->fd = PETSC_STDOUT; 807 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII; 808 809 ierr = PetscViewerDestroy(outviewer);CHKERRQ(ierr); 810 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 811 PetscFunctionReturn(0); 812 } 813 814 #undef __FUNCT__ 815 #define __FUNCT__ "PetscViewerView_ASCII" 816 PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer) 817 { 818 PetscErrorCode ierr; 819 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data; 820 821 PetscFunctionBegin; 822 if (ascii->filename) { 823 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr); 824 } 825 PetscFunctionReturn(0); 826 } 827 828 #undef __FUNCT__ 829 #define __FUNCT__ "PetscViewerCreate_ASCII" 830 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer) 831 { 832 PetscViewer_ASCII *vascii; 833 PetscErrorCode ierr; 834 835 PetscFunctionBegin; 836 ierr = PetscNewLog(viewer,PetscViewer_ASCII,&vascii);CHKERRQ(ierr); 837 viewer->data = (void*)vascii; 838 839 viewer->ops->destroy = PetscViewerDestroy_ASCII; 840 viewer->ops->flush = PetscViewerFlush_ASCII; 841 viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII; 842 viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII; 843 viewer->ops->getsubcomm = PetscViewerGetSubcomm_ASCII; 844 viewer->ops->restoresubcomm = PetscViewerRestoreSubcomm_ASCII; 845 viewer->ops->view = PetscViewerView_ASCII; 846 847 /* defaults to stdout unless set with PetscViewerFileSetName() */ 848 vascii->fd = PETSC_STDOUT; 849 vascii->mode = FILE_MODE_WRITE; 850 vascii->bviewer = 0; 851 vascii->sviewer = 0; 852 vascii->tab = 0; 853 vascii->tab_store = 0; 854 vascii->filename = 0; 855 vascii->closefile = PETSC_TRUE; 856 857 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr); 858 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr); 859 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr); 860 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr); 861 PetscFunctionReturn(0); 862 } 863 864 865 #undef __FUNCT__ 866 #define __FUNCT__ "PetscViewerASCIISynchronizedPrintf" 867 /*@C 868 PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from 869 several processors. Output of the first processor is followed by that of the 870 second, etc. 871 872 Not Collective, must call collective PetscViewerFlush() to get the results out 873 874 Input Parameters: 875 + viewer - the ASCII PetscViewer 876 - format - the usual printf() format string 877 878 Level: intermediate 879 880 Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called. 881 882 Fortran Note: 883 Can only print a single character* string 884 885 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 886 PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(), 887 PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow() 888 889 @*/ 890 PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...) 891 { 892 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 893 PetscErrorCode ierr; 894 PetscMPIInt rank,size; 895 PetscInt tab = vascii->tab; 896 MPI_Comm comm; 897 FILE *fp; 898 PetscBool iascii; 899 int err; 900 901 PetscFunctionBegin; 902 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 903 PetscValidCharPointer(format,2); 904 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 905 if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer"); 906 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);CHKERRQ(ierr); 907 if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call"); 908 if (!viewer->ops->flush) PetscFunctionReturn(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */ 909 910 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 911 fp = vascii->fd; 912 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 913 914 /* First processor prints immediately to fp */ 915 if (!rank) { 916 va_list Argp; 917 918 while (tab--) { 919 ierr = PetscFPrintf(PETSC_COMM_SELF,fp," ");CHKERRQ(ierr); 920 } 921 922 va_start(Argp,format); 923 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 924 err = fflush(fp); 925 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 926 if (petsc_history) { 927 va_start(Argp,format); 928 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 929 err = fflush(petsc_history); 930 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 931 } 932 va_end(Argp); 933 } else { /* other processors add to local queue */ 934 char *string; 935 va_list Argp; 936 size_t fullLength; 937 PrintfQueue next; 938 939 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 940 if (petsc_printfqueue) { 941 petsc_printfqueue->next = next; 942 petsc_printfqueue = next; 943 } else { 944 petsc_printfqueuebase = petsc_printfqueue = next; 945 } 946 petsc_printfqueuelength++; 947 next->size = QUEUESTRINGSIZE; 948 ierr = PetscMalloc(next->size*sizeof(char), &next->string);CHKERRQ(ierr); 949 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 950 string = next->string; 951 tab *= 2; 952 while (tab--) { 953 *string++ = ' '; 954 } 955 va_start(Argp,format); 956 ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr); 957 va_end(Argp); 958 } 959 PetscFunctionReturn(0); 960 } 961 962 963