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