Assign 2D Array with Reals in Fortran - Help Needed

In summary, the main issue with the code was improper declaration and allocation of variables outside the get_energy_and_grad subroutine. The call statements also needed to be written correctly. Additionally, using global variables within a subroutine is not good practice. The reshape function may also require a variable instead of a list of constants as its first argument.
  • #1
davidfur
18
2
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:

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:
 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:
Technology news on Phys.org
  • #2
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:

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/) )
 
  • #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

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

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:
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)
 
  • #4
davidfur said:
Here's an excerpt from the 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
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.
 
  • Like
Likes jim mcnamara
  • #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!
 

1. What is a 2D array in Fortran?

A 2D array in Fortran is a data structure that allows for storing and accessing data in a two-dimensional grid or matrix. It is a collection of elements or values organized in rows and columns, where each element is identified by its position in the array.

2. How do I declare and define a 2D array with real numbers in Fortran?

To declare and define a 2D array with real numbers in Fortran, you can use the REAL data type and specify the size of the array using the DIMENSION attribute. For example, REAL, DIMENSION(3,3) :: my_array will create a 2D array with 3 rows and 3 columns.

3. How do I assign values to a 2D array in Fortran?

You can assign values to a 2D array in Fortran by using nested DO loops, where the outer loop iterates over the rows and the inner loop iterates over the columns. You can also use the ASSIGNMENT statement to assign values to the array elements directly.

4. Can I initialize a 2D array with real numbers in Fortran?

Yes, you can initialize a 2D array with real numbers in Fortran by using the DATA statement. This allows you to specify the initial values for each element in the array. Alternatively, you can also use the PARAMETER statement to declare and initialize a constant 2D array.

5. How do I access and manipulate elements in a 2D array in Fortran?

To access and manipulate elements in a 2D array in Fortran, you can use the standard array indexing notation, where the first index represents the row and the second index represents the column. You can also use array operations and built-in functions to perform operations on the entire array or specific elements.

Similar threads

  • Programming and Computer Science
Replies
4
Views
618
  • Programming and Computer Science
Replies
11
Views
2K
  • Programming and Computer Science
Replies
5
Views
7K
  • Programming and Computer Science
Replies
13
Views
2K
  • Programming and Computer Science
Replies
5
Views
12K
  • Programming and Computer Science
Replies
8
Views
2K
  • Programming and Computer Science
Replies
10
Views
25K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
1K
  • Programming and Computer Science
Replies
5
Views
8K
  • Programming and Computer Science
Replies
4
Views
4K
Back
Top