Fortran Language
Fortran90 is the programming language used for OpenRadioss development. Fortran95, Fortran2003, Fortran2008 and future extensions may be used only if necessary, and explicitly approved by OpenRadioss maintainers. In such case, these programming guidelines will have to be amended accordingly. It is allowed to use Intrinsic functions coming from Fortran95 up to Fortran2008
For Fortran code, the files should be named “<subroutine_name>.F”, “<module_name>_mod.F>” and “<include_file_name>.inc”. Only fixed format is allowed, extended to 132 columns
C/C++ Language
C routines deal with low level I/O, system calls. C++11 may be used
Preprocessor
C Preprocessor directives can be used to include files, define constants and macros
IMPLICIT NONE
Every OpenRadioss Fortran routine needs to include implicit_f.inc that contains IMPLICIT NONE
Fortran90 Restrictions
Fortran90 features that penalize performance should be avoided:
Object oriented features like operator overloading
Array manipulation, and especially non-contiguous section as subroutine argument is forbidden (assumed-shape-array)
Fortran77 extensions which are not Fortran90 standard are refused
Obsolete Fortran77 Coding
The following statements are not allowed in new code:
EQUIVALENCE
COMMON
SAVE
GOTO
It is also forbidden to use label for DO
loops, multiple RETURN
statements in a subroutine
Data Types
Integer
All integers are by default 32-bit integers (INTEGER
). Where it is required 64-bit integer (INTEGER8
) can be used explicitly. Use of INTEGER8
in the code is limited to such specific usage
Real
The MY_REAL
alias should be used for REAL numbers, it will be replaced by REAL(*)
or DOUBLE PRECISION
depending on what version of OpenRadioss is built
Logical
LOGICAL
operators are restricted to .NOT.
, .AND.
, .OR.
, .EQV.
, .NEQV.
In particular, it is forbidden to use “==
" with LOGICAL
, .EQV.
needs to be used instead
Derived Data Type
The name of a new type should use suffix _STRUCT_
Example:
! Example of data structure definition
TYPE DUMMY_STRUCT_
INTEGER :: L_ITAB ! size of ITAB
INTEGER :: L_RTAB ! size of RTAB
INTEGER, DIMENSION(:) , POINTER :: ITAB ! integer pointer
my_real, DIMENSION(:) , POINTER :: RTAB ! real pointer
END TYPE DUMMY_STRUCT_
! Definition of a variable of type DUMMY_STRUCT_
TYPE (DUMMY_STRUCT_), INTENT(INOUT) :: MY_DUM
! Use of the variable MY_DUM
MY_DUM%L_ITAB = NITEMS1
MY_DUM%L_RTAB = NITEMS2
ALLOCATE(MY_DUM%ITAB(MY_DUM%L_ITAB),MY_DUM%RTAB(MY_DUM%L_RTAB),
& STAT=ierror)
Intrinsic Functions
Programmers are only allowed to use generic functions compatible with both single and double precision: SQRT
, SIN
, COS
, MAX
, MIN
, LOG
, EXP
, ...
Explicitly typed functions are prohibited: DSQRT
, DSIN
, DCOS
, AMAX1
, AMAX0
, AMIN1
, DMAX1
, DLOG
, DEXP
Numerical Constants
All real constant variables are declared inside constant.inc common and initialized using INICONSTANT
routine (iniconstant.F)
Examples:
| |
---|
A = MAX(B,1.E-20) CALL SUB(0.,2.*A) | A = MAX(B,EM20) CALL SUB(ZERO,TWO*A) EM20, ZERO and TWO declared in constant.inc and initialized by INICONSTANT |
Zero and Infinite Values
To avoid division by zero, it is advised to test against EM20
To avoid infinite value, it is advised to test against EP20
These values are generally a good compromise for both double and single precision
Interfacing Fortran and C
Calling Convention
Here is described the way it is handled in OpenRadioss by defining every potential calling convention
Fortran90 Calling Routine and C Callee Routine
INTEGER :: L
my_real :: A(*)
...
CALL DUMMY(A,L)
...
C callee routine:
void dummy(a,l)
double *a;
int *l;
{
/* dummy function definition */
...
}
void dummy_(a,l)
double *a;
int *l;
{
dummy(a,l);
}
void _FCALL DUMMY(a,l)
double *a;
int *l;
{
dummy(a,l);
}
Note:
dummy
, dummy_
and DUMMY
share the 3 possible formats encountered
Argument Variable Correspondence
| |
---|
INTEGER
| *int
|
REAL
| *float
|
DOUBLE_PRECISION
| *double
|
A variable of type my_real
is never transferred from Fortran to C directly. It is copied into a REAL
or DOUBLE PRECISION
variable first
Variable of type CHARACTER
should not be transferred from Fortran to C directly. It is mandatory to use INTEGER
conversion through conversion function ICHAR
at Fortran level and type (char)
at the C level
Every variable is passed by address at Fortran level, therefore a pointer variable must match at the C level