<!-- source-page: 661 -->

```txt
a(1) = 11 ! use as a native Fortran array
a(2) = 22 ! use as a native Fortran array 
```

C++ interface:   
```c
#include <SMAAspUserSubroutines.h>
// Locate and open array with ID=1
int* a = SMALocalArrayIntAccess(1);
a[1] = 11; // use as a native array
a[2] = 22; // use as a native array 
```  
NOTE: If a request is made to access an array that has not been created, the function will return 0.

# Variable to be provided to the utility routine

ID

ID of the array (an integer), chosen by the user at the time of creation. Using this ID, an array can be opened in any other user subroutine.

# Variable returned from the utility routine

INTEGER\*8 ( address )

Returns a pointer to the array created. This pointer can be associated with a native Fortran array or native C/C++ array. Each thread will receive a different pointer. Each thread, as it passes through this code, will create and hold its own array. For example, Array(1) in Thread 0 is a separate array from Array(1) in Thread 4. These arrays are nonoverlapping and nonintersecting in any way.

SMALocalIntArraySize, SMALocalFloatArraySize

Interface

Fortran interface:

```txt
INTEGER*4 SMALocalIntArraySize(ID)
INTEGER*4 SMALocalFloatArraySize(ID) 
```

Example:

<!-- source-page: 662 -->

```c
#include <SMAAspUserSubroutines.hdr>
    integer a_size, d_size

C Get the size of Array(1) as the number of INTEGERs
    a_size = SMALocalIntArraySize(1)

! Get the size of Array(1) as the number of REALs
    d_size = SMALocalFloatArraySize(1)
    do k=1,a_size
    ...
    end do

C++:
    #include <SMAAspUserSubroutines.h>
    // Lookup the size of Array(1) as the number of ints
    int a_size = SMALocalIntArraySize(1);
    // Lookup the size of Array(1) as the number of doubles
    int d_size = SMALocalFloatArraySize(1);
    for(int i=1; i<=size; i++) {
    ...
    } 
```

# Variable to be provided to the utility routine

ID

ID of the array (an integer), chosen by the user at the time of creation. Using this ID, an array can be opened in any other user subroutine.

# Variable returned from the utility routine

INTEGER\*4

Size of the array.

<!-- source-page: 663 -->

Interface   
```asm
Fortran interface:
    subroutine SMALocalIntArrayDelete(ID)
    subroutine SMALocalFloatArrayDelete(ID)

Example:
#include <SMAAspUserSubroutines.hdr>
    call SMALocalIntArrayDelete(1) ! Delete Array(1)

C++ interface:
#include <SMAAspUserSubroutines.h>
    SMALocalIntArrayDelete(1); // Delete Array(1)

NOTE: Deletion of arrays is optional. All storage allocated for these arrays will be freed when Abaqus threads terminate (at the very end of the analysis). It is, however, a good programming practice to delete all allocations explicitly, especially when they are no longer needed, as this will free up memory for something else. 
```

# Variable to be provided to the utility routine

ID of the array (an integer), chosen by the user at the time of creation. Using this ID, an array can be opened in any other user subroutine.

SMAIntArrayCreate, SMAFloatArrayCreate

# Interface

Fortran interface:

INTEGER\*8 SMAIntArrayCreate(ID,SIZE,INITVAL)

<!-- source-page: 664 -->

INTEGER\*8 SMAFloatArrayCreate(ID,SIZE,INITVAL)   
Example:   
```fortran
#include <SMAAspUserSubroutines.hdr>

integer a(100)
pointer(ptra, a)
double b(100)
pointer(ptrb, b)

! create a global array with ID=1, SIZE=100, and
! INITVAL=-1.0
ptra = SMAIntArrayCreate(1, 100, -1.0)

a(1) = 11 ! use as a native Fortran array
a(2) = 22 ! use as a native Fortran array

! create a global array with ID=2, SIZE=100, and
! INITVAL=-1.0
ptrb = SMAFloatArrayCreate(2, 100, -1.0) 
```  
C++ interface:

```c
#include <SMAAspUserSubroutines.h>

// Create an integer array of with ID=1, size=100,
// and initial value=-1.0
int* a = SMAIntArrayCreate(1,100,-1.0);

// Create a float array of with ID=2, size=20,
// and initial value=-1.0
Real* b = SMAFloatArrayCreate(2,20,-1.0); 
```  
NOTE: Float Arrays can store both SINGLE PRECISION and DOUBLE PRECISION numbers. Internally, they allocate storage in 64-bit units (double/real\*8).   
NOTE: To resize an array, simply call Create() with the same ID, but give it a new SIZE parameter. If the size has increased, the old data will be copied over to the new array. No data is lost during resizing.

<!-- source-page: 665 -->

For example:

```fortran
! resize array with ID=1 to 300 integers
ptra = SMAIntArrayCreate(1,300,-1) 
```

# Variables to be provided to the utility routine

ID

ID of the array (an integer), chosen by the user at the time of creation. Using this ID, an array can be opened in any other user subroutine.

SIZE

Size of the array as the number of ints or doubles. The maximum size is INT\_MAX.

INITVAL

Initial value for each item of the array. This argument is required.

# Variables returned from the utility routine

INTEGER\*8 ( address )

Returns a pointer to the array created. This pointer can be associated with a native Fortran array or native C/C++ array. All threads with see the same address when they try to access this array through its ID.

SMAIntArrayAccess, SMAFloatArrayAccess

Interface

Fortran interface:

```cmake
INTEGER*8 SMAIntArrayAccess(ID)
INTEGER*8 SMAFloatArrayAccess(ID) 
```

Example:

#include <SMAAspUserSubroutines.hdr>

```txt
integer a(100)
pointer(ptra, a) 
```

C Locate Array(1) and associate a native array pointer with it

<!-- source-page: 666 -->

```txt
ptra = SMAIntArrayAccess(1)

a(1) = 11 ! use as a native Fortran array
a(2) = 22 ! use as a native Fortran array

C++ interface:
#include <SMAAspUserSubroutines.h>

// Locate and open array with ID=1
int* a = SMAIntArrayAccess(1);

a[1] = 11; // use as a native array
a[2] = 22; // use as a native array 
```

NOTE: If a request is made to access an array which has not been created, the function will return 0.

# Variable to be provided to the utility routine

ID

ID of the array (an integer), chosen by the user at the time of creation. Using this ID, an array can be opened in any other user subroutine.

# Variable returned from the utility routine

INTEGER\*8 ( address )

Returns a pointer to the array, or 0 if an array with the requested ID does not exist. This pointer can be associated with a native Fortran or C/C++ array.

SMAIntArraySize, SMAFloatArraySize

# Interface

```txt
Fortran interface:
INTEGER SMAIntArraySize(ID)
INTEGER SMAFloatArraySize(ID) 
```

Example:

<!-- source-page: 667 -->

```cpp
#include <SMAAspUserSubroutines.hdr>
    integer a_size, d_size

C Get the size of Array(1) as the number of INTEGERs
    a_size = SMAIntArraySize(1)

! Get the size of Array(1) as the number of REALs
    d_size = SMAFloatArraySize(1)

    do k=1,a_size
    ...
    end do

C++ interface:
    #include <SMAAspUserSubroutines.h>

    // Lookup the size of Array(1) as the number of INTS
    int a_size = SMAIntArraySize(1);

    // Lookup the size of Array(1) as the number of doubles
    int d_size = SMAFloatArraySize(1);

    for(int i=1; i<=d_size; i++) {
    ...
    } 
```

# Variable to be provided to the utility routine

# ID

ID of the array (an integer), chosen by the user at the time of creation. Using this ID, an array can be opened in any other user subroutine.

# Variable returned from the utility routine

# INTEGER\*4

Size of the array.

<!-- source-page: 668 -->

Interface   
```txt
Fortran:
#include <SMAAspUserSubroutines.hdr>
    call SMAIntArrayDelete(1) ! Delete global Array(1)
C++:
    #include <SMAAspUserSubroutines.h>
    SMAIntArrayDelete(1); // Delete global Array(1)
NOTE: Deletion of arrays is optional. All storage allocated for these arrays will be freed when Abaqus terminates (at the very end of the analysis). It is, however, a good programming practice to delete all allocations explicitly, especially when they are no longer needed, as this will free up memory for use somewhere else. 
```

# Variable to be provided to the utility routine

# ID

ID of the array (an integer), chosen by the user at the time of creation. Using this ID, an array can be opened in any other user subroutine.

# Allocatable global arrays of variable precision

The usage of real arrays is exactly the same as that of integer and floating point arrays except for the handling of precision. The precision of real arrays varies, changing along with the precision of Abaqus/Explicit. In single precision the values of real arrays are 32-bits long, and in double precision their values are 64-bits. For this automatic switching to work in Fortran, the type of such an array should not be declared explicitly. Abaqus relies on the implicit naming to alternate between single precision and double precision. In C/C++ the type of the native array should be Real\*. The typedef declaration changes between float and double depending on the precision of Abaqus/Explicit. The precision does not change during a run; it is determined at the beginning of the analysis and remains the same until the end.

When you create real arrays, you give each array an identifier. Arrays can be created in one user subroutine and operated on in another simply by referencing this identifier. You need not capture the

<!-- source-page: 669 -->

pointer to the array and pass it between routines. The arrays persist in memory from the moment they are created until you delete them explicitly or until the analysis ends. The arrays do not disappear when any particular user subroutine terminates. They are accessible from all user subroutines and all threads. Each MPI process is separate in memory from other MPI processes and has its own arrays. There is no cross-referencing of these arrays across MPI processes.

These arrays can be resized dynamically as needed. A call to Create() on an existing array but with a different size resizes the array. If the new size is larger than the previous size, there is no loss of data and the previous contents are carried over.

# Interface

Fortran:   
```fortran
#include <vaba_param.inc>
#include <SMAAspUserSubroutines.hdr>

! Note: we do not explicitly declare the type of 'ra', we
! rely on rules of implicit typing: it will become real*4
! or real*8 depending on the precision of Abaqus

dimension ra(*)
pointer(ptrra,ra)

integer sz

rinitval = -1.0e36 ! again, implicit typing

! Creating an array

! ID=1, SIZE=10, no initializer
ptrra = SMARrealArrayCreate(1, 10)
! ID=2, SIZE=10, rinitval used to initialize
ptrra = SMARrealArrayCreate(2, 10, rinitval)
! ID=3, SIZE=10, initial value is -3.3d0
ptrra = SMARrealArrayCreate(3, 10, -3.3d0)
! ID=4, SIZE=10, initial value is -3.3
ptrra = SMARrealArrayCreate(4, 10, -3.3)

! Use ( from another subroutine )

ptrra = SMARrealArrayAccess(1) 
```

<!-- source-page: 670 -->

```txt
if (ptrra.eq.0) then
    write(*,*) '### Array',i, 'does not exist'
end if
! Use as a native array in Fortran
ra(1) = 11.11
ra(2) = 22.22
! Looping
! Find out the current size of the array #1
sz = SMARealArraySize(1)
do k=1,sz
    write(*,*) k, '=', ra(k)
end do
! Resizing
ptrra = SMARealArrayCreate(1, 1000, -1.0)
! Array #1 is resized; the original 10 entries
! are intact and carried over to the new array;
! all new entries are set to -1.0
! Deletion
call SMARealArrayDelete(1)
call SMARealArrayDelete(2)
call SMARealArrayDelete(3)
call SMARealArrayDelete(4)
C/C++:
#include <omi_for_types.h>
#include <SMAAspUserSubroutines.h>
Real* ra = 0;    // Type 'Real' switches precision with Explicit
int    sz = 0; 
```
