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/Standard

  • vaba_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