Search code examples
textfortranread-data

Read data from updating dat file in Fortran


I have an output from a code in dat format. The file has the following format

Text
Text
Text
Text
3241234234
234234
23423423
34123424
1324234
iteration pressure temperature density
1 1234 312 2.12
2 1235 321 2.15
3 1234 312 2.12
4 1235 321 2.15
5 1234 312 2.12
6 1235 321 2.15
pressure temperature density
7 1234 312 2.12
8 1235 321 2.15
9 1234 312 2.12
10 1235 321 2.15
11 1234 312 2.12
warning pressure update is not linked
12 1235 321 2.15
pressure temperature density
13 1234 312 2.12
14 1235 321 2.15
15 1234 312 2.12
warning pressure update is not linked
16 1235 321 2.15
17 1234 312 2.12
18 1235 321 2.15
end of iterations
simulation time
end loop
end of code

I have written a code in which I open the dat file. Read it as a text using iostat. Then I skip the header text line and random numbers etc up to iteration line. Then read the numbers (iterations pressure temperature density). But I am stuck at few places where I need help.

  1. The opening text lines are not constant. Sometimes these are 4 lines and sometimes five or six. Every time I have to adjust the number of lines and compile it again. Is there a way to automate this. I mean the code itself will count the text lines and skip them. Same is the next random numbers.

  2. What I want to do is to skip the lines from start to iteration. But these are changing too. Read the numeric data only

    1 1234 312 2.12 2 1235 321 2.15 3 1234 312 2.12 4 1235 321 2.15 5 1234 312 2.12 6 1235 321 2.15 7 1234 312 2.12 8 1235 321 2.15 9 1234 312 2.12 10 1235 321 2.15 11 1234 312 2.12 12 1235 321 2.15 13 1234 312 2.12 14 1235 321 2.15 15 1234 312 2.12 16 1235 321 2.15 17 1234 312 2.12 18 1235 321 2.15

and then write this data as the output file.


Solution

  • The following code does what you asked for. This code assumes that the data is stored in input.dat and will print the output to output.dat. The logic is quite simple. First, the lines are read until a line starting with the keyword WORD_OF_INTEREST (here iteration) is detected. Then we start reading the remaining lines, assuming that there are 4 fields per line (i.e. iteration, pressure temperature density). Lines that do not obey this pattern are skipped.

    The comments will help you understand the algorithm.

        program readData
    
           implicit none
    
           integer, parameter :: wp = selected_real_kind(15) ! double-precision floats
           integer, parameter :: ip = selected_int_kind(8) ! long integers
    
           character (len = *), parameter ::               &
              WORD_OF_INTEREST = 'iteration'      
    
           integer (kind = ip), parameter ::               & 
              LENGTH_WORD = len(WORD_OF_INTEREST),         &! calculate length of the word you are trying to find; that is, "iteration"
              NO_READING_ERROR = 0,                        &
              END_OF_FILE = -1
    
           integer (kind = ip) ::                          &
              handleFileInput,                             &
              handleFileOutput,                            &
              iteration,                                   &
              idError
    
           real (kind = wp) ::                             &
              pressure,                                    &
              temperature,                                 &
              density
    
           character (len = LENGTH_WORD) ::                & 
              line
    
        ! --------------------------------------------------------------------------------------------------
        ! --------------------------------------------------------------------------------------------------
        ! --------------------------------------------------------------------------------------------------
        ! Start executable section 
        ! --------------------------------------------------------------------------------------------------
        ! --------------------------------------------------------------------------------------------------
        ! --------------------------------------------------------------------------------------------------
    
           ! Open the input and output files
           open(newUnit = handleFileInput, file = 'input.dat')
           open(newUnit = handleFileOutput, file = 'output.dat')
    
           ! Read data file until a line starting with WORD_OF_INTEREST is encountered
           do
    
              read(handleFileInput, *) line
              if (line == WORD_OF_INTEREST) exit
    
           end do
    
    
           ! Read the rest of the file
           do
    
              read(handleFileInput, *, iostat = idError) iteration, pressure, temperature, density
    
              ! Handle different types of errors
              if (idError == NO_READING_ERROR) then
    
                 write(handleFileOutput, *) iteration, pressure, temperature, density
    
              else if (idError == END_OF_FILE) then
    
                 exit
    
              else
    
                 continue 
    
              end if
    
           end do
    
    
    
           close(handleFileInput)
           close(handleFileOutput)
    
        end program readData