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