Explicit Typing with Abaqus#
Implicit Typing#
Backwards-compatibility is very important for the Fortran standard due to the age of the language and consequently large amount of legacy code still in use. This means that many legacy features remain in the language standard despite their use being discouraged or them being made obsolete.
One such legacy feature that is strongly discouraged is implicit typing which describes a feature where variables need not have their type declared explicitly, but rather it is implicitly inferred based on the first letter of the variable.
Note
The default rules of implicit typing are that variables with names beginning
with the letters i
,j
,k
,l
,m
,n
are integer
and all other variables
are real
.
Important
The use of implicit typing is strongly discouraged since it easily leads to errors which are difficult to detect.
Abaqus user subroutines are usually implicitly typed, this guide will explain how to write Abaqus user subroutines with explicit typing.
Explicit Typing#
Info
When implicit typing is disabled, all variables must have their type explicitly declared - this is explicit typing.
Implicit typing is disabled by adding the following statement to the beginning of all program units:
implicit none
The statement is placed after any module use
statements but before any
variable declarations.
Example: explicit typing in a subroutine
subroutine test(a,b)
use iso_fortran_env, only: dp=>real64
implicit none
integer, intent(in) :: a
real(dp), intent(out) :: b
b = 3.0d0*a
end subroutine test
Explicit Typing with Abaqus#
Abaqus uses implicit typing to define the floating point (real) precision to be used; this allows it to switch between single precision and double precision. The implicit precision is defined in the include files:
aba_param.inc
for Abaqus/Standardvaba_param.inc
for Abaqus/Explicit
The precision in these files depends one whether you are running Abaqus in single precision or double precision, and it determines the precision of real variables that are passed into your user subroutine.
Instead of including these files directly in our code, we can define an implicitly typed module which extracts this information from Abaqus. We can then use this module in the rest of our code, which will be explicitly typed.
See also
See the sample repository on Github which gives a complete working example of the concepts presented in this guide.
Step 1:
See the Abaqus_Definitions.f
file printed below and save it as a new file
in the same folder as your main user subroutine file.
Step 2:
Include the Abaqus_Definitions.f
file at the beginning of your top-level
user subroutine file.
#include 'Abaqus_Definitions.f'
Step 3:
Import the module in your explicitly typed modules/subroutines and define the
working precision (wp
) with the following syntax:
use Abaqus_Definitions, only: wp=>abaqus_real_kind
implicit none
Step 4: Define real variables that come from Abaqus with the following syntax:
real(wp) :: stateNew(:,:)
Abaqus_Definitions.f
#
!DIR$ FREEFORM
module Abaqus_Definitions
! This module exports a kind parameter "abaqus_real_kind" that defines
! the real kind (precision) currently in use by Abaqus.
! This allows explict typing in Fortran user subroutines.
!DIR$ NOFREEFORM
!DIR$ FIXEDFORMLINESIZE:132
include "vaba_param.inc" ! Abaqus/Explicit
!DIR$ FREEFORM
private
! Detect and export the Abaqus real kind precision
parameter(a = 0)
integer, parameter, public :: abaqus_real_kind = kind(a)
end module Abaqus_Definitions
!DIR$ NOFREEFORM
!DIR$ FIXEDFORMLINESIZE:132
Example Usage#
module demo
use iso_fortran_env, only: sp=>real32, dp=>real64
use Abaqus_Definitions, only: wp=>abaqus_real_kind
implicit none
contains
subroutine check_precision()
real(sp), parameter :: pi_sp = 4.0*atan(1.0) ! single precision
real(dp), parameter :: pi_dp = 4.0d0*atan(1.0d0) ! double precision
real(wp), parameter :: pi_wp = 4.0d0*atan(1.0d0) ! working precision
write(*,*) "Single precision: ",pi_sp
write(*,*) "Double precision: ",pi_dp
write(*,*) "Abaqus precision: ",pi_wp
end subroutine check_precision
end module demo