Individual datasets are grouped in special folders that hold all the datasets for a specific geometry. These folders are called multi-dataset groups. Multi-dataset groups may or may not be in the same file as the geometry. In Figure 6 the multi-data group for the mesh has the path 2DMeshModule/mesh/Datasets. Multi-dataset groups store the GUID of the geometry to which they belong. Within a multi-dataset group, generic groups may be used to organize the data sets. In Figure 6 the folder named Solution under the multi-dataset group is an example of using generic groups to organize data sets. These generic groups would be especially useful for stochastic simulations and could be used to organize the datasets belonging to individual runs.
When writing datasets using XMDF the following items of information are necessary:
Inside XMDF there is a function to make it easier for models to set up the paths to begin writing data sets. This function takes for arguments the five items mentioned above and returns the File ID and the ID of the group to begin writing datasets to. This function should always be used to setup a model to begin writing data sets using XMDF because it ensures that everything is setup regardless of whether or not the file or the required paths exist. The function is named xfSetupToWriteDatasets.
Once the file id and group id to start writing datasets has been obtained from xfSetupToWriteDatasets, the following steps are used to add each dataset to the file:
Often steps 1 and 2 will be done together for all of the datasets to be written at the beginning of the model execution. Then when timesteps are computed, step 3 will be performed for each dataset. When all the timesteps are completed steps 4 and 5 are used to close the file and all the resources.
C/C++ static int fg_nTimes; static double *fg_Times; static int fg_nValues; static float **fg_Values; int WriteDataset (const char *a_Filename, const char *a_MultiDatasetsGroupPath, const char *a_SpatialDataObjectGuid, int a_OverwriteOption, int a_Compression) { xid xFileId, xDsetsId, xScalarId; int iTimestep, iActive; double dTime; int status; status = xfSetupToWriteDatasets(a_Filename, a_MultiDatasetsGroupPath, a_SpatialDataObjectGuid, a_OverwriteOption, &xFileId, &xDsetsId); if (status < 0) { printf("Error initializing files to write datasets."); return status; } // Create the scalar A dataset group status = xfCreateScalarDataset(xDsetsId, "Concentration", "mg/L", TS_HOURS, a_Compression, &xScalarId); if (status < 0) { printf("Error creating scalar datasets."); xfCloseGroup(xDsetsId); xfCloseFile(xFileId); return FALSE; } // Loop through timesteps adding them to the file for (iTimestep = 0; iTimestep < fg_nTimes; iTimestep++) { // We will have an 0.5 hour timestep dTime = fg_Times[iTimestep]; // write the dataset array values status = xfWriteScalarTimestep(xScalarAId, dTime, fg_nValues, fg_Values[iTimestep]); if (status < 0) { xfCloseGroup(xScalarId); xfCloseGroup(xDsetsId); xfCloseFile(xFileId); return status; } } // close the dataset xfCloseGroup(xScalarId); xfCloseGroup(xDsetsId); xfCloseFile(xFileId); return FALSE; } // tdWriteScalarA
FORTRAN INTEGER fg_nTimes; REAL(DOUBLE), ALLOCATABLE :: fg_Times(:) INTEGER fg_nValues REAL, ALLOCATABLE :: fg_Values(:,:) SUBROUTINE WRITE_DATASET (a_Filename, a_MultiDatasetsGroupPath, a_SpatialDataOjbectGuid, a_OverwriteOption, a_Compression, error) CHARACTER(LEN=*), INTENT(IN) :: a_Filename, a_MultiDatasetsGroupPath CHARACTER(LEN=*), INTENT(IN) :: a_SpatialDataObjectGuid INTEGER, INTENT(IN) :: a_OverwriteOption, a_Compression INTEGER, INTENT(OUT) :: error INTEGER(HID_T) xFileId, xDsetsId, xScalarId INTEGER iTimestep, iActive REAL(DOUBLE) dTime REAL, ALLOCATABLE :: Values(:) call XF_SETUP_TO_WRITE_DATASETS(a_Filename, a_MultiDatasestsGroupPath, & a_SpatialDataObjectGuid, a_OverwriteOption, & xFileId, xScalarId, error) if (error .LT. 0) then WRITE(*,*) 'Error initializing files to write datasets.' return endif ! Create the scalar A dataset group call XF_CREATE_SCALAR_DATASET(xDsetsId, 'Concentration', 'mg/L', & TS_HOURS, a_Compression, xScalarAd, error) if (error .LT. 0) then ! close the dataset call XF_CLOSE_GROUP(xScalarId, error) call XF_CLOSE_GROUP(xDsetsId, error) call XF_CLOSE_FILE(xFileId, error) return endif ! allocate the values for an individual timestep allocate (Values(fg_nValues)) ! Loop through timesteps adding them to the file do iTimestep = 1, fg_nTimes ! We will have an 0.5 hour timestep dTime = fg_Times(iTimestep) do iVal = 1, fg_nValues Values(iVal) = fg_Values(iTimestep, iVal) enddo ! write the dataset array values call XF_WRITE_SCALAR_TIMESTEP(xScalarId, dTime, fg_nValues, & Values, error) if (error .LT. 0) then deallocate (Values) call XF_CLOSE_GROUP(xScalarAId, error) call XF_CLOSE_GROUP(xDsetsId, error) call XF_CLOSE_FILE(xFileId, error) return endif enddo deallocate (Values) ! close the dataset call XF_CLOSE_GROUP(xScalarAId, error) call XF_CLOSE_GROUP(xDsetsId, error) call XF_CLOSE_FILE(xFileId, error) return END SUBROUTINE