TABLE OF CONTENTS


read_a_file

[ Top ] [ etsf_io_tutorials ] [ Tutorials ]

NAME

read_a_file

FUNCTION

In this example, we will describe how to read some variables from a file. This is a basic tutorial where the common ETSF routines (low level and specification level) will be used. We will see how to handle errors.

This tutorial assume that the second tutorial (read_write_sub_access) has been done and has produced its file (read_write_sub_access.nc).

To compile this exemple, use (assuming default installation paths):

   ${F90} -I/opt/include/${F90} -o read_a_file read_a_file.f90
          -L/opt/lib -letsf_io -letsf_io_utils -L/usr/lib -lnetcdf

SOURCE

program read_a_file

  use etsf_io_low_level
  use etsf_io
  use etsf_io_tools

  integer :: i, j, k
  logical :: symmetry

  ! Variables related to ETSF reading
  ! ---------------------------------
  ! An id to access the read file.
  integer                 :: ncid
  ! A flag for all etsf_io routine to know if everything went right.
  logical                 :: lstat
  ! The storage for the detailled error.
  type(etsf_io_low_error) :: error_data
  ! The ETSF_IO structure to store all relevant dimensions.
  type(etsf_dims)         :: dims
  ! The ETSF_IO structure to store all the split definitions.
  type(etsf_split)        :: split
  ! The ETSF_IO structure to store the basis set and the k points definitions.
  type(etsf_kpoints)      :: kpoints
  type(etsf_basisdata)    :: basisdata
  type(etsf_main)         :: main

  ! Variables independent from ETSF
  ! -------------------------------
  ! This array will store the wavefunctions.
  double precision, allocatable, target :: pw_coeff(:, :, :, :)
  ! Variables that will be used in the basisdata group.
  integer, allocatable, target          :: number_of_coefficients(:)
  integer, allocatable, target          :: red_coord_pw(:, :, :)
  ! Variables that will be used in the kpoints group.
  double precision, allocatable, target :: red_coord_kpt(:, :)
  double precision, allocatable, target :: kpoint_weights(:)
  ! Variable to store the definition of the basis set
  character(len = etsf_charlen), target :: basis

NOTES

The file is simply open using a low level routine. We simply want to read its content so we specify it in the routine we use.

By default, this routine will check that the header is a valid ETSF one, with the right Convention global attribute, as for the file_format global attribute.

We also check that the file is at least version 2.1 using the optional argument @version_min.

SOURCE

  call etsf_io_low_open_read(ncid, "read_write_sub_access.nc", lstat, &
       & error_data = error_data, version_min = 2.1)
  if (.not. lstat) then
     ! We use the default writing of the error to stderr.
     call etsf_io_low_error_handle(error_data)
     stop
  end if

NOTES

We consider that the file contains the wavefunction description in plane waves. We thus read the dimensions first to allocate the program arrays.

SOURCE

  call etsf_io_dims_get(ncid, dims, lstat, error_data)
  if (.not. lstat) then
     call etsf_io_low_error_handle(error_data)
     stop
  end if

NOTES

The coefficients of the wavefunctions may be splitted. We know this, thanks to the my_<something> attributes of the dims structure we have just read.

In the case of splitting, we allocate a new structure called split with etsf_io_split_allocate() and we read its contents with etsf_io_split_get(). In the case where the file contains no split informations, then all these routines will do nothing.

A split that has been allocated must be freed after use with etsf_io_split_free(). Since the split informations are not relevent for the purpose of this tutorial we will free it just after having output some informations to the user.

SOURCE

  call etsf_io_split_allocate(split, dims)
  call etsf_io_split_get(ncid, split, lstat, error_data)
  if (.not. lstat) then
     call etsf_io_low_error_handle(error_data)
     stop
  end if
  ! We warn the user.
  write(*,"(A,L1)") " Split over kpoints     : ", associated(split%my_kpoints)
  write(*,"(A,L1)") " Split over spins       : ", associated(split%my_spins)
  write(*,"(A,L1)") " Split over states      : ", associated(split%my_states)
  write(*,"(A,L1)") " Split over coefficients: ", associated(split%my_coefficients)
  ! We don't use the split informations further so we free them.
  call etsf_io_split_free(split)

NOTES

Before reading the coefficients of wavefunctions, we will get the definition of the basis set and the kpoints definitions.

This is done using the structure of types etsf_kpoints and etsf_basisdata and the etsf_io level etsf_io_kpoints_get() and etsf_io_basisdata_get(). As for the put routines, we associate the variables we want to read and only them.

Then we read the coefficients as all other variables, using the main group.

SOURCE

  ! The main program allocate memory for storage of the basis set.
  allocate(pw_coeff(dims%real_or_complex_coefficients, &
       & dims%max_number_of_coefficients, &
       & dims%max_number_of_states, &
       & dims%number_of_spins * &
       & dims%number_of_kpoints * &
       & dims%number_of_spinor_components))
  allocate(number_of_coefficients(dims%number_of_kpoints))
  allocate(red_coord_pw(dims%number_of_reduced_dimensions, &
       & dims%max_number_of_coefficients, dims%number_of_kpoints))
  allocate(red_coord_kpt(dims%number_of_reduced_dimensions, dims%number_of_kpoints))
  allocate(kpoint_weights(dims%number_of_kpoints))

  ! We set the associations.
  kpoints%reduced_coordinates_of_kpoints => red_coord_kpt
  kpoints%kpoint_weights => kpoint_weights
  basisdata%basis_set => basis
  basisdata%reduced_coordinates_of_plane_waves%data3D => red_coord_pw
  basisdata%number_of_coefficients => number_of_coefficients
  main%coefficients_of_wavefunctions%data4D => pw_coeff

  ! We call the get routines.
  call etsf_io_kpoints_get(ncid, kpoints, lstat, error_data)
  if (.not. lstat) then
     call etsf_io_low_error_handle(error_data)
     stop
  end if
  call etsf_io_basisdata_get(ncid, basisdata, lstat, error_data)
  if (.not. lstat) then
     call etsf_io_low_error_handle(error_data)
     stop
  end if
  call strip(basis)
  call etsf_io_main_get(ncid, main, lstat, error_data)
  if (.not. lstat) then
     call etsf_io_low_error_handle(error_data)
     stop
  end if

NOTES

We poll the file using an etsf_io_tools routine to know if the number of coefficients have been reduced using the time reversal symmetry at Gamma.

SOURCE

  call etsf_io_tools_get_time_reversal_symmetry(ncid, symmetry, &
       & lstat, error_data)
  if (.not. lstat) then
     call etsf_io_low_error_handle(error_data)
     stop
  end if

NOTES

The following is just output on screen.

SOURCE

  ! We output the informations to the user.
  write(*,*)
  write(*,"(A,I0)") " Number of k points     : ", dims%number_of_kpoints
  write(*,*) "k point weights        : ", kpoints%kpoint_weights
  write(*,"(A)") " k point coordinates    : "
  do i = 1, dims%number_of_kpoints, 1
     write(*, "(3F10.5)") red_coord_kpt(:, i)
  end do
  write(*,*)
  write(*,"(A,A)") " Used basis set         : ", trim(basis)
  write(*,"(A,L1)") " Time reversal symmetry : ", symmetry
  write(*,"(A,I0)") " Max number of coeffs   : ", dims%max_number_of_coefficients
  do i = 1, dims%number_of_kpoints, 1
     write(*,*)
     write(*,"(A,I0)") " Informations at k point: ", i
     write(*,"(A,I0)") " Number of coefficients : ", number_of_coefficients(i)
     write(*,"(A)") " Coordinates of g vector: "
     do j = 1, min(dims%max_number_of_coefficients, 5), 1
        write(*, "(3I5,A,I2,A)") red_coord_pw(:, j, i), " (g vector ", j, ")"
     end do
     if (j < dims%max_number_of_coefficients) then
        write(*,*) "   ..."
     end if
     write(*,"(A)") " Coeffs of wavefunctions: "
     do k = 1, dims%max_number_of_states, 1
        write(*,"(A,I0)") " Band number            : ", k
        do j = 1, min(dims%max_number_of_coefficients, 5), 1
           write(*, "(2F12.5,A,I2,A)") pw_coeff(:, j, k, i), " (g vector ", j, ")"
        end do
        if (j < dims%max_number_of_coefficients) then
           write(*,*) "   ..."
        end if
     end do
  end do

  ! We deallocate everything
  deallocate(pw_coeff)
  deallocate(number_of_coefficients)
  deallocate(red_coord_pw)
  deallocate(kpoint_weights)
  deallocate(red_coord_kpt)

end program read_a_file