read_xyz_string Subroutine

public pure subroutine read_xyz_string(xyz_string, geom, error)

Parse molecular geometry from XYZ format string

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: xyz_string
type(geometry_type), intent(out) :: geom
type(error_t), intent(out) :: error

Calls

proc~~read_xyz_string~~CallsGraph proc~read_xyz_string read_xyz_string proc~error_set error_t%error_set proc~read_xyz_string->proc~error_set proc~int_to_string int_to_string proc~read_xyz_string->proc~int_to_string proc~split_lines split_lines proc~read_xyz_string->proc~split_lines

Called by

proc~~read_xyz_string~~CalledByGraph proc~read_xyz_string read_xyz_string proc~read_xyz_file read_xyz_file proc~read_xyz_file->proc~read_xyz_string proc~initialize_system_geometry initialize_system_geometry proc~initialize_system_geometry->proc~read_xyz_file

Variables

Type Visibility Attributes Name Initial
character(len=256), private :: element
integer, private :: iatom
integer, private :: io_stat
character(len=:), private, allocatable :: lines(:)
integer, private :: nlines
real(kind=dp), private :: x
real(kind=dp), private :: y
real(kind=dp), private :: z

Source Code

   pure subroutine read_xyz_string(xyz_string, geom, error)
      !! Parse molecular geometry from XYZ format string
      character(len=*), intent(in) :: xyz_string
      type(geometry_type), intent(out) :: geom
      type(error_t), intent(out) :: error

      character(len=:), allocatable :: lines(:)
      integer :: nlines, iatom, io_stat
      character(len=256) :: element
      real(dp) :: x, y, z

      ! Split into lines
      call split_lines(xyz_string, lines, nlines)

      if (nlines < 2) then
         call error%set(ERROR_PARSE, "XYZ file must have at least 2 lines (natoms + comment)")
         return
      end if

      ! Read number of atoms from first line
      read (lines(1), *, iostat=io_stat) geom%natoms
      if (io_stat /= 0) then
         call error%set(ERROR_PARSE, "Failed to read number of atoms from first line")
         return
      end if

      if (geom%natoms < 0) then
         call error%set(ERROR_PARSE, "Number of atoms must be non-negative")
         return
      end if

      ! Store comment line
      geom%comment = trim(adjustl(lines(2)))

      ! Check we have enough lines
      if (nlines < 2 + geom%natoms) then
         call error%set(ERROR_PARSE, "XYZ file has insufficient lines: expected "// &
                        trim(int_to_string(2 + geom%natoms))//", got "// &
                        trim(int_to_string(nlines)))
         return
      end if

      ! Allocate arrays
      allocate (character(len=MAX_ELEMENT_SYMBOL_LEN) :: geom%elements(geom%natoms))
      allocate (geom%coords(3, geom%natoms))

      ! Read atom data
      do iatom = 1, geom%natoms
         read (lines(2 + iatom), *, iostat=io_stat) element, x, y, z
         if (io_stat /= 0) then
            call error%set(ERROR_PARSE, "Failed to parse atom data on line "// &
                           trim(int_to_string(2 + iatom))//": '"// &
                           trim(lines(2 + iatom))//"'")
            return
         end if

         geom%elements(iatom) = trim(adjustl(element))
         geom%coords(1, iatom) = x
         geom%coords(2, iatom) = y
         geom%coords(3, iatom) = z
      end do

   end subroutine read_xyz_string