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