Program that decodes a message in Fortran - fortran

How can I take a text file that first lists a 2x2 matrix that was used to encrypt a message, followed by one integer per line (total 32 lines) that encode a message? Basically, I want to create a program that will:
1) Read and invert the 2x2 encryption matrix
2) Write a subroutine for determinant function to help invert matrix
3) Decrypt by reading in two integers at a time and inserting them into a character string (chracter*32 = full string)
And finally, print the hidden message.
I am pretty new to Fortran (and programming in general) but here is what I have so far and would appreciate any help.
program Program2
implicit none
INTEGER, DIMENSION(2,2) :: M, M2, M3
INTEGER :: B(32)
INTEGER :: row,col,max_rows,max_cols, Det, i, n, a
max_rows = 2
max_cols = 2
open(11, file = 'Data3.txt')
DO row = 1,max_rows
READ(11,*) (M(row,col),col=1,max_cols)
END DO
!Finding the inverse of a 2x2 matrix and reassigning.
M2(1,1) = M(2,2)
M2(2,2) = M(1,1)
M2(1,2) = -M(1,2)
M2(2,1) = -M(2,1)
! Could not get determinant function to yield correct answer (calc by hand)
M3 = M2/-1
print*, M3
print*, Det
open(11, file = 'Data3.txt')
i = a
do i = 1, 16
read(11,*) n
print*, n
enddo
close(11)
end program Program2
! Determinant function for a 2x2 matrix
function Determinant(M2) result(Det)
implicit none
INTEGER, DIMENSION(2,2) :: M, M2, M3
INTEGER :: B(32)
INTEGER :: row,col,max_rows,max_cols, Det, i, n, a
Det = M2(1,1)*M2(2,2) - M2(1,2)*M2(2,1)
end function Determinant
Here is the text file (or just a copy of what it looks like):
3 11
2 7
1488
955
703
458
1379
887
1465
943
1196
764
1392
895
1433
922
1403
902
1372
876
1467
943
697
454
1518
975
1596
1026
1392
895
1536
988
726
473

First of all, to get your Determinant function working, it needs a type (see Function has no implicit type):
INTEGER :: Determinant
Edit:
No need to be referenced as external, as pointed out in the comments. Thanks.
Then it can be used and it works well:
Det = Determinant(M2)
print*, Det
prints -1.
Second, could you please provide more explanation about what you want to do in step 3) so that we can help you out.
3) Decrypt by reading in two integers at a time and inserting them into a character string (chracter*32 = full string)

Related

Infinite do loop issue

Just to preface this question, I am a couple weeks new to Fortran and I have run into an infinite do loop error when running the actual program.
I am 99% sure that the infinite sequence is coming from the do loop, but I thought I should ask just to be sure. I am not sure what part of the do loop is causing the infinite do loop but any help would be greatly appreciated!
Here is the code:
implicit none
! Declare variables - Add variables as necessary (integer only!)
! M will store the encoding matrix, MInv will store its inverse
! Decoded_message will store the decoded message
integer :: M(2,2), MInv(2,2), Determinant, a, b, c, d, detM, i, v(:,:), ascIIcode(:,:)
allocatable :: v, ascIIcode
character*32 :: Decoded_Message
! open data file and read in the encoding matrix
open(42,file='Data3.txt')
read(42,*) M(1,1), M(1,2)
read(42,*) M(2,1), M(2,2)
! Invert the encoding matrix and store it in MInv
detM = determinant(M)
MInv(1,1) = +detM *M(2,2)
MInv(1,2) = -detM *M(2,1)
MInv(2,1) = -detM *M(1,2)
MInv(2,2) = +detM *M(1,1)
! Processing steps required:
! Read from the file in 2 numbers at a time and store in a vector array
do i = 2, 31
allocate (v(2,1), ascIIcode(2,1))
read(42,*) v(1,1)
read(42,*) v(2,1)
! decode the 2 numbers read in (1) by multiplying Minv by the vector array from (1)
ascIIcode(1,1) = ((MInv(1,1)*v(1,1))+(MInv(1,2)*v(2,1)))
ascIIcode(2,1) = ((MInv(2,1)*v(1,1))+(MInv(2,2)*v(2,1)))
! Insert the result from (2) into the character string Decoded_Message. To concatinate
Decoded_Message = char(ascIIcode(1,1))//char(ascIIcode(2,1))
! Use a loop that advances in steps of 2 and goes to 31
deallocate (v)
deallocate (ascIIcode)
end do
! print results.
print*, Decoded_Message
! close files
close(42)
end program Decode
integer function Determinant(M)
! This function computes the determinant of matices of size 2 or 3
! M is the matrix for which the determinant is calculated (square matrix only)
! n is the number of rows or columns in M
implicit none
integer :: M(2,2), a, b, c, d, e, f, g, h, i, Det
do
a = M(1,1)
b = M(1,2)
c = M(2,1)
d = M(2,2)
Det = (a*d)-(b*c)
end do
end function Determinant

FFTW Array Order in Fortran

I'd like to use FFTW to compute the Fourier Harmonics for a 2D dataset. And I think I'm getting the hang of it but I need to 'decipher' the complex output in terms of harmonics. First here's my toy code:
PROGRAM FFTW_TEST
USE, intrinsic :: iso_c_binding
IMPLICIT NONE
INTEGER :: i, j, n, m, l, k
REAL :: pi2, norm, norm2
REAL(C_DOUBLE), POINTER, DIMENSION(:) :: theta, func
COMPLEX(C_DOUBLE_COMPLEX), POINTER, DIMENSION(:) :: fmn_1d
REAL(C_DOUBLE), POINTER, DIMENSION(:,:) :: func_2d, r_2d, i_2d
COMPLEX(C_DOUBLE_COMPLEX), POINTER, DIMENSION(:,:) :: fmn_2d
INCLUDE 'fftw3.f03'
TYPE(C_PTR) :: plan
TYPE(C_PTR) :: real_1d, complex_1d
TYPE(C_PTR) :: real_2d, complex_2d
pi2 = 8.0 * ATAN(1.0)
!------ 1D Example
n = 64
real_1d = FFTW_ALLOC_REAL(INT(n,C_SIZE_T))
complex_1d = FFTW_ALLOC_COMPLEX(INT(n,C_SIZE_T))
CALL C_F_POINTER(real_1d, func, [n])
CALL C_F_POINTER(complex_1d, fmn_1d, [n])
ALLOCATE(theta(n))
FORALL(i=1:n) theta(i) = DBLE(i-1)/DBLE(n)
FORALL(i=1:n) func(i) = 1.0+2.0*cos(2*pi2*theta(i))-3.0*cos(3*pi2*theta(i)) ! Even Values
! FORALL(i=1:n) func(i) = 0.0+2.0*sin(4*pi2*theta(i))-3.0*sin(5*pi2*theta(i)) ! Odd Values
WRITE(401,*) func(1:n)
CALL FLUSH(401)
norm = n/2
norm2 = n
plan = FFTW_PLAN_DFT_R2C_1D(n, func, fmn_1d, FFTW_ESTIMATE)
CALL FFTW_EXECUTE_DFT_R2C(plan, func, fmn_1d)
CALL FFTW_DESTROY_PLAN(plan)
func = REAL(fmn_1d)/norm
func(1) = 2*func(1)
WRITE(402,*) func; CALL FLUSH(402)
func = -AIMAG(fmn_1d)/norm
func(1) = 2*func(1) ! note should be zero
WRITE(403,*) func; CALL FLUSH(403)
plan = FFTW_PLAN_DFT_C2R_1D(n, fmn_1d, func, FFTW_ESTIMATE)
CALL FFTW_EXECUTE_DFT_C2R(plan, fmn_1d, func)
CALL FFTW_DESTROY_PLAN(plan)
WRITE(404,*) func/norm2; CALL FLUSH(404)
CALL FFTW_FREE(real_1d)
CALL FFTW_FREE(complex_1d)
IF (ASSOCIATED(theta)) DEALLOCATE(theta)
!------- 2D Example
m=16
n=8
real_2d = FFTW_ALLOC_REAL(INT(m*n,C_SIZE_T))
complex_2d = FFTW_ALLOC_COMPLEX(INT(m*n,C_SIZE_T))
CALL C_F_POINTER(real_2d, func_2d, [m,n])
CALL C_F_POINTER(complex_2d, fmn_2d, [m,n])
PRINT *,LBOUND(func_2d,DIM=1)
ALLOCATE(fmn_1d(m),r_2d(m,n),i_2d(m,n))
func_2d = 0.5
DO i = 1, m
DO j = 1, n
DO l = 0, 8
DO k = -4,4
func_2d(i,j) = func_2d(i,j) + (l*100+k) * cos(l*pi2*(i-1)/m + k*pi2*(j-1)/n)
END DO
END DO
END DO
WRITE(501,*) func_2d(i,1:n); CALL FLUSH(501)
END DO
! Note in the m direction we read m=0,1,2,3,4...
! in the n direction we read n=0..nx/2,-nx/2+1...-1
norm = m*n/2
norm2 = norm*2
plan = FFTW_PLAN_DFT_R2C_2D(n, m, func_2d, fmn_2d, FFTW_ESTIMATE)
CALL FFTW_EXECUTE_DFT_R2C(plan, func_2d, fmn_2d)
CALL FFTW_DESTROY_PLAN(plan)
r_2d = REAL(fmn_2d)/norm
r_2d(1,1) = r_2d(1,1)/2
DO i = 1, m
WRITE(502,*) r_2d(i,1:n); CALL FLUSH(502)
END DO
i_2d = -AIMAG(fmn_2d)/norm
i_2d(1,1) = i_2d(1,1)/2
DO i = 1, m
WRITE(503,*) i_2d(i,1:n); CALL FLUSH(503)
END DO
DO i = 1, m
DO j = 1, n
IF (abs(r_2d(i,j))>1.0E-5 .or. ABS(i_2d(i,j))>1.0E-5) &
WRITE(6,*) i,j,r_2d(i,j),i_2d(i,j)
END DO
END DO
plan = FFTW_PLAN_DFT_C2R_2D(n, m, fmn_2d, func_2d, FFTW_ESTIMATE)
CALL FFTW_EXECUTE_DFT_C2R(plan, fmn_2d, func_2d)
CALL FFTW_DESTROY_PLAN(plan)
DO i = 1, m
WRITE(504,*) func_2d(i,1:n)/norm2; CALL FLUSH(504)
END DO
CALL FFTW_FREE(real_2d)
CALL FFTW_FREE(complex_2d)
IF (ASSOCIATED(fmn_1d)) DEALLOCATE(fmn_1d)
END PROGRAM FFTW_TEST
Now I'd like to extract the harmonics of a function which looks like:
$A_{mn} \cos(m\theta+n\phi)$, where $\theta$ and $\phi$ are the real-space grid. First, taking the real part of the complex array appears to be correct. The harmonics seem correct for simple functions. However, in the final test case it seems that the array has an odd ordering. Here's the ordering
m/n
0/0 1/0 2/0 3/0 4/0 5/0 6/0 7/0 8/0 0/1 1/1 2/1 3/1 4/1 5/1 6/1
7/1 8/1 0/2 1/2 2/2 3/2 4/2 5/2 6/2 7/2 8/2 0/3 1/3 2/3 3/3 4/3
5/3 6/3 7/3 8/3 0/4 1/4 2/4 3/4 5/4 6/4 7/4 8/4 ?/? ?/? ?/? ?/?
For reference here's what I'd expect the ordering to look like:
m/n
0/0 1/0 2/0 3/0 4/0 5/0 6/0 7/0 8/0 -7/0 -6/0 -5/0 -4/0 -3/0 -2/0 -1/0
0/1 1/1 2/1 3/1 4/1 5/1 6/1 7/1 8/1 -7/1 -6/1 -5/1 -4/1 -3/1 -2/1 -1/1
0/2 1/2 2/2 3/2 4/2 5/2 6/2 7/2 8/2 -7/2 -6/2 -5/2 -4/2 -3/2 -2/2 -1/2
It seems like the code is just treating the array like a linear array. But what what I can read in the FFTW documentation this should not be the case. One dimension of the array should correspond to the transforms along one dimension and the other the other. Thus in some sense we should be able to read off m and n harmonics.
Can someone explain how the complex array should be ordered in terms of harmonics and the proper normalizations?

'x' argument of 'log10' intrinsic at (1) must be real [duplicate]

I want to calculate z value as the coordinate in range of x:-50~50 and y:-50~50 like below code.
program test
implicit none
! --- [local entities]
real*8 :: rrr,th,U0,amp,alp,Ndiv
real*8 :: pi,alpR,NR,Rmin,Rmax,z
integer :: ir, i, j
do i=0, 50
do j=0, 50
th=datan2(i,j)
pi=datan(1.d0)*4.d0
!
Ndiv= 24.d0 !! Number of circumferential division
alp = 90.d0/180.d0*pi !! phase [rad]
U0 = 11.4d0 !! average velocity
amp = 0.5d0 !! amplitude of velocity
Rmin = 10 !! [m]
Rmax = 50 !! [m]
NR = 6.d0 !! Number of radial division
!
rrr=dsqrt(i**2+j**2)
ir=int((rrr-Rmin)/(Rmax-Rmin)*NR)
alpR=2.d0*pi/dble(Ndiv)*dble(mod(ir,2))
z=U0*(1.d0+amp*dsin(0.5d0*Ndiv*th+alp+alpR))
write(*,*) 'i, j, z'
write(*,*) i, j, z
end do
end do
stop
end program test
But I couldn't make it work like below error. I think because i, j are in datan(i,j). How should I change these code?
test.f90:10.16:
th=datan2(i,j)
1
Error: 'y' argument of 'datan2' intrinsic at (1) must be REAL
test.f90:21.16:
rrr=dsqrt(i**2+j**2)
1
Error: 'x' argument of 'dsqrt' intrinsic at (1) must be REAL
Inspired by the comments of #Rodrigo Rodrigues, #Ian Bush, and #Richard, here is a suggested rewrite of the code segment from #SW. Kim
program test
use, intrinsic :: iso_fortran_env, only : real64
implicit none
! --- [local entities]
! Determine the kind of your real variables (select one):
! for specifying a given numerical precision
integer, parameter :: wp = selected_real_kind(15, 307) !15 digits, 10**307 range
! for specifying a given number of bits
! integer, parameter :: wp = real64
real(kind=wp), parameter :: pi = atan(1._wp)*4._wp
real(kind=wp) :: rrr, th, U0, amp, alp, Ndiv
real(kind=wp) :: alpR, NR, Rmin, Rmax, z
integer :: ir, i, j
do i = 0, 50
do j = 0, 50
th = atan2(real(i, kind=wp), real(j, kind=wp))
!
Ndiv= 24._wp !! Number of circumferential division
alp = 90._wp/180._wp*pi !! phase [rad]
U0 = 11.4_wp !! average velocity
amp = 0.5_wp !! amplitude of velocity
Rmin = 10 !! [m]
Rmax = 50 !! [m]
NR = 6._wp !! Number of radial division
!
rrr = sqrt(real(i, kind=wp)**2 + real(j, kind=wp)**2)
ir = int((rrr - Rmin) / (Rmax - Rmin) * NR)
alpR = 2._wp * pi / Ndiv * mod(ir, 2)
z = U0 * (1._wp + amp * sin(0.5_wp * Ndiv * th + alp + alpR))
!
write(*,*) 'i, j, z'
write(*,*) i, j, z
end do
end do
stop
end program test
Specifically, the following changes were made with respect to the original code posted:
Minimum change to answer the question: casting integer variables i and j to real values for using them in the real valued functions datan and dsqrt.
Using generic names for intrinsic procedures, i.e sqrt instead of dsqrt, atan instead of datan, and sin instead of dsin. One benefit of this approach, is that the kind of working precision wp can be changed in one place, without requiring explicit changes elsewhere in the code.
Defining the kind of real variables and calling it wp. Extended discussion of this topic, its implications and consequences can be found on this site, for example here and here. Also #Steve Lionel has an in depth post on his blog, where his general advice is to use selected_real_kind.
Defining pi as a parameter calculating its value once, instead of calculating the same value repeatedly within the nested for loops.

Fortran Error: 'y' argument of 'datan2' intrinsic at (1) must be REAL

I want to calculate z value as the coordinate in range of x:-50~50 and y:-50~50 like below code.
program test
implicit none
! --- [local entities]
real*8 :: rrr,th,U0,amp,alp,Ndiv
real*8 :: pi,alpR,NR,Rmin,Rmax,z
integer :: ir, i, j
do i=0, 50
do j=0, 50
th=datan2(i,j)
pi=datan(1.d0)*4.d0
!
Ndiv= 24.d0 !! Number of circumferential division
alp = 90.d0/180.d0*pi !! phase [rad]
U0 = 11.4d0 !! average velocity
amp = 0.5d0 !! amplitude of velocity
Rmin = 10 !! [m]
Rmax = 50 !! [m]
NR = 6.d0 !! Number of radial division
!
rrr=dsqrt(i**2+j**2)
ir=int((rrr-Rmin)/(Rmax-Rmin)*NR)
alpR=2.d0*pi/dble(Ndiv)*dble(mod(ir,2))
z=U0*(1.d0+amp*dsin(0.5d0*Ndiv*th+alp+alpR))
write(*,*) 'i, j, z'
write(*,*) i, j, z
end do
end do
stop
end program test
But I couldn't make it work like below error. I think because i, j are in datan(i,j). How should I change these code?
test.f90:10.16:
th=datan2(i,j)
1
Error: 'y' argument of 'datan2' intrinsic at (1) must be REAL
test.f90:21.16:
rrr=dsqrt(i**2+j**2)
1
Error: 'x' argument of 'dsqrt' intrinsic at (1) must be REAL
Inspired by the comments of #Rodrigo Rodrigues, #Ian Bush, and #Richard, here is a suggested rewrite of the code segment from #SW. Kim
program test
use, intrinsic :: iso_fortran_env, only : real64
implicit none
! --- [local entities]
! Determine the kind of your real variables (select one):
! for specifying a given numerical precision
integer, parameter :: wp = selected_real_kind(15, 307) !15 digits, 10**307 range
! for specifying a given number of bits
! integer, parameter :: wp = real64
real(kind=wp), parameter :: pi = atan(1._wp)*4._wp
real(kind=wp) :: rrr, th, U0, amp, alp, Ndiv
real(kind=wp) :: alpR, NR, Rmin, Rmax, z
integer :: ir, i, j
do i = 0, 50
do j = 0, 50
th = atan2(real(i, kind=wp), real(j, kind=wp))
!
Ndiv= 24._wp !! Number of circumferential division
alp = 90._wp/180._wp*pi !! phase [rad]
U0 = 11.4_wp !! average velocity
amp = 0.5_wp !! amplitude of velocity
Rmin = 10 !! [m]
Rmax = 50 !! [m]
NR = 6._wp !! Number of radial division
!
rrr = sqrt(real(i, kind=wp)**2 + real(j, kind=wp)**2)
ir = int((rrr - Rmin) / (Rmax - Rmin) * NR)
alpR = 2._wp * pi / Ndiv * mod(ir, 2)
z = U0 * (1._wp + amp * sin(0.5_wp * Ndiv * th + alp + alpR))
!
write(*,*) 'i, j, z'
write(*,*) i, j, z
end do
end do
stop
end program test
Specifically, the following changes were made with respect to the original code posted:
Minimum change to answer the question: casting integer variables i and j to real values for using them in the real valued functions datan and dsqrt.
Using generic names for intrinsic procedures, i.e sqrt instead of dsqrt, atan instead of datan, and sin instead of dsin. One benefit of this approach, is that the kind of working precision wp can be changed in one place, without requiring explicit changes elsewhere in the code.
Defining the kind of real variables and calling it wp. Extended discussion of this topic, its implications and consequences can be found on this site, for example here and here. Also #Steve Lionel has an in depth post on his blog, where his general advice is to use selected_real_kind.
Defining pi as a parameter calculating its value once, instead of calculating the same value repeatedly within the nested for loops.

reading selected data from multiple files

I need some technical help in modifying my FORTRAN coding. I have searched the Internet but I can't fine one which can solve my need.
Basically I am analyzing simulation data using FORTRAN program. Firstly, I shall explain the format of my data to make easy the understanding of what I want. I have 10 files. Each file contains x, y z, data for 1000 frames and each frame contains 20736 (x,y,z) data. Since the total size of all data is about 10 GB for all 10,000 frames, I have to break them into small chunks (10 files) to avoid any crash during calculation. At the beginning of each file (first line) there is a text which can be neglected and each frame ending with information of the box size (bx,by,bz). This is the format of my data files.
I have attached the coding which I have been using for analysis.
The current codding will do calculation file after file and frame after frame in the sequential order. But now I want to do the calculation on selected frames only by jumping frame after frame with certain pattern. For example, I choose frame 1, 4, 8, 12, 16.... and so on until the last frame (10,000).
I have no idea how to choose the frames which are more then 1000 which fall in the second or third files.
I have shown my code below:
module all_parameter
integer,parameter :: MAXATOM=20736
integer,parameter :: nat = 20736
integer, parameter :: startFiles=31
integer, parameter :: endFiles=40
integer,parameter :: NO_OF_FILES=10
integer,parameter :: FRAMES_IN=1000
integer, parameter :: totalFrames = ( NO_OF_FILES * FRAMES_IN )
integer :: i, j, k, IFram, nhb, nlipid, jjj
integer :: BIN, iat, jat
!real :: DELR, fnid, GNRM, RCUT, rlower, rupper
real :: junk, dR, bx, by, bz, bbx
real :: only_head, only_tail, only_water
real :: mass_head, mass_tail, mass_water
character*4 at(MAXATOM)
real,dimension(MAXATOM) :: x, y, z
real,dimension(3) :: rcm
real,dimension(MAXATOM) :: rx, ry, rz
real,dimension(MAXATOM) :: mass
integer, parameter :: startlipid=1
integer, parameter :: endlipid=64
integer, parameter :: lipidNo=64
real, parameter :: PI = (22.0/7.0)
real, dimension(startlipid:endlipid) :: array_UniVekLx, array_UniVekLy, array_UniVekLz
integer :: no, no2, c71, c72, c80, c81
real :: p1x, p1y, p1z, p2x, p2y, p2z, vekx, veky, vekz
real :: mag_vekp1p2, unit_vekx, unit_veky, unit_vekz
real :: sum_UniVekLx, sum_UniVekLy, sum_UniVekLz
real :: avg_frame_vekx, avg_frame_veky, avg_frame_vekz
real :: xx, yy, zz, frame_MagLipVek, theta,theta2, uni_frame_Vekx, uni_frame_Veky, uni_frame_Vekz
real :: xxx, yyy, zzz,UniVekLx, UniVekLy, UniVekLz, FrameAvgUniVekMag
real :: avg_UniVekLx, avg_UniVekLy,avg_UniVekLz, MagLipVek
end module all_parameter
PROGRAM order_parameter
use all_parameter
implicit none
!=========================================================================
! Open files to be read and to write on
!=========================================================================
!
! Topology file !CHANGE
open(unit=31,status="old",file="../malto_thermoNEW_Ori_50ns-set1.traj ")
open(unit=32,status="old",file="../malto_thermoNEW_Ori_50ns-set2.traj ")
open(unit=33,status="old",file="../malto_thermoNEW_Ori_50ns-set3.traj ")
open(unit=34,status="old",file="../malto_thermoNEW_Ori_50ns-set4.traj ")
open(unit=35,status="old",file="../malto_thermoNEW_Ori_50ns-set5.traj ")
open(unit=36,status="old",file="../malto_thermoNEW_Ori_50ns-set6.traj ")
open(unit=37,status="old",file="../malto_thermoNEW_Ori_50ns-set7.traj ")
open(unit=38,status="old",file="../malto_thermoNEW_Ori_50ns-set8.traj ")
open(unit=39,status="old",file="../malto_thermoNEW_Ori_50ns-set9.traj ")
open(unit=40,status="old",file="../malto_thermoNEW_Ori_50ns-set10.traj ")
! Open New Files
open(unit=51,status="unknown",file="BOXinfo.dat ")
open(unit=75,status="unknown",file="magnitude_theta_lipid-thermo-malto.dat")
do k = startlipid, endlipid
array_UniVekLx(k) =0.0
array_UniVekLy(k) =0.0
array_UniVekLz(k) =0.0
end do
! READ COORDINATES IN FRAMES FROM TRAJ file
INPUTFILES: do jjj = startFiles, endFiles
! LOOP OVER FRAMES
IFram = 1
read(jjj,'(a)') junk
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
!IFram = 1
WHOLE: do while ( IFram <= FRAMES_IN)
read(jjj,'(10F8.3)') (x(i),y(i),z(i),i = 1,nat) ! reading TRAJ file
read(jjj,'(3F8.3)') bx,by,bz
write(51,'(a,3F8.3)') 'BOXINFO', bx,by,bz
! LOOP OVER ATOMS
loop1: do j = startlipid, endlipid !nat in lipids
loop2: do i = 45, 45 !,3 !atoms in a lipid
no= i + (j-1)*81
!no2= (no + 18)
c71=no
c72=(no+3)
p1x=((x(c71) + x(c72))/2.0 )
p1y=((y(c71) + y(c72))/2.0 )
p1z=((z(c71) + z(c72))/2.0 )
.
.
.
.
enddo loop2 ! going to next lipid
!CLOSE LOOP OVER ATOMS
enddo loop1 ! going to next frame , before that
!CLOSE LOOP OVER A FRAME
IFram = IFram + 1
enddo WHOLE
!CLOSE LOOP OVER ALL FILES
enddo INPUTFILES
end program order_parameter
I really appreciate your help in advance.
Thanks.
Well, in the loop, unless mod(framenumber, 4) == 0 skip to the next iteration (the CYCLE statement does that in Fortran). That way, you'll process only every fourth frame.
Also, you way want to use a somewhat more precise value for PI. 22/7, WTF?
Obviously the program needs to know which file it is reading, 1, 2... 10. Call that ifile. Then the frame with the file, say frame_in_file. Then you have frame = (ifile-1) * frame_in_file. Do you have a rule to decide whether you want to process "frame"? If the rule is to process every fourth, use mod and cycle as suggested #janneb. Otherwise, I'm not sure what you are asking.
With ten files, it would be easier to write the filename to a string and process them with a loop, opening each file in turn with the same unit number and closing at the end of the loop. This would be a little easier if you used the convention that the number in the file name was always two digits, with a leading zero if less than 10:
do ifile=1, 10
write (filename, '( "myfile_number", I2.2, ".data" )' ) ifile
open (unit=30, file=filename, ...)
loop: read from the file...
calculate overall frame number ...
cycle out of read loop if unsuitable frame...
process the frame...
end read loop
close (unit=30)
end do