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!
I am trying to increase the number of possible steps in the following Fortran self avoiding random walk program.
Increasing the number of steps would result in more accuracy regarding the square mean distance
I would appropriate your solutions and suggestions.
PROGRAM Two_dimensional_Self_Avoiding__Random_Walks
implicit none
integer, dimension(:,:), allocatable :: lattice
integer, dimension(1:46):: na
integer :: i,x,y,xt,yt,id,step,xx, ns,n,ii,III,choice
real :: r,dis,dis2,square,d,d2
Logical :: terminate,newsite
CALL RANDOM_SEED()
! intial values for end to end distance
read(*,*) choice
if (choice == 1) then
print*, ' Enter ns and n '
read(*,*) ns
na = (/(III, III=5, 50, 1)/)
do ii= 1, 46
dis = 0.0; dis2 = 0.0
n = na(ii)
allocate(lattice(-n:n,-n:n))
CALL walks() ! self avoiding walks
IF (ALLOCATED (lattice)) DEALLOCATE (lattice)
enddo
elseif (choice == 2) then
print*, ' Enter ns and n '
read(*,*) ns , n
dis = 0.0; dis2 = 0.0
allocate(lattice(-n:n,-n:n))
CALL walks()
endif
CONTAINS
SUBROUTINE walks
DO i = 1,ns
lattice = 0; x = 0; y = 0
step = 0; terminate = .FALSE.
DO WHILE ((.NOT. terminate) .AND. (step <= n))
xt = x; yt = y
xx = lattice(x+1,y)+lattice(x-1,y) &
+lattice(x,y+1)+lattice(x,y-1)
IF (xx == 4) THEN
terminate = .TRUE.
ELSE
newsite = .FALSE.
DO WHILE (.NOT. newsite)
CALL RANDOM_NUMBER(r)
id = INT(r*4.0)
IF (id == 0) THEN
x = xt + 1; y = yt
ELSEIF (id == 1) THEN
x = xt - 1; y = yt
ELSEIF (id == 2) THEN
x = xt; y = yt + 1
ELSEIF (id == 3) THEN
x = xt; y = yt - 1
ENDIF
IF (lattice(x,y) == 0) newsite = .TRUE.
ENDDO
step = step + 1; lattice(x,y) = 1
ENDIF
write(7,*) x,y
ENDDO
write(10,*),step
square = float(x**2+y**2)
dis = dis + sqrt(square); dis2 = dis2 + square
d = dis/ns; d2=dis2/ns
ENDDO
write(11,*), ns,n, d, d2
print*, ns,n, d, d2
END SUBROUTINE walks
END PROGRAM Two_dimensional_Self_Avoiding__Random_Walks
The following is a program for self avoiding random walk. The program works fine but I need to make a minor modification but I do not know how.
Currently the program receives n and ns as inputs and then calculates a distance (dis). I want the program to receive more than one n and calculate the distance for each n.
Example of current output
n = 100 ns = 100 dis = 10.8
I want the program to output
n = 100 ns = 100 dis = 10.8
n = 200 ns = 100 dis = 11.6
and go on for all input vales of n.
This can be done by running the program every time with different n but I need to do it with one run.
PROGRAM Two_dimensional_Self_Avoiding__Random_Walks
implicit none
integer, dimension(:,:), allocatable :: lattice
integer :: i,x,y,xt,yt,id,step,xx, ns,n
real :: r,dis,dis2,square,d,d2
Logical :: terminate,newsite
print*, ' Enter ns and n '
read(*,*) ns,n
allocate(lattice(-n:n,-n:n))
CALL RANDOM_SEED()
dis = 0.0; dis2 = 0.0 ! intial values for end to end distance
CALL walks() ! self avoiding walks
dis = dis/float(ns); dis2 = dis2/float(ns)
print*,ns,n,dis,dis2
CONTAINS
SUBROUTINE walks
DO i = 1,ns
lattice = 0; x = 0; y = 0
step = 0; terminate = .FALSE.
!do ii = 1, n
DO WHILE ((.NOT. terminate) .AND. (step <= n))
xt = x; yt = y
xx = lattice(x+1,y)+lattice(x-1,y) &
+lattice(x,y+1)+lattice(x,y-1)
IF (xx == 4) THEN
terminate = .TRUE.
ELSE
newsite = .FALSE.
DO WHILE (.NOT. newsite)
CALL RANDOM_NUMBER(r)
id = INT(r*4.0)
IF (id == 0) THEN
x = xt + 1; y = yt
ELSEIF (id == 1) THEN
x = xt - 1; y = yt
ELSEIF (id == 2) THEN
x = xt; y = yt + 1
ELSEIF (id == 3) THEN
x = xt; y = yt - 1
ENDIF
IF (lattice(x,y) == 0) newsite = .TRUE.
ENDDO
step = step + 1; lattice(x,y) = 1
ENDIF
write(10,*),step
!print*, x,y
write(7,*) x,y
ENDDO
square = float(x**2+y**2)
dis = dis + sqrt(square); dis2 = dis2 + square
d = dis/ns; d2=dis2/ns
write(8,*) step, d, d2
!enddo
ENDDO
END SUBROUTINE walks
END PROGRAM Two_dimensional_Self_Avoiding__Random_Walks
I am trying to run a stress autocorrelation function code to calculate the stress autocorrelation function,then from there I would like to calculate viscosity using Green -Kubo equation. Now the Fortran code I have does not read out my stress data in order to calculate stress auot-correlarion function. Anyone can please help me with this. I have attached my code and data I want to correlate. Hope to here from you soon.
Here is the error
./a.out
**** Program Stress_autocorrelation ****
Calculation of time Correlation Functions
Enter data file name
DFILE
Enter results file name
RFILE
0.00000000
0.00000000
0.00000000
0.00000000
0.00000000
0.00000000
0.00000000
0.00000000
At line 106 of file main.f95 (unit = 10, file = 'DFILE')
Fortran runtime error: Bad value during floating point read
Code and below is Input data:
! Program to claculate pressure autocorrelation function
program stress_autocorrelation
implicit none
common / block1 / STORA, STORB, STORC, STORD,STORE,STORF,STORG, STORH, STORI
common / block2 / PA, PB, PC, PD, PE, PF, PG, PH , PI
common / block3 / PACF, ANORM
! *******************************************************************
! ............ PRINCIPAL VARIABLES............
!
! ** integer N Number of atoms
! ** integer NSTEP Number of steps on the tape
! ** integer IOR Interval for time origins
! ** integer NT Correlation length, Including T=0
! ** integer NTIMOR Number of time origin
! ** integer NLABEL Label for step (1,2,3.....Nstep)
!
!
! ** real PACF(NT) The pressure correlation function
! ** NSTEP and NT should be multiples of IOR.
! ** PA,PB,PC = Pxx,Pxy,Pxz
! ** PD,PE,PF = Pyx,Pyy,Pyz
! ** PG,PH,PI = Pzx,Pzy,Pzz
!
!
! ...............ROUTINES REFERENCED..........................
!
! ....Subroutine Store (J1)..........
!Routine to store the data for correlation
! .....Subroutine Corr (J1,J2,IT).........
!Routine to correlate the stored time origin
!
!
! .....................USAGE..............................
!
! Data in file DFILE on fortrran UNIT DUNIT
! Results in File RFILE on fortran UNIT RUNIT
! *******************************************************************
integer N, NSTEP, IOR, NT, NDIM, DUNIT, RUNIT, NTIMOR
integer FULLUP
parameter ( N = 78, NSTEP = 10, IOR = 4, NT = 8 )
parameter ( DUNIT = 10, RUNIT = 11 )
parameter ( NDIM = NT / IOR + 1, NTIMOR = NSTEP / IOR )
parameter ( FULLUP = NDIM - 1 )
real PA(N), PB(N), PC(N), PD(N), PE(N), PF(N), PG(N), PH(N), PI(N)
real STORA(NDIM,N), STORB(NDIM,N), STORC(NDIM,N),STORD(NDIM,N), STORE(NDIM,N),STORF(NDIM,N),STORG(NDIM,N),STORH(NDIM,N)
real STORI(NDIM,N)
REAL PACF(NT), ANORM(NT)
integer S(NTIMOR), TM(NTIMOR)
integer TS, TSS, L, NINCOR, K, R, JA, IB, IN, IA, JO, I
integer NLABEL
character DUMMY * 5
character DFILE * 115
character RFILE * 115
! *******************************************************************
write(*,'('' **** Program Stress_autocorrelation **** '')')
write(*,'('' Calculation of time Correlation Functions '')')
!.....READ IN FILE NAMES.........
write(*,'('' Enter data file name'')')
read (*,'(A)') DFILE
write (*,'('' Enter results file name'')')
read (*,'(A)') RFILE
!......INITIALIZE COUNTERS.......
NINCOR = FULLUP
JA = 1
IA = 1
IB = 1
!........ZERO ARRAYS.............
do 5 I = 1, NT
PACF(I) = 0.0
ANORM(I) = 0.0
write(*,*) PACF(I)
5 continue
!..........OPEN DATA FILE AND RESULTS FILE...........
open ( UNIT = DUNIT, FILE = DFILE, STATUS = 'OLD', FORM = 'FORMATTED')
open ( UNIT = RUNIT, FILE = RFILE, STATUS = 'NEW' )
!.........CALCULATION BEGINS............
do 40 L = 1, NTIMOR
JA = JA + 1
S(L) = JA - 1
read ( DUNIT, '(A5,I4)') DUMMY, NLABEL
do 7 R = 1, N
read (DUNIT,'(F9.6,8(9X,F9.6))')PA(R),PB(R),PC(R),PD(R),PE(R),PF(R),PG(R),PH(R),PI(R)
7 continue
TM(L) = NLABEL
write(*,*) TM(L)
!.......STORE STEP AS A TIME ORIGIN......
call STOREE ( JA )
!........CORRELATE THE ORIGINS IN STORE......
do 10 IN = IA, L
TSS = TM(L) - TM(IN)
TS = TSS + 1
JO = S(IN) + 1
call CORR ( JO, JA, TS )
10 continue
!Read IN data between time origins. This can
!Be conveniently stored IN element 1 of the
!Array storx etc. and can then ben correlated
!With the time origins
do 30 K = 1, IOR - 1
read ( DUNIT, '(A5,I4)') DUMMY, NLABEL
do 15 R = 1, N
read ( DUNIT,'(F17.14,8(13X,F17.14))')PA(R),PB(R),PC(R),PD(R),PE(R),PF(R),PG(R),PH(R),PI(R)
15 continue
call STOREE ( 1 )
do 20 IN = IA, L
TSS = NLABEL - TM(IN)
TS = TSS + 1
JO = S(IN) + 1
call CORR ( JO, 1, TS )
20 continue
30 continue
if ( L .GE. FULLUP ) then
if ( L .EQ. NINCOR ) then
NINCOR = NINCOR + FULLUP
JA = 1
endif
IA = IA + 1
endif
40 continue
close ( DUNIT )
!.....NORMALISE CORRELATION FUNCTIONS.......
PACF(1) = PACF(1) / ANORM(1) / REAL ( N )
do 50 I = 2, NT
PACF(I) = PACF(I) / ANORM(I) / REAL ( N ) / PACF(1)
50 continue
write ( RUNIT, '('' Pressure ACF '')')
write ( RUNIT, '(I6,E15.6)') ( I, PACF(I), I = 1, NT )
close ( RUNIT )
stop
end
subroutine STOREE ( J1 )
common / BLOCK1 / STORA, STORB, STORC, STORD,STORE,STORF,STORG,STORH,STORI
common/ BLOCK2 / PA, PB, PC, PD, PE, PF, PG, PH, PI
! *******************************************************************
!.........SUBROUTINE TO STORE TIME ORIGINS..............
! *******************************************************************
integer J1
integer N, NT, IOR, NDIM
parameter ( N = 78, NT = 8, IOR =4 )
parameter ( NDIM = NT / IOR + 1 )
real STORA(NDIM,N), STORB(NDIM,N), STORC(NDIM,N),STORD(NDIM,N)
real STORE(NDIM,N),STORF(NDIM,N),STORG(NDIM,N),STORH(NDIM,N),STORI(NDIM,N)
real PA(N), PB(N), PC(N), PD(N), PE(N), PF(N),PG(N), PH(N), PI(N)
integer I
do 10 I = 1, N
STORA(J1,I) = PA(I)
STORB(J1,I) = PB(I)
STORC(J1,I) = PC(I)
STORD(J1,I) = PD(I)
STORE(J1,I) = PE(I)
STORF(J1,I) = PF(I)
STORG(J1,I) = PG(I)
STORH(J1,I) = PH(I)
STORI(J1,I) = PI(I)
10 continue
return
end
subroutine CORR ( J1, J2, IT )
common / block1 / STORA, STORB, STORC, STORD,STORE,STORF,STORG,STORH,STORI
common/ block3 / PACF, ANORM
! *******************************************************************
!......SUBROUTINE TO CORRELATE TIME ORIGINS....
! *******************************************************************
integer J1, J2, IT
integer N, NT, IOR, NDIM
parameter ( N = 78, NT = 8, IOR = 4 )
parameter ( NDIM = NT / IOR + 1 )
real STORA(NDIM,N), STORB(NDIM,N), STORC(NDIM,N),STORD(NDIM,N)
real STORE(NDIM,N),STORF(NDIM,N),STORG(NDIM,N),STORH(NDIM,N),STORI(NDIM,N)
real PACF(NT), ANORM(NT)
integer I
!********************************************************************
do 10 I = 1, N
PACF(IT) = PACF(IT) + STORA(J1,I) * STORA(J2,I) &
+ STORB(J1,I) * STORB(J2,I) &
+ STORC(J1,I) * STORC(J2,I) &
+ STORD(J1,I) * STORD(J2,I) &
+ STORE(J1,I) * STORE(J2,I) &
+ STORF(J1,I) * STORF(J2,I) &
+ STORG(J1,I) * STORG(J2,I) &
+ STORH(J1,I) * STORH(J2,I) &
+ STORI(J1,I) * STORI(J2,I)
10 continue
ANORM(IT) = ANORM(IT) + 1.0
return
end
Data: has 9 columns
-9.568336E+00 -1.615161E+00 1.042644E+00 -1.615161E+00 -1.131916E+01 -6.979813E-01 1.042644E+00 -6.979813E-01 -1.182917E+01
-4.765572E-01 9.005122E-01 -2.282920E+00 9.005122E-01 -3.827857E+00 -3.206736E+00 -2.282920E+00 -3.206736E+00 -6.252462E+00
-1.012710E+01 4.672368E-01 8.791873E-02 4.672368E-01 -4.680832E+00 -5.271814E-01 8.791873E-02 -5.271814E-01 -1.898345E-01
-7.699012E+00 -9.906154E-01 7.450304E-01 -9.906154E-01 -1.061230E+00 -3.546956E+00 7.450304E-01 -3.546956E+00 -6.843898E+00
-3.544260E+00 4.254020E+00 -1.963602E+00 4.254020E+00 3.740858E+00 -4.587760E+00 -1.963602E+00 -4.587760E+00 -6.776258E+00
1.755595E-01 -9.625855E-01 -2.395960E+00 -9.625855E-01 -1.701399E+00 -8.483695E-01 -2.395960E+00 -8.483695E-01 -4.165223E+00
-3.244186E+00 5.540608E+00 -4.951768E-01 5.540608E+00 3.068601E+00 -1.613010E-01 -4.951768E-01 -1.613010E-01 -5.641277E+00
-8.985849E+00 1.870244E+00 -2.295795E-01 1.870244E+00 -4.635924E+00 -4.787461E+00 -2.295795E-01 -4.787461E+00 -3.014272E+00
-1.651073E-01 -6.326584E-01 -3.028051E+00 -6.326584E-01 -2.621833E+00 -2.640439E+00 -3.028051E+00 -2.640439E+00 1.668877E+00
1.250349E+00 3.054784E+00 -2.898975E+00 3.054784E+00 8.419503E-01 9.620184E-01 -2.898975E+00 9.620184E-01 1.479256E+00
-7.796195E-01 1.942983E+00 -2.736569E+00 1.942983E+00 6.073043E+00 -2.520281E+00 -2.736569E+00 -2.520281E+00 -9.600832E-01
4.697066E-01 3.138124E+00 -1.092573E+00 3.138124E+00 -2.099285E+00 -1.581031E+00 -1.092573E+00 -1.581031E+00 -6.285002E-01
3.017532E-01 -9.701574E-02 1.611936E+00 -9.701574E-02 -1.762075E+00 -3.401961E+00 1.611936E+00 -3.401961E+00 -6.889746E-01
1.177410E-01 5.090611E-01 1.452691E-01 5.090611E-01 5.695570E+00 -3.573245E+00 1.452691E-01 -3.573245E+00 -1.099615E+00
-5.180126E+00 -1.876409E-01 -2.067182E+00 -1.876409E-01 1.611177E+00 5.458450E-01 -2.067182E+00 5.458450E-01 1.026071E+00
1.477567E+00 1.598949E+00 -1.577546E+00 1.598949E+00 3.933810E+00 -2.698132E+00 -1.577546E+00 -2.698132E+00 3.485029E+00
-2.533324E+00 1.753033E+00 1.425241E-01 1.753033E+00 2.406501E+00 -1.147217E+00 1.425241E-01 -1.147217E+00 3.065603E-01
-2.360274E+00 1.312721E+00 -3.711419E-01 1.312721E+00 2.556935E+00 3.152605E-01 -3.711419E-01 3.152605E-01 3.378170E+00
-1.698217E+00 1.105760E+00 3.780822E-01 1.105760E+00 2.736574E+00 7.920578E-01 3.780822E-01 7.920578E-01 -6.596856E-01
-5.099544E+00 1.647542E-01 -1.036544E+00 1.647542E-01 3.845429E+00 -1.034068E+00 -1.036544E+00 -1.034068E+00 -3.152053E+00
-2.686567E+00 1.335786E+00 -1.889911E-01 1.335786E+00 9.755267E-01 9.322043E-01 -1.889911E-01 9.322043E-01 3.229615E-01
1.542994E-01 3.104663E+00 -1.634353E-01 3.104663E+00 4.090105E+00 -1.128244E+00 -1.634353E-01 -1.128244E+00 -2.909383E-01
-4.235419E-01 1.554157E+00 3.475430E+00 1.554157E+00 4.701173E+00 -1.789414E+00 3.475430E+00 -1.789414E+00 1.517218E+00
-8.054924E-01 -1.167935E+00 -1.123460E+00 -1.167935E+00 1.169303E+00 -2.171076E+00 -1.123460E+00 -2.171076E+00 -5.636150E+00
i would like someone to assist in converting this code to C++
c ----------------------------------------------------------------------
c Calculate pressure based on the generalized Peng-Robinson equation of state.
c for water.
c Variables Used ...
c T ... temperature (K)
c P ... vapor pressure (MPa)
c V ... volume (m^3/kmol)
c ----------------------------------------------------------------------
c Instructor: Nam Sun Wang
c ----------------------------------------------------------------------
common /cblock/T
c Program Header -------------------------------------------------------
print *, 'This program calculates pressure based on the'
print *, 'generalized Peng-Robinson equation of state for water.'
print *, ' '
c Temperature ----------------------------------------------------------
print *, 'Enter temperature (K): '
read *, T
c Generate a table of P at different values of V in 0.5 increments.
print *, ' '
print *, '------------------------'
print *, ' Volume Pressure '
print *, '(m^3/kmol) (MPa) '
print *, '------------------------'
c xx.x123456789012345678 --- ruler
do i=1, 100
V = 0.5*float(i)
print 650, V, P(V)
end do
c Some formats ---------------------------------------------------------
650 format(f7.1, 1p, e18.6)
end
c ----------------------------------------------------------------------
function P(V)
c ----------------------------------------------------------------------
c Calculate pressure based on the generalized Peng-Robinson equation of state.
c for water.
c ----------------------------------------------------------------------
common /cblock/T
c Gas Constant ---------------------------------------------------------
R = 8.314E-3 ! (in MPa m3/kmol K)
c Critical parameters for water ----------------------------------------
Tc = 647.3 ! (critical temperature in K)
Pc = 22.048 ! (critical pressure in MPa)
w = 0.344 ! (acentric factor, dimensionless)
c Peng-Robinson EOS parameters -----------------------------------------
xk = 0.37464 + 1.54226*w - 0.26992*w*w
alpha = ( 1. + xk*(1.-sqrt(T/Tc)) )**2
a = 0.45724*R*R*Tc*Tc*alpha/Pc
b = 0.07780*R*Tc/Pc
P = R*T/(V-b) - a/(V*(V+b)+b*(V-b))
end
Here are Some conversions for you, have a go and then post your results. We can then help you complete it.
a message
print *, '...'
replace with
cout << "..."
a counted loop
do i=1, 100
...
end do
replace with
for(int i = 1; i <= 100; ++i) {
....
}
a comment
.... ! A comment
replace with
....; // a comment
a variable
X = 99.879
replace with
float X = 99.879
a function
function P(V)
.
.
.
P = .... ! the result
replace with
double P(double V){
.
.
.
return ....; // the result
}
I know this is late but I came here looking for an answer and found another solution.
Try the package f2c. I just used it on your code sample and it worked perfectly. Although it is a bit ugly as it links to libraries that emulate Fortran functions like print but you could just use the main logic part and do the I/O yourself.