Fortran bug: rank problem gfortran

Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
3 replies · 14K views
billiards
Messages
765
Reaction score
16
This is my own code, and it won't compile with gfortran. All I want to do is extract the location of the cell with the minimum value in an array. A seemingly simple task but one that does not work with the intrinsic function minloc, for reasons I do not understand.

The error message:

Code:
    iclosept=minloc(dist)
    1
Error: Incompatible ranks 0 and 1 in assignment at (1)

The code:

Code:
  subroutine distance_to_trench(pt,tr,mindist,iclosept)
  ! find (great circle) distance from point to each point on the trench
  ! distance = the minimum distance to the trench
  
    type(point) :: pt
    type(trench) :: tr
    real, parameter :: pi=3.14159265359
    real, parameter :: eradius=6371
    real :: rad,deg
    real :: x1,y1,z1,x2,y2,z2
    real,dimension(:),allocatable :: dist
    real :: mindist
    integer :: ii, length, iclosept, a
    
    rad=pi/180
    deg=180/pi
    
    length=size(tr%poly%points%x)
    allocate(dist(length))
    
  ! method:
  ! convert lat lons to cartesian vectors
  ! use angle between vectors to find the distance
  
    x1=cos(rad*pt%y)*cos(rad*pt%x)
    y1=cos(rad*pt%y)*sin(rad*pt%x)
    z1=sin(rad*pt%y)
  
    do ii=1, length
      
      x2=cos(rad*tr%poly%points(ii)%y)*cos(rad*tr%poly%points(ii)%x)
      y2=cos(rad*tr%poly%points(ii)%y)*sin(rad*tr%poly%points(ii)%x)
      z2=sin(rad*tr%poly%points(ii)%y)
  
      dist(ii)=eradius*acos(x1*x2+y1*y2+z1*z2)
      
      print *,dist(ii)
    
    enddo
    
    mindist=minval(dist)
    
    a=size(dist)
    print *,'size of dist', size(dist), a

    iclosept=minloc(dist)
    print *,'minloc', minloc(dist), iclosept
    
    deallocate(dist)
    
  end subroutine distance_to_trench
 
Physics news on Phys.org
Fixed it.

Turns out I was confused about the output of the minloc function. It returns an array of integer(s). I was assuming it returned an integer. Because I was only thinking about a 1-d array. But in the case of a 1-d array, it actually returns an array of size 1, where the element contains the integer I was after.

To fix my above code I introduced a temporary array and assigned it by minloc. Then I extracted the single element from it into a pure integer.

Thus:

Code:
  subroutine distance_to_trench(pt,tr,mindist,iclosept)
  ! find (great circle) distance from point to each point on the trench
  ! distance = the minimum distance to the trench
  
    type(point) :: pt
    type(trench) :: tr
    real, parameter :: pi=3.14159265359
    real, parameter :: eradius=6371
    real :: rad,deg
    real :: x1,y1,z1,x2,y2,z2
    real,dimension(:),allocatable :: dist
    real :: mindist
    integer :: ii, length, iclosept, temp(1)
    
    rad=pi/180
    deg=180/pi
    
    length=size(tr%poly%points%x)
    allocate(dist(length))
    
  ! method:
  ! convert lat lons to cartesian vectors
  ! use angle between vectors to find the distance
  
    x1=cos(rad*pt%y)*cos(rad*pt%x)
    y1=cos(rad*pt%y)*sin(rad*pt%x)
    z1=sin(rad*pt%y)
  
    do ii=1, length
      
      x2=cos(rad*tr%poly%points(ii)%y)*cos(rad*tr%poly%points(ii)%x)
      y2=cos(rad*tr%poly%points(ii)%y)*sin(rad*tr%poly%points(ii)%x)
      z2=sin(rad*tr%poly%points(ii)%y)
  
      dist(ii)=eradius*acos(x1*x2+y1*y2+z1*z2)
      
      print *,dist(ii)
    
    enddo
    
    mindist=minval(dist)
    temp=minloc(dist)
    
    iclosept=temp(1)
    
    deallocate(dist)
    
  end subroutine distance_to_trench