1 2 #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I "petscviewer.h" I*/ 3 4 #define QUEUESTRINGSIZE 8192 5 6 static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer) 7 { 8 PetscErrorCode ierr; 9 PetscMPIInt rank; 10 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 11 int err; 12 13 PetscFunctionBegin; 14 if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 15 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 16 if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) { 17 if (vascii->fd && vascii->closefile) { 18 err = fclose(vascii->fd); 19 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 20 } 21 if (vascii->storecompressed) { 22 char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN]; 23 FILE *fp; 24 ierr = PetscStrncpy(par,"gzip ",sizeof(par));CHKERRQ(ierr); 25 ierr = PetscStrlcat(par,vascii->filename,sizeof(par));CHKERRQ(ierr); 26 #if defined(PETSC_HAVE_POPEN) 27 ierr = PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);CHKERRQ(ierr); 28 if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf); 29 ierr = PetscPClose(PETSC_COMM_SELF,fp);CHKERRQ(ierr); 30 #else 31 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine"); 32 #endif 33 } 34 } 35 ierr = PetscFree(vascii->filename);CHKERRQ(ierr); 36 PetscFunctionReturn(0); 37 } 38 39 /* ----------------------------------------------------------------------*/ 40 PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer) 41 { 42 PetscErrorCode ierr; 43 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 44 PetscViewerLink *vlink; 45 PetscBool flg; 46 47 PetscFunctionBegin; 48 if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 49 ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr); 50 ierr = PetscFree(vascii);CHKERRQ(ierr); 51 52 /* remove the viewer from the list in the MPI Communicator */ 53 if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) { 54 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr); 55 } 56 57 ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr); 58 if (flg) { 59 if (vlink && vlink->viewer == viewer) { 60 if (vlink->next) { 61 ierr = MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);CHKERRQ(ierr); 62 } else { 63 ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);CHKERRQ(ierr); 64 } 65 ierr = PetscFree(vlink);CHKERRQ(ierr); 66 } else { 67 while (vlink && vlink->next) { 68 if (vlink->next->viewer == viewer) { 69 PetscViewerLink *nv = vlink->next; 70 vlink->next = vlink->next->next; 71 ierr = PetscFree(nv);CHKERRQ(ierr); 72 } 73 vlink = vlink->next; 74 } 75 } 76 } 77 78 if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) { 79 PetscViewer aviewer; 80 ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);CHKERRQ(ierr); 81 if (flg && aviewer == viewer) { 82 ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);CHKERRQ(ierr); 83 } 84 } 85 if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) { 86 PetscViewer aviewer; 87 ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);CHKERRQ(ierr); 88 if (flg && aviewer == viewer) { 89 ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);CHKERRQ(ierr); 90 } 91 } 92 PetscFunctionReturn(0); 93 } 94 95 PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer) 96 { 97 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 98 PetscErrorCode ierr; 99 100 PetscFunctionBegin; 101 ierr = PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);CHKERRQ(ierr); 102 PetscFunctionReturn(0); 103 } 104 105 PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer) 106 { 107 PetscErrorCode ierr; 108 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 109 int err; 110 MPI_Comm comm; 111 PetscMPIInt rank,size; 112 FILE *fd = vascii->fd; 113 114 PetscFunctionBegin; 115 if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 116 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 117 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 118 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 119 120 if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) { 121 err = fflush(vascii->fd); 122 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed"); 123 } 124 125 if (vascii->allowsynchronized) { 126 PetscMPIInt tag,i,j,n = 0,dummy = 0; 127 char *message; 128 MPI_Status status; 129 130 ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr); 131 132 /* First processor waits for messages from all other processors */ 133 if (!rank) { 134 /* flush my own messages that I may have queued up */ 135 PrintfQueue next = vascii->petsc_printfqueuebase,previous; 136 for (i=0; i<vascii->petsc_printfqueuelength; i++) { 137 if (!vascii->bviewer) { 138 ierr = PetscFPrintf(comm,fd,"%s",next->string);CHKERRQ(ierr); 139 } else { 140 ierr = PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);CHKERRQ(ierr); 141 } 142 previous = next; 143 next = next->next; 144 ierr = PetscFree(previous->string);CHKERRQ(ierr); 145 ierr = PetscFree(previous);CHKERRQ(ierr); 146 } 147 vascii->petsc_printfqueue = NULL; 148 vascii->petsc_printfqueuelength = 0; 149 for (i=1; i<size; i++) { 150 /* to prevent a flood of messages to process zero, request each message separately */ 151 ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr); 152 ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 153 for (j=0; j<n; j++) { 154 PetscMPIInt size = 0; 155 156 ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 157 ierr = PetscMalloc1(size, &message);CHKERRQ(ierr); 158 ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr); 159 if (!vascii->bviewer) { 160 ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr); 161 } else { 162 ierr = PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);CHKERRQ(ierr); 163 } 164 ierr = PetscFree(message);CHKERRQ(ierr); 165 } 166 } 167 } else { /* other processors send queue to processor 0 */ 168 PrintfQueue next = vascii->petsc_printfqueuebase,previous; 169 170 ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr); 171 ierr = MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 172 for (i=0; i<vascii->petsc_printfqueuelength; i++) { 173 ierr = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 174 ierr = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr); 175 previous = next; 176 next = next->next; 177 ierr = PetscFree(previous->string);CHKERRQ(ierr); 178 ierr = PetscFree(previous);CHKERRQ(ierr); 179 } 180 vascii->petsc_printfqueue = NULL; 181 vascii->petsc_printfqueuelength = 0; 182 } 183 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 184 } 185 PetscFunctionReturn(0); 186 } 187 188 /*@C 189 PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer. 190 191 Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer 192 193 Input Parameter: 194 . viewer - PetscViewer context, obtained from PetscViewerASCIIOpen() 195 196 Output Parameter: 197 . fd - file pointer 198 199 Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer 200 201 Level: intermediate 202 203 Fortran Note: 204 This routine is not supported in Fortran. 205 206 207 .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(), 208 PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush() 209 @*/ 210 PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd) 211 { 212 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 213 214 PetscFunctionBegin; 215 *fd = vascii->fd; 216 PetscFunctionReturn(0); 217 } 218 219 PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode) 220 { 221 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 222 223 PetscFunctionBegin; 224 *mode = vascii->mode; 225 PetscFunctionReturn(0); 226 } 227 228 PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode) 229 { 230 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 231 232 PetscFunctionBegin; 233 vascii->mode = mode; 234 PetscFunctionReturn(0); 235 } 236 237 /* 238 If petsc_history is on, then all Petsc*Printf() results are saved 239 if the appropriate (usually .petschistory) file. 240 */ 241 PETSC_INTERN FILE *petsc_history; 242 243 /*@ 244 PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times 245 246 Not Collective, but only first processor in set has any effect 247 248 Input Parameters: 249 + viewer - obtained with PetscViewerASCIIOpen() 250 - tabs - number of tabs 251 252 Level: developer 253 254 Fortran Note: 255 This routine is not supported in Fortran. 256 257 258 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(), 259 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 260 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab() 261 @*/ 262 PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs) 263 { 264 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 265 PetscBool iascii; 266 PetscErrorCode ierr; 267 268 PetscFunctionBegin; 269 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 270 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 271 if (iascii) ascii->tab = tabs; 272 PetscFunctionReturn(0); 273 } 274 275 /*@ 276 PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer. 277 278 Not Collective, meaningful on first processor only. 279 280 Input Parameters: 281 . viewer - obtained with PetscViewerASCIIOpen() 282 283 Output Parameters: 284 . tabs - number of tabs 285 286 Level: developer 287 288 Fortran Note: 289 This routine is not supported in Fortran. 290 291 292 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(), 293 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 294 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab() 295 @*/ 296 PetscErrorCode PetscViewerASCIIGetTab(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 && tabs) *tabs = ascii->tab; 306 PetscFunctionReturn(0); 307 } 308 309 /*@ 310 PetscViewerASCIIAddTab - Add to 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 - obtained 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 324 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 325 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 326 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab() 327 @*/ 328 PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs) 329 { 330 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 331 PetscBool iascii; 332 PetscErrorCode ierr; 333 334 PetscFunctionBegin; 335 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 336 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 337 if (iascii) ascii->tab += tabs; 338 PetscFunctionReturn(0); 339 } 340 341 /*@ 342 PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing 343 344 Not Collective, but only first processor in set has any effect 345 346 Input Parameters: 347 + viewer - obtained with PetscViewerASCIIOpen() 348 - tabs - number of tabs 349 350 Level: developer 351 352 Fortran Note: 353 This routine is not supported in Fortran. 354 355 356 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 357 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 358 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab() 359 @*/ 360 PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs) 361 { 362 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 363 PetscBool iascii; 364 PetscErrorCode ierr; 365 366 PetscFunctionBegin; 367 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 368 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 369 if (iascii) ascii->tab -= tabs; 370 PetscFunctionReturn(0); 371 } 372 373 /*@C 374 PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer 375 376 Collective on PetscViewer 377 378 Input Parameters: 379 . viewer - obtained with PetscViewerASCIIOpen() 380 381 Level: intermediate 382 383 Notes: 384 See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly. 385 386 387 .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(), 388 PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(), 389 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType() 390 @*/ 391 PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer) 392 { 393 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 394 PetscBool iascii; 395 PetscErrorCode ierr; 396 397 PetscFunctionBegin; 398 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 399 if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 400 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 401 if (iascii) ascii->allowsynchronized++; 402 PetscFunctionReturn(0); 403 } 404 405 /*@C 406 PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer 407 408 Collective on PetscViewer 409 410 Input Parameters: 411 . viewer - obtained with PetscViewerASCIIOpen() 412 413 Level: intermediate 414 415 Notes: 416 See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly. 417 418 419 .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), 420 PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(), 421 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType() 422 @*/ 423 PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer) 424 { 425 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 426 PetscBool iascii; 427 PetscErrorCode ierr; 428 429 PetscFunctionBegin; 430 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 431 if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 432 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 433 if (iascii) { 434 ascii->allowsynchronized--; 435 if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()"); 436 } 437 PetscFunctionReturn(0); 438 } 439 440 /*@C 441 PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf() 442 lines are tabbed. 443 444 Not Collective, but only first processor in set has any effect 445 446 Input Parameters: 447 . viewer - obtained with PetscViewerASCIIOpen() 448 449 Level: developer 450 451 Fortran Note: 452 This routine is not supported in Fortran. 453 454 455 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 456 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 457 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer() 458 @*/ 459 PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer) 460 { 461 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 462 PetscBool iascii; 463 PetscErrorCode ierr; 464 465 PetscFunctionBegin; 466 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 467 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 468 if (iascii) ascii->tab++; 469 PetscFunctionReturn(0); 470 } 471 472 /*@C 473 PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf() 474 lines are tabbed. 475 476 Not Collective, but only first processor in set has any effect 477 478 Input Parameters: 479 . viewer - obtained with PetscViewerASCIIOpen() 480 481 Level: developer 482 483 Fortran Note: 484 This routine is not supported in Fortran. 485 486 487 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 488 PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(), 489 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer() 490 @*/ 491 PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer) 492 { 493 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 494 PetscErrorCode ierr; 495 PetscBool iascii; 496 497 PetscFunctionBegin; 498 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 499 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 500 if (iascii) { 501 if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed"); 502 ascii->tab--; 503 } 504 PetscFunctionReturn(0); 505 } 506 507 /*@ 508 PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer 509 510 Not Collective, but only first processor in set has any effect 511 512 Input Parameters: 513 + viewer - obtained with PetscViewerASCIIOpen() 514 - flg - PETSC_TRUE or PETSC_FALSE 515 516 Level: developer 517 518 Fortran Note: 519 This routine is not supported in Fortran. 520 521 522 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 523 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(), 524 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer() 525 @*/ 526 PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg) 527 { 528 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 529 PetscBool iascii; 530 PetscErrorCode ierr; 531 532 PetscFunctionBegin; 533 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 534 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 535 if (iascii) { 536 if (flg) ascii->tab = ascii->tab_store; 537 else { 538 ascii->tab_store = ascii->tab; 539 ascii->tab = 0; 540 } 541 } 542 PetscFunctionReturn(0); 543 } 544 545 /* ----------------------------------------------------------------------- */ 546 547 548 /*@C 549 PetscViewerASCIIPrintf - Prints to a file, only from the first 550 processor in the PetscViewer 551 552 Not Collective, but only first processor in set has any effect 553 554 Input Parameters: 555 + viewer - obtained with PetscViewerASCIIOpen() 556 - format - the usual printf() format string 557 558 Level: developer 559 560 Fortran Note: 561 The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran. 562 That is, you can only pass a single character string from Fortran. 563 564 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(), 565 PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), 566 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized() 567 @*/ 568 PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...) 569 { 570 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 571 PetscMPIInt rank; 572 PetscInt tab,intab = ascii->tab; 573 PetscErrorCode ierr; 574 FILE *fd = ascii->fd; 575 PetscBool iascii; 576 int err; 577 578 PetscFunctionBegin; 579 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 580 if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()"); 581 PetscValidCharPointer(format,2); 582 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 583 if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer"); 584 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 585 if (rank) PetscFunctionReturn(0); 586 587 if (ascii->bviewer) { /* pass string up to parent viewer */ 588 char *string; 589 va_list Argp; 590 size_t fullLength; 591 592 ierr = PetscCalloc1(QUEUESTRINGSIZE, &string);CHKERRQ(ierr); 593 va_start(Argp,format); 594 ierr = PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);CHKERRQ(ierr); 595 va_end(Argp); 596 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);CHKERRQ(ierr); 597 ierr = PetscFree(string);CHKERRQ(ierr); 598 } else { /* write directly to file */ 599 va_list Argp; 600 /* flush my own messages that I may have queued up */ 601 PrintfQueue next = ascii->petsc_printfqueuebase,previous; 602 PetscInt i; 603 for (i=0; i<ascii->petsc_printfqueuelength; i++) { 604 ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);CHKERRQ(ierr); 605 previous = next; 606 next = next->next; 607 ierr = PetscFree(previous->string);CHKERRQ(ierr); 608 ierr = PetscFree(previous);CHKERRQ(ierr); 609 } 610 ascii->petsc_printfqueue = NULL; 611 ascii->petsc_printfqueuelength = 0; 612 tab = intab; 613 while (tab--) { 614 ierr = PetscFPrintf(PETSC_COMM_SELF,fd," ");CHKERRQ(ierr); 615 } 616 617 va_start(Argp,format); 618 ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr); 619 err = fflush(fd); 620 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 621 if (petsc_history) { 622 va_start(Argp,format); 623 tab = intab; 624 while (tab--) { 625 ierr = PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");CHKERRQ(ierr); 626 } 627 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 628 err = fflush(petsc_history); 629 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 630 } 631 va_end(Argp); 632 } 633 PetscFunctionReturn(0); 634 } 635 636 /*@C 637 PetscViewerFileSetName - Sets the name of the file the PetscViewer uses. 638 639 Collective on PetscViewer 640 641 Input Parameters: 642 + viewer - the PetscViewer; either ASCII or binary 643 - name - the name of the file it should use 644 645 Level: advanced 646 647 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(), 648 PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 649 650 @*/ 651 PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[]) 652 { 653 PetscErrorCode ierr; 654 char filename[PETSC_MAX_PATH_LEN]; 655 656 PetscFunctionBegin; 657 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 658 PetscValidCharPointer(name,2); 659 ierr = PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename));CHKERRQ(ierr); 660 ierr = PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename));CHKERRQ(ierr); 661 PetscFunctionReturn(0); 662 } 663 664 /*@C 665 PetscViewerFileGetName - Gets the name of the file the PetscViewer uses. 666 667 Not Collective 668 669 Input Parameter: 670 . viewer - the PetscViewer; either ASCII or binary 671 672 Output Parameter: 673 . name - the name of the file it is using 674 675 Level: advanced 676 677 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName() 678 679 @*/ 680 PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name) 681 { 682 PetscErrorCode ierr; 683 684 PetscFunctionBegin; 685 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 686 PetscValidPointer(name,2); 687 ierr = PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));CHKERRQ(ierr); 688 PetscFunctionReturn(0); 689 } 690 691 PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name) 692 { 693 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 694 695 PetscFunctionBegin; 696 *name = vascii->filename; 697 PetscFunctionReturn(0); 698 } 699 700 PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[]) 701 { 702 PetscErrorCode ierr; 703 size_t len; 704 char fname[PETSC_MAX_PATH_LEN],*gz; 705 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 706 PetscBool isstderr,isstdout; 707 PetscMPIInt rank; 708 709 PetscFunctionBegin; 710 ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr); 711 if (!name) PetscFunctionReturn(0); 712 ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr); 713 714 /* Is this file to be compressed */ 715 vascii->storecompressed = PETSC_FALSE; 716 717 ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr); 718 if (gz) { 719 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 720 if (len == 3) { 721 if (vascii->mode != FILE_MODE_WRITE) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first"); 722 *gz = 0; 723 vascii->storecompressed = PETSC_TRUE; 724 } 725 } 726 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 727 if (!rank) { 728 ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr); 729 ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr); 730 /* empty filename means stdout */ 731 if (name[0] == 0) isstdout = PETSC_TRUE; 732 if (isstderr) vascii->fd = PETSC_STDERR; 733 else if (isstdout) vascii->fd = PETSC_STDOUT; 734 else { 735 736 737 ierr = PetscFixFilename(name,fname);CHKERRQ(ierr); 738 switch (vascii->mode) { 739 case FILE_MODE_READ: 740 vascii->fd = fopen(fname,"r"); 741 break; 742 case FILE_MODE_WRITE: 743 vascii->fd = fopen(fname,"w"); 744 break; 745 case FILE_MODE_APPEND: 746 vascii->fd = fopen(fname,"a"); 747 break; 748 case FILE_MODE_UPDATE: 749 vascii->fd = fopen(fname,"r+"); 750 if (!vascii->fd) vascii->fd = fopen(fname,"w+"); 751 break; 752 case FILE_MODE_APPEND_UPDATE: 753 /* I really want a file which is opened at the end for updating, 754 not a+, which opens at the beginning, but makes writes at the end. 755 */ 756 vascii->fd = fopen(fname,"r+"); 757 if (!vascii->fd) vascii->fd = fopen(fname,"w+"); 758 else { 759 ierr = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr); 760 } 761 break; 762 default: 763 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode); 764 } 765 if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname); 766 } 767 } 768 #if defined(PETSC_USE_LOG) 769 PetscLogObjectState((PetscObject)viewer,"File: %s",name); 770 #endif 771 PetscFunctionReturn(0); 772 } 773 774 PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer) 775 { 776 PetscErrorCode ierr; 777 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii; 778 779 PetscFunctionBegin; 780 ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 781 if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored"); 782 /* 783 The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work 784 because it relies on this behavior in other places. In particular this line causes the synchronized flush to occur when the viewer is destroyed 785 (since the count never gets to zero) in some examples this displays information that otherwise would be lost 786 787 This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example, 788 PCView_GASM(). 789 */ 790 ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 791 ierr = PetscViewerCreate(subcomm,outviewer);CHKERRQ(ierr); 792 ierr = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr); 793 ierr = PetscViewerASCIIPushSynchronized(*outviewer);CHKERRQ(ierr); 794 ovascii = (PetscViewer_ASCII*)(*outviewer)->data; 795 ovascii->fd = vascii->fd; 796 ovascii->tab = vascii->tab; 797 ovascii->closefile = PETSC_FALSE; 798 799 vascii->sviewer = *outviewer; 800 801 (*outviewer)->format = viewer->format; 802 803 ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer; 804 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer; 805 PetscFunctionReturn(0); 806 } 807 808 PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer) 809 { 810 PetscErrorCode ierr; 811 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 812 813 PetscFunctionBegin; 814 if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer"); 815 if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer"); 816 817 ierr = PetscViewerASCIIPopSynchronized(*outviewer);CHKERRQ(ierr); 818 ascii->sviewer = NULL; 819 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII; 820 ierr = PetscViewerDestroy(outviewer);CHKERRQ(ierr); 821 ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 822 PetscFunctionReturn(0); 823 } 824 825 PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer) 826 { 827 PetscErrorCode ierr; 828 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data; 829 830 PetscFunctionBegin; 831 if (ascii->filename) { 832 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr); 833 } 834 PetscFunctionReturn(0); 835 } 836 837 /*MC 838 PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file 839 840 841 .seealso: PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(), 842 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB, 843 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType() 844 845 Level: beginner 846 847 M*/ 848 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer) 849 { 850 PetscViewer_ASCII *vascii; 851 PetscErrorCode ierr; 852 853 PetscFunctionBegin; 854 ierr = PetscNewLog(viewer,&vascii);CHKERRQ(ierr); 855 viewer->data = (void*)vascii; 856 857 viewer->ops->destroy = PetscViewerDestroy_ASCII; 858 viewer->ops->flush = PetscViewerFlush_ASCII; 859 viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII; 860 viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII; 861 viewer->ops->view = PetscViewerView_ASCII; 862 viewer->ops->read = PetscViewerASCIIRead; 863 864 /* defaults to stdout unless set with PetscViewerFileSetName() */ 865 vascii->fd = PETSC_STDOUT; 866 vascii->mode = FILE_MODE_WRITE; 867 vascii->bviewer = NULL; 868 vascii->subviewer = NULL; 869 vascii->sviewer = NULL; 870 vascii->tab = 0; 871 vascii->tab_store = 0; 872 vascii->filename = NULL; 873 vascii->closefile = PETSC_TRUE; 874 875 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr); 876 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr); 877 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr); 878 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr); 879 PetscFunctionReturn(0); 880 } 881 882 /*@C 883 PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from 884 several processors. Output of the first processor is followed by that of the 885 second, etc. 886 887 Not Collective, must call collective PetscViewerFlush() to get the results out 888 889 Input Parameters: 890 + viewer - the ASCII PetscViewer 891 - format - the usual printf() format string 892 893 Level: intermediate 894 895 Notes: 896 You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called. 897 Then you can do multiple independent calls to this routine. 898 The actual synchronized print is then done using PetscViewerFlush(). 899 PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output 900 to conclude the "synchronized session". 901 So the typical calling sequence looks like 902 $ PetscViewerASCIIPushSynchronized(viewer); 903 $ PetscViewerASCIISynchronizedPrintf(viewer, ...); 904 $ PetscViewerASCIISynchronizedPrintf(viewer, ...); 905 $ ... 906 $ PetscViewerFlush(viewer); 907 $ PetscViewerASCIISynchronizedPrintf(viewer, ...); 908 $ PetscViewerASCIISynchronizedPrintf(viewer, ...); 909 $ ... 910 $ PetscViewerFlush(viewer); 911 $ PetscViewerASCIIPopSynchronized(viewer); 912 913 Fortran Note: 914 Can only print a single character* string 915 916 .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(), 917 PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(), 918 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType() 919 @*/ 920 PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...) 921 { 922 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 923 PetscErrorCode ierr; 924 PetscMPIInt rank; 925 PetscInt tab = vascii->tab; 926 MPI_Comm comm; 927 FILE *fp; 928 PetscBool iascii,hasbviewer = PETSC_FALSE; 929 int err; 930 931 PetscFunctionBegin; 932 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 933 PetscValidCharPointer(format,2); 934 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 935 if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer"); 936 if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call"); 937 938 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 939 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 940 941 if (vascii->bviewer) { 942 hasbviewer = PETSC_TRUE; 943 if (!rank) { 944 vascii = (PetscViewer_ASCII*)vascii->bviewer->data; 945 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 946 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 947 } 948 } 949 950 fp = vascii->fd; 951 952 if (!rank && !hasbviewer) { /* First processor prints immediately to fp */ 953 va_list Argp; 954 /* flush my own messages that I may have queued up */ 955 PrintfQueue next = vascii->petsc_printfqueuebase,previous; 956 PetscInt i; 957 for (i=0; i<vascii->petsc_printfqueuelength; i++) { 958 ierr = PetscFPrintf(comm,fp,"%s",next->string);CHKERRQ(ierr); 959 previous = next; 960 next = next->next; 961 ierr = PetscFree(previous->string);CHKERRQ(ierr); 962 ierr = PetscFree(previous);CHKERRQ(ierr); 963 } 964 vascii->petsc_printfqueue = NULL; 965 vascii->petsc_printfqueuelength = 0; 966 967 while (tab--) { 968 ierr = PetscFPrintf(PETSC_COMM_SELF,fp," ");CHKERRQ(ierr); 969 } 970 971 va_start(Argp,format); 972 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 973 err = fflush(fp); 974 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 975 if (petsc_history) { 976 va_start(Argp,format); 977 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 978 err = fflush(petsc_history); 979 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 980 } 981 va_end(Argp); 982 } else { /* other processors add to queue */ 983 char *string; 984 va_list Argp; 985 size_t fullLength; 986 PrintfQueue next; 987 988 ierr = PetscNew(&next);CHKERRQ(ierr); 989 if (vascii->petsc_printfqueue) { 990 vascii->petsc_printfqueue->next = next; 991 vascii->petsc_printfqueue = next; 992 } else { 993 vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next; 994 } 995 vascii->petsc_printfqueuelength++; 996 next->size = QUEUESTRINGSIZE; 997 ierr = PetscCalloc1(next->size, &next->string);CHKERRQ(ierr); 998 string = next->string; 999 tab *= 2; 1000 while (tab--) { 1001 *string++ = ' '; 1002 } 1003 va_start(Argp,format); 1004 ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr); 1005 va_end(Argp); 1006 if (fullLength > (size_t) (next->size-2*vascii->tab)) { 1007 ierr = PetscFree(next->string);CHKERRQ(ierr); 1008 next->size = fullLength + 2*vascii->tab; 1009 ierr = PetscCalloc1(next->size, &next->string);CHKERRQ(ierr); 1010 string = next->string; 1011 tab = 2*vascii->tab; 1012 while (tab--) { 1013 *string++ = ' '; 1014 } 1015 va_start(Argp,format); 1016 ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);CHKERRQ(ierr); 1017 va_end(Argp); 1018 } 1019 } 1020 PetscFunctionReturn(0); 1021 } 1022 1023 /*@C 1024 PetscViewerASCIIRead - Reads from a ASCII file 1025 1026 Only process 0 in the PetscViewer may call this 1027 1028 Input Parameters: 1029 + viewer - the ascii viewer 1030 . data - location to write the data 1031 . num - number of items of data to read 1032 - datatype - type of data to read 1033 1034 Output Parameters: 1035 . count - number of items of data actually read, or NULL 1036 1037 Level: beginner 1038 1039 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName() 1040 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 1041 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead() 1042 @*/ 1043 PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype) 1044 { 1045 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 1046 FILE *fd = vascii->fd; 1047 PetscInt i; 1048 int ret = 0; 1049 PetscMPIInt rank; 1050 PetscErrorCode ierr; 1051 1052 PetscFunctionBegin; 1053 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1054 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1055 if (rank) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer"); 1056 for (i=0; i<num; i++) { 1057 if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char*)data)[i])); 1058 else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char*)data)[i])); 1059 else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt*)data)[i])); 1060 else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int*)data)[i])); 1061 else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64*)data)[i])); 1062 else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long*)data)[i])); 1063 else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float*)data)[i])); 1064 else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double*)data)[i])); 1065 #if defined(PETSC_USE_REAL___FLOAT128) 1066 else if (dtype == PETSC___FLOAT128) { 1067 double tmp; 1068 ret = fscanf(fd, "%lg", &tmp); 1069 ((__float128*)data)[i] = tmp; 1070 } 1071 #endif 1072 else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype); 1073 if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype); 1074 else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */ 1075 } 1076 if (count) *count = i; 1077 else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num); 1078 PetscFunctionReturn(0); 1079 } 1080