Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Fortran Assignment of 2D array

  1. Oct 11, 2018 #1
    Hi guys,
    On with my Fortran adventures...I'm trying to accomplish a simple task: assign a 2D array with some reals. Here's an excerpt from the code:

    Code (Fortran):

    subroutine get_energy_and_grad(natoms_,coords,ereal,gradmat)

        include 'cbka.blk'
        include 'opt.blk'
        integer, intent(in)    :: natoms_
        double precision, intent(in)    :: coords(3*natoms_)
        real*8, intent(out)    :: ereal    ! total energy
        real*8, dimension(3,3), intent(out)    :: gradmat

        call vlist
        call srtbon1
        call encalc
         
        ereal = estrc ! total energy

    !    write (*,*) 'natoms_ is: ', natoms_

        write (*,*) 'size of gradmat is:', size(gradmat)
        write (*,*) 'size of d is:', size(d)
        write (*,*) 'shape of gradmat is:', shape(gradmat)
        write (*,*) 'shape of d is:', shape(d)

        gradmat = reshape((/ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 /),(/3, 3/))

        write(*,*) 'gradmat is: ', gradmat(2,3)

    end subroutine get_energy_and_grad
     
    This just won't assign the 1.0-9.0 reals into gradmat and throws out the following:

    Code (Text):

     size of gradmat is:           9
     size of d is:        7500
     shape of gradmat is:           3           3
     shape of d is:           3        2500

    Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

    Backtrace for this error:
    #0  0x7F3B8F78EE08
    #1  0x7F3B8F78DF90
    #2  0x7F3B8F0D54AF
    #3  0x40151C in __reaxff_interface_MOD_get_energy_and_grad
    #4  0x402C5E in MAIN__ at main.f90:?
    Segmentation fault (core dumped)
     
    I'm obviously doing something really stupid, but I just can't figure out what's wrong... need help!

    Dave
     
    Last edited: Oct 11, 2018
  2. jcsd
  3. Oct 11, 2018 #2

    jedishrfu

    Staff: Mentor

    Here's a tutorial on the reshape function:

    https://www.tutorialspoint.com/fortran/reshape.htm

    I don't see what wrong but a memory error often indicates referencing an element outside the array bounds.

    Perhaps, you could try being more explicit and breaking the statement up a bit:

    Code (Fortran):

     
     real*8, dimension (1:9) :: b = (/ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 /)

     gradmat = reshape( b , (/3, 3/) )

     
     
  4. Oct 11, 2018 #3
    Thanks jedishrfu, but it doesn't work either. I suspect there's something wrong with my declarations....
    I post here the full code if this helps

    Main program

    Code (Fortran):

    program main

    use reaxff_interface
    implicit none

    integer natoms_
    real*8 ereal
    real*8, allocatable :: coords(:,:)
    real*8, allocatable :: gradvec(:,:)

    call get_energy_and_grad(gradvec)

    write (*,*) "This is main. grad(3,3) is : ", gradvec(3,3)

    end program main
     
    Module

    Code (Fortran):

        module reaxff_interface
        implicit none

    subroutine get_energy_and_grad(grad)
        include 'cbka.blk'
        include 'opt.blk'
        real*8, dimension(3,3), intent(out)     :: grad
        real*8, dimension (1:9) :: b

        b = (/ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 /)
        grad = reshape( b , (/3, 3/) )
    end subroutine get_energy_and_grad

    end module reaxff_interface
     
    output:
    Code (Text):

    Program received signal SIGBUS: Access to an undefined portion of a memory object.

    Backtrace for this error:
    #0  0x7F4FB566DE08
    #1  0x7F4FB566CF90
    #2  0x7F4FB4FB44AF
    #3  0x7F4FB574563F
    #4  0x7F4FB5748154
    #5  0x7F4FB5748D3E
    #6  0x402DBF in MAIN__ at main.f90:?
    Bus error (core dumped)
     
     
  5. Oct 13, 2018 #4

    Mark44

    Staff: Mentor

    I see two or maybe three problems:
    1. In your three call statements, none of the subroutine calls is written correctly. The syntax for a call statement is
    call SubName(argument1, argument2, ...). If a subroutine has no parameters, the parentheses still must be used. See http://pages.mtu.edu/~shene/COURSES/cs201/NOTES/F90-Subprograms.pdf, on page titled "Subroutines: 2/2".
    You don't show the definitions for the three subroutines, so I can't tell if any of them takes any arguments.

    2. What is d? There is no declaration for d in either the parameter list or in the declarations for local variables, so d apparently is a global variable. It's very bad practice for a function of subroutine to access global variables. At the very least, doing this makes debugging much more difficult.

    3. I'm not sure that reshape will take a list of constants as its first argument. Per the GNU Fortran Compiler man page for reshape (https://gcc.gnu.org/onlinedocs/gfortran/RESHAPE.html), it appears to me that the first argument has to be a variable, but I'm not certain of this.
     
  6. Oct 15, 2018 #5
    Thanks Mark44 for your help!
    I managed to solve the problem by properly declaring and allocating coords and gradvec variables outside the get_energy_and_grad subroutine.

    Cheers!
     
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted