I have wrote down Fortran code to calculate the distance and then sorting, but there is some problem in calling executable command.
Here is the code
program sort implicit none character CN*8,O*7 integer j,iconf,nconf integer i,m integer n,nmax,num parameter (n=5) double precision xbox,rq parameter (nmax=3091,nconf=1) double precision atom(nmax),id(nmax),ox(nmax),oy(nmax),oz(nmax) double precision xij,yij,zij,rij,t double precision r(n,n) open(unit=1,status='unknown',file='a.gro') do iconf= 1,nconf read(1,*) read(1,*) do i=1,n read(1,'(A8,A7,1i5,3f8.3)')CN,O,num,ox(i),oy(i),oz(i) enddo read(1,*)xbox open(unit=3,file='dist.txt') do i=1,n do j=1,n if(i .ne. j) then xij=ox(i)-ox(j) yij=oy(i)-oy(j) zij=oz(i)-oz(j) xij=xij - nint(xij/xbox)*xbox yij=yij - nint(yij/xbox)*xbox zij=zij - nint(zij/xbox)*xbox r(i,j)=dsqrt(xij**2 + yij**2 + zij**2) write(3,'(i3,2x,i3,4x,f17.15)') i,j, r(i,j) call execute_command_line(sort -t, -k1 -g r(i,j)) write(*,*) endif enddo enddo enddo END program
The input file is a.gro
Generated by trjconv : 360 water t= 1000.00000 216 1water OW1 1 0.764 0.617 0.582 2water OW1 2 0.865 1.469 1.696 3water OW1 3 0.423 1.400 1.324 4water OW1 4 0.381 1.464 0.392 5water OW1 5 1.279 0.872 0.131 1.87759 1.87759 1.87759
outfile file 3, dist.txt
1 2 1.148553302245917 1 3 1.131341681367747 1 4 0.948787647474397 1 5 0.730514202462895 2 1 1.148553302245917 2 3 0.581815262776768 2 4 0.750524142249935 2 5 0.790896648178509 3 1 1.131341681367747 3 2 0.581815262776768 3 4 0.935138492417032 3 5 1.216627908647504 4 1 0.948787647474397 4 2 0.750524142249935 4 3 0.935138492417032 4 5 1.106792211754311 5 1 0.730514202462895 5 2 0.790896648178509 5 3 1.216627908647504 5 4 1.106792211754311
so, I want to sort r(i,j)
, keeping i same j different.but call line is not working in fortran code.
error that is coming
tetra.f(48): error #6413: This global name is invalid in this context. [SORT] call execute_command_line(sort -t, -k1 -g r(i,j)) ----------------------------------^ tetra.f(48): error #6404: This name does not have a type, and must have an explicit type. [K1] call execute_command_line(sort -t, -k1 -g r(i,j)) --------------------------------------------^ tetra.f(48): error #6404: This name does not have a type, and must have an explicit type. [GR] call execute_command_line(sort -t, -k1 -g r(i,j)) ------------------------------------------------^ tetra.f(48): error #6362: The data types of the argument(s) are invalid. [EXECUTE_COMMAND_LINE] call execute_command_line(sort -t, -k1 -g r(i,j)) ---------------------------------------^ tetra.f(48): error #6362: The data types of the argument(s) are invalid. [EXECUTE_COMMAND_LINE] call execute_command_line(sort -t, -k1 -g r(i,j)) -----------------------------------------------^ compilation aborted for tetra.f (code 1)
Please let me know how can I execute shell command in Fortran code.
Advertisement
Answer
I understand that what you are trying to do is order the four values of r(i,j) for each possible value of i (which I call irow in the following). If that is the case, and if you need a fortran answer (rather than a Linux answer), then the following should work. Sorting is a central concern in computer science, and there are many algorithms. I chose bubble sort because it is fairly easy to understand, and very well documented eg https://en.wikipedia.org/wiki/Bubble_sort. It is definitely not very fast. Please note that the ordered results have the smallest value first, the order is ascending.
Module BSort use, intrinsic :: iso_c_binding contains Subroutine f_Bubble_Sort(a,order) implicit none integer (c_int),intent(out) :: order(:) integer (c_int) :: kx,ky,length,otemp real (c_float),intent(in) :: a(:) real (c_float),allocatable :: locala(:) real (c_float) :: temp logical(c_bool) :: swapped length=size(a) allocate(locala(length));order=(/(kx,kx=1,length)/);locala=a do kx = length-1, 1, -1 !from top -> down swapped = .false. do ky = 1, kx if (locala(ky) > locala(ky+1)) then temp = locala(ky) locala(ky) = locala(ky+1) locala(ky+1) = temp otemp=order(ky) order(ky)=order(ky+1) order(ky+1)=otemp swapped = .true. end if end do if (.not. swapped) exit end do End Subroutine f_Bubble_Sort End Module BSort Program Q52001740 use, intrinsic :: iso_c_binding use BSort implicit none real(kind=c_float) :: r(5,4) integer(c_int) :: out(4),irow,jcol,column(5,4),order(5,4) open(unit=3,file='Q52001740.dist.txt') ! note no diagonal values in r do irow=1,5 do jcol=1,4 read(3,'(5x,i3,4x,f17.15)') column(irow,jcol), r(irow,jcol) end do call f_Bubble_Sort(r(irow,:),out) order(irow,:)=out write(*,fmt='("irow= ",i2)')irow write(*,fmt='(i2,4f8.5,4i3)')irow,r(irow,:),out write(*,fmt='(a10,i2,4f8.5)')"sorted r:",irow,r(irow,out) write(*,fmt='(a16,4i4)')"sorted columns:",column(irow,out) end do End Program Q52001740
The output is:
irow= 1 1 1.14855 1.13134 0.94879 0.73051 4 3 2 1 sorted r: 1 0.73051 0.94879 1.13134 1.14855 sorted columns: 5 4 3 2 irow= 2 2 1.14855 0.58182 0.75052 0.79090 2 3 4 1 sorted r: 2 0.58182 0.75052 0.79090 1.14855 sorted columns: 3 4 5 1 irow= 3 3 1.13134 0.58182 0.93514 1.21663 2 3 1 4 sorted r: 3 0.58182 0.93514 1.13134 1.21663 sorted columns: 2 4 1 5 irow= 4 4 0.94879 0.75052 0.93514 1.10679 2 3 1 4 sorted r: 4 0.75052 0.93514 0.94879 1.10679 sorted columns: 2 3 1 5 irow= 5 5 0.73051 0.79090 1.21663 1.10679 1 2 4 3 sorted r: 5 0.73051 0.79090 1.10679 1.21663 sorted columns: 1 2 4 3