I have a problem with a Fortran project and figured out maybe you could help me.
I'm using codeblocks as IDE and there you can make projects, so I created a project with two files in it: a main program and a fuction (I don't know what else to use, I could use something different from a fuction maybe).
So I have my function that reads values from a .txt and saves them as real numbers and everything is working good. What I want to do is, from the file main, call this function and save in main the data I collected with my function so that the main remains cleaner.
How would I do that? I can post the whole script if you want, but I don't think it would add that much more.
EDIT: As you asked, here it is (uncut):
program main
! Variables
real :: d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, &
Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax
real :: data_input
! Call the funcion
data_input=data_module(d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, &
Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax)
! Error
if (data_input/=1) then
print*, 'ERROR: data_module did not work'
end if
!Just to show it
print*,'After'
print*, d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, &
Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax
end program main
real function data_module ()
! Variables
implicit none
integer :: flag_read=0, w_int, d_int
real:: coefficient, d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, &
Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax
character (LEN=35) :: starting_string, name*15, coefficient_string*20, w_string, d_string, number_format
character :: w*2, d
! Open file
open (11, file = 'Data.txt', status = 'old', access = 'sequential', form = 'formatted')
! Read a new line for every iteration
sentence_reader: do while (flag_read==0)
read (11, fmt='(A)', iostat = flag_read) starting_string
! Error
if (flag_read>0)then
print*, 'ERROR: could not read data'
stop
end if
! Skip useless lines
if (starting_string(1:1)=='%' .OR. starting_string(1:1)==' ') then
cycle
end if
! Exit when you're done
if (flag_read<0)then
exit sentence_reader
end if
! Just stuff to prepare it
name=trim(starting_string(1:index(starting_string, '=')-1))
coefficient_string=trim(adjustl(starting_string(index(starting_string, '=')+1:index(starting_string,';')-1)))
if (scan(coefficient_string,'E')/=0) then
w_string=coefficient_string
w_int=len_trim(w_string)
write(w, '(BN,I2)') w_int
d_string=coefficient_string(index(coefficient_string, '.')+1:index(coefficient_string, 'E')-1)
d_int=len_trim(d_string)
write(d, '(BN,I1)') d_int
!All togheter
number_format='(BN,F' // trim(w) // '.' // d // ')'
else
w_string=coefficient_string
w_int=len_trim(w_string)
write(w, '(BN,I1)') w_int
d_string=coefficient_string(index(coefficient_string, '.')+1:len_trim(coefficient_string))
d_int=len_trim(d_string)
write(d, '(BN,I1)') d_int
number_format='(BN,F' // trim(w) // '.' // d // ')'
end if
! Read the number
read(coefficient_string,number_format) coefficient
! Save where it's needed (is there an easier way to do it?)
select case (name)
case ('d1')
d1=coefficient
case ('r1')
r1=coefficient
case ('r2')
r2=coefficient
case ('a')
exit
case ('teta')
exit
case ('freq')
freq=coefficient
case ('Dt')
exit
case ('mu')
mu=coefficient
case ('g0')
g0=coefficient
case ('r_t')
r_t=coefficient
case ('height')
height=coefficient
case ('lx')
lx=coefficient
case ('ly')
ly=coefficient
case ('lz')
lz=coefficient
case ('m_c0')
m_c0=coefficient
case ('Jx')
Jx=coefficient
case ('Jy')
Jy=coefficient
case ('Jz')
Jz=coefficient
case ('gmax')
gmax=coefficient
case ('I_s')
I_s=coefficient
case ('K')
K=coefficient
case ('Vmin')
Vmin=coefficient
case ('tsp_0')
tsp_0=coefficient
case ('Fmax')
Fmax=coefficient
case ('Isp')
Isp=coefficient
case ('n')
n=coefficient
case ('tfin')
tfin=coefficient
case ('cont')
cont=coefficient
case ('Tmax')
Tmax=coefficient
case default
print*, 'Variable ', name, ' is not recognized'
end select
end do sentence_reader
! Other stuff I need
teta=atan((r1 - r2)/d1)
a=sqrt(d1**2 + (r1 - r2)**2)
Dt=1/freq
r=r_t + height
omega=(mu/(r**3))**0.5
H=(r*mu)**0.5
Jx0=Jx - I_s
Jy0=Jy - I_s
Jz0=Jz - I_s
c1=Isp*g0
F=n*Fmax
DV=(F/m_c0)*tsp_0
! Shows that the function is correctly executed
data_module=1
print*,'Before'
print*, d1, r1, r2, a, teta, freq, Dt, mu, g0, r_t, height, r, omega, H, lx, ly, lz, m_c0, &
Jx, Jy, Jz, gmax, I_s, K, Jx0, Jy0, Jz0, Vmin, tsp_0, Fmax, Isp, c1, n, F, DV, tfin, cont, Tmax
end function data_module
PS. I know modules, but with open and all the other stuff I couldn't get them to work. Would love to.
What I want to do is to pass the data d1, r1, ecc that I collected in data_module to main and save them in main, but doing it this way it doesn't save them (if you run it, when you print them "before" everything is fine, when you print them "after" you got all zeros.
real function data_module (d1,r1,r2,...)(If you actually use amodulethis sort of mistake would give you a pretty clear error message )subroutinenot afunctionsince you never set the function return value (I don't seedata_module= ..anywhere) or try to use it.