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