OpenRadioss Coding Standards

Introduction

The aim of this document is to give OpenRadioss development guidelines. These guidelines cover the style and the efficiency of the code. OpenRadioss is mostly written in Fortran (Fortran77 and Fortran90 and above) Fortran Programming Language Homepage. A few functions are written in C and C++. The following rules apply for new code

OpenRadioss Coding Standards

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:

Forbidden

Allowed

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

Fortran

C

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

 

 Related articles

OpenRadioss Coding Recommendations

OpenRadioss Performance Aspects: Vectorization and Optimization

OpenRadioss Reader (Radioss Block Format)

OpenRadioss HMPP Development Insights