Actual source code: hdf5v.c

petsc-3.5.0 2014-06-30
Report Typos and Errors
  1: #include <petsc-private/viewerimpl.h>    /*I   "petscsys.h"   I*/
  2: #include <petscviewerhdf5.h>    /*I   "petscviewerhdf5.h"   I*/

  4: typedef struct GroupList {
  5:   const char       *name;
  6:   struct GroupList *next;
  7: } GroupList;

  9: typedef struct {
 10:   char          *filename;
 11:   PetscFileMode btype;
 12:   hid_t         file_id;
 13:   PetscInt      timestep;
 14:   GroupList     *groups;
 15: } PetscViewer_HDF5;

 19: static PetscErrorCode PetscViewerFileClose_HDF5(PetscViewer viewer)
 20: {
 21:   PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*)viewer->data;
 22:   PetscErrorCode   ierr;

 25:   PetscFree(hdf5->filename);
 26:   if (hdf5->file_id) H5Fclose(hdf5->file_id);
 27:   return(0);
 28: }

 32: PetscErrorCode PetscViewerDestroy_HDF5(PetscViewer viewer)
 33: {
 34:   PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*) viewer->data;
 35:   PetscErrorCode   ierr;

 38:   PetscViewerFileClose_HDF5(viewer);
 39:   while (hdf5->groups) {
 40:     GroupList *tmp = hdf5->groups->next;

 42:     PetscFree(hdf5->groups->name);
 43:     PetscFree(hdf5->groups);
 44:     hdf5->groups = tmp;
 45:   }
 46:   PetscFree(hdf5);
 47:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",NULL);
 48:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",NULL);
 49:   return(0);
 50: }

 54: PetscErrorCode  PetscViewerFileSetMode_HDF5(PetscViewer viewer, PetscFileMode type)
 55: {
 56:   PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*) viewer->data;

 60:   hdf5->btype = type;
 61:   return(0);
 62: }

 66: PetscErrorCode  PetscViewerFileSetName_HDF5(PetscViewer viewer, const char name[])
 67: {
 68:   PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*) viewer->data;
 69: #if defined(PETSC_HAVE_H5PSET_FAPL_MPIO)
 70:   MPI_Info          info = MPI_INFO_NULL;
 71: #endif
 72:   hid_t             plist_id;
 73:   herr_t            herr;
 74:   PetscErrorCode    ierr;

 77:   PetscStrallocpy(name, &hdf5->filename);
 78:   /* Set up file access property list with parallel I/O access */
 79:   plist_id = H5Pcreate(H5P_FILE_ACCESS);
 80: #if defined(PETSC_HAVE_H5PSET_FAPL_MPIO)
 81:   herr = H5Pset_fapl_mpio(plist_id, PetscObjectComm((PetscObject)viewer), info);CHKERRQ(herr);
 82: #endif
 83:   /* Create or open the file collectively */
 84:   switch (hdf5->btype) {
 85:   case FILE_MODE_READ:
 86:     hdf5->file_id = H5Fopen(name, H5F_ACC_RDONLY, plist_id);
 87:     break;
 88:   case FILE_MODE_APPEND:
 89:     hdf5->file_id = H5Fopen(name, H5F_ACC_RDWR, plist_id);
 90:     break;
 91:   case FILE_MODE_WRITE:
 92:     hdf5->file_id = H5Fcreate(name, H5F_ACC_TRUNC, H5P_DEFAULT, plist_id);
 93:     break;
 94:   default:
 95:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER, "Must call PetscViewerFileSetMode() before PetscViewerFileSetName()");
 96:   }
 97:   if (hdf5->file_id < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB, "H5Fcreate failed for %s", name);
 98:   H5Pclose(plist_id);
 99:   return(0);
100: }

104: PETSC_EXTERN PetscErrorCode PetscViewerCreate_HDF5(PetscViewer v)
105: {
106:   PetscViewer_HDF5 *hdf5;
107:   PetscErrorCode   ierr;

110:   PetscNewLog(v,&hdf5);

112:   v->data         = (void*) hdf5;
113:   v->ops->destroy = PetscViewerDestroy_HDF5;
114:   v->ops->flush   = 0;
115:   hdf5->btype     = (PetscFileMode) -1;
116:   hdf5->filename  = 0;
117:   hdf5->timestep  = -1;
118:   hdf5->groups    = NULL;

120:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_HDF5);
121:   PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_HDF5);
122:   return(0);
123: }

127: /*@C
128:    PetscViewerHDF5Open - Opens a file for HDF5 input/output.

130:    Collective on MPI_Comm

132:    Input Parameters:
133: +  comm - MPI communicator
134: .  name - name of file
135: -  type - type of file
136: $    FILE_MODE_WRITE - create new file for binary output
137: $    FILE_MODE_READ - open existing file for binary input
138: $    FILE_MODE_APPEND - open existing file for binary output

140:    Output Parameter:
141: .  hdf5v - PetscViewer for HDF5 input/output to use with the specified file

143:    Level: beginner

145:    Note:
146:    This PetscViewer should be destroyed with PetscViewerDestroy().

148:    Concepts: HDF5 files
149:    Concepts: PetscViewerHDF5^creating

151: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
152:           VecView(), MatView(), VecLoad(), MatLoad(),
153:           PetscFileMode, PetscViewer
154: @*/
155: PetscErrorCode  PetscViewerHDF5Open(MPI_Comm comm, const char name[], PetscFileMode type, PetscViewer *hdf5v)
156: {

160:   PetscViewerCreate(comm, hdf5v);
161:   PetscViewerSetType(*hdf5v, PETSCVIEWERHDF5);
162:   PetscViewerFileSetMode(*hdf5v, type);
163:   PetscViewerFileSetName(*hdf5v, name);
164:   return(0);
165: }

169: /*@C
170:   PetscViewerHDF5GetFileId - Retrieve the file id, this file ID then can be used in direct HDF5 calls

172:   Not collective

174:   Input Parameter:
175: . viewer - the PetscViewer

177:   Output Parameter:
178: . file_id - The file id

180:   Level: intermediate

182: .seealso: PetscViewerHDF5Open()
183: @*/
184: PetscErrorCode  PetscViewerHDF5GetFileId(PetscViewer viewer, hid_t *file_id)
185: {
186:   PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*) viewer->data;

190:   if (file_id) *file_id = hdf5->file_id;
191:   return(0);
192: }

196: /*@C
197:   PetscViewerHDF5PushGroup - Set the current HDF5 group for output

199:   Not collective

201:   Input Parameters:
202: + viewer - the PetscViewer
203: - name - The group name

205:   Level: intermediate

207: .seealso: PetscViewerHDF5Open(),PetscViewerHDF5PopGroup(),PetscViewerHDF5GetGroup()
208: @*/
209: PetscErrorCode  PetscViewerHDF5PushGroup(PetscViewer viewer, const char *name)
210: {
211:   PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*) viewer->data;
212:   GroupList        *groupNode;
213:   PetscErrorCode   ierr;

218:   PetscMalloc(sizeof(GroupList), &groupNode);
219:   PetscStrallocpy(name, (char**) &groupNode->name);

221:   groupNode->next = hdf5->groups;
222:   hdf5->groups    = groupNode;
223:   return(0);
224: }

228: /*@
229:   PetscViewerHDF5PopGroup - Return the current HDF5 group for output to the previous value

231:   Not collective

233:   Input Parameter:
234: . viewer - the PetscViewer

236:   Level: intermediate

238: .seealso: PetscViewerHDF5Open(),PetscViewerHDF5PushGroup(),PetscViewerHDF5GetGroup()
239: @*/
240: PetscErrorCode  PetscViewerHDF5PopGroup(PetscViewer viewer)
241: {
242:   PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*) viewer->data;
243:   GroupList        *groupNode;
244:   PetscErrorCode   ierr;

248:   if (!hdf5->groups) SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_ARG_WRONGSTATE, "HDF5 group stack is empty, cannot pop");
249:   groupNode    = hdf5->groups;
250:   hdf5->groups = hdf5->groups->next;
251:   PetscFree(groupNode->name);
252:   PetscFree(groupNode);
253:   return(0);
254: }

258: /*@C
259:   PetscViewerHDF5GetGroup - Get the current HDF5 group for output. If none has been assigned, returns NULL.

261:   Not collective

263:   Input Parameter:
264: . viewer - the PetscViewer

266:   Output Parameter:
267: . name - The group name

269:   Level: intermediate

271: .seealso: PetscViewerHDF5Open(),PetscViewerHDF5PushGroup(),PetscViewerHDF5PopGroup()
272: @*/
273: PetscErrorCode  PetscViewerHDF5GetGroup(PetscViewer viewer, const char **name)
274: {
275:   PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5 *) viewer->data;

280:   if (hdf5->groups) *name = hdf5->groups->name;
281:   else *name = NULL;
282:   return(0);
283: }

287: /*@
288:   PetscViewerHDF5IncrementTimestep - Increments the current timestep for the HDF5 output. Fields are stacked in time.

290:   Not collective

292:   Input Parameter:
293: . viewer - the PetscViewer

295:   Level: intermediate

297: .seealso: PetscViewerHDF5Open(), PetscViewerHDF5SetTimestep(), PetscViewerHDF5GetTimestep()
298: @*/
299: PetscErrorCode PetscViewerHDF5IncrementTimestep(PetscViewer viewer)
300: {
301:   PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*) viewer->data;

305:   ++hdf5->timestep;
306:   return(0);
307: }

311: /*@
312:   PetscViewerHDF5SetTimestep - Set the current timestep for the HDF5 output. Fields are stacked in time. A timestep
313:   of -1 disables blocking with timesteps.

315:   Not collective

317:   Input Parameters:
318: + viewer - the PetscViewer
319: - timestep - The timestep number

321:   Level: intermediate

323: .seealso: PetscViewerHDF5Open(), PetscViewerHDF5IncrementTimestep(), PetscViewerHDF5GetTimestep()
324: @*/
325: PetscErrorCode  PetscViewerHDF5SetTimestep(PetscViewer viewer, PetscInt timestep)
326: {
327:   PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*) viewer->data;

331:   hdf5->timestep = timestep;
332:   return(0);
333: }

337: /*@
338:   PetscViewerHDF5GetTimestep - Get the current timestep for the HDF5 output. Fields are stacked in time.

340:   Not collective

342:   Input Parameter:
343: . viewer - the PetscViewer

345:   Output Parameter:
346: . timestep - The timestep number

348:   Level: intermediate

350: .seealso: PetscViewerHDF5Open(), PetscViewerHDF5IncrementTimestep(), PetscViewerHDF5SetTimestep()
351: @*/
352: PetscErrorCode  PetscViewerHDF5GetTimestep(PetscViewer viewer, PetscInt *timestep)
353: {
354:   PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*) viewer->data;

359:   *timestep = hdf5->timestep;
360:   return(0);
361: }


366: /*@C
367:   PetscDataTypeToHDF5DataType - Converts the PETSc name of a datatype to its HDF5 name.

369:   Not collective

371:   Input Parameter:
372: . ptype - the PETSc datatype name (for example PETSC_DOUBLE)

374:   Output Parameter:
375: . mtype - the MPI datatype (for example MPI_DOUBLE, ...)

377:   Level: advanced

379: .seealso: PetscDataType, PetscHDF5DataTypeToPetscDataType()
380: @*/
381: PetscErrorCode PetscDataTypeToHDF5DataType(PetscDataType ptype, hid_t *htype)
382: {
384:   if (ptype == PETSC_INT)
385: #if defined(PETSC_USE_64BIT_INDICES)
386:                                        *htype = H5T_NATIVE_LLONG;
387: #else
388:                                        *htype = H5T_NATIVE_INT;
389: #endif
390:   else if (ptype == PETSC_DOUBLE)      *htype = H5T_NATIVE_DOUBLE;
391:   else if (ptype == PETSC_LONG)        *htype = H5T_NATIVE_LONG;
392:   else if (ptype == PETSC_SHORT)       *htype = H5T_NATIVE_SHORT;
393:   else if (ptype == PETSC_ENUM)        *htype = H5T_NATIVE_DOUBLE;
394:   else if (ptype == PETSC_BOOL)        *htype = H5T_NATIVE_DOUBLE;
395:   else if (ptype == PETSC_FLOAT)       *htype = H5T_NATIVE_FLOAT;
396:   else if (ptype == PETSC_CHAR)        *htype = H5T_NATIVE_CHAR;
397:   else if (ptype == PETSC_BIT_LOGICAL) *htype = H5T_NATIVE_UCHAR;
398:   else if (ptype == PETSC_STRING)      *htype = H5Tcopy(H5T_C_S1);
399:   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unsupported PETSc datatype");
400:   return(0);
401: }

405: /*@C
406:   PetscHDF5DataTypeToPetscDataType - Finds the PETSc name of a datatype from its HDF5 name

408:   Not collective

410:   Input Parameter:
411: . htype - the HDF5 datatype (for example H5T_NATIVE_DOUBLE, ...)

413:   Output Parameter:
414: . ptype - the PETSc datatype name (for example PETSC_DOUBLE)

416:   Level: advanced

418: .seealso: PetscDataType, PetscHDF5DataTypeToPetscDataType()
419: @*/
420: PetscErrorCode PetscHDF5DataTypeToPetscDataType(hid_t htype, PetscDataType *ptype)
421: {
423: #if defined(PETSC_USE_64BIT_INDICES)
424:   if      (htype == H5T_NATIVE_INT)    *ptype = PETSC_LONG;
425:   else if (htype == H5T_NATIVE_LLONG)  *ptype = PETSC_INT;
426: #else
427:   if      (htype == H5T_NATIVE_INT)    *ptype = PETSC_INT;
428: #endif
429:   else if (htype == H5T_NATIVE_DOUBLE) *ptype = PETSC_DOUBLE;
430:   else if (htype == H5T_NATIVE_LONG)   *ptype = PETSC_LONG;
431:   else if (htype == H5T_NATIVE_SHORT)  *ptype = PETSC_SHORT;
432:   else if (htype == H5T_NATIVE_FLOAT)  *ptype = PETSC_FLOAT;
433:   else if (htype == H5T_NATIVE_CHAR)   *ptype = PETSC_CHAR;
434:   else if (htype == H5T_NATIVE_UCHAR)  *ptype = PETSC_CHAR;
435:   else if (htype == H5T_C_S1)          *ptype = PETSC_STRING;
436:   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unsupported HDF5 datatype");
437:   return(0);
438: }

442: /*@
443:  PetscViewerHDF5WriteAttribute - Write a scalar attribute

445:   Input Parameters:
446: + viewer - The HDF5 viewer
447: . parent - The parent name
448: . name   - The attribute name
449: . datatype - The attribute type
450: - value    - The attribute value

452:   Level: advanced

454: .seealso: PetscViewerHDF5Open(), PetscViewerHDF5ReadAttribute(), PetscViewerHDF5HasAttribute()
455: @*/
456: PetscErrorCode PetscViewerHDF5WriteAttribute(PetscViewer viewer, const char parent[], const char name[], PetscDataType datatype, const void *value)
457: {
458:   hid_t          h5, dataspace, dataset, attribute, dtype, status;

466:   PetscDataTypeToHDF5DataType(datatype, &dtype);
467:   if (datatype == PETSC_STRING) {
468:     size_t len;
469:     PetscStrlen((const char *) value, &len);
470:     status = H5Tset_size(dtype, len+1);CHKERRQ(status);
471:   }
472:   PetscViewerHDF5GetFileId(viewer, &h5);
473:   dataspace = H5Screate(H5S_SCALAR);
474:   if (dataspace < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_LIB, "Could not create dataspace for attribute %s of %s", name, parent);
475: #if (H5_VERS_MAJOR * 10000 + H5_VERS_MINOR * 100 + H5_VERS_RELEASE >= 10800)
476:   dataset = H5Dopen2(h5, parent, H5P_DEFAULT);
477:   if (dataset < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_LIB, "Could not open parent dataset for attribute %s of %s", name, parent);
478:   attribute = H5Acreate2(dataset, name, dtype, dataspace, H5P_DEFAULT, H5P_DEFAULT);
479: #else
480:   dataset = H5Dopen(h5, parent);
481:   if (dataset < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_LIB, "Could not open parent dataset for attribute %s of %s", name, parent);
482:   attribute = H5Acreate(dataset, name, dtype, dataspace, H5P_DEFAULT);
483: #endif
484:   if (attribute < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_LIB, "Could not create attribute %s of %s", name, parent);
485:   status = H5Awrite(attribute, dtype, value);CHKERRQ(status);
486:   if (datatype == PETSC_STRING) {status = H5Tclose(dtype);CHKERRQ(status);}
487:   status = H5Aclose(attribute);CHKERRQ(status);
488:   status = H5Dclose(dataset);CHKERRQ(status);
489:   status = H5Sclose(dataspace);CHKERRQ(status);
490:   return(0);
491: }

495: /*@
496:  PetscViewerHDF5ReadAttribute - Read a scalar attribute

498:   Input Parameters:
499: + viewer - The HDF5 viewer
500: . parent - The parent name
501: . name   - The attribute name
502: - datatype - The attribute type

504:   Output Parameter:
505: . value    - The attribute value

507:   Level: advanced

509: .seealso: PetscViewerHDF5Open(), PetscViewerHDF5WriteAttribute(), PetscViewerHDF5HasAttribute()
510: @*/
511: PetscErrorCode PetscViewerHDF5ReadAttribute(PetscViewer viewer, const char parent[], const char name[], PetscDataType datatype, void *value)
512: {
513:   hid_t          h5, dataspace, dataset, attribute, dtype, status;

521:   PetscDataTypeToHDF5DataType(datatype, &dtype);
522:   PetscViewerHDF5GetFileId(viewer, &h5);
523:   dataspace = H5Screate(H5S_SCALAR);
524:   if (dataspace < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_LIB, "Could not create dataspace for attribute %s of %s", name, parent);
525: #if (H5_VERS_MAJOR * 10000 + H5_VERS_MINOR * 100 + H5_VERS_RELEASE >= 10800)
526:   dataset = H5Dopen2(h5, parent, H5P_DEFAULT);
527:   if (dataset < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_LIB, "Could not open parent dataset for attribute %s of %s", name, parent);
528: #else
529:   dataset = H5Dopen(h5, parent);
530:   if (dataset < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_LIB, "Could not open parent dataset for attribute %s of %s", name, parent);
531: #endif
532:   attribute = H5Aopen_name(dataset, name);
533:   if (attribute < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_LIB, "Could not open attribute %s of %s", name, parent);
534:   status = H5Aread(attribute, dtype, value);CHKERRQ(status);
535:   status = H5Aclose(attribute);CHKERRQ(status);
536:   status = H5Dclose(dataset);CHKERRQ(status);
537:   status = H5Sclose(dataspace);CHKERRQ(status);
538:   return(0);
539: }

543: static PetscErrorCode PetscViewerHDF5HasObject(PetscViewer viewer, const char name[], H5O_type_t otype, PetscBool *has)
544: {
545:   hid_t          h5;

552:   *has = PETSC_FALSE;
553:   PetscViewerHDF5GetFileId(viewer, &h5);
554:   if (H5Lexists(h5, name, H5P_DEFAULT)) {
555:     H5O_info_t info;
556:     hid_t      obj;
557:     herr_t     err;

559:     obj = H5Oopen(h5, name, H5P_DEFAULT);if (obj < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_LIB, "Could not open object %s", name);
560:     err = H5Oget_info(obj, &info);CHKERRQ(err);
561:     if (otype == info.type) *has = PETSC_TRUE;
562:     err = H5Oclose(obj);CHKERRQ(err);
563:   }
564:   return(0);
565: }

569: /*@
570:  PetscViewerHDF5HasAttribute - Check whether a scalar attribute exists

572:   Input Parameters:
573: + viewer - The HDF5 viewer
574: . parent - The parent name
575: - name   - The attribute name

577:   Output Parameter:
578: . has    - Flag for attribute existence

580:   Level: advanced

582: .seealso: PetscViewerHDF5Open(), PetscViewerHDF5WriteAttribute(), PetscViewerHDF5ReadAttribute()
583: @*/
584: PetscErrorCode PetscViewerHDF5HasAttribute(PetscViewer viewer, const char parent[], const char name[], PetscBool *has)
585: {
586:   hid_t          h5, dataset, status;
587:   htri_t         hhas;
588:   PetscBool      exists;

596:   *has = PETSC_FALSE;
597:   PetscViewerHDF5GetFileId(viewer, &h5);
598:   PetscViewerHDF5HasObject(viewer, parent, H5O_TYPE_DATASET, &exists);
599:   if (exists) {
600: #if (H5_VERS_MAJOR * 10000 + H5_VERS_MINOR * 100 + H5_VERS_RELEASE >= 10800)
601:     dataset = H5Dopen2(h5, parent, H5P_DEFAULT);
602:     if (dataset < 0) return(0);
603: #else
604:     dataset = H5Dopen(h5, parent);
605:     if (dataset < 0) return(0);
606: #endif
607:     hhas = H5Aexists(dataset, name);
608:     if (hhas < 0) {status = H5Dclose(dataset);CHKERRQ(status); return(0);}
609:     status = H5Dclose(dataset);CHKERRQ(status);
610:     *has = hhas ? PETSC_TRUE : PETSC_FALSE;
611:   }
612:   return(0);
613: }

615: /*
616:   The variable Petsc_Viewer_HDF5_keyval is used to indicate an MPI attribute that
617:   is attached to a communicator, in this case the attribute is a PetscViewer.
618: */
619: static int Petsc_Viewer_HDF5_keyval = MPI_KEYVAL_INVALID;

623: /*@C
624:   PETSC_VIEWER_HDF5_ - Creates an HDF5 PetscViewer shared by all processors in a communicator.

626:   Collective on MPI_Comm

628:   Input Parameter:
629: . comm - the MPI communicator to share the HDF5 PetscViewer

631:   Level: intermediate

633:   Options Database Keys:
634: . -viewer_hdf5_filename <name>

636:   Environmental variables:
637: . PETSC_VIEWER_HDF5_FILENAME

639:   Notes:
640:   Unlike almost all other PETSc routines, PETSC_VIEWER_HDF5_ does not return
641:   an error code.  The HDF5 PetscViewer is usually used in the form
642: $       XXXView(XXX object, PETSC_VIEWER_HDF5_(comm));

644: .seealso: PetscViewerHDF5Open(), PetscViewerCreate(), PetscViewerDestroy()
645: @*/
646: PetscViewer PETSC_VIEWER_HDF5_(MPI_Comm comm)
647: {
649:   PetscBool      flg;
650:   PetscViewer    viewer;
651:   char           fname[PETSC_MAX_PATH_LEN];
652:   MPI_Comm       ncomm;

655:   PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_HDF5_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
656:   if (Petsc_Viewer_HDF5_keyval == MPI_KEYVAL_INVALID) {
657:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_HDF5_keyval,0);
658:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_HDF5_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
659:   }
660:   MPI_Attr_get(ncomm,Petsc_Viewer_HDF5_keyval,(void**)&viewer,(int*)&flg);
661:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_HDF5_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
662:   if (!flg) { /* PetscViewer not yet created */
663:     PetscOptionsGetenv(ncomm,"PETSC_VIEWER_HDF5_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
664:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_HDF5_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
665:     if (!flg) {
666:       PetscStrcpy(fname,"output.h5");
667:       if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_HDF5_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
668:     }
669:     PetscViewerHDF5Open(ncomm,fname,FILE_MODE_WRITE,&viewer);
670:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_HDF5_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
671:     PetscObjectRegisterDestroy((PetscObject)viewer);
672:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_HDF5_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
673:     MPI_Attr_put(ncomm,Petsc_Viewer_HDF5_keyval,(void*)viewer);
674:     if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_HDF5_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
675:   }
676:   PetscCommDestroy(&ncomm);
677:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_HDF5_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");return(0);}
678:   PetscFunctionReturn(viewer);
679: }

681: #if defined(oldhdf4stuff)
684: PetscErrorCode  PetscViewerHDF5WriteSDS(PetscViewer viewer, float *xf, int d, int *dims,int bs)
685: {
686:   int              i;
687:   PetscViewer_HDF5 *vhdf5 = (PetscViewer_HDF5*)viewer->data;
688:   int32            sds_id,zero32[3],dims32[3];

691:   for (i = 0; i < d; i++) {
692:     zero32[i] = 0;
693:     dims32[i] = dims[i];
694:   }
695:   sds_id = SDcreate(vhdf5->sd_id, "Vec", DFNT_FLOAT32, d, dims32);
696:   if (sds_id < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SDcreate failed");
697:   SDwritedata(sds_id, zero32, 0, dims32, xf);
698:   SDendaccess(sds_id);
699:   return(0);
700: }

702: #endif