Tests.f90

Tests.f90 provides Fortran code examples for many XMDF APIs.
00001 MODULE TestDatasets
00002 
00003 USE Xmdf
00004 
00005 CHARACTER(LEN=*), PARAMETER :: DATASETS_LOCATION = 'Datasets'
00006 CHARACTER(LEN=*), PARAMETER :: SCALAR_A_LOCATION = 'Scalars/ScalarA'
00007 CHARACTER(LEN=*), PARAMETER :: SCALAR_B_LOCATION = 'Scalars/ScalarB'
00008 CHARACTER(LEN=*), PARAMETER :: VECTOR2D_A_LOCATION = 'Vectors/Vector2D_A'
00009 CHARACTER(LEN=*), PARAMETER :: VECTOR2D_B_LOCATION = 'Vectors/Vector2D_B'
00010 
00011 CONTAINS
00012 
00013 ! --------------------------------------------------------------------------
00014 ! FUNCTION tdReadDatasets
00015 ! PURPOSE  Read a dataset group from an XMDF file and output information to
00016 !          to a text file
00017 ! NOTES    
00018 ! --------------------------------------------------------------------------
00019 RECURSIVE SUBROUTINE TD_READ_DATASETS (a_xGroupId, a_FileUnit, error)
00020 INTEGER, INTENT(IN) :: a_xGroupId
00021 INTEGER, INTENT(IN)        :: a_FileUnit
00022 INTEGER, INTENT(OUT)       :: error
00023 INTEGER                   nPaths, nMaxPathLength, j
00024 CHARACTER, ALLOCATABLE, DIMENSION(:) :: Paths
00025 CHARACTER(LEN=500)       IndividualPath
00026 INTEGER                   nStatus, i
00027 INTEGER            xScalarId, xVectorId, xMultiId
00028 INTEGER                   nMultiDatasets
00029 
00030 xScalarId = NONE
00031 xVectorId = NONE
00032 
00033 nMultiDatasets = 0
00034 nPaths = 0
00035 nMaxPathLength = 0
00036 
00037   ! Look for scalar datasets
00038 call XF_GET_SCALAR_DATASETS_INFO(a_xGroupId, nPaths, nMaxPathLength, nStatus)
00039 if (nStatus >= 0 .AND. nPaths > 0) then
00040   allocate(Paths(nPaths*nMaxPathLength))
00041   call XF_GET_SCALAR_DATASET_PATHS(a_xGroupId, nPaths, nMaxPathLength, Paths, &
00042                                                                          error)
00043 endif
00044 if (nStatus < 0) then
00045   error = -1
00046   return
00047 endif
00048 
00049   ! Output number and paths to scalar datasets
00050 WRITE(a_FileUnit,*) 'Number of Scalars ', nPaths
00051 do i=2, nPaths
00052   IndividualPath = ''
00053   do j=1, nMaxPathLength-1
00054     IndividualPath(j:j) = Paths((i-1)*nMaxPathLength+j)
00055   enddo
00056   WRITE(a_FileUnit,*) 'Reading scalar: ', IndividualPath(1:nMaxPathLength-1)
00057   call XF_OPEN_GROUP(a_xGroupId, IndividualPath(1:nMaxPathLength-1), &
00058                                                            xScalarId, nStatus)
00059   if (nStatus < 0) then
00060     error = -1
00061   return
00062   endif
00063 
00064   call TDI_READ_SCALAR(xScalarId, a_FileUnit, nStatus)
00065   call XF_CLOSE_GROUP(xScalarId, error)
00066   if (nStatus < 0) then
00067     WRITE(*,*) 'Error reading scalar dataset.'
00068     error = -1
00069   return
00070   endif
00071 enddo
00072 
00073 if (allocated(Paths)) deallocate(Paths)
00074   ! Look for vector datasets
00075 call XF_GET_VECTOR_DATASETS_INFO(a_xGroupId, nPaths, nMaxPathLength, nStatus)
00076 if (nStatus >= 0 .AND. nPaths > 0) then
00077   allocate(Paths(nPaths*nMaxPathLength))
00078   call XF_GET_VECTOR_DATASET_PATHS(a_xGroupId, nPaths, nMaxPathLength, Paths, error)
00079 endif
00080 if (nStatus < 0) then
00081   error = -1
00082   return
00083 endif
00084 
00085   ! Output number and paths to scalar datasets
00086 WRITE(a_FileUnit,*) 'Number of Vectors ', nPaths
00087 do i=2, nPaths
00088   do j=1, nMaxPathLength-1
00089     IndividualPath(j:j) = Paths((i-1)*nMaxPathLength+j)
00090   enddo
00091   WRITE(a_FileUnit,*) 'Reading Vector: ', &
00092                       IndividualPath(1:nMaxPathLength-1)
00093   call XF_OPEN_GROUP(a_xGroupId, IndividualPath(1:nMaxPathLength-1), &
00094                                                           xVectorId, nStatus)
00095   if (nStatus < 0) then
00096     error = -1
00097   return
00098   endif
00099   call TDI_READ_VECTOR(xVectorId, a_FileUnit, nStatus)
00100   call XF_CLOSE_GROUP(xVectorId, error)
00101   if (nStatus < 0) then
00102     WRITE(*,*) 'Error reading vector dataset.'
00103     error = -1
00104   return
00105   endif
00106 enddo
00107 
00108 if (allocated(Paths)) deallocate(Paths)
00109 
00110 ! find multidataset folders
00111 call XF_GET_GRP_PTHS_SZ_MLT_DSETS(a_xGroupId, nMultiDatasets, &
00112                                                       nMaxPathLength, nStatus)
00113 if (nStatus >= 0 .AND. nMultiDatasets > 0) then
00114   allocate(Paths(nMultiDatasets*nMaxPathLength))
00115   call XF_GET_ALL_GRP_PATHS_MLT_DSETS(a_xGroupId, nMultiDatasets, &
00116                                                  nMaxPathLength, Paths, error)
00117   if (nStatus < 0) then
00118     error = -1
00119     return
00120   endif
00121 
00122   ! Output number and paths to multidatasets
00123   WRITE(a_FileUnit,*) 'Number of Multidatasets ', nMultiDatasets
00124   do i=2, nMultiDatasets
00125     IndividualPath = ''
00126     do j=1, nMaxPathLength-1
00127       IndividualPath(j:j) = Paths((i-1)*nMaxPathLength+j)
00128     enddo
00129     WRITE(a_FileUnit,*) 'Reading multidataset: ', &
00130                                              IndividualPath(1:nMaxPathLength-1)
00131     call XF_OPEN_GROUP(a_xGroupId, IndividualPath(1:nMaxPathLength-1), &
00132                                                            xMultiId, nStatus)
00133     if (nStatus < 0) then
00134       error = -1
00135     return
00136     endif
00137 
00138     call TD_READ_DATASETS(xMultiId, a_FileUnit, nStatus)
00139     call XF_CLOSE_GROUP(xMultiId, error)
00140     if (nStatus < 0) then
00141       WRITE(*,*) 'Error reading multidatasets.'
00142       error = -1
00143     return
00144     endif
00145   enddo
00146 endif
00147 if (allocated(Paths)) deallocate(Paths)
00148 
00149 error = 1
00150 return
00151 
00152 END SUBROUTINE
00153 !tdReadDatasets
00154 ! --------------------------------------------------------------------------
00155 ! FUNCTION tdReadActivityScalarAIndex
00156 ! PURPOSE  Read all timestep values for a particular index
00157 ! NOTES    
00158 ! --------------------------------------------------------------------------
00159 SUBROUTINE TD_READ_ACTIVITY_SCALAR_A_INDEX(a_Filename, a_Index, error)
00160 CHARACTER(LEN=*), INTENT(IN) :: a_Filename
00161 INTEGER, INTENT(IN)   :: a_Index
00162 INTEGER, INTENT(OUT)  :: error
00163 INTEGER                  status
00164 INTEGER           xFileId, xDsetsId, xScalarAId
00165 INTEGER                  nTimesteps, i
00166 INTEGER, ALLOCATABLE  :: bActive(:)
00167 
00168 xFileId = NONE
00169 xDsetsId = NONE
00170 xScalarAId = NONE
00171 
00172   ! open the file
00173 call XF_OPEN_FILE(a_Filename, .TRUE., xFileId, status)
00174 if (status < 0) then
00175   error = -1
00176   return
00177 endif
00178 
00179   ! open the dataset group
00180 call XF_OPEN_GROUP(xFileId, DATASETS_LOCATION, xDsetsId, status)
00181 if (status >= 0) then
00182   call XF_OPEN_GROUP(xDsetsId, SCALAR_A_LOCATION, xScalarAId, status)
00183 endif
00184 if (status < 0) then
00185   error = status
00186   return
00187 endif
00188 
00189   ! Find out the number of timesteps in the file
00190 CALL XF_GET_DATASET_NUM_TIMES(xScalarAId, nTimesteps, status)
00191 if (status < 0) then
00192   error = status
00193   return
00194 endif
00195 
00196 if (nTimesteps < 1) then
00197   error = -1
00198   return
00199 endif
00200 
00201   ! Read the values for the index
00202 allocate(bActive(nTimesteps))
00203 call XF_READ_ACTIVE_VALS_AT_INDEX(xScalarAId, a_Index, 1, nTimesteps, &
00204                                        bActive, status)
00205   ! output the data
00206 WRITE(*,*) ''
00207 WRITE(*,*) 'Reading activity for scalar A slice at index: ', a_Index
00208 do i=1, nTimesteps
00209   WRITE(*,*) bActive(i), ' '
00210 enddo
00211 
00212 deallocate(bActive)
00213 
00214 error = status
00215 return
00216 
00217 END SUBROUTINE
00218 ! tdReadActivityScalarAIndex
00219 
00220 ! --------------------------------------------------------------------------
00221 ! FUNCTION tdReadScalarAIndex
00222 ! PURPOSE  Read all timestep values for a particular index
00223 ! NOTES    
00224 ! --------------------------------------------------------------------------
00225 SUBROUTINE TD_READ_SCALAR_A_INDEX (a_Filename, a_Index, error)
00226 CHARACTER(LEN=*), INTENT(IN) :: a_Filename
00227 INTEGER, INTENT(IN)   :: a_Index
00228 INTEGER, INTENT(OUT)  :: error
00229 INTEGER              status
00230 INTEGER       xFileId, xDsetsId, xScalarAId
00231 INTEGER              nTimesteps, i
00232 REAL, ALLOCATABLE :: fValues(:)
00233 
00234 xFileId = NONE
00235 xDsetsId = NONE
00236 xScalarAId = NONE
00237 
00238   ! open the file
00239 call XF_OPEN_FILE(a_Filename, .TRUE., xFileId, status)
00240 if (status < 0) then
00241   error = -1
00242   return
00243 endif
00244 
00245   ! open the dataset group
00246 call XF_OPEN_GROUP(xFileId, DATASETS_LOCATION, xDsetsId, status)
00247 if (status >= 0) then
00248   call XF_OPEN_GROUP(xDsetsId, SCALAR_A_LOCATION, xScalarAId, status)
00249 endif
00250 if (status < 0) then
00251   error = status
00252   return
00253 endif
00254 
00255   ! Find out the number of timesteps in the file
00256 call XF_GET_DATASET_NUM_TIMES(xScalarAId, nTimesteps, status)
00257 if (status < 0) then
00258   error = status
00259   return
00260 endif
00261 
00262 if (nTimesteps < 1) then
00263   error = -1
00264   return
00265 endif
00266 
00267   ! Read the values for the index
00268 allocate (fValues(nTimesteps))
00269 call XF_READ_SCALAR_VALUES_AT_INDEX(xScalarAId, a_Index, 1, nTimesteps, &
00270                                      fValues, status)
00271 
00272   ! output the data
00273 WRITE(*,*) ''
00274 WRITE(*,*) 'Reading scalar A slice at index: ', a_Index
00275 do i=1, nTimesteps
00276   WRITE(*,*) fValues(i), ' '
00277 enddo
00278 
00279 deallocate(fValues)
00280 
00281 error = status
00282 return
00283 
00284 END SUBROUTINE
00285 ! tdReadScalarAtIndex
00286 
00287 ! --------------------------------------------------------------------------
00288 ! FUNCTION tdWriteScalarA
00289 ! PURPOSE  Write scalar Dataset to an HDF5 File
00290 ! NOTES    This tests dynamic data sets, and activity
00291 !          This dataset is dynamic concentrations (mg/L) with output times
00292 !          in minutes.
00293 !          Dataset is for a mesh and so nActive is the number of elements
00294 !          which is not the same as the nValues which would be number of nodes
00295 !          reads/writes a reference time in julian days
00296 ! --------------------------------------------------------------------------
00297 SUBROUTINE TD_WRITE_SCALAR_A (a_Filename, a_Compression, error)
00298   CHARACTER(LEN=*), INTENT(IN) :: a_Filename
00299   INTEGER, INTENT(IN)          :: a_Compression
00300   INTEGER, INTENT(OUT)         :: error
00301   INTEGER      xFileId, xDsetsId, xScalarAId, xCoordId
00302   INTEGER      nValues, nTimes, nActive
00303   REAL(DOUBLE) dTime, dJulianReftime
00304   INTEGER      iTimestep, iActive, iHpgnZone
00305   REAL         fValues(10) ! nValues
00306   INTEGER*1    bActivity(10) ! activity
00307   INTEGER      i, status
00308 
00309   ! initialize the data
00310   nValues = 10
00311   nTimes = 3
00312   nActive = 8
00313   dTime = 0.0
00314 
00315   ! 5th item in data set is always inactive, others active
00316   do iActive = 1, nActive
00317     bActivity(iActive) = 1
00318   enddo 
00319   bActivity(6) = 0
00320 
00321 
00322   ! create the file
00323   call XF_CREATE_FILE(a_Filename, .TRUE., xFileId, error)
00324   if (error .LT. 0) then
00325       ! close the file
00326     call XF_CLOSE_FILE(xFileId, error)
00327     return
00328   endif
00329 
00330   ! create the group where we will put all the datasets 
00331   call XF_CREATE_GENERIC_GROUP(xFileId, DATASETS_LOCATION, xDsetsId, status)
00332   if (status < 0) then
00333     call XF_CLOSE_FILE(xFileId, error)
00334     error = -1
00335   return
00336   endif
00337 
00338   ! Create the scalar A dataset group
00339   call XF_CREATE_SCALAR_DATASET(xDsetsId, SCALAR_A_LOCATION, 'mg/L', &
00340               TS_HOURS, a_Compression, xScalarAId, status)
00341   if (status .LT. 0) then
00342       ! close the dataset
00343     call XF_CLOSE_GROUP(xScalarAId, error)
00344     call XF_CLOSE_GROUP(xDsetsId, error)
00345     call XF_CLOSE_FILE(xFileId, error)
00346     error = status
00347     return 
00348   endif
00349 
00350   ! Add in a reftime.  This is a julian day for:
00351   ! noon July 1, 2003
00352   dJulianReftime = 2452822.0;
00353   call XF_WRITE_REFTIME(xScalarAId, dJulianReftime, status)
00354   if (status < 0) then
00355     call XF_CLOSE_GROUP(xScalarAId, error)
00356     call XF_CLOSE_GROUP(xDsetsId, error)
00357     call XF_CLOSE_FILE(xFileId, error)
00358   endif
00359 
00360   ! Loop through timesteps adding them to the file
00361   do iTimestep = 1, nTimes
00362     ! We will have an 0.5 hour timestep
00363     dTime = iTimestep * 0.5
00364 
00365     fValues(1) = dTime
00366     do i = 2, nValues
00367       fValues(i) = fValues(i-1)*2.5
00368     end do
00369 
00370     ! write the dataset array values
00371     call XF_WRITE_SCALAR_TIMESTEP(xScalarAId, dTime, nValues, fValues, error)
00372     if (error .GE. 0) then
00373       ! write activity array
00374       call XF_WRITE_ACTIVITY_TIMESTEP(xScalarAId, nActive, bActivity, error)
00375     end if 
00376   enddo
00377 
00378   ! Write Coordinate file - for ScalarA, we will set the coordinate system
00379   !   to be Geographic HPGN, with HPGN settings written to the file.
00380   call XF_CREATE_COORDINATE_GROUP(xFileId, xCoordId, status)
00381   if (status < 0) then
00382     call XF_CLOSE_GROUP(xScalarAId, error)
00383     call XF_CLOSE_GROUP(xDsetsId, error)
00384     call XF_CLOSE_FILE(xFileId, error)
00385     error = -1
00386   return
00387   endif
00388 
00389     ! set HPGN Zone for test
00390   iHpgnZone = 29   ! Utah
00391     ! Write Coordinate Information to file
00392   call XF_SET_HORIZ_DATUM(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN, error)
00393   call XF_SET_HORIZ_UNITS(xCoordId, COORD_UNITS_METERS, error)
00394   call XF_SET_VERT_DATUM(xCoordId, VERT_DATUM_LOCAL, error)
00395   call XF_SET_VERT_UNITS(xCoordId, COORD_UNITS_METERS, error)
00396 
00397     ! write additional information
00398   call XF_SET_HPGN_AREA(xCoordId, iHpgnZone, error)
00399 
00400   call XF_CLOSE_GROUP(xCoordId, error)
00401   xCoordId = 0;
00402 
00403   ! close the dataset
00404   call XF_CLOSE_GROUP(xScalarAId, error)
00405   call XF_CLOSE_GROUP(xDsetsId, error)
00406   call XF_CLOSE_FILE(xFileId, error)
00407 
00408   return
00409 END SUBROUTINE
00410 ! tdWriteScalarA
00411 
00412 ! --------------------------------------------------------------------------
00413 ! FUNCTION TD_WRITE_SCALAR_B
00414 ! PURPOSE  Write scalar Dataset to an HDF5 File
00415 ! NOTES    This tests dynamic data sets, and activity
00416 !          This dataset is dynamic concentrations (mg/L) with output times
00417 !          in minutes.
00418 !          Dataset is for a mesh and so nActive is the number of elements
00419 !          which is not the same as the nValues which would be number of nodes
00420 !          reads/writes a reference time in julian days
00421 ! --------------------------------------------------------------------------
00422 SUBROUTINE TD_WRITE_SCALAR_B (a_Filename, a_Compression, a_Overwrite, error)
00423   CHARACTER(LEN=*), INTENT(IN) :: a_Filename
00424   INTEGER, INTENT(IN)          :: a_Compression
00425   LOGICAL, INTENT(IN)          :: a_Overwrite
00426   INTEGER, INTENT(OUT)         :: error
00427   INTEGER      xFileId, xDsetsId, xScalarBId, xCoordId
00428   INTEGER      nValues, nTimes, nActive
00429   REAL(DOUBLE) dTime, dJulianReftime
00430   INTEGER      iTimestep, iActive
00431   REAL         fValues(10) ! nValues
00432   INTEGER*1    bActivity(10) ! activity
00433   INTEGER      i, status
00434 
00435   ! initialize the data
00436   nValues = 10
00437   nTimes = 3
00438   nActive = 8
00439   dTime = 0.0
00440   i = 0
00441 
00442   ! 5th item in data set is always inactive, others active
00443   do iActive = 1, nActive
00444     bActivity(iActive) = 1
00445   enddo 
00446   bActivity(6) = 0
00447 
00448   if (a_Overwrite) then
00449       ! open the already-existing file
00450     call XF_OPEN_FILE(a_Filename, .FALSE., xFileId, status)
00451     if (status < 0) then
00452       error = -1
00453       return
00454     endif
00455       ! open the group where we have all the datasets
00456     call XF_OPEN_GROUP(xFileId, DATASETS_LOCATION, xDsetsId, status)
00457     if (status < 0) then
00458       call XF_CLOSE_FILE(xFileId, error)
00459       error = -1
00460       return
00461     endif
00462   else
00463       ! create the file
00464     call XF_CREATE_FILE(a_Filename, .TRUE., xFileId, error)
00465     if (error .LT. 0) then
00466         ! close the file
00467       call XF_CLOSE_FILE(xFileId, error)
00468       return
00469     endif
00470 
00471       ! create the group where we will put all the datasets 
00472     call XF_CREATE_GENERIC_GROUP(xFileId, DATASETS_LOCATION, xDsetsId, status)
00473     if (status < 0) then
00474       call XF_CLOSE_FILE(xFileId, error)
00475       error = -1
00476     return
00477     endif
00478   endif
00479 
00480   ! Create/Overwrite the scalar B dataset group
00481   call XF_CREATE_SCALAR_DATASET(xDsetsId, SCALAR_B_LOCATION, 'mg/L', &
00482               TS_HOURS, a_Compression, xScalarBId, status)
00483   if (status < 0) then
00484       ! close the dataset
00485     call XF_CLOSE_GROUP(xScalarBId, error)
00486     call XF_CLOSE_GROUP(xDsetsId, error)
00487     call XF_CLOSE_FILE(xFileId, error)
00488     error = status
00489     return 
00490   endif
00491 
00492   ! Add in a reftime.  This is a julian day for:
00493   ! noon July 1, 2003
00494   dJulianReftime = 2452822.0;
00495   call XF_WRITE_REFTIME(xScalarBId, dJulianReftime, status)
00496   if (status < 0) then
00497     call XF_CLOSE_GROUP(xScalarBId, error)
00498     call XF_CLOSE_GROUP(xDsetsId, error)
00499     call XF_CLOSE_FILE(xFileId, error)
00500   endif
00501 
00502   if (.NOT. a_Overwrite) then
00503       ! Loop through timesteps adding them to the file
00504     do iTimestep = 1, nTimes
00505         ! We will have an 0.5 hour timestep
00506       dTime = iTimestep * 0.5
00507 
00508       fValues(1) = dTime
00509       do i = 2, nValues
00510         fValues(i) = fValues(i-1)*2.5
00511       end do
00512 
00513         ! write the dataset array values
00514       call XF_WRITE_SCALAR_TIMESTEP(xScalarBId, dTime, nValues, fValues, error)
00515       if (error .GE. 0) then
00516           ! write activity array
00517         call XF_WRITE_ACTIVITY_TIMESTEP(xScalarBId, nActive, bActivity, error)
00518       end if
00519       if (error < 0) then
00520           call XF_CLOSE_GROUP(xScalarBId, error)
00521           call XF_CLOSE_GROUP(xDsetsId, error)
00522           call XF_CLOSE_FILE(xFileId, error)
00523       endif
00524     enddo
00525   else
00526       ! Loop through timesteps adding them to the file
00527     do iTimestep = 1, nTimes
00528         ! We will have an 1.5 hour timestep
00529       dTime = iTimestep * 1.5
00530 
00531       fValues(1) = dTime
00532       do i = 2, nValues
00533         fValues(i) = fValues(i-1)*1.5
00534       end do
00535 
00536         ! write the dataset array values
00537       call XF_WRITE_SCALAR_TIMESTEP(xScalarBId, dTime, nValues, fValues, error)
00538       if (error .GE. 0) then
00539           ! write activity array
00540         call XF_WRITE_ACTIVITY_TIMESTEP(xScalarBId, nActive, bActivity, error)
00541       end if
00542       if (error < 0) then
00543           call XF_CLOSE_GROUP(xScalarBId, error)
00544           call XF_CLOSE_GROUP(xDsetsId, error)
00545           call XF_CLOSE_FILE(xFileId, error)
00546       endif
00547     enddo
00548   endif
00549 
00550   if (.NOT. a_Overwrite) then
00551     ! Write Coordinate file - for ScalarB, we will set the coordinate system
00552     !   to be UTM, with UTM Zone settings written to the file.
00553     call XF_CREATE_COORDINATE_GROUP(xFileId, xCoordId, status)
00554     if (status < 0) then
00555       call XF_CLOSE_GROUP(xScalarBId, error)
00556       call XF_CLOSE_GROUP(xDsetsId, error)
00557       call XF_CLOSE_FILE(xFileId, error)
00558     error = -1
00559     return
00560     endif
00561 
00562      ! Write Coord Info to file
00563     call XF_SET_HORIZ_DATUM(xCoordId, HORIZ_DATUM_UTM, error)
00564     call XF_SET_HORIZ_UNITS(xCoordId, COORD_UNITS_METERS, error)
00565 
00566     call XF_SET_VERT_DATUM(xCoordId, VERT_DATUM_LOCAL, error)
00567     call XF_SET_VERT_UNITS(xCoordId, COORD_UNITS_METERS, error)
00568 
00569       ! write additional information - we'll use the max value for this test
00570     call XF_SET_UTM_ZONE(xCoordId, UTM_ZONE_MAX, error)
00571 
00572     call XF_CLOSE_GROUP(xCoordId, error)
00573     xCoordId = 0
00574   endif
00575 
00576   ! close the dataset
00577   call XF_CLOSE_GROUP(xScalarBId, error)
00578   call XF_CLOSE_GROUP(xDsetsId, error)
00579   call XF_CLOSE_FILE(xFileId, error)
00580 
00581   error = 1
00582   return
00583 END SUBROUTINE
00584 ! tdWriteScalarB
00585 !------------------------------------------------------------------------------
00586 !  FUNCTION TD_WRITE_COORDS_TO_MULTI
00587 !  PURPOSE  Write coordinate system to a multidataset file
00588 !  NOTES
00589 !------------------------------------------------------------------------------
00590 SUBROUTINE TD_WRITE_COORDS_TO_MULTI (a_xFileId, error)
00591 INTEGER, INTENT(IN) :: a_xFileId
00592 INTEGER, INTENT(OUT)       :: error
00593 INTEGER    xCoordId
00594 INTEGER           status
00595 
00596   ! Write Coordinate file - for Multidatasets, we will set the coordinate system
00597   !   to be UTM, with UTM Zone settings written to the file.
00598   call XF_CREATE_COORDINATE_GROUP(a_xFileId, xCoordId, status)
00599   if (status < 0) then
00600     error = status
00601   return
00602   endif
00603 
00604     ! Write Coord Info to file
00605   call XF_SET_HORIZ_DATUM(xCoordId, HORIZ_DATUM_UTM, error)
00606   call XF_SET_HORIZ_UNITS(xCoordId, COORD_UNITS_METERS, error)
00607 
00608   call XF_SET_VERT_DATUM(xCoordId, VERT_DATUM_LOCAL, error)
00609   call XF_SET_VERT_UNITS(xCoordId, COORD_UNITS_METERS, error)
00610 
00611     ! write additional information - we'll use the max value for this test
00612   call XF_SET_UTM_ZONE(xCoordId, UTM_ZONE_MAX, error)
00613 
00614   call XF_CLOSE_GROUP(xCoordId, error)
00615   xCoordId = 0
00616 
00617   return
00618 END SUBROUTINE
00619 
00620 ! --------------------------------------------------------------------------
00621 ! FUNCTION tdWriteScalarAToMulti
00622 ! PURPOSE  Write scalar Dataset to an HDF5 File
00623 ! NOTES    This tests dynamic data sets, and activity
00624 !          This dataset is dynamic concentrations (mg/L) with output times
00625 !          in minutes.
00626 !          Dataset is for a mesh and so nActive is the number of elements
00627 !          which is not the same as the nValues which would be number of nodes
00628 !          reads/writes a reference time in julian days
00629 ! --------------------------------------------------------------------------
00630 SUBROUTINE TD_WRITE_SCALAR_A_TO_MULTI (a_GroupID, status)
00631  ! CHARACTER(LEN=*), INTENT(IN) :: a_Filename
00632  ! INTEGER, INTENT(IN)          :: a_Compression
00633  ! INTEGER, INTENT(OUT)         :: error
00634   INTEGER      xFileId, xDsetsId, xScalarAId
00635   INTEGER      a_GroupID
00636   INTEGER      nValues, nTimes, nActive
00637   REAL(DOUBLE) dTime, dJulianReftime
00638   INTEGER      iTimestep, iActive
00639   REAL         fValues(10) ! nValues
00640   INTEGER*1    bActivity(10) ! activity
00641   INTEGER      i, status
00642 
00643   ! initialize the data
00644   nValues = 10
00645   nTimes  = 3
00646   nActive = 8
00647   dTime   = 0.0
00648 
00649   ! 5th item in data set is always inactive, others active
00650   do iActive = 1, nActive
00651     bActivity(iActive) = 1
00652   enddo 
00653   bActivity(6) = 0
00654 
00655   ! Create the scalar A dataset group
00656   call XF_CREATE_SCALAR_DATASET(a_GroupID, SCALAR_A_LOCATION, 'mg/L', &
00657               TS_HOURS, NONE, xScalarAId, status)
00658   if (status .LT. 0) then
00659       ! close the dataset
00660     call XF_CLOSE_GROUP(xScalarAId, status)
00661     call XF_CLOSE_GROUP(xDsetsId, status)
00662     call XF_CLOSE_FILE(xFileId, status)
00663     return 
00664   endif
00665 
00666   ! Add in a reftime.  This is a julian day for:
00667   ! noon July 1, 2003
00668   dJulianReftime = 2452822.0;
00669   call XF_WRITE_REFTIME(xScalarAId, dJulianReftime, status)
00670   if (status < 0) then
00671     call XF_CLOSE_GROUP(xScalarAId, status)
00672     call XF_CLOSE_GROUP(xDsetsId, status)
00673     call XF_CLOSE_FILE(xFileId, status)
00674   endif
00675 
00676   ! Loop through timesteps adding them to the file
00677   do iTimestep = 1, nTimes
00678     ! We will have an 0.5 hour timestep
00679     dTime = iTimestep * 0.5
00680 
00681     fValues(1) = dTime
00682     do i = 2, nValues
00683       fValues(i) = fValues(i-1)*2.5
00684     end do
00685 
00686     ! write the dataset array values
00687     call XF_WRITE_SCALAR_TIMESTEP(xScalarAId, dTime, nValues, fValues, status)
00688     if (status .GE. 0) then
00689       ! write activity array
00690       call XF_WRITE_ACTIVITY_TIMESTEP(xScalarAId, nActive, bActivity, status)
00691     end if 
00692   enddo
00693 
00694   ! close the dataset
00695   call XF_CLOSE_GROUP(xScalarAId, status)
00696   !call XF_CLOSE_GROUP(a_GroupID, status)
00697   !call XF_CLOSE_FILE(a_FileID, status)
00698 
00699   return
00700 END SUBROUTINE
00701 ! tdWriteScalarAToMulti
00702 ! --------------------------------------------------------------------------
00703 ! FUNCTION tdReadVector2DAIndex
00704 ! PURPOSE  Read all timestep values for a particular index
00705 ! NOTES    
00706 ! --------------------------------------------------------------------------
00707 SUBROUTINE TD_READ_VECTOR2D_A_INDEX (a_Filename, a_Index, error)
00708 CHARACTER(LEN=*), INTENT(IN) :: a_Filename
00709 INTEGER, INTENT(IN)   :: a_Index
00710 INTEGER, INTENT(OUT)  :: error
00711 INTEGER           status
00712 INTEGER    xFileId, xDsetsId, xVector2DA
00713 INTEGER           nTimesteps, i
00714 REAL, ALLOCATABLE     :: fValues(:)
00715 
00716 xFileId = NONE
00717 xDsetsId = NONE
00718 xVector2DA = NONE
00719 
00720   ! open the file
00721 call XF_OPEN_FILE(a_Filename, .TRUE., xFileId, status)
00722 if (status < 0) then
00723   error = -1
00724   return
00725 endif
00726 
00727   ! open the dataset group
00728 call XF_OPEN_GROUP(xFileId, DATASETS_LOCATION, xDsetsId, status)
00729 if (status >= 0) then
00730   call XF_OPEN_GROUP(xDsetsId, VECTOR2D_A_LOCATION, xVector2DA, status)
00731 endif
00732 if (status < 0) then
00733   error = status
00734   return
00735 endif
00736 
00737   ! Find out the number of timesteps in the file
00738 call XF_GET_DATASET_NUM_TIMES(xVector2DA, nTimesteps, status)
00739 if (status < 0) then
00740   error = status
00741   return
00742 endif
00743 
00744 if (nTimesteps < 1) then
00745   error = -1
00746   return
00747 endif
00748 
00749   ! Read the values for the index
00750 allocate(fValues(nTimesteps*2))
00751 call XF_READ_VECTOR_VALUES_AT_INDEX(xVector2DA, a_Index, 1, nTimesteps, 2, &
00752                                      fValues, status)
00753 
00754   ! output the data
00755 WRITE(*,*) ''
00756 WRITE(*,*) 'Reading vector 2D A slice at index: ', a_Index
00757 do i=1, nTimesteps
00758   WRITE(*,*) fValues(i*2-1), ' ', fValues(i*2)
00759 enddo
00760 WRITE(*,*) ''
00761 
00762 deallocate(fValues)
00763 
00764 error = status
00765 return
00766 
00767 END SUBROUTINE
00768 !tdReadVector2DAIndex
00769 
00770 ! --------------------------------------------------------------------------
00771 ! FUNCTION tdWriteVector2D_A
00772 ! PURPOSE  Write scalar Dataset to an HDF5 File
00773 ! NOTES    This tests dynamic data sets, and activity
00774 !          This dataset is dynamic concentrations (mg/L) with output times
00775 !          in minutes.
00776 !          Dataset is for a mesh and so nActive is the number of elements
00777 !          which is not the same as the nValues which would be number of nodes
00778 !          reads/writes a reference time in julian days
00779 ! --------------------------------------------------------------------------
00780 SUBROUTINE TD_WRITE_VECTOR2D_A (a_Filename, a_Compression, error)
00781   CHARACTER(LEN=*), INTENT(IN) :: a_Filename
00782   INTEGER, INTENT(IN)          :: a_Compression
00783   INTEGER, INTENT(OUT)         :: error
00784   INTEGER      xFileId, xDsetsId, xVector2D_A, xCoordId
00785   INTEGER      nValues, nTimes, nComponents, nActive
00786   REAL(DOUBLE) dTime
00787   INTEGER      iTimestep, iActive
00788   REAL, DIMENSION(2, 100) :: fValues ! nComponents, nValues
00789   INTEGER*1    bActivity(100) ! activity
00790   INTEGER      i, j, status
00791   INTEGER      iHpgnZone
00792 
00793   ! initialize the data
00794   nComponents = 2
00795   nValues = 100
00796   nTimes = 6
00797   nActive = 75
00798   dTime = 0.0
00799 
00800   ! 5th item in data set is always inactive, others active
00801   bActivity(1) = 0
00802   do iActive = 2, nActive
00803     if (mod(iActive-1, 3) == 0) then
00804       bActivity(iActive) = 0
00805     else
00806     bActivity(iActive) = 1
00807   endif
00808   enddo
00809 
00810   ! create the file
00811   call XF_CREATE_FILE(a_Filename, .TRUE., xFileId, error)
00812   if (error .LT. 0) then
00813     ! close the dataset
00814     call XF_CLOSE_FILE(xFileId, error)
00815     return
00816   endif
00817 
00818   ! create the group where we will put all the datasets 
00819   call XF_CREATE_GENERIC_GROUP(xFileId, DATASETS_LOCATION, xDsetsId, status)
00820   if (status < 0) then
00821     call XF_CLOSE_FILE(xFileId, error)
00822     error = -1
00823   return
00824   endif
00825 
00826   ! Create the vector dataset group
00827   call XF_CREATE_VECTOR_DATASET(xDsetsId, VECTOR2D_A_LOCATION, 'ft/s', &
00828               TS_SECONDS, a_Compression, xVector2D_A, status)
00829   if (status .LT. 0) then
00830       ! close the dataset
00831     call XF_CLOSE_GROUP(xVector2D_A, error)
00832     call XF_CLOSE_GROUP(xDsetsId, error)
00833     call XF_CLOSE_FILE(xFileId, error)
00834     error = status
00835     return 
00836   endif
00837 
00838   ! Loop through timesteps adding them to the file
00839   do iTimestep = 1, nTimes
00840     ! We will have an 0.5 hour timestep
00841     dTime = iTimestep * 0.5
00842 
00843     do i = 1, nValues
00844       do j = 1, nComponents
00845         fValues(j,i) = ((i-1)*nComponents + j)*dTime
00846       end do
00847     end do
00848 
00849     ! write the dataset array values
00850     call XF_WRITE_VECTOR_TIMESTEP(xVector2D_A, dTime, nValues, nComponents, &
00851                                   fValues, error)
00852     if (error .GE. 0) then
00853       ! write activity array
00854       call XF_WRITE_ACTIVITY_TIMESTEP(xVector2D_A, nActive, bActivity, error)
00855     end if 
00856   enddo
00857 
00858   ! Write Coordinate file - for Vector2D_A, we will set the coordinate system
00859   !   to be Geographic HPGN, with HPGN settings written to the file.
00860   call XF_CREATE_COORDINATE_GROUP(xFileId, xCoordId, status)
00861   if (status < 0) then
00862     call XF_CLOSE_GROUP(xVector2D_A, error)
00863     call XF_CLOSE_GROUP(xDsetsId, error)
00864     call XF_CLOSE_FILE(xFileId, error)
00865   error = -1
00866   return
00867   endif
00868 
00869     ! set HPGN info for test
00870   iHpgnZone = 29   ! Utah
00871 
00872   call XF_SET_HORIZ_DATUM(xCoordId, HORIZ_DATUM_GEOGRAPHIC_HPGN, error)
00873   call XF_SET_HORIZ_UNITS(xCoordId, COORD_UNITS_METERS, error)
00874   call XF_SET_VERT_DATUM(xCoordId, VERT_DATUM_LOCAL, error)
00875   call XF_SET_VERT_UNITS(xCoordId, COORD_UNITS_METERS, error)
00876 
00877     ! write additional information
00878   call XF_SET_HPGN_AREA(xCoordId, iHpgnZone, error)
00879 
00880   call XF_CLOSE_GROUP(xCoordId, error)
00881   xCoordId = 0
00882 
00883   ! close the dataset
00884   call XF_CLOSE_GROUP(xVector2D_A, error)
00885   call XF_CLOSE_GROUP(xDsetsId, error)
00886   call XF_CLOSE_FILE(xFileId, error)
00887 
00888   return
00889 END SUBROUTINE
00890 ! tdWriteVector2D_A
00891 
00892 ! --------------------------------------------------------------------------
00893 ! FUNCTION TD_WRITE_VECTOR2D_B
00894 ! PURPOSE  Write scalar Dataset to an HDF5 File
00895 ! NOTES    This tests dynamic data sets, and activity
00896 !          This dataset is dynamic concentrations (mg/L) with output times
00897 !          in minutes.
00898 !          Dataset is for a mesh and so nActive is the number of elements
00899 !          which is not the same as the nValues which would be number of nodes
00900 !          reads/writes a reference time in julian days
00901 ! --------------------------------------------------------------------------
00902 SUBROUTINE TD_WRITE_VECTOR2D_B (a_Filename, a_Compression, a_Overwrite, error)
00903   CHARACTER(LEN=*), INTENT(IN) :: a_Filename
00904   INTEGER, INTENT(IN)          :: a_Compression
00905   LOGICAL, INTENT(IN)          :: a_Overwrite
00906   INTEGER, INTENT(OUT)         :: error
00907   INTEGER      xFileId, xDsetsId, xVector2D_B, xCoordId
00908   INTEGER      nValues, nTimes, nComponents, nActive
00909   REAL(DOUBLE) dTime
00910   INTEGER      iTimestep, iActive
00911   REAL, DIMENSION(2, 100) :: fValues
00912   INTEGER*1    bActivity(100)
00913   INTEGER      i, j, status
00914 
00915     ! initialize the data
00916   nComponents = 2
00917   nValues = 100
00918   nTimes = 6
00919   nActive = 75
00920   dTime = 0.0
00921 
00922     ! 5th item in data set is always inactive, others active
00923   bActivity(1) = 0
00924   do iActive = 2, nActive
00925     if (mod(iActive-1, 3) == 0) then
00926       bActivity(iActive) = 0
00927     else
00928       bActivity(iActive) = 1
00929     endif
00930   enddo
00931 
00932   if (a_Overwrite) then
00933       ! open the already-existing file
00934     call XF_OPEN_FILE(a_Filename, .FALSE., xFileId, status)
00935     if (status < 0) then
00936       error = -1
00937       return
00938     endif
00939       ! open the group where we have all the datasets
00940     call XF_OPEN_GROUP(xFileId, DATASETS_LOCATION, xDsetsId, status)
00941     if (status < 0) then
00942       call XF_CLOSE_FILE(xFileId, error)
00943       error = -1
00944       return
00945     endif
00946   else
00947       ! create the file
00948     call XF_CREATE_FILE(a_Filename, .TRUE., xFileId, error)
00949     if (error .LT. 0) then
00950         ! close the dataset
00951       call XF_CLOSE_FILE(xFileId, error)
00952       return
00953     endif
00954 
00955       ! create the group where we will put all the datasets 
00956     call XF_CREATE_GENERIC_GROUP(xFileId, DATASETS_LOCATION, xDsetsId, status)
00957     if (status < 0) then
00958       call XF_CLOSE_FILE(xFileId, error)
00959       error = -1
00960       return
00961     endif
00962   endif
00963 
00964     ! Create/Overwrite the vector dataset group
00965   call XF_CREATE_VECTOR_DATASET(xDsetsId, VECTOR2D_B_LOCATION, 'ft/s', &
00966                                 TS_SECONDS, a_Compression, xVector2D_B, status)
00967   if (status .LT. 0) then
00968       ! close the dataset
00969     call XF_CLOSE_GROUP(xVector2D_B, error)
00970     call XF_CLOSE_GROUP(xDsetsId, error)
00971     call XF_CLOSE_FILE(xFileId, error)
00972     error = status
00973     return 
00974   endif
00975 
00976   if (.NOT. a_Overwrite) then
00977       ! Loop through timesteps adding them to the file
00978     do iTimestep = 1, nTimes
00979         ! We will have an 0.5 hour timestep
00980       dTime = iTimestep * 0.5
00981       do i = 1, nValues
00982         do j = 1, nComponents
00983           fValues(j,i) = ((i-1)*nComponents + j)*dTime
00984         end do
00985       end do
00986         ! write the dataset array values
00987       call XF_WRITE_VECTOR_TIMESTEP(xVector2D_B, dTime, nValues, nComponents, &
00988                                     fValues, error)
00989       if (error .GE. 0) then
00990           ! write activity array
00991         call XF_WRITE_ACTIVITY_TIMESTEP(xVector2D_B, nActive, bActivity, error)
00992       end if
00993       if (error < 0) then
00994         call XF_CLOSE_GROUP(xVector2D_B, error)
00995         call XF_CLOSE_GROUP(xDsetsId, error)
00996         call XF_CLOSE_FILE(xFileId, error)
00997       endif
00998     enddo
00999   else
01000       ! Loop through timesteps adding them to the file
01001     do iTimestep = 1, nTimes
01002         ! We will have an 1.5 hour timestep
01003       dTime = iTimestep * 1.5
01004       do i = 1, nValues
01005         do j = 1, nComponents
01006           fValues(j,i) = ((i-1)*nComponents + j)*dTime
01007         end do
01008       end do
01009         ! write the dataset array values
01010       call XF_WRITE_VECTOR_TIMESTEP(xVector2D_B, dTime, nValues, nComponents, &
01011                                     fValues, error)
01012       if (error .GE. 0) then
01013           ! write activity array
01014         call XF_WRITE_ACTIVITY_TIMESTEP(xVector2D_B, nActive, bActivity, error)
01015       end if
01016       if (error < 0) then
01017         call XF_CLOSE_GROUP(xVector2D_B, error)
01018         call XF_CLOSE_GROUP(xDsetsId, error)
01019         call XF_CLOSE_FILE(xFileId, error)
01020       endif
01021     enddo
01022   endif
01023 
01024   if (.NOT. a_Overwrite) then
01025     ! Write Coordinate file - for ScalarB, we will set the coordinate system
01026     !   to be UTM, with UTM Zone settings written to the file.
01027     call XF_CREATE_COORDINATE_GROUP(xFileId, xCoordId, status)
01028     if (status < 0) then
01029       call XF_CLOSE_GROUP(xVector2D_B, error)
01030       call XF_CLOSE_GROUP(xDsetsId, error)
01031       call XF_CLOSE_FILE(xFileId, error)
01032     error = -1
01033     return
01034     endif
01035 
01036       ! write the coordinate data to the file
01037     call XF_SET_HORIZ_DATUM(xCoordId, HORIZ_DATUM_UTM, error)
01038     call XF_SET_HORIZ_UNITS(xCoordId, COORD_UNITS_METERS, error)
01039     call XF_SET_VERT_DATUM(xCoordId, VERT_DATUM_LOCAL, error)
01040     call XF_SET_VERT_UNITS(xCoordId, COORD_UNITS_METERS, error)
01041 
01042       ! write additional information - we'll use the max UTM zone for the test
01043     call XF_SET_UTM_ZONE(xCoordId, UTM_ZONE_MAX, error)
01044 
01045     call XF_CLOSE_GROUP(xCoordId, error)
01046     xCoordId = 0
01047   endif
01048 
01049   ! close the dataset
01050   call XF_CLOSE_GROUP(xVector2D_B, error)
01051   call XF_CLOSE_GROUP(xDsetsId, error)
01052   call XF_CLOSE_FILE(xFileId, error)
01053 
01054   return
01055 END SUBROUTINE
01056 ! tdWriteVector2D_B
01057 
01058 ! --------------------------------------------------------------------------
01059 ! FUNCTION tdWriteVector2D_AToMulti
01060 ! PURPOSE  Write scalar Dataset to an HDF5 File
01061 ! NOTES    This tests dynamic data sets, and activity
01062 !          This dataset is dynamic concentrations (mg/L) with output times
01063 !          in minutes.
01064 !          Dataset is for a mesh and so nActive is the number of elements
01065 !          which is not the same as the nValues which would be number of nodes
01066 !          reads/writes a reference time in julian days
01067 ! --------------------------------------------------------------------------
01068 SUBROUTINE TD_WRITE_VECTOR2D_A_TO_MULTI (a_FileID, a_GroupID, status)
01069   INTEGER      xVector2D_A
01070   INTEGER      a_FileID, a_GroupID
01071   INTEGER      nValues, nTimes, nComponents, nActive
01072   REAL(DOUBLE) dTime
01073   INTEGER      iTimestep, iActive
01074   REAL, DIMENSION(2, 100) :: fValues ! nComponents, nValues
01075   INTEGER*1    bActivity(100) ! activity
01076   INTEGER      i, j, status
01077 
01078   ! initialize the data
01079   nComponents = 2
01080   nValues = 100
01081   nTimes = 6
01082   nActive = 75
01083   dTime = 0.0
01084 
01085   ! 5th item in data set is always inactive, others active
01086   bActivity(1) = 0
01087   do iActive = 2, nActive
01088     if (mod(iActive-1, 3) == 0) then
01089       bActivity(iActive) = 0
01090     else
01091     bActivity(iActive) = 1
01092   endif
01093   enddo
01094 
01095   ! Create the vector dataset group
01096   call XF_CREATE_VECTOR_DATASET(a_GroupID, VECTOR2D_A_LOCATION, 'ft/s', &
01097               TS_SECONDS, NONE, xVector2D_A, status)
01098   if (status .LT. 0) then
01099       ! close the dataset
01100     call XF_CLOSE_GROUP(xVector2D_A, status)
01101     call XF_CLOSE_GROUP(a_GroupID, status)
01102     call XF_CLOSE_FILE(a_FileID, status)
01103     return 
01104   endif
01105 
01106   ! Loop through timesteps adding them to the file
01107   do iTimestep = 1, nTimes
01108     ! We will have an 0.5 hour timestep
01109     dTime = iTimestep * 0.5
01110 
01111     do i = 1, nValues
01112       do j = 1, nComponents
01113         fValues(j,i) = ((i-1)*nComponents + j)*dTime
01114       end do
01115     end do
01116 
01117     ! write the dataset array values
01118     call XF_WRITE_VECTOR_TIMESTEP(xVector2D_A, dTime, nValues, nComponents, &
01119                                   fValues, status)
01120     if (status .GE. 0) then
01121       ! write activity array
01122       call XF_WRITE_ACTIVITY_TIMESTEP(xVector2D_A, nActive, bActivity, status)
01123     end if 
01124   enddo
01125 
01126   ! close the dataset
01127   call XF_CLOSE_GROUP(xVector2D_A, status)
01128   return
01129 END SUBROUTINE
01130 ! tdWriteVector2D_AToMulti
01131 ! --------------------------------------------------------------------------
01132 ! FUNCTION tdiReadScalar
01133 ! PURPOSE  Read a scalar from an XMDF file and output information to
01134 !          to a text file
01135 ! NOTES    
01136 ! --------------------------------------------------------------------------
01137 SUBROUTINE TDI_READ_SCALAR (a_xScalarId, FileUnit, error)
01138   INTEGER, INTENT(IN) ::  a_xScalarId
01139   INTEGER, INTENT(IN) ::         FileUnit
01140   INTEGER, INTENT(OUT) :: error
01141   INTEGER             nTimes, nValues, nActive
01142   LOGICAL*2             bUseReftime
01143   INTEGER             iTime
01144   CHARACTER(LEN=100)   TimeUnits
01145   REAL(DOUBLE), ALLOCATABLE :: Times(:)
01146   REAL, ALLOCATABLE         :: Values(:), Minimums(:), Maximums(:)
01147   INTEGER, ALLOCATABLE      :: Active(:)
01148   REAL(DOUBLE)                 Reftime
01149 nTimes = NONE
01150 nValues = NONE
01151 nActive = None
01152 
01153   ! read the time units
01154   call XF_GET_DATASET_TIME_UNITS(a_xScalarId, TimeUnits, error)
01155   if (error < 0) return
01156 
01157   WRITE(FileUnit,*) 'Time units: ', TimeUnits(1:LEN_TRIM(TimeUnits))
01158 
01159   ! see if we are using a reftime
01160   call XF_USE_REFTIME (a_xScalarId, bUseReftime, error)
01161   if (error < 0) then
01162     return
01163   endif
01164   if (bUseReftime) then
01165     call XF_READ_REFTIME (a_xScalarId, Reftime, error)
01166     if (error < 0) then
01167       return
01168   endif
01169     WRITE(FileUnit,*) 'Reftime: ', Reftime
01170   endif
01171 
01172   ! read in the number of values and number of active values
01173   call XF_GET_DATASET_NUMVALS(a_xScalarId, nValues, error)
01174   if (error .GE. 0) then
01175     call XF_GET_DATASET_NUMACTIVE(a_xScalarId, nActive, error)
01176   endif
01177   if (error .LT. 0) return 
01178 
01179   if (nValues <= 0) then
01180     WRITE(FileUnit, *) 'No data to read in.'
01181     error = -1
01182     return 
01183   endif
01184 
01185   ! read in the number of times
01186   call XF_GET_DATASET_NUM_TIMES(a_xScalarId, nTimes, error)
01187   if (error < 0) then
01188     return 
01189   endif
01190 
01191   ! Read in the individual time values
01192   allocate(Times(nTimes))
01193 
01194   call XF_GET_DATASET_TIMES(a_xScalarId, nTimes, Times, error)
01195   if (error < 0) return 
01196 
01197   ! Read in the minimum and maximum values
01198   allocate(Minimums(nTimes))
01199   allocate(Maximums(nTimes))
01200 
01201   call XF_GET_DATASET_MINS(a_xScalarId, nTimes, Minimums, error)
01202   if (error >= 0) then
01203     call XF_GET_DATASET_MAXS(a_xScalarId, nTimes, Maximums, error)
01204   endif
01205   if (error < 0) then
01206     deallocate(Times)
01207     deallocate(Minimums)
01208     deallocate(Maximums)
01209     return
01210   endif
01211 
01212   allocate(Values(nValues))
01213   if (nActive .GT. 0) then
01214     allocate(Active(nActive))
01215   endif
01216 
01217   WRITE(FileUnit,*) 'Number Timesteps: ', nTimes
01218   WRITE(FileUnit,*) 'Number Values: ', nValues
01219   WRITE(FileUnit,*) 'Number Active: ', nActive
01220   WRITE(FileUnit,*) ''
01221 
01222   ! loop through the timesteps, read the values and active values and write
01223   ! them to the text file
01224   do iTime = 1, nTimes
01225     call XF_READ_SCALAR_VALUES_TIMESTEP(a_xScalarId, iTime, nValues, Values, error)
01226     if (error >= 0 .AND. nActive > 0) then
01227       call XF_READ_ACTIVITY_TIMESTEP(a_xScalarId, iTime, nActive, Active, error)
01228     endif
01229 
01230     ! Write the time, min, max, values and active values to the text output
01231     ! file.
01232     WRITE(FileUnit,*) 'Timestep at  ', Times(iTime)
01233     WRITE(FileUnit,*) 'Min: ', Minimums(iTime)
01234     WRITE(FileUnit,*) 'Max: ', Maximums(iTime)
01235 
01236     WRITE(FileUnit,*) 'Values:'
01237     WRITE(FileUnit,*) Values(1:nValues)
01238     WRITE(FileUnit,*) ''
01239 
01240     WRITE(FileUnit,*) 'Activity:'
01241     WRITE(FileUnit,*) Active(1:nActive)
01242     WRITE(FileUnit,*) ''
01243   end do
01244 
01245   if (allocated(Times)) then
01246     deallocate(Times)
01247   endif
01248   
01249   if (allocated(Minimums)) then
01250     deallocate(Minimums)
01251   endif
01252 
01253   if (allocated(Maximums)) then
01254     deallocate(Maximums)
01255   endif
01256 
01257   if (allocated(Values)) then
01258     deallocate(Values)
01259   endif
01260 
01261   if (allocated(Active)) then
01262     deallocate(Active)
01263   endif
01264 
01265   return
01266 END SUBROUTINE
01267 ! tdiReadScalar
01268 
01269 ! --------------------------------------------------------------------------
01270 ! FUNCTION TDI_READ_VECTOR
01271 ! PURPOSE  Read a vector from an XMDF file and output information to
01272 !          to a text file
01273 ! NOTES    
01274 ! --------------------------------------------------------------------------
01275 SUBROUTINE TDI_READ_VECTOR (a_xVectorId, FileUnit, error)
01276   INTEGER, INTENT(IN) ::  a_xVectorId
01277   INTEGER, INTENT(IN) ::         FileUnit
01278   INTEGER, INTENT(OUT) :: error
01279   INTEGER             nTimes, nValues, nActive, nComponents
01280   INTEGER             iTime, i
01281   LOGICAL*2            bUseReftime
01282   CHARACTER(LEN=100)   TimeUnits
01283   REAL(DOUBLE), ALLOCATABLE :: Times(:)
01284   REAL, ALLOCATABLE, DIMENSION (:, :) :: Values
01285   REAL, ALLOCATABLE         :: Minimums(:), Maximums(:)
01286   INTEGER, ALLOCATABLE      :: Active(:)
01287   REAL(DOUBLE)                 Reftime
01288 
01289 nTimes = NONE
01290 nValues = NONE
01291 nActive = NONE
01292 nComponents = NONE
01293 
01294   ! read the time units
01295   call XF_GET_DATASET_TIME_UNITS(a_xVectorId, TimeUnits, error)
01296   if (error < 0) return
01297 
01298   WRITE(FileUnit,*) 'Time units: ', TimeUnits(1:LEN_TRIM(TimeUnits))
01299 
01300   ! see if we are using a reftime
01301   call XF_USE_REFTIME (a_xVectorId, bUseReftime, error)
01302   if (error < 0) then
01303     return
01304   endif
01305   if (bUseReftime) then
01306     call XF_READ_REFTIME (a_xVectorId, Reftime, error)
01307     if (error < 0) then
01308       return
01309   endif
01310     WRITE(FileUnit,*) 'Reftime: ', Reftime
01311   endif
01312 
01313   ! read in the number of values and number of active values
01314   call XF_GET_DATASET_NUMVALS(a_xVectorId, nValues, error)
01315   if (error .GE. 0) then
01316     call XF_GET_DATASET_NUMCOMPONENTS(a_xVectorId, nComponents, error)
01317     if (error .GE. 0) then
01318       call XF_GET_DATASET_NUMACTIVE(a_xVectorId, nActive, error)
01319     endif
01320   endif
01321   if (error .LT. 0) return 
01322 
01323   if (nValues <= 0) then
01324     WRITE(FileUnit, *) 'No data to read in.'
01325     error = -1
01326     return 
01327   endif
01328 
01329   ! read in the number of times
01330   call XF_GET_DATASET_NUM_TIMES(a_xVectorId, nTimes, error)
01331   if (error < 0) then
01332     return 
01333   endif
01334 
01335   ! Read in the individual time values
01336   allocate(Times(nTimes))
01337 
01338   call XF_GET_DATASET_TIMES(a_xVectorId, nTimes, Times, error)
01339   if (error < 0) return 
01340 
01341   ! Read in the minimum and maximum values
01342   allocate(Minimums(nTimes))
01343   allocate(Maximums(nTimes))
01344 
01345   call XF_GET_DATASET_MINS(a_xVectorId, nTimes, Minimums, error)
01346   if (error >= 0) then
01347     call XF_GET_DATASET_MAXS(a_xVectorId, nTimes, Maximums, error)
01348   endif
01349   if (error < 0) then
01350     deallocate(Times)
01351     deallocate(Minimums)
01352     deallocate(Maximums)
01353     return
01354   endif
01355 
01356   allocate(Values(nComponents, nValues))
01357   if (nActive .GT. 0) then
01358     allocate(Active(nActive))
01359   endif
01360 
01361   WRITE(FileUnit,*) 'Number Timesteps: ', nTimes
01362   WRITE(FileUnit,*) 'Number Values: ', nValues
01363   WRITE(FileUnit,*) 'Number Components: ', nComponents
01364   WRITE(FileUnit,*) 'Number Active: ', nActive
01365 
01366   ! loop through the timesteps, read the values and active values and write
01367   ! them to the text file
01368   do iTime = 1, nTimes
01369     call XF_READ_VECTOR_VALUES_TIMESTEP(a_xVectorId, iTime, nValues, &
01370                                         nComponents, Values, error)
01371     if (error >= 0 .AND. nActive > 0) then
01372       call XF_READ_ACTIVITY_TIMESTEP(a_xVectorId, iTime, nActive, Active, error)
01373     endif
01374 
01375     ! Write the time, min, max, values and active values to the text output
01376     ! file.
01377   WRITE(FileUnit,*) ''
01378     WRITE(FileUnit,*) 'Timestep at  ', Times(iTime)
01379     WRITE(FileUnit,*) 'Min: ', Minimums(iTime)
01380     WRITE(FileUnit,*) 'Max: ', Maximums(iTime)
01381 
01382     WRITE(FileUnit,*) 'Values:'
01383     do i=1, nValues
01384       WRITE(FileUnit,*) Values(1:nComponents,i:i)
01385     enddo
01386     WRITE(FileUnit,*) ''
01387 
01388     WRITE(FileUnit,*) 'Activity:'
01389     WRITE(FileUnit,*) Active(1:nActive)
01390     WRITE(FileUnit,*) ''    
01391   WRITE(FileUnit,*) ''    
01392 
01393   end do
01394 
01395   if (allocated(Times)) then
01396     deallocate(Times)
01397   endif
01398   
01399   if (allocated(Minimums)) then
01400     deallocate(Minimums)
01401   endif
01402 
01403   if (allocated(Maximums)) then
01404     deallocate(Maximums)
01405   endif
01406 
01407   if (allocated(Values)) then
01408     deallocate(Values)
01409   endif
01410 
01411   if (allocated(Active)) then
01412     deallocate(Active)
01413   endif
01414 
01415   return
01416 END SUBROUTINE
01417 ! tdiReadVector
01418 
01419 END MODULE TestDatasets
TestDatasets.f90 tests datasets
00001 MODULE TestGeomPaths
00002 
00003 USE TestDatasets
00004 USE Xmdf
00005 USE ErrorDefinitions
00006 USE XmdfDefs
00007 
00008 CONTAINS
00009 
00010 SUBROUTINE TM_READ_TEST_PATHS(Filename, OutFilename, error)
00011   CHARACTER(LEN=*), INTENT(IN) :: Filename, OutFilename
00012   INTEGER, INTENT(OUT)         :: error
00013   INTEGER                         OutUnit  
00014   INTEGER               :: xFileId, xGroupId
00015   INTEGER                         nGroups, nMaxPathLength, nDims, nPaths, nTimes
00016   INTEGER                         i, j, nStatus
00017   CHARACTER,ALLOCATABLE        :: Paths(:)
00018   REAL(DOUBLE), ALLOCATABLE    :: times(:), locs(:)
00019   REAL(DOUBLE)                    Nullval
00020   CHARACTER(LEN=BIG_STRING_SIZE) :: IndividualPath
00021   INTEGER                           StartLoc
00022   INTEGER, DIMENSION(2)        :: PathIndices
00023   INTEGER                         iTime, iPath
00024 
00025   ! open the XMDF file 
00026   CALL XF_OPEN_FILE(Filename, .FALSE., xFileId, nStatus)
00027   if (nStatus < 0) then
00028    WRITE(*) 'Unable to open XMDF file TM_READ_TEST_PATHS.'
00029     error = nStatus;
00030     return
00031   endif
00032 
00033   ! open the Output file 
00034   OutUnit = 79
00035   OPEN(UNIT=OutUnit, FILE=OutFilename, STATUS='REPLACE', ACTION='WRITE', &
00036      IOSTAT = error)
00037   if (OutUnit == 0) then
00038     call XF_CLOSE_FILE(xFileId, error)
00039     error = -1
00040     return
00041   endif
00042 
00043   ! find the geomotric path groups
00044   ! Get the number and paths of datasets in the file.
00045   CALL XF_GRP_PTHS_SZ_FOR_GEOM_PTHS(xFileId, nGroups,             &
00046                                               nMaxPathLength, nStatus)
00047   if (nStatus >= 0 .AND. nGroups > 0) then
00048     allocate (Paths(nMaxPathLength*nGroups))
00049     CALL XF_GRP_PTHS_FOR_GEOM_PTHS(xFileId, nGroups,                &
00050                                          nMaxPathLength, Paths, nStatus)
00051   endif
00052   if (nStatus < 0) then
00053     CALL XF_CLOSE_FILE(xFileId, nStatus)
00054   error = -1
00055     return
00056   endif
00057   ! Report the number and paths to individual geom paths groups in the file.
00058   WRITE(OutUnit,*) 'Number of geometric paths in file: ', nGroups
00059 
00060   do i = 1, nGroups 
00061     StartLoc = (i-1)*nMaxPathLength + 1
00062   IndividualPath = ''
00063   do j = 1, nMaxPathLength - 1
00064     IndividualPath(j:j) = Paths(StartLoc+j-1)
00065   enddo
00066     WRITE(OutUnit,*) 'Reading particles in group: ', &
00067                                      IndividualPath(1:LEN_TRIM(IndividualPath))
00068 
00069     CALL XF_OPEN_GROUP(xFileId, IndividualPath, xGroupId, nStatus)
00070     if (nStatus >= 0) then
00071       ! read the dimensionality of the paths
00072       CALL XF_GET_PATH_DIMENSIONALITY(xGroupId, nDims, nStatus)
00073       if (nStatus >= 0) then
00074         WRITE(OutUnit,*) 'Group dimensionality:', nDims
00075         ! read the number of paths
00076         CALL XF_GET_NUMBER_OF_PATHS(xGroupId, nPaths, nStatus)
00077         if (nStatus >= 0) then
00078           WRITE(OutUnit,*) 'Number of paths in group:', nPaths
00079           ! read the number of timesteps
00080           CALL XF_GET_NUMBER_OF_TIMES(xGroupId, nTimes, nStatus)
00081           if (nStatus >= 0) then
00082             WRITE(OutUnit,*) 'Number of timesteps in group:', nTimes
00083             ! allocate times array
00084       allocate(times(nTimes))
00085             CALL XF_GET_PATH_TIMES_ARRAY(xGroupId, nTimes, times, nStatus)
00086             if (nStatus >= 0) then
00087                 ! get space for the data location values
00088               allocate(locs(nPaths*nDims))
00089                 ! read null value 
00090               CALL XF_GET_PATH_NULL_VAL(xGroupId, NullVal, nStatus)
00091               if (nStatus >= 0) then
00092                 WRITE(OutUnit,*) 'Null value:', NullVal
00093                 do iTime=1, nTimes
00094                   WRITE(OutUnit,*) 'Timestep: ', times(iTime)
00095                     ! read the data for this timestep
00096                   CALL XF_READ_PATH_LOCATIONS_AT_TIME(xGroupId, iTime,    &
00097                                                      1, nPaths, locs, nStatus)
00098                   if (nStatus >= 0) then
00099                       ! write  the data for this timestep
00100                     WRITE(OutUnit,*) '  X        Y'
00101                     if (nDims == 3) then
00102                       WRITE(OutUnit,*) '       Z'
00103                     endif
00104                     WRITE(OutUnit,*) ''
00105                     do j=1, nPaths 
00106                       if (locs(j*nDims) == NullVal) then
00107                         WRITE(OutUnit,*) 'Particle not active yet'
00108                       else 
00109                         WRITE(OutUnit,*) locs((j-1)*nDims+1), ' ', locs((j-1)*nDims+2)
00110                         if (nDims == 3) then
00111                           WRITE(OutUnit,*) ' ', locs((j-1)*nDims+3)
00112                         endif
00113                         WRITE(OutUnit,*) ''
00114                       endif
00115                     enddo ! Loop through the paths
00116                   endif ! if timestep read
00117                 enddo ! Loop through timesteps
00118               endif ! if null value read
00119               if (allocated(locs)) deallocate (locs)
00120             endif ! if we get get the times array
00121                     ! get space for the data location values - 1 particle 
00122                     ! all times
00123         allocate(locs(nTimes*nDims))
00124             do iPath=1, nPaths
00125                 ! read the values for this particle for all timesteps
00126               CALL XF_READ_PATH_LOCS_FOR_PART(xGroupId, iPath, &
00127                                    1, nTimes, locs, nStatus)
00128               if (nStatus >= 0) then
00129                 ! write  the data for this path
00130                 WRITE(OutUnit,*) 'Time       X        Y'
00131                 if (nDims == 3) then
00132                   WRITE(OutUnit,*) '        Z'
00133                 endif
00134                 WRITE(OutUnit, *) ''
00135                 do j=1, nTimes
00136                   if (locs((j-1)*nDims+1) .NE. NullVal) then
00137                     WRITE(OutUnit,*) times(j), ' ', locs((j-1)*nDims + 1), ' ', &
00138                             locs((j-1)*nDims+2)
00139                     if (nDims == 3) then
00140                       WRITE(OutUnit,*) ' ', locs((j-1)*nDims+3)
00141                     endif
00142                     WRITE(OutUnit,*) ''
00143                   endif
00144                 enddo ! Loop through the times
00145               endif ! if read path locations for particle
00146             enddo ! Loop through the paths
00147             if (allocated(locs)) deallocate(locs)
00148           endif ! if allocation of locs suceeded
00149                 ! get space for the data location values - 2 particle 
00150                 ! all times
00151       allocate(locs(nTimes*nDims*2))
00152           PathIndices(1) = 1
00153           PathIndices(2) = nPaths                
00154           CALL XF_READ_PATH_LOCS_FOR_PARTS(xGroupId, 2,    &
00155                               PathIndices, 1, nTimes, locs, nStatus)
00156           if (nStatus >= 0) then
00157             ! write  the data for these 2 paths
00158             if (nDims == 3) then
00159               WRITE(OutUnit,*) 'Timestep       X1        Y1        Z1        Xn        Yn        Zn'
00160             else
00161               WRITE(OutUnit,*) 'Timestep       X1        Y1        Xn        Yn'
00162             endif
00163             do j=1, nTimes
00164               if (nDims == 3) then
00165                 WRITE(OutUnit,*) times(j), ' ', locs((j-1)*2*nDims+1), ' ',  &
00166              locs((j-1)*2*nDims+2),' ', locs((j-1)*2*nDims+3),' ',       &
00167            locs((j-1)*2*nDims+4), locs((j-1)*2*nDims+5), ' ',locs((j-1)*2*nDims+6)
00168               else
00169                 WRITE(OutUnit,*) times(j),' ', locs((j-1)*2*nDims + 1), ' ',         &
00170                            locs((j-1)*2*nDims+2), ' ',locs((j-1)*2*nDims+3)
00171               endif
00172       enddo
00173         else
00174           WRITE(*,*) 'Error reading path locations for multiple particles'
00175         endif
00176       endif
00177           if (allocated(locs)) deallocate(locs)
00178           if (allocated(times)) deallocate(times)
00179           CALL XF_CLOSE_GROUP(xGroupId, nStatus)
00180         if (nStatus < 0) then
00181           WRITE(*)'Error reading geometric paths..'
00182         endif
00183       endif
00184   endif
00185   enddo ! loop through groups
00186     ! free the paths
00187   if (allocated(Paths)) deallocate(Paths)
00188     ! close the files
00189   close(OutUnit)
00190   CALL XF_CLOSE_FILE(xFileId, nStatus)
00191   error = nStatus;
00192   return
00193 
00194 END SUBROUTINE
00195 ! tmReadTestPaths 
00196 
00197 SUBROUTINE TM_WRITE_TEST_PATHS(Filename, Compression, error)
00198   CHARACTER(LEN=*), INTENT(IN) :: Filename
00199   INTEGER, INTENT(IN)         :: Compression
00200   INTEGER, INTENT(OUT)         :: error 
00201   INTEGER                      nPaths
00202   REAL(DOUBLE), DIMENSION(6)   :: pLocs
00203   REAL, DIMENSION(2)           :: pSpeeds
00204   REAL(DOUBLE)                 NullVal
00205 
00206   REAL                         NullValSinglePrec
00207   INTEGER               xFileId, xPathGroupId, xSpeedId, xPropGroupId
00208   INTEGER                      status
00209   REAL(DOUBLE)                 Timeval
00210 
00211   nPaths = 0
00212   NullVal = -99999.9d0
00213   NullValSinglePrec = -99999.9
00214 
00215   ! create the file
00216   call XF_CREATE_FILE(Filename, .TRUE., xFileId, status)
00217   if (status < 0) then
00218     error = -1
00219     return
00220   endif
00221 
00222   ! create the group to store the particle paths 
00223   call XF_CREATE_GEOMETRIC_PATH_GROUP(xFileId, "particles", &
00224            'abcdefglasdfjoaieur', Compression, xPathGroupId, NullVal, status)
00225   if (status < 0) then
00226     error = -1
00227     return
00228   endif
00229 
00230   ! create the data set to store the speed 
00231   call XF_CREATE_SCALAR_DSET_EXTNDBL(xPathGroupId, 'Vmag', 'm/s', &
00232              TS_SECONDS, NullValSinglePrec, Compression, xSpeedId, status)
00233   if (status < 0) then
00234     error = -1
00235     return
00236   endif
00237 
00238   call XF_CREATE_PROPERTY_GROUP(xSpeedId, xPropGroupId, status)
00239   if (status < 0) then
00240     call XF_CLOSE_GROUP(xSpeedId, status)
00241     error = -1
00242     return
00243   endif
00244   call XF_WRITE_PROPERTY_FLOAT(xPropGroupId, PROP_NULL_VALUE, 1, &
00245                                NullValSinglePrec, -1, status)
00246   call XF_CLOSE_GROUP(xPropGroupId, status)
00247 
00248   ! Setup the arrays for the path group at timestep 0 
00249   ! particle location at the first timestep
00250   nPaths = 1
00251   pLocs(1) = 1.0
00252   pLocs(2) = 2.0
00253   pLocs(3) = 3.0
00254   
00255     ! store the particles for the first timestep
00256   Timeval = 0.0
00257   call XF_WRITE_PARTICLE_TIMESTEP(xPathGroupId, 3, Timeval, nPaths, pLocs, status)
00258   if (status < 0) then
00259     error = -1
00260     return 
00261   endif
00262    ! set up and store the speed at timestep 0
00263   pSpeeds(1) = 1.1
00264   Timeval = 0.0
00265   call XF_WRITE_SCALAR_TIMESTEP(xSpeedId, Timeval, 1, pSpeeds, status) 
00266   if (status < 0) then
00267     error = -1
00268     return
00269   endif
00270 
00271   ! Setup the arrays for the path group at timestep 1 
00272   ! particle location at the first timestep
00273   pLocs(1) = 4.0
00274   pLocs(2) = 5.0
00275   pLocs(3) = 6.0
00276   
00277   ! store the particles for the second timestep
00278   Timeval = 1.0
00279   call XF_WRITE_PARTICLE_TIMESTEP(xPathGroupId, 3, Timeval, nPaths, pLocs, status)
00280   if (status < 0) then
00281     error = -1
00282     return
00283   endif
00284   
00285   ! set up and store the speed at timestep 2
00286   pSpeeds(1) = 1.2
00287   call XF_WRITE_SCALAR_TIMESTEP(xSpeedId, Timeval, 1, pSpeeds, status) 
00288   if (status < 0) then
00289     error = -1
00290     return
00291   endif
00292 
00293   ! Setup the arrays for the path group at timestep 3-add a particle
00294   ! particle location at the first timestep
00295   nPaths = 2
00296   pLocs(1) = 7.0
00297   pLocs(2) = 8.0
00298   pLocs(3) = 9.0
00299   pLocs(4) = -1.0
00300   pLocs(5) = -2.0
00301   pLocs(6) = -3.0
00302   
00303   ! store the particles for the timestep 3
00304   Timeval = 2.0
00305   call XF_WRITE_PARTICLE_TIMESTEP(xPathGroupId, 3, Timeval, nPaths, pLocs, status)
00306   if (status < 0) then
00307     error = -1
00308     return
00309   endif
00310 
00311   ! extend the data set for speed
00312   call XF_EXTEND_SCALAR_DATASET(xSpeedId, 2, status)
00313   if (status < 0) then
00314     error = -1
00315     return
00316   endif
00317 
00318   ! set up and store the speed at timestep 4
00319   pSpeeds(1) = 1.3
00320   pSpeeds(2) = 2.1
00321   call XF_WRITE_SCALAR_TIMESTEP(xSpeedId, Timeval, 2, pSpeeds, status) 
00322   if (status < 0) then
00323     error = -1
00324     return
00325   endif
00326 
00327   ! Setup the arrays for the path group at timestep 3-inactive particle(static)
00328   ! particle location at the first timestep
00329   pLocs(1) = 7.0
00330   pLocs(2) = 8.0
00331   pLocs(3) = 9.0
00332   pLocs(4) = -4.0
00333   pLocs(5) = -5.0
00334   pLocs(6) = -6.0
00335   
00336   ! store the particles for timestep 4
00337   Timeval = 3.0
00338   call XF_WRITE_PARTICLE_TIMESTEP(xPathGroupId, 3, Timeval, nPaths, pLocs, status)
00339   if (status < 0) then
00340     error = -1
00341     return
00342   endif
00343 
00344   ! set up and store the speed at timestep 4
00345   pSpeeds(1) = NullVal
00346   pSpeeds(2) = 2.2
00347   call XF_WRITE_SCALAR_TIMESTEP(xSpeedId, Timeval, 2, pSpeeds, status) 
00348   if (status < 0) then
00349     error = -1
00350     return
00351   endif
00352 
00353   ! close the resources
00354   call XF_CLOSE_GROUP(xSpeedId, status)
00355   call XF_CLOSE_GROUP(xPathGroupId, status)
00356   call XF_CLOSE_FILE(xFileId, status)
00357 
00358   error = 1
00359   return
00360 END SUBROUTINE
00361 
00362 END MODULE TestGeomPaths
TestGeomPaths.f90 tests geometry paths
00001 MODULE TestGrid
00002 
00003 USE ErrorDefinitions
00004 USE XmdfDefs
00005 USE Xmdf
00006 
00007 CHARACTER(LEN=*),PARAMETER :: GRID_CART2D_GROUP_NAME = 'Grid Cart2D Group'
00008 CHARACTER(LEN=*),PARAMETER :: GRID_CURV2D_GROUP_NAME = 'Grid Curv2D Group'
00009 CHARACTER(LEN=*),PARAMETER :: GRID_CART3D_GROUP_NAME = 'Grid Cart3D Group'
00010 
00011 CONTAINS
00012 
00013 !****************************
00014 ! ---------------------------------------------------------------------------
00015 ! FUNCTION  TG_READ_GRID
00016 ! PURPOSE   Read a grid and write data to a text file
00017 ! NOTES     
00018 ! ---------------------------------------------------------------------------
00019 SUBROUTINE  TG_READ_GRID(a_Id, a_Outfile, error)
00020 INTEGER, INTENT(IN) :: a_Id
00021 INTEGER, INTENT(IN)        :: a_Outfile
00022 INTEGER, INTENT(OUT)       :: error
00023 INTEGER nGridType, nExtrudeType, nDims, nCellsI, nCellsJ
00024 INTEGER nCellsK, nLayers, nOrientation, nValsI, nValsJ
00025 INTEGER nValsK, nExtrudeVals, nCompOrigin, nUDir
00026 CHARACTER(265) strGridType, strExtrudeType
00027 LOGICAL*2 bDefined
00028 REAL(DOUBLE) dOrigin(3), dBearing, dDip, dRoll
00029 REAL(DOUBLE), ALLOCATABLE :: dExtrudeVals(:), dCoordI(:), dCoordJ(:)
00030 REAL(DOUBLE), ALLOCATABLE :: dCoordK(:)
00031 INTEGER i
00032 
00033 nGridType = 0
00034 nExtrudeType = 0
00035 nDims = 0
00036 nCellsI = 0
00037 nCellsJ = 0
00038 nCellsK = 0
00039 nLayers = 0
00040 nOrientation = 0
00041 nValsI = 0
00042 nValsJ = 0
00043 nValsK = 0
00044 nExtrudeVals = 0
00045 nCompOrigin = 1
00046 nUDir = 1
00047 bDefined = .FALSE.
00048 dBearing = 0.0
00049 dDip = 0.0
00050 dRoll =0.0
00051 i = 0
00052 error = 1
00053 
00054   ! Grid type
00055 call XF_GET_GRID_TYPE(a_Id, nGridType, error)
00056 if (error < 0) then
00057   return
00058 endif
00059 SELECT CASE (nGridType) 
00060   CASE (GRID_TYPE_CARTESIAN)
00061     strGridType = 'Cartesian'
00062   CASE (GRID_TYPE_CURVILINEAR)
00063     strGridType = 'Curvilinear'
00064   CASE (GRID_TYPE_CARTESIAN_EXTRUDED)
00065     strGridType = 'Cartesian extruded'
00066   CASE (GRID_TYPE_CURVILINEAR_EXTRUDED)
00067     strGridType = 'Curvilinear extruded'
00068   CASE DEFAULT
00069     WRITE(*,*) 'Invalid grid type'
00070     error = -1
00071 END SELECT
00072 WRITE(a_Outfile,*) 'The grid type is: ', strGridType(1:LEN_TRIM(strGridType))
00073 
00074   ! Number of dimensions
00075 call XF_GET_NUMBER_OF_DIMENSIONS(a_Id, nDims, error)
00076 if (error .LT. 0) then
00077   return
00078 endif
00079 if (nDims == 2) then
00080   WRITE(a_Outfile,*) 'The grid is two-dimensional'
00081 elseif (nDims == 3) then
00082   WRITE(a_Outfile,*) 'The grid is three-dimensional'
00083 else
00084   WRITE(*,*) 'The grid dimensions are invalid'
00085   error = -1
00086 endif
00087 
00088   ! Extrusion type if applicable
00089 if (nGridType .EQ. GRID_TYPE_CARTESIAN_EXTRUDED .OR. &
00090     nGridType .EQ. GRID_TYPE_CURVILINEAR_EXTRUDED) then
00091   call XF_GET_EXTRUSION_TYPE(a_Id, nExtrudeType, error)
00092   if (error < 0) then
00093     return
00094   endif
00095   SELECT CASE (nExtrudeType)
00096     case (EXTRUDE_SIGMA)
00097       strExtrudeType = 'Sigma stretch'
00098     case (EXTRUDE_CARTESIAN)
00099       strExtrudeType = 'Cartesian'
00100     case (EXTRUDE_CURV_AT_CORNERS)
00101       strExtrudeType = 'Curvilinear at Corners'
00102     case (EXTRUDE_CURV_AT_CELLS)
00103       strExtrudeType = 'Curvilinear at Cells'
00104   END SELECT
00105   WRITE(a_Outfile,*) 'The grid is extruding using: ', &
00106                      strExtrudeType(1:LEN_TRIM(strExtrudeType))
00107 endif
00108 
00109   ! Origin
00110 call XF_ORIGIN_DEFINED(a_Id, bDefined, error)
00111 if (error < 0) then
00112   return
00113 endif
00114 if (bDefined) then
00115   call XF_GET_ORIGIN(a_Id, dOrigin(1), dOrigin(2), dOrigin(3), error)
00116   if (error < 0) then
00117     return
00118   endif
00119   WRITE(a_Outfile,*) 'The grid origin is ', dOrigin(1), ' ',&
00120                       dOrigin(2), ' ', dOrigin(3)
00121 endif
00122   
00123   ! Orientation
00124 call XF_GET_ORIENTATION(a_Id, nOrientation, error)
00125 if (error < 0) then
00126   return
00127 endif
00128 if (nOrientation == ORIENTATION_RIGHT_HAND) then
00129   WRITE(a_Outfile,*) 'The grid has a right hand orientation'
00130 elseif (nOrientation == ORIENTATION_LEFT_HAND) then
00131   WRITE(a_Outfile,*) 'The grid has a left hand orientation'
00132 else 
00133   WRITE(*,*) 'Invalid grid orientation';
00134   error = -1
00135   return
00136 endif
00137 
00138   ! Bearing
00139 call XF_BEARING_DEFINED(a_Id, bDefined, error)
00140 if (error < 0) then
00141   return
00142 endif
00143 if (bDefined) then
00144   call XF_GET_BEARING(a_Id, dBearing, error)
00145   if (error < 0) then
00146     return
00147   endif
00148   WRITE(a_Outfile,*) 'The grid bearing is ', dBearing
00149 endif
00150 
00151   ! Dip
00152 call XF_DIP_DEFINED(a_Id, bDefined, error)
00153 if (error < 0) then
00154   return
00155 endif
00156 if (bDefined) then
00157   call XF_GET_DIP(a_Id, dDip, error)
00158   if (error < 0) then
00159     return
00160   endif
00161   WRITE(a_Outfile,*) 'The grid Dip is ', dDip
00162 endif
00163 
00164 if (nDims == 3) then
00165   ! Roll
00166   call XF_ROLL_DEFINED(a_Id, bDefined, error)
00167   if (error < 0) then
00168     return
00169   endif
00170   if (bDefined) then
00171     call XF_GET_ROLL(a_Id, dRoll, error)
00172     if (error < 0) then
00173       return
00174     endif
00175     WRITE(a_Outfile,*) 'The grid Roll is ', dRoll
00176   endif
00177 endif
00178 
00179   ! Computational origin
00180 call XF_COMPUTATIONAL_ORIGIN_DEFINED(a_Id, bDefined, error)
00181 if (error < 0) then
00182   return
00183 endif
00184 if (bDefined) then
00185   call XF_GET_COMPUTATIONAL_ORIGIN(a_Id, nCompOrigin, error)
00186   if (error < 0) then
00187     return
00188   endif
00189   WRITE(a_Outfile,*) 'The grid Computational Origin is ', nCompOrigin
00190 else 
00191   WRITE(a_Outfile,*) 'The grid Computational Origin is not defined';
00192 endif
00193 
00194 
00195   ! U Direction
00196 call XF_GET_U_DIRECTION_DEFINED(a_Id, bDefined, error)
00197 if (error < 0) then
00198   return 
00199 endif
00200 if (bDefined) then
00201   call XF_GET_U_DIRECTION(a_Id, nUDir, error)
00202   if (error < 0) then
00203     return
00204   endif
00205     WRITE(a_Outfile,*) 'The grid U Direction is ', nUDir
00206 else 
00207   WRITE(a_Outfile,*) 'The grid U Direction is not defined'
00208 endif
00209 
00210   ! number of cells in each direction
00211 call XF_GET_NUMBER_CELLS_IN_I(a_Id, nCellsI, error)
00212 if (error >= 0) then
00213   call XF_GET_NUMBER_CELLS_IN_J(a_Id, nCellsJ, error)
00214   if ((error >= 0) .AND. (nDims == 3)) then 
00215     call XF_GET_NUMBER_CELLS_IN_K(a_Id, nCellsK, error)
00216   endif
00217 endif
00218 if (error < 0) then
00219   return
00220 endif
00221 WRITE(a_Outfile,*) 'Number of cells in I ', nCellsI
00222 WRITE(a_Outfile,*) 'Number of cells in J ', nCellsJ
00223 if (nDims == 3) then
00224   WRITE(a_Outfile,*) 'Number of cells in K ', nCellsK
00225 endif
00226 
00227   ! Grid coordinates 
00228 if (nGridType == GRID_TYPE_CARTESIAN .OR. &
00229     nGridType == GRID_TYPE_CARTESIAN_EXTRUDED) then
00230   nValsI = nCellsI
00231   nValsJ = nCellsJ
00232   if (nDims == 3) then
00233     nValsK = nCellsK
00234   endif
00235 elseif (nGridType == GRID_TYPE_CURVILINEAR .OR. &
00236         nGridType == GRID_TYPE_CURVILINEAR_EXTRUDED) then
00237   if (nDims == 3) then
00238       ! three dimensions
00239     nValsK = (nCellsI + 1) * (nCellsJ + 1) * (nCellsK + 1)
00240     nValsJ = nValsK
00241     nValsI = nValsJ
00242   else
00243       ! two dimensions
00244     nValsJ = (nCellsI + 1) * (nCellsJ + 1)
00245     nValsI = nValsJ
00246   endif
00247 else
00248   WRITE(*,*) 'Invalid grid type'
00249   error = -1
00250   return
00251 endif
00252 
00253 ALLOCATE(dCoordI(nValsI))
00254 ALLOCATE(dCoordJ(nValsJ))
00255 if (nDims == 3) then
00256   ALLOCATE(dCoordK(nValsK))
00257 endif
00258 
00259 call XF_GET_GRID_COORDS_I(a_Id, nValsI, dCoordI, error)
00260 if (error >= 0) then
00261   call XF_GET_GRID_COORDS_J(a_Id, nValsJ, dCoordJ, error)
00262   if ((error >= 0) .AND. (nDims == 3)) then
00263     call XF_GET_GRID_COORDS_K(a_Id, nValsK, dCoordK, error)
00264   endif
00265 endif
00266 if (error < 0) then
00267   WRITE(*,*) 'Error reading coordinates'
00268   error = -1
00269   return
00270 endif
00271 
00272 WRITE(a_Outfile,*) 'The Coordinates in direction I:'
00273 do i = 1, nValsI 
00274   if (mod(i,5) == 0) then
00275     WRITE(a_Outfile,*) ''
00276   endif
00277   WRITE(a_Outfile,*) dCoordI(i)
00278 enddo
00279 WRITE(a_Outfile,*) ''
00280 
00281 WRITE(a_Outfile,*) 'The Coordinates in direction J:'
00282 do i = 1, nValsJ
00283   if (mod(i,5) == 0) then
00284     WRITE(a_Outfile,*) ''
00285   endif
00286   WRITE(a_Outfile,*) dCoordJ(i)
00287 enddo
00288 WRITE(a_Outfile,*) ''
00289 
00290 if (nDims == 3) then
00291   WRITE(a_Outfile,*) 'The Coordinates in direction K:'
00292   do i = 1, nValsK
00293     if (mod(i,5) == 0) then
00294       WRITE(a_Outfile,*) ''
00295     endif
00296     WRITE(a_Outfile,*) dCoordK(i)
00297   enddo
00298 endif
00299 WRITE(a_Outfile,*) ''
00300 
00301 if (ALLOCATED(dCoordI)) DEALLOCATE(dCoordI)
00302 if (ALLOCATED(dCoordJ)) DEALLOCATE(dCoordJ)
00303 if (ALLOCATED(dCoordK)) DEALLOCATE(dCoordK)
00304 
00305 !  // Extrude data
00306 if (nGridType .EQ. GRID_TYPE_CARTESIAN_EXTRUDED .OR. &
00307     nGridType .EQ. GRID_TYPE_CURVILINEAR_EXTRUDED) then
00308   call XF_GET_EXTRUDE_NUM_LAYERS(a_Id, nLayers, error)
00309   if (error < 0) then
00310     return
00311   endif
00312 
00313   SELECT CASE(nExtrudeType)
00314     case (EXTRUDE_SIGMA)
00315       nExtrudeVals = nLayers
00316     case (EXTRUDE_CURV_AT_CORNERS)
00317       nExtrudeVals = (nCellsI + 1) * (nCellsJ + 1) * nLayers
00318     case (EXTRUDE_CURV_AT_CELLS)
00319       nExtrudeVals = nCellsI * nCellsJ * nLayers
00320   END SELECT
00321 
00322   ALLOCATE(dExtrudeVals(nExtrudeVals))
00323 
00324   call XF_GET_EXTRUDE_VALUES(a_Id, nExtrudeVals, dExtrudeVals, error)
00325   if (error < 0) then
00326     return
00327   endif
00328 
00329   WRITE(*,*) 'The extrude values are:'
00330   do i = 1, nExtrudeVals
00331     if (mod(i,5) == 0) then
00332       WRITE(a_Outfile,*) ''
00333     endif
00334     WRITE(a_Outfile,*) dExtrudeVals(i)
00335   enddo
00336   if (ALLOCATED(dExtrudeVals)) DEALLOCATE(dExtrudeVals)
00337 endif
00338 
00339 return
00340 
00341 END SUBROUTINE TG_READ_GRID
00342 
00343 !****************************
00344 !----------------------------------------------------------------------------
00345 ! FUNCTION   TG_WRITE_TEST_GRID_CART_2D
00346 ! PURPOSE    Write a file that contains data for a 2D Cartesian Grid
00347 ! NOTES      A picture of the grid is in the file (TestGridCart2D.gif)
00348 !            returns TRUE on success and FALSE on failure
00349 !----------------------------------------------------------------------------
00350 SUBROUTINE TG_WRITE_TEST_GRID_CART_2D(Filename, error)
00351 CHARACTER(LEN=*), INTENT(IN) :: Filename
00352 INTEGER, INTENT(OUT) :: error
00353 INTEGER        nDimensions
00354 INTEGER        nCellsI, nCellsJ
00355 INTEGER        nGridType
00356 INTEGER        nCompOrigin, nUDir
00357 REAL(DOUBLE)   dOriginX, dOriginY, dOriginZ
00358 INTEGER        nOrientation
00359 REAL(DOUBLE)   dBearing
00360 REAL(DOUBLE)   PlanesI(5), PlanesJ(5)
00361 INTEGER        i, j, iSpcZone
00362 INTEGER xFileId, xGridId, xCoordId
00363 INTEGER        status
00364 INTEGER        tmpOut1, tmpOut2
00365 
00366   nDimensions = 2
00367   nCellsI = 5
00368   nCellsJ = 5
00369   nGridType = GRID_TYPE_CARTESIAN
00370   nCompOrigin = 4
00371   nUDir = -2
00372   dOriginX = 10.0
00373   dOriginY = 10.0
00374   dOriginZ = 0.0
00375   nOrientation = ORIENTATION_RIGHT_HAND
00376   dBearing = 45.0
00377   xFileId = NONE
00378   xGridId = NONE
00379 
00380     ! Fill in the grid plane data with a constant size of 30
00381   do i = 1, nCellsI
00382     PlanesI(i) = i*30.0
00383   enddo
00384   do j = 1, nCellsJ
00385     PlanesJ(j) = j*30.0
00386   enddo
00387 
00388     ! create the file
00389   call XF_CREATE_FILE(Filename, .TRUE., xFileId, status)
00390   if (status < 0) then
00391     error = -1  
00392     return
00393   endif
00394 
00395     ! create the group to store the grid
00396   call XF_CREATE_GROUP_FOR_GRID(xFileId, GRID_CART2D_GROUP_NAME, xGridId, status)
00397   if (status < 0) then
00398     call XF_CLOSE_FILE(xFileId, error)
00399     error = -1
00400     return
00401   endif
00402 
00403     ! Write the grid information to the file
00404   call XF_SET_GRID_TYPE(xGridId, nGridType, tmpOut1)
00405   call XF_SET_NUMBER_OF_DIMENSIONS(xGridId, nDimensions, tmpOut2)
00406 
00407   if ((tmpOut1 < 0) .OR. (tmpOut2 < 0)) then
00408     call XF_CLOSE_GROUP(xGridId, error)
00409     call XF_CLOSE_FILE(xFileId, error)
00410     error = -1
00411     return
00412   endif
00413 
00414     ! set origin and orientation
00415   call XF_SET_ORIGIN(xGridId, dOriginX, dOriginY, dOriginZ, tmpOut1) 
00416   call XF_SET_ORIENTATION(xGridId, nOrientation, tmpOut2)
00417 
00418   if ((tmpOut1 < 0) .OR. (tmpOut2 .LT. 0)) then
00419     call XF_CLOSE_GROUP(xGridId, error)
00420     call XF_CLOSE_FILE(xFileId, error)
00421     error = -1
00422     return
00423   endif
00424 
00425     ! Set bearing
00426   call XF_SET_BEARING(xGridId, dBearing, tmpOut1)
00427   if (tmpOut1 < 0) then
00428     call XF_CLOSE_GROUP(xGridId, error)
00429     call XF_CLOSE_FILE(xFileId, error)
00430     error = -1
00431     return
<