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.
_REAL_
actually do in this code?AR
values be assigned to BR
? Is there type incompatibility problem between them?AR
to BR
using a C function extern "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 between AR
and BR
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:
!+ Specification and control of Amber's working precision
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 with real(kind=4)
or real(kind=8)
. According to the description for Amber, the default build is double precision, which implies that when compiled, _REAL_
would be replaced with real(kind=8)
. This should answer question 1.
Note that in fortran values of AR
can always be assigned to BR
, but they will require casting to the appropriate type. I.e. if BR
is an integer array, the values of AR
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, then BR
is a double precision array just as AR
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:
#define _REAL_ real(kind=8)
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_
with real(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.