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 PetscMPIInt rank; 777 PetscErrorCode ierr; 778 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii; 779 780 PetscFunctionBegin; 781 ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 782 if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored"); 783 /* 784 The following line is a bug; but if it is removed the code won't work because it relies on this behavior. In particular 785 this line causes the synchronized flush to occur when the viewer is destroyed (since the count never gets to zero) 786 in some examples this displays information that otherwise would be lost 787 */ 788 ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 789 ierr = PetscViewerCreate(subcomm,outviewer);CHKERRQ(ierr); 790 ierr = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr); 791 ierr = PetscViewerASCIIPushSynchronized(*outviewer);CHKERRQ(ierr); 792 ovascii = (PetscViewer_ASCII*)(*outviewer)->data; 793 ovascii->fd = vascii->fd; 794 ovascii->tab = vascii->tab; 795 ovascii->closefile = PETSC_FALSE; 796 797 vascii->sviewer = *outviewer; 798 799 (*outviewer)->format = viewer->format; 800 801 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 802 ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer; 803 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer; 804 PetscFunctionReturn(0); 805 } 806 807 PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer) 808 { 809 PetscErrorCode ierr; 810 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data; 811 812 PetscFunctionBegin; 813 if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer"); 814 if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer"); 815 816 ascii->sviewer = NULL; 817 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII; 818 ierr = PetscViewerDestroy(outviewer);CHKERRQ(ierr); 819 ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 820 PetscFunctionReturn(0); 821 } 822 823 PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer) 824 { 825 PetscErrorCode ierr; 826 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data; 827 828 PetscFunctionBegin; 829 if (ascii->filename) { 830 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr); 831 } 832 PetscFunctionReturn(0); 833 } 834 835 /*MC 836 PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file 837 838 839 .seealso: PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(), 840 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB, 841 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType() 842 843 Level: beginner 844 845 M*/ 846 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer) 847 { 848 PetscViewer_ASCII *vascii; 849 PetscErrorCode ierr; 850 851 PetscFunctionBegin; 852 ierr = PetscNewLog(viewer,&vascii);CHKERRQ(ierr); 853 viewer->data = (void*)vascii; 854 855 viewer->ops->destroy = PetscViewerDestroy_ASCII; 856 viewer->ops->flush = PetscViewerFlush_ASCII; 857 viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII; 858 viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII; 859 viewer->ops->view = PetscViewerView_ASCII; 860 viewer->ops->read = PetscViewerASCIIRead; 861 862 /* defaults to stdout unless set with PetscViewerFileSetName() */ 863 vascii->fd = PETSC_STDOUT; 864 vascii->mode = FILE_MODE_WRITE; 865 vascii->bviewer = NULL; 866 vascii->subviewer = NULL; 867 vascii->sviewer = NULL; 868 vascii->tab = 0; 869 vascii->tab_store = 0; 870 vascii->filename = NULL; 871 vascii->closefile = PETSC_TRUE; 872 873 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr); 874 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr); 875 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr); 876 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr); 877 PetscFunctionReturn(0); 878 } 879 880 /*@C 881 PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from 882 several processors. Output of the first processor is followed by that of the 883 second, etc. 884 885 Not Collective, must call collective PetscViewerFlush() to get the results out 886 887 Input Parameters: 888 + viewer - the ASCII PetscViewer 889 - format - the usual printf() format string 890 891 Level: intermediate 892 893 Notes: 894 You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called. 895 Then you can do multiple independent calls to this routine. 896 The actual synchronized print is then done using PetscViewerFlush(). 897 PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output 898 to conclude the "synchronized session". 899 So the typical calling sequence looks like 900 $ PetscViewerASCIIPushSynchronized(viewer); 901 $ PetscViewerASCIISynchronizedPrintf(viewer, ...); 902 $ PetscViewerASCIISynchronizedPrintf(viewer, ...); 903 $ ... 904 $ PetscViewerFlush(viewer); 905 $ PetscViewerASCIISynchronizedPrintf(viewer, ...); 906 $ PetscViewerASCIISynchronizedPrintf(viewer, ...); 907 $ ... 908 $ PetscViewerFlush(viewer); 909 $ PetscViewerASCIIPopSynchronized(viewer); 910 911 Fortran Note: 912 Can only print a single character* string 913 914 .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(), 915 PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(), 916 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType() 917 @*/ 918 PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...) 919 { 920 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 921 PetscErrorCode ierr; 922 PetscMPIInt rank; 923 PetscInt tab = vascii->tab; 924 MPI_Comm comm; 925 FILE *fp; 926 PetscBool iascii,hasbviewer = PETSC_FALSE; 927 int err; 928 929 PetscFunctionBegin; 930 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 931 PetscValidCharPointer(format,2); 932 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 933 if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer"); 934 if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call"); 935 936 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 937 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 938 939 if (vascii->bviewer) { 940 hasbviewer = PETSC_TRUE; 941 if (!rank) { 942 vascii = (PetscViewer_ASCII*)vascii->bviewer->data; 943 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 944 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 945 } 946 } 947 948 fp = vascii->fd; 949 950 if (!rank && !hasbviewer) { /* First processor prints immediately to fp */ 951 va_list Argp; 952 /* flush my own messages that I may have queued up */ 953 PrintfQueue next = vascii->petsc_printfqueuebase,previous; 954 PetscInt i; 955 for (i=0; i<vascii->petsc_printfqueuelength; i++) { 956 ierr = PetscFPrintf(comm,fp,"%s",next->string);CHKERRQ(ierr); 957 previous = next; 958 next = next->next; 959 ierr = PetscFree(previous->string);CHKERRQ(ierr); 960 ierr = PetscFree(previous);CHKERRQ(ierr); 961 } 962 vascii->petsc_printfqueue = NULL; 963 vascii->petsc_printfqueuelength = 0; 964 965 while (tab--) { 966 ierr = PetscFPrintf(PETSC_COMM_SELF,fp," ");CHKERRQ(ierr); 967 } 968 969 va_start(Argp,format); 970 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 971 err = fflush(fp); 972 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 973 if (petsc_history) { 974 va_start(Argp,format); 975 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 976 err = fflush(petsc_history); 977 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 978 } 979 va_end(Argp); 980 } else { /* other processors add to queue */ 981 char *string; 982 va_list Argp; 983 size_t fullLength; 984 PrintfQueue next; 985 986 ierr = PetscNew(&next);CHKERRQ(ierr); 987 if (vascii->petsc_printfqueue) { 988 vascii->petsc_printfqueue->next = next; 989 vascii->petsc_printfqueue = next; 990 } else { 991 vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next; 992 } 993 vascii->petsc_printfqueuelength++; 994 next->size = QUEUESTRINGSIZE; 995 ierr = PetscCalloc1(next->size, &next->string);CHKERRQ(ierr); 996 string = next->string; 997 tab *= 2; 998 while (tab--) { 999 *string++ = ' '; 1000 } 1001 va_start(Argp,format); 1002 ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr); 1003 va_end(Argp); 1004 if (fullLength > (size_t) (next->size-2*vascii->tab)) { 1005 ierr = PetscFree(next->string);CHKERRQ(ierr); 1006 next->size = fullLength + 2*vascii->tab; 1007 ierr = PetscCalloc1(next->size, &next->string);CHKERRQ(ierr); 1008 string = next->string; 1009 tab = 2*vascii->tab; 1010 while (tab--) { 1011 *string++ = ' '; 1012 } 1013 va_start(Argp,format); 1014 ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);CHKERRQ(ierr); 1015 va_end(Argp); 1016 } 1017 } 1018 PetscFunctionReturn(0); 1019 } 1020 1021 /*@C 1022 PetscViewerASCIIRead - Reads from a ASCII file 1023 1024 Only process 0 in the PetscViewer may call this 1025 1026 Input Parameters: 1027 + viewer - the ascii viewer 1028 . data - location to write the data 1029 . num - number of items of data to read 1030 - datatype - type of data to read 1031 1032 Output Parameters: 1033 . count - number of items of data actually read, or NULL 1034 1035 Level: beginner 1036 1037 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName() 1038 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 1039 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead() 1040 @*/ 1041 PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype) 1042 { 1043 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 1044 FILE *fd = vascii->fd; 1045 PetscInt i; 1046 int ret = 0; 1047 PetscMPIInt rank; 1048 PetscErrorCode ierr; 1049 1050 PetscFunctionBegin; 1051 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1052 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1053 if (rank) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer"); 1054 for (i=0; i<num; i++) { 1055 if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char*)data)[i])); 1056 else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char*)data)[i])); 1057 else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt*)data)[i])); 1058 else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int*)data)[i])); 1059 else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64*)data)[i])); 1060 else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long*)data)[i])); 1061 else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float*)data)[i])); 1062 else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double*)data)[i])); 1063 #if defined(PETSC_USE_REAL___FLOAT128) 1064 else if (dtype == PETSC___FLOAT128) { 1065 double tmp; 1066 ret = fscanf(fd, "%lg", &tmp); 1067 ((__float128*)data)[i] = tmp; 1068 } 1069 #endif 1070 else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype); 1071 if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype); 1072 else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */ 1073 } 1074 if (count) *count = i; 1075 else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num); 1076 PetscFunctionReturn(0); 1077 } 1078