I have following line in the middle of data:
Lattice="14.118460851 0.0 0.0 0.0 14.296182713 0.0 0.0 0.0 13.970592923" Properties=species:S:1:pos:R:3:forces:R:3 energy=-1558.14096522 stress="0.01917032092545686 0.004679034697346147 -0.002715150092396106 0.004679034697346147 0.02270959988283459 -0.0033934086475967138 -0.002715150092396106 -0.0033934086475967138 0.02437748091748962" free_energy=-1558.0193295 pbc="T T T"
In this line, each keyword contains specific properties.
Here, I want to read this line and define some values to variable or array. I hope to read 9 real numbers after 'Lattice="' and store them as a, b, c, d, e, f, and I hope to read a single real number after 'energy=' and store it as g.
But I don't know how to write a Fortran script to read and recognize 'Lattice="' and 'energy=', and then select 9 or one next numbers.
How can I do this using Fortran?
As with Steve's answer: a combination of index(), plus reading from an internal file (i.e from a character string). Whether it works will be a bit sensitive to how precise your input file is (right case; no spaces around '=' etc.) You might want to pre-process the string to ensure that.
It's possible that Fortran's newer stream IO might give an easier solution, but I haven't tried that.
subroutine getLatticeEnergy( str, L, E )
use iso_fortran_env, only: real64
implicit none
character(len=*), intent(in) :: str
real(real64), intent(out) :: L(9)
real(real64), intent(out) :: E
integer start, finish
! Find start of lattice components
start = index( str, 'Lattice="') + 9
finish = start + index( str(start:), '"' ) - 2
read( str(start:finish), * ) L
! Find start of energy
start = index( str, 'energy=') + 7
read( str(start:), * ) E
end subroutine getLatticeEnergy
!=======================================================================
program test
use iso_fortran_env, only: real64
implicit none
character(len=:), allocatable :: str
real(real64) L(9)
real(real64) E
str = 'Lattice="14.118460851 0.0 0.0 0.0 14.296182713 0.0 0.0 0.0 13.970592923"' &
// ' Properties=species:S:1:pos:R:3:forces:R:3 energy=-1558.14096522 stress="0.01917032092545686' &
// ' 0.004679034697346147 -0.002715150092396106 0.004679034697346147 0.02270959988283459' &
// ' -0.0033934086475967138 -0.002715150092396106 -0.0033934086475967138 0.02437748091748962"' &
// ' free_energy=-1558.0193295 pbc="T T T"'
call getLatticeEnergy( str, L, E )
write( *, * ) "Lattice = ", L
write( *, * ) "Energy = ", E
end program test
Output:
Lattice = 14.118460851000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 14.296182713000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 13.970592923000000
Energy = -1558.1409652200000