Question

I'm trying to check if my arrays are returning nonsense by accessing out of bounds elements, in fortran. And I want to check these values are less than one, and if they are, change them to one.

This is the piece of my code causing issues:

lastNeighLabel=(/clusterLabel(jj-1,kk,ll), clusterLabel(jj,kk-1,ll), clusterLabel(jj,kk,ll-1)/) LastNeighLabel contains the cluster label (between 1 and n, where n isthe total number of unique seperate clusters found) for the last neighbour in the x,y,z direction respectively.

When jj or kk or ll are 1, they try and access the 0th element in the array, and as FORTRAN counts from 1 in arrays, it tries to destroy the universe. I'm currently in a tangled mess of about 8 if/elseif statements trying to code for every eventuality. But I was hoping there was a way of operating on each element. So basically I'd like to say where((/jj-1,kk-1,ll-1/).lt.1) do clusterLabel(jj-1,kk,ll)=0 etc depending on which element is causing the problem.

But I can't think of a way to do that because where will only manipulate the variables passed to it, not a different array at the same index. Or am I wrong?

Will gladly edit if this doesn't make sense.

Was it helpful?

Solution

Maybe you could use a function?

  real function f(A,i,j,k)  
   real :: A(:,:,:)
   integer :: i,j,k

   if (i==0.or.j==0.or.k==0) then
    f=0
   else
    f=A(i,j,k)
   endif

  end function f

and then use f(clusterLabel,jj-1,kk,ll) etc.

OTHER TIPS

It is not obligatory that Fortran accesses arrays starting from one. Any starting value is allowed. If it more convenient to you to have a zero indexed array, declare the array as:

real, dimension (0:N-1, 0:M-1) :: array

Or

real, dimension (0:N, 0:M) :: array

and have the 0 indices be extra to catch special cases.

This might be another solution to your problem, since zero index values would be legal.

Another possible way to approach this, is to create an extended cluster label array (with index bounds starting at 0), which is equal to the cluster label array with a layer of zeroes tacked on the outside. You can then let your loop run safely over all values of jj, kk, and ll. It depends on the size of the array if this is a feasible solution.

integer :: extended_cluster_label(0:size(cluster_label,1),   &
                                  0:size(cluster_label,2),   &
                                  0:size(cluster_label,3)    &
                                 )

extended_cluster_label(0,:,:) = 0
extended_cluster_label(:,0,:) = 0
extended_cluster_label(:,:,0) = 0

extended_cluster_label(1:, 1:, 1:) = cluster_label
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top