Fortran WRITE Not Writing - fortran

I have just added the following section of code to a model built on Fortran. I was told the write statement would print to a file named fort.70 on the local terminal in which the code is compiled and run, but no such file is created. Would anyone be able to point out what is causing this issue and how to solve it? Thank you in advance!
YSTART = 2020
YEND = 2100
DO IYEAR = NYSTART, 351
RI = (YEND-(1749+IYEAR))/(YEND-YSTART)
IF (IYEAR .LT. YSTART) RI = 1.0
IF (IYEAR .GT. YEND) RI = 0.0
WRITE (UNIT=70, FMT=*) IYEAR, RI
DO ISPECY = 1, NTRMAX
EMISSIONS(IYEAR, ISPECY) = RI*EMISSIONS(IYEAR, ISPECY)
END DO
END DO

Related

How to subtract values from one row from values of another row using Fortran

I am fairly new to fortran and am using it for some molecular dynamics work
I have a text file that contains xyz coordinates of multiple atoms. Edit: The data is repetitive
12
xyz
OH2 2.056771 0.152501 -3.407425
H1 2.086389 -0.658114 -2.899234
H2 1.325328 0.643692 -3.033321
OH2 -1.620865 1.026821 -4.353753
H1 -1.045534 1.344086 -5.049863
H2 -1.107708 1.130454 -3.552402
OH2 -2.064113 1.377066 -1.093998
H1 -1.228430 1.344786 -1.559641
H2 -2.692285 1.681116 -1.749120
OH2 1.451636 1.645941 -0.456822
H1 0.841741 1.630468 -1.194400
H2 1.251076 0.850951 0.037141
Where OH2 and H1/H2 are atoms.
I would like to be able subtract the xyz coor of the H2(hydrogen) following the preceding OH2(oxygen) for every OH2 that is recognized.
So far my code looks as follows:
program placepoint
implicit none
real(kind(0.0d0)) :: xCoor(1:12), yCoor(1:12), zCoor(1:12)
real(kind(0.0d0)) :: v1_x, v1_y, v1_z, dOH, nx, ny, nz
real(kind(0.0d0)) :: ip_x, ip_y, ip_z, norm
integer :: j, n
character*20 :: dumch(1:12)
open(unit = 10, file = 'hoh.xyz')
open(unit = 13, file = 'ipcoor.txt')
do j= 1, 12
read(10,*) dumch(j) , xCoor(j), yCoor(j), zCoor(j)
!Calculate vector 1 along OXR-HX bond that can be used to place a point ip (R1)
if (dumch(j) .eq. "OH2") then
v1_x = xCoor(j+2) - xCoor(j)
v1_y = yCoor(j+2) - yCoor(j)
v1_z = zCoor(j+2) - zCoor(j)
dOH = sqrt((v1_x)**2 + (v1_y)**2 + (v1_z)**2)
! Normalize vector
nx = v1_x/dOH
ny = v1_y/dOH
nz = v1_z/dOH
!Place ip at 0.7Å along the OH bond (this is not exactly at the correct HX-OXR-OR angle but these are for dummy atoms and shake should take care of this during dyn runs)
ip_x = xCoor(1) + 0.7*nx
ip_y = yCoor(1) + 0.7*ny
ip_z = zCoor(1) + 0.7*nz
end if
end do
write(13,*) 'ip' , ip_x, ip_y, ip_z, dOH
end program place point
I realize I am being to naive using the j+2 as a identifier to find the value of H2 immediately following the OH2, but unfortunately I have not found any other better way. I also get the fortran error "End of file" after proper compilation. So I am expecting that I am perhaps making multiple mistakes here. Any help with this will be so appreciated!

How to use close statement in case of reading error from file?

My IDE is:
Code::Blocks 20.3 ( compiler: mingw 9.2.0 )
The example code is:
module mod_close_file
implicit none
integer :: n_something
contains
function proc_calling() result(err_loc)
logical :: err_loc
err_loc = .false.
open( unit = 15, file = 'data_aa.txt', action = 'read', status = 'old', err = 100 )
read(15,*, err = 101) n_something
close(unit = 15, status = 'keep' )
return
100 write(*,'(5x,a)') "err_loc - proc_calling - reading format - 100"
err_loc = .true.
!close(unit = 15, status = 'keep' )
return
101 write(*,'(5x,a)') "err_loc - proc_calling - reading format - 101"
err_loc = .true.
!close(unit = 15, status = 'keep' )
end function proc_calling
end module mod_close_file
program close_file
use, non_intrinsic :: mod_close_file
implicit none
logical :: err_glo
err_glo = proc_calling()
if ( err_glo ) stop "err_glo - proc_calling"
end program close_file
In case that the value n_something in the specified file is not an integer the program will report an error. In that case, is it necessary to write the close command after the return command?
You are asking, if you need to close the file prior stopping execution or if it will be closed automatically?
Fortran 2008 Final Draft 9.5.7.1-6 (page 211):
During the completion step (2.3.5) of termination of execution of a program, all units that are connected are closed.
2.3.5-4 (page 33):
Normal termination of execution of an image is initiated when a STOP statement or end-program-stmt is executed.
So no you don't need to close it prior calling STOP, it should close without calling close. (personally I would do it anyway)

Problems with unformatted file write/read compatibility between Intel Fortran and gfortran [duplicate]

This question already has answers here:
Unexpected "padding" in a Fortran unformatted file
(4 answers)
Closed 2 years ago.
I am trying to use a code on both Windows with an Intel compiler and on Mac OS with gfortran 6.5.0 and can't get the gfortran version to read parts of an unformatted file written on Windows. I wrote a test code that has the problematic section and verified it works in writing and reading the file on the Intel compiler and on the gfortran compiler. However, if I comment out the write portion and just try to read the file written on the Windows side of the machine (Parallels) with the gfortran version, some of the data is not read properly. I'm including the test code below. The "cel(1), f_ei,f_en,f_egyro,f_wall,f_ex,f_wallBC =" data are not read correctly (the data before that are read in properly, however). Is there some incompatibility in unformatted files?
PROGRAM Testo
IMPLICIT NONE
INTEGER, PARAMETER :: ncelMAX=6800
REAL*8 :: dt
LOGICAL :: MagON,BFmesh
INTEGER :: nslice_Ver, nslice_verzr, nslice_Edg, nslice_edgzr
INTEGER :: nFluid, nChrge, nCel, nBCs, nEdg, nVer , nCelzr, nBCszr, nEdgzr, &
nVerzr, MinSliceCel, MaxSliceCel, MinSliceCelzr, MaxSliceCelzr
TYPE cell_obj
INTEGER*4 verNo(4),edgNo(4)
INTEGER*4 Bln !BField Mesh
REAL*8 f_ei,f_en,f_egyro,f_wall,f_ex, f_wallBC
END TYPE cell_obj
TYPE(cell_obj) cel(ncelMAX)
dt = 2.0E-8
MagON = .TRUE.
BFmesh = .TRUE.
nslice_Ver = 1
nslice_verzr = 2
nslice_Edg = 3
nslice_edgzr = 4
nFluid = 3
nChrge = 3
nCel = 3000
nBCs = 4000
nEdg = 5000
nVer = 6000
nCelzr = 7000
nBCszr = 8000
nEdgzr = 9000
nVerzr = 10000
MinSliceCel = 100
MaxSliceCel = 200
MinSliceCelzr = 300
MaxSliceCelzr = 400
cel(1)%verNo(1) = 1
cel(1)%verNo(2) = 2
cel(1)%verNo(3) = 3
cel(1)%verNo(4) = 4
cel(1)%edgNo(1) = 1
cel(1)%edgNo(2) = 2
cel(1)%edgNo(3) = 3
cel(1)%edgNo(4) = 4
cel(1)%Bln = 1000
cel(1)%f_ei = 2.0E6
cel(1)%f_en = 2.0E7
cel(1)%f_egyro = 2.0E8
cel(1)%f_wall = 3.0E6
cel(1)%f_ex = 3.0E7
cel(1)%f_wallBC = 3.0E8
OPEN(UNIT=10,FILE='restartData_TEST',FORM='UNFORMATTED')
REWIND(10)
WRITE(10) dt, MagON, nslice_Ver, nslice_Edg, nslice_verzr, nslice_edgzr, BFmesh
WRITE(10) nFluid, nChrge, nCel, nBCs, nEdg, nVer , nCelzr, nBCszr, nEdgzr, nVerzr, MinSliceCel, MaxSliceCel,MinSliceCelzr,MaxSliceCelzr
WRITE(10) cel
CLOSE(10)
OPEN(UNIT=10,FILE='restartData_TEST',FORM='UNFORMATTED')
REWIND(10)
READ(10) dt,MagON,nslice_Ver,nslice_Edg, nslice_verzr, nslice_edgzr, BFmesh
PRINT *, "First line = ", dt,MagON,nslice_Ver,nslice_Edg, nslice_verzr, nslice_edgzr, BFmesh
READ(10) nFluid, nChrge, nCel, nBCs, nEdg, nVer , nCelzr, nBCszr, nEdgzr, nVerzr, MinSliceCel, MaxSliceCel,MinSliceCelzr,MaxSliceCelzr
PRINT *, "Second line = ", nFluid, nChrge, nCel, nBCs, nEdg, nVer , nCelzr, nBCszr, nEdgzr, nVerzr, MinSliceCel, MaxSliceCel,MinSliceCelzr,MaxSliceCelzr
READ(10) cel
PRINT *, "cel(1), verNo(4),edgNo(4) = ",cel(1)%verNo(1),cel(1)%verNo(2),cel(1)%verNo(3),cel(1)%verNo(4),cel(1)%edgNo(1),cel(1)%edgNo(2),cel(1)%edgNo(3),cel(1)%edgNo(4)
PRINT *, "cel(1), Bln = ",cel(1)%Bln
PRINT *, "cel(1), f_ei,f_en,f_egyro,f_wall,f_ex,f_wallBC = ",cel(1)%f_ei,cel(1)%f_en,cel(1)%f_egyro,cel(1)%f_wall,cel(1)%f_ex,cel(1)%f_wallBC
PAUSE 'DONE'
END PROGRAM Testo
There is absolutely no guarantee of the portability of Fortran unformatted files - if you don't use exactly the same hardware and compiler combination (down to the version of the compiler) all bets are off. If you need portability use a formatted file, or possibly stream I/O, or probably best one of the portable data formats such as netcdf (https://www.unidata.ucar.edu/software/netcdf/) or hdf5 (https://www.hdfgroup.org/solutions/hdf5/)
Also please don't use the non standard real*8 and integer*4 - see Fortran 90 kind parameter for how to do it properly

Fortran not writing to screen while file is open

Context: I have the intention to put a certain Fortran subroutine to some tests to see what is wrong with it. It's a numerical simulation and the results are not matching with theory. I use the write statement to do some simple debugging.
The problem: While a file is open in my main routine, I can't seem to write anything to the screen (so I can't check which stuff are being incorrectly passed to a certain chain of subroutines and etc.). It writes all fine when I do it before opening the file, but not inside it (after opening and after closing it).
Here is the code I'm referring to:
WRITE(*,*) 'BLA !<---------------------------------------
WRITE(*,*) 'BLA BLA' !<---------------------------------------
do p=1,N !open files
write(posvel, "(a,i0,a)") "1Dposveldatacomelasticaxy1", p, ".dat"
OPEN(unit=p, file=trim(posvel), status="unknown")
end do
WRITE(*,*) 'bla' !<---------------------------------------
t = tmin
cont = 0
do while ((t + dt) < (tmax))
t = t+dt
cont = cont+1
do i = 1, N
forcax(i) = 0.0d0
forcay(i) = flagy(i)*gravidade(m(i))
do j = 1, N
call coefficients(m(i), m(j), gama_n, k_n)
Fx_elastica(j,i) = 0.0d0
Fy_elastica(j,i) = 0.0d0
Fx_viscosa(j,i) = 0.0d0
Fy_viscosa(j,i) = 0.0d0
WRITE(*,*) 'inside j loop' !<---------------------------------------
if (i .NE. j) then
if ( (abs(sqrt(((xold(i)-xold(j))**2)+(yold(i)-yold(j))**2))).LE. (a(i)+a(j)) ) then
WRITE(*,*) 'inside collision' !<---------------------------------------
call forca_elastica(k_n, a(i), a(j), xold(i), xold(j), yold(i), yold(j), Fx_elastica(j,i),&
Fy_elastica(j,i))
if (Fx_elastica(j,i) .GT. 0.0d0) then
Fx_elastica(i,j) = -Fx_elastica(j,i)
WRITE(*,*) 'elastic x is being passed' !<---------------------------------------
end if
if (Fy_elastica(j,i) .GT. 0.0d0) then
Fy_elastica(i,j) = -Fy_elastica(j,i)
WRITE(*,*) 'elastic y is being passed' !<---------------------------------------
end if
forcax(i) = forcax(i) + flagex(i)*Fx_elastica(j,i)
forcay(i) = forcay(i) + flagey(i)*Fy_elastica(j,i)
end do
call integracao_Euler_xy (xold(i),xnew(i),vxold(i),vxnew(i),forcax(i),yold(i),ynew(i),vyold(i),vynew(i),forcay(i),m(i))
if (mod (cont,5000).eq. 0) then
WRITE(p, *) int(cont/5000), t, xold(i), yold(i), forcax(i), forcay(i) !<---------------------------------------
end if
end do
end do
do p = 1,N !close files
close(unit=p)
end do
Just look at the WRITE statements. The first two appear on the screen alright. After OPENing the files, though... It doesn't. The WRITE statements that depend on conditions are the ones I want to see, but Fortran is not even writing the ones that don't depend on those conditions. Also, take a look at the last WRITE statement - it writes to the file with no problems.
Any ideas on how to fix/contour this problem?
I'm using Fortran 90.
You should not use small numbers for unit numbers. You are looping from 1 with a step of 1. You are almost guaranteed to hit the pre-connected units for standard output and standard input. See also Standard input and output units in Fortran 90?
Loop from some larger number, say from 100, or use newunit= and store the unit numbers in some array.
Also note that p has value N+1 at WRITE(p, *) ....

Fortran Error - attempt to call a routine with argument number three as a real(kind =1) when procedure was required

I have a fortran project linked to various subroutines, which are called from the main program. Variables are passed using modules. I can compile the code without any error. When I run the code, during the subroutine call i get an error "attempt to call a routine with argument number three as a real(kind =1) when procedure was required. I am not sure where i am going wrong. Can someone point out the error? Your help is very much appreciated. The error appears when the subroutine 'ncalc' is called inside the loop
program partbal
use const
use times
use density
use parameters
use rateconst
use ploss
implicit none
integer :: i
real :: nclp_init, ncl2p_init, ncln_init, ne_init
real :: ncl_init, ncl2_init, Te_init, neTe_init
open (10,file='in.dat')
read (10,*)
read (10,*) pressure
read (10,*)
read (10,*) P, pfreq, duty
read (10,*)
read (10,*) nclp_init, ncl2p_init, ncln_init, Te_init, Ti
pi = 3.14159265
R = 0.043
L = 0.1778
Al = 2*pi*R*R
Ar = 2*pi*R*L
V = pi*R*R*L
S = 0.066
e = 1.6e-19
me = 9.1e-31
mCl = 35.5/(6.023e26)
mCl2 = 2*mCl
k = 1.3806e-23
vi = (3*Ti*e/(53.25/6.023e26))**0.5
ncl2_init = pressure*0.1333/(1.3806e-23*298)/2
ncl_init = ncl2_init
ne_init = nclp_init + ncl2p_init - ncln_init
tot_time = 1/(pfreq*1000)
off_time = duty*tot_time
npoints = 10000
dt = tot_time/npoints
neTe_init = ne_init*Te_init
t_step = 0
call kcalc(Te_init)
call param(nclp_init, ncl2p_init, ncln_init, ne_init, ncl_init,ncl2_init, Te_init, Ti)
do i = 1, npoints, 1
t_step = i*dt + t_step
if (t_step > 0 .and. t_step <= 500) then
Pabs = 500
else if (t_step > 500) then
Pabs = 0
end if
if (i <= 1) then
call ncalc(ne_init, ncl_init, ncl2_init, nclp_init, ncln_init, ncl2p_init)
call powerloss(ne_init, ncl_init, ncl2_init, Pabs, neTe_init)
Te = neTe/ne
call kcalc(Te)
call param(nclp, ncl2p, ncln, ne, ncl, ncl2, Te, Ti)
else
call ncalc(ne, ncl, ncl2, nclp, ncln, ncl2p)
call powerloss(ne, ncl, ncl2, Pabs, neTe)
Te = neTe/ne
call kcalc(Te)
call param(nclp, ncl2p, ncln, ne, ncl, ncl2, Te, Ti)
end if
!open( 70, file = 'density.txt' )
!open( 80, file = 'Te.txt')
!do i = 1, 1001, 1
! np(i) = ncl2p(i) + nclp(i)
!write (70, *) ncl(i), ncl2(i), ncl2p(i), nclp(i), np(i), ncln(i), ne(i)
!close(70)
!write (80, *) Te(i), phi(i)
!close(80)
!end do
end do
end program partbal
subroutine ncalc(n_e, n_cl, n_cl2, n_clp, n_cln, n_cl2p)
use parameters
use const
use density
use rateconst
use times
implicit none
real :: n_e, n_cl, n_cl2, n_clp, n_cln, n_cl2p
nclp = (((kCliz*n_e*n_cl)+((kpair+kdisiz)*n_e*n_cl2)-(5e-14*n_clp*n_cln)-(S*n_clp/V)-((hlclp*Al+hrclp*Ar)*n_clp*ubclp))*dt)+n_clp
ncl2p = (((kCl2iz*n_e*n_cl2)-(5e-14*n_cl2p*n_cln) - (((hlcl2p*Al + hrcl2p*Ar)*n_cl2p*ubcl2p)/V)-(S*n_cl2p/V))*dt)+n_cl2p
ncln = ((((katt+kpair)*n_e*n_cl2)-(5e-14*n_clp*n_cln)-(5e-14*n_cl2p*n_cln)-(kdet*n_e*n_cln)-(S*n_cln/V)-(taun*(Al+Ar)/V))*dt)+n_cln
ne = ncl2p+nclp-ncln
ncl = ((((2*kdis+katt+kdisiz)*n_e*n_cl2)-(kCliz*n_e*n_cl)+(5e-14*n_cl2p *n_cln)+(2*5e-14*n_clp*n_cln)+ (kdet*n_e*n_cln) - (300*n_cl) + ((hlclp*Al + hrclp*Ar)*n_clp*ubclp/V)-(S*n_cl/V))*dt)+n_cl
ncl2 = ((n_cl2(1) + (5e-14*n_cl2p*n_cln) - ((kCl2iz+kdis+katt+kpair+kdisiz)*n_e*n_cl2) + (0.5*300*n_cl) + ((hlcl2p*Al + hrcl2p*Ar)*n_cl2p*ubcl2p/V)-(S*n_cl2/V))*dt)+n_cl2
return
end subroutine ncalc
In the line in subroutine ncalc immediately before the return statement, you have a reference to n_cl2(1) very early in the right hand side of the assignment statement. n_cl2 has not been declared as an array, therefore the compiler assumes that it must be a reference to a function that takes a single default integer argument. Because n_cl2 is a dummy argument, the it then expects you to provide a function for the corresponding actual argument when the routine is called.
(How your compiler manages to compile the preceding references to n_cl2 is a bit of a mystery - I suspect this error violates the syntax rules and hence you should see some sort of compile time diagnostic.)
Given you are using modules, it seems odd that you have not placed the ncalc routine in a module. If you did so, the error would probably become a compile time error rather than a runtime.