I am trying to understand a part of code written in fortran. The code contains the following part:
REAL(KIND=8), DIMENSION(x,y), INTENT(INOUT) :: AR
_REAL_, DIMENSION(x,y), INTENT(INOUT) :: BR
From this page , i came to know that _REAL_
is a preprocessor for precision control.
- What does
_REAL_
actually do in this code? - Can
AR
values be assigned toBR
? Is there type incompatibility problem between them? - I was trying to assign the values of
AR
toBR
using a C functionextern "C" void assign_(double *AR, double *BR , int *x, int*y)
But I am having a problem, and it seems like the problem is due to the incompatibility issue betweenAR
andBR
because if I change the above code to:
REAL(KIND=8), DIMENSION(x,y), INTENT(INOUT) :: AR REAL(KIND=8), DIMENSION(x,y), INTENT(INOUT) :: BR
, the problem is solved. Is there any problem if I changed the code this way?
The page that you referenced seems to be a bug report on building the Molecular Dynamics software package, Amber. I infer this from the link (.../gcc-bugs/...), from the second line of the page which states:
and finally from the description which explains how to change the precision of the Amber build (installing a single or double precision version the software).
If the written code you are looking at is a part of Amber, then the page you have referenced does explain what
_REAL_
does in the code. Namely, it's a general type definition that based on the working precision either is replaced at compile time withreal(kind=4)
orreal(kind=8)
. According to the description for Amber, the default build is double precision, which implies that when compiled,_REAL_
would be replaced withreal(kind=8)
. This should answer question 1.Note that in fortran values of
AR
can always be assigned toBR
, but they will require casting to the appropriate type. I.e. ifBR
is an integer array, the values ofAR
will be need to be casted into integers. Assuming that the written code you are looking at is for Amber again, and that the default double precision is not overriden, thenBR
is a double precision array just asAR
is, so values can be freely assigned between them.As for question 3., you maybe need to define a macro so that
_REAL_
actually does mean double precision. While not often discussed, many fortran compilers will happily apply a preprocessor. For automatic preprocessing (allowing the compiler to determine the flags), one just needs to ensure that the fortran source file has the correct extension, such as.F90
,.F
,.fpp
, or.FPP
as outlined in the first paragraph on this documentation page for gfortran (quick note that these are understood by the intel compilers as well). As I usually code in Fortran 90 or later, the extension.F90
works wonders for me. Then, probably in the header of your source file, just add the following line:note that I add more than one space between the last underscore and real as to emphasize that there must be a space there. Doing this will allow the Fortran compiler to replace all occurrences of
_REAL_
withreal(kind=8)
and give you a way to globally modify real precision by modifying one line without invoking a compiler flag.I think that doing this might get your external C reference to work.