Hopefully, someone can help me out with this problem. It would be greatly appreciated.
Background. I am working on extending a piece of Legacy code for our research group that does some heat transfer, thermal convection, etc. type of numerical modeling. What I am trying to do is read in a temperature input file so that I can adjust the temperature of the model as it model progresses in time. While that info is largely irrelevant. I keep getting a segmentation fault upon trying to close a file I opened and am reading from. I have attached the code below along with what a typical temperature input file may look like (but greatly simplified since there will be thousands of data points). Any help would be appreciated in eliminating the segmentation fault and/or correcting the code to make it more efficient.
subroutine Read_Temp_Input(Temp_in)!(dt)!(filename)!,dt,Temp_out)
implicit none
character*80 :: filename
integer, parameter :: dp = selected_real_kind(15)
real(kind=dp), allocatable, dimension(:,:) :: Temp_in, Temp_out
integer :: i,j,ierror,n
real (kind=dp) :: in_time, in_temp, dt, inter_time, inter_temp, max_time
character*80 :: line
!Variable definitions
!in_time is the time given from the input file
!in_temp is the temp given from the input file
!inter_time is the interpolated time using dt, max_time, and linear interpolation
!inter_temp is the interpolated temp using dt, max_time, and linear interpolation
!max_time is the largest time value in the input file
!dt is the time step utilized in the simulation, provided by main routine
!read in the temperature input file
filename = "temps.txt"
Open(UNIT=1,FILE=filename,ACTION="Read")
!Determine the size of the necessary allocation
n = 0
do
Read(1,*,iostat=ierror) in_time, in_temp
if (ierror.ne.0) then
exit
else
print*, in_time, in_temp
n = n + 1
endif
enddo
!Allocate the Temp_in array to a n x 2 array.
allocate(Temp_in(n,2))
close(unit=1)
Open(UNIT=1,FILE=filename,ACTION="Read")
n = 0
do
Read(1,*,iostat=ierror) in_time, in_temp
if (n.ne.0) then
if (ierror.ne.0) then
exit
else
Temp_in(n-1,0) = in_time
Temp_in(n-1,1) = in_temp
endif
endif
n = n + 1
enddo
dt = 0.5_dp
print*, 'is the fault before here?'
close(1)
print*, 'is the fault here?'
end subroutine
Temperature File
Time Temp
1 300
2 400
3 500
5 600
Attached is also an output I have been getting. I will get rid of the random print statements in time, just using them as a way to test where my code is breaking.
Thank you for your help, it is greatly appreciated.
Fortran arrays are 1-based by default, and so is Temp_in
in your example. So the lines
Temp_in(n-1,0) = in_time
Temp_in(n-1,1) = in_temp
will write out of bounds (for n=1
, both are out of bounds and the first one is always out of bounds).
You can make the compiler check that for you by using the --check=bounds
flag, it will then throw a runtime error if you attempt to access an array in that manner.
So either allocate Temp_in
as
allocate(Temp_in(0:n-1,0:1))
or use 1-based indices for writing as a solution.
UPDATE
Also, reading the first line of the example temps.txt
file will fail when determining the number of entries, as it tries to read two real
but instead finds something else. So you will need to do a dummy read after opening the file to read in the first line (or use the same additional check as in the second loop)
Open(UNIT=1,FILE=filename,ACTION="Read")
! read in the first line and throw it away
read(1,*)
! go on