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