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