Fortran routine returns invalid values

Hey, I am working on a fortran program and ran into some strange problem. When I try to print some values ​​of an array immediately before calling a particular routine, I get the correct values. Then I try to print some values ​​of the same array immediately after starting the subroutine, and they are 0. I finally print the values ​​of the array after the subroutine, and the values ​​return to the expected values. Can someone help me understand why? My code is below:

Firstly, calling the subroutine in the main function with the values ​​that I want to display in the write statements:

if (iter .eq. 5) then write(*,*) 'vp vals: ',vp(0,23471), vp(0,23475) end if CALL GRID_DIVISION( & & NPTMAX, DIM, TYPEMAX, NEIGHMAX, NPTC, GRIDLIMIT, & & GRIDN, GRIDNUM, GRID, GNEIGH, XP, PTTYPE, TYPE, & & GRIDP, TEMP_GRIDP, GNEIGHMAX, PAINT, VP, ITER, gridvel & & ) if (iter .eq. 5) then write(*,*) 'vp vals: ',vp(0,23471), vp(0,23475) end if 

This calls the following routine, from which I will publish only the relevant part:

 SUBROUTINE GRID_DIVISION( & & NPTMAX, DIM, TYPEMAX, NEIGHMAX, NPTC, GRIDLIMIT, & & GRIDN, GRIDNUM, GRID, GNEIGH, XP, PTTYPE, TYPE, & & GRIDP, TEMP_GRIDP, GNEIGHMAX, PAINT,VP,ITER, gridvel & & ) IMPLICIT NONE INTEGER, INTENT(IN) :: NPTMAX, DIM, TYPEMAX, NEIGHMAX, GNEIGHMAX INTEGER, INTENT(IN) :: NPTC INTEGER, INTENT(IN) :: GRIDLIMIT INTEGER, INTENT(IN) :: GRIDN(0: DIM - 1) INTEGER, INTENT(IN) :: GRIDNUM INTEGER, INTENT(IN) :: PTTYPE(0: NPTMAX) INTEGER, INTENT(IN) :: TYPE(0: TYPEMAX) INTEGER, INTENT(INOUT) :: GRIDP(0: NPTMAX) INTEGER, INTENT(INOUT) :: GNEIGH(1: GRIDLIMIT, 0: GNEIGHMAX) REAL , INTENT(IN) :: GRID(1: GRIDLIMIT, 0: DIM - 1, 0: 1) REAL , INTENT(IN) :: XP(0: DIM - 1, 0: NPTMAX) REAL , INTENT(IN) :: VP(0: DIM - 1, 0: NPTMAX) INTEGER, INTENT(INOUT) :: TEMP_GRIDP(0: NPTMAX) INTEGER, INTENT(INOUT) :: PAINT(0:NPTMAX) INTEGER, INTENT(INOUT) :: ITER real, intent(inout) :: gridvel(GRIDNUM,0:1) INTEGER :: II, JJ, KK INTEGER :: DNUM INTEGER :: GRIDXP INTEGER :: SGRIDXP INTEGER :: EGRIDXP INTEGER :: SGRIDYP INTEGER :: EGRIDYP INTEGER :: SEARCH INTEGER :: SCOUNT INTEGER :: FCOUNT INTEGER :: ERROR INTEGER, PARAMETER :: CELL = 2 if (iter .eq. 5) then write(*,*) 'vp vals: ',vp(0,23471), vp(0,23475) end if ... end subroutine 

With a lot of materials after this section, which does not exist. When I run the code, my outputs are at iteration 5 for this section:

 vp vals: 75.00000 75.00000 vp vals: 0.00000000E+00 0.0000000E+00 vp vals: 75.00000 75.00000 

I just can't understand why my VP array has no values ​​in the routine.

+1
source share
2 answers

I understood that. VP was highlighted as

 VP(0:DIM,0:NPTMAX) 

in the main program and

 VP(0:DIM-1,0:NPTMAX) 

in the routine! This caused an error.

+1
source

In manual mode, setting explicit arrays a(0:N-1,0:M) extremely error prone. I suggest using arrays of supposed forms a(:,:) to pass arguments. In addition, when you pass arrays as arguments to routines, the upper and lower bounds of the actual argument are not supported in the call if the lower bound is not 1. However, when passing the pointers, the lower and upper bounds are preserved. For instance,

 program main use, intrinsic :: iso_fortran_env, only: & stdout => OUTPUT_UNIT, & compiler_version, & compiler_options ! Explicit typing only implicit none real :: foo(10,10) real, target :: bar(0:9,0:9) real, pointer :: ptr(:,:) => null() call peek_assumed_shape(foo, 'peek_assumed_shape: foo(10,10)') call peek_assumed_shape(bar, 'peek_assumed_shape: bar(0:9,0:9)') ptr => bar call peek_pointer(ptr, 'peek_pointer: ptr => bar') ptr(42:,42:) => bar call peek_pointer(ptr, 'peek_pointer: ptr(42:,42:) => bar') nullify( ptr ) write (stdout, '(/4a/)') & 'This file was compiled using compiler version ', compiler_version(), & ' and compiler options ', compiler_options() contains subroutine peek_assumed_shape(array, description) ! Calling arguments real, intent (in) :: array(:,:) character (len=*), intent (in) :: description write (stdout, '(/a)') description write (stdout, *) 'dim=1 ', lbound(array, dim=1), ubound(array,dim=1) write (stdout, *) 'dim=2 ', lbound(array, dim=2), ubound(array,dim=2) end subroutine peek_assumed_shape subroutine peek_pointer(array, description) ! Calling arguments real, pointer, intent (in) :: array(:,:) character (len=*), intent (in) :: description if (associated(array)) then write (stdout, '(/a)') description write (stdout, *) 'dim=1 ', lbound(array, dim=1), ubound(array,dim=1) write (stdout, *) 'dim=2 ', lbound(array, dim=2), ubound(array,dim=2) end if end subroutine peek_pointer end program main 

returns next

 peek_assumed_shape: foo(10,10) dim=1 1 10 dim=2 1 10 peek_assumed_shape: bar(0:9,0:9) dim=1 1 10 dim=2 1 10 peek_pointer: ptr => bar dim=1 0 9 dim=2 0 9 peek_pointer: ptr(42:,42:) => bar dim=1 42 51 dim=2 42 51 This file was compiled using compiler version GCC version 5.4.0 20160609 and compiler options -mtune=generic -march=x86-64 -O3 -Wall -std=f2008ts 
+2
source

Source: https://habr.com/ru/post/1013022/


All Articles