ProductsAbaqus/StandardAbaqus/Explicit SMALocalIntArrayCreate, SMALocalFloatArrayCreateYou can create any number of thread-local or global arrays. You give each array an identifier (an arbitrary positive integer) at the time of its creation. You create an array in one user subroutine and reference it in another simply by its identifier. The arrays persist in memory until you explicitly delete them or until the analysis terminates.
Utility routine interfaceFortran:
INTEGER*8 SMALocalIntArrayCreate(ID,SIZE,INITVAL)
INTEGER*8 SMALocalFloatArrayCreate(ID,SIZE,INITVAL)
Example:
#include <SMAAspUserSubroutines.hdr>
integer a(100)
pointer(ptra,a)
real*8 b(*)
pointer(ptrb,b)
! create a local array with ID=1 and SIZE=100
ptra = SMALocalIntArrayCreate(1,100)
a(1) = 11 ! use as a native Fortran array
a(2) = 22 ! use as a native Fortran array
! create a local float array with ID=1 and SIZE=100, and
! initial value = -1.0
ptrb = SMALocalFloatArrayCreate(1,100,-1.0)
C++:
#include <SMAAspUserSubroutines.h>
// Create a local integer array of with ID=1 and size=100
int* a = SMALocalIntArrayCreate(1,100);
// Create a local float array of with ID=1, size=20, and
// initial value = -1.0
real* b = SMALocalFloatArrayCreate(1,100,-1.0);
NOTE: Float Arrays can store both SINGLE PRECISION
and DOUBLE PRECISION numbers. Internally,
memory is allocated in units of 64 bits (double/real*8).
NOTE: To resize an array, simply call Create() with the same ID,
but give it a new SIZE parameter. If the new size is larger,
the old data are copied over to the new array. No data are lost
during resizing.
For example:
! resize array with ID=1 to 300 integers
ptra = SMALocalIntArrayCreate(1,300)
NOTE: In Create() functions, there is an optional third
argument -- initial value. If not supplied, all Int
arrays are initialized with INT_MAX ( 2,147,483,647 ).
All Float Arrays are initialized with Signaling NANs.
The values of INT_MAX and signaling NANs are accessible
via the 'SMAAspNumericLimits.h' and 'SMAAspNumericLimit.hdr'
header files.Variables to be provided to the utility routine
Variables returned from the utility routine
SMALocalIntArrayAccess, SMALocalFloatArrayAccessUtility routine interface
Fortran interface:
INTEGER*8 SMALocalIntArrayAccess(ID)
INTEGER*8 SMALocalFloatArrayAccess(ID)
Example:
#include <SMAAspUserSubroutines.hdr>
integer a(100)
pointer(ptra,a)
C Locate local Array(1) and associate a native array pointer with it
ptra = SMALocalIntArrayAccess(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 = 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. Variables to be provided to the utility routine
Variables returned from the utility routine
SMALocalIntArraySize, SMALocalFloatArraySizeUtility routine interface
Fortran interface:
INTEGER*4 SMALocalIntArraySize(ID)
INTEGER*4 SMALocalFloatArraySize(ID)
Example:
#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++) {
...
}Variables to be provided to the utility routine
Variables returned from the utility routine
SMALocalFloatArrayDelete, SMALocalFloatArrayDeleteUtility routine interfaceFortran 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.Variables to be provided to the utility routine
SMAIntArrayCreate, SMAFloatArrayCreateUtility routine interfaceFortran interface:
INTEGER*8 SMAIntArrayCreate(ID,SIZE,INITVAL)
INTEGER*8 SMAFloatArrayCreate(ID,SIZE,INITVAL)
Example:
#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:
#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.
For example:
! resize array with ID=1 to 300 integers
ptra = SMAIntArrayCreate(1,300,-1)
Variables to be provided to the utility routine
Variables returned from the utility routine
SMAIntArrayAccess, SMAFloatArrayAccessUtility routine interfaceFortran interface:
INTEGER*8 SMAIntArrayAccess(ID)
INTEGER*8 SMAFloatArrayAccess(ID)
Example:
#include <SMAAspUserSubroutines.hdr>
integer a(100)
pointer(ptra,a)
C Locate Array(1) and associate a native array pointer with it
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.
Variables to be provided to the utility routine
Variables returned from the utility routine
SMAIntArraySize, SMAFloatArraySizeUtility routine interfaceFortran interface:
INTEGER SMAIntArraySize(ID)
INTEGER SMAFloatArraySize(ID)
Example:
#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++) {
...
}
Variables to be provided to the utility routine
Variables returned from the utility routine
SMAFloatArrayDelete, SMAFloatArrayDeleteUtility routine interfaceFortran:
#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.
Variables to be provided to the utility routine
Allocatable global arrays of variable precisionThe 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 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. Utility routine interfaceFortran:
#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 = SMARealArrayCreate(1, 10)
! ID=2, SIZE=10, rinitval used to initialize
ptrra = SMARealArrayCreate(2, 10, rinitval)
! ID=3, SIZE=10, initial value is -3.3d0
ptrra = SMARealArrayCreate(3, 10, -3.3d0)
! ID=4, SIZE=10, initial value is -3.3
ptrra = SMARealArrayCreate(4, 10, -3.3)
! Use ( from another subroutine )
ptrra = SMARealArrayAccess(1)
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;
// Examples of Array Creation
// ID=1, SIZE=10, no initializer used
ra = SMARealArrayCreate(1, 10);
// ID=2, SIZE=10, initial value = -1.0
ra = SMARealArrayCreate(2, 10, -1.0);
// Access from another User Subroutine
ra = SMARealArrayAccess(1);
if ( ra == 0 ) {
fprintf(stderr,
"*** Error: array %d does not exist ***\n", 1 );
}
// Looping over the entries
// obtain the current size of array #1
sz = SMARealArraySize(1);
for (int i=0; i<sz; i++) {
sum = sum + ra[i];
}
// Deletion
SMARealArrayDelete(1);
SMARealArrayDelete(2);Variables to be provided to the utility routine
Variables returned from the utility routine
Allocatable global arrays of user-defined typesThe usage and syntax of arrays of structures are exactly the same as those of integer, floating point, and real arrays. These arrays are designed to store any user-defined types or classes, defined either in Fortran or in C/C++. The only information an array needs to know about these structures is their memory size. Most compilers provide the sizeof() operator, which returns the size of any object in memory in bytes. This size is one additional argument to the routines that operate on arrays of structures. When you create arrays of structures, 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 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 from 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 data loss and the previous contents are carried over. Utility routine interfaceFortran:
! Include a user module called, for example, 'mod',
! which defines some user structure 'UserStruct'
use mod
#include <aba_param.inc> ! include this for Abaqus/Standard
#include <vaba_param.inc> ! include this for Abaqus/Explicit
#include <SMAAspUserSubroutines.hdr>
type(UserStruct):: us(10)
type(UserStruct):: structs(10)
type(UserStruct):: initval,s
pointer(ptrstructs, structs)
integer:: size1, size2, size3, size4
integer(kind=8) :: arraySize
! Create an initializer for the values of the array
!(optional)
initval%a = 100
initval%b = 200
initval%c = 300
! Different ways of obtaining the size of a structure
size1 = storage_size( us(1) ) / 8 ! returns the size
! in bits
size2 = sizeof( us(1) )
size3 = storage_size( initval ) / 8 ! returns the size
! in bits
size4 = sizeof( initval )
! Creating an array
write(*,*) 'Array without initializers:'
ptrstructs = SMAStructArrayCreate(1, 10, sizeof(initval))
write(*,*) 'Array with initializers:'
ptrstructs = SMAStructArrayCreate(2, 10, sizeof(initval),
& initval)
! Use ( from another subroutine )
ptrstructs = SMAStructArrayAccess(2)
if (ptrstructs.eq.0) then
write(*,*) '### Array 2 does not exist'
end if
! Use as a native array in Fortran
structs(5).a = -51
structs(5).b = -52
structs(5).c = -53
structs(10).a = 111
structs(10).b = 222
structs(10).c = 333
! Looping over the entries
arraySize = SMAStructArraySize(2)
do k=1,arraySize
s = structs(k); call PrintStruct(s)
end do
! Resize an array without using initializer
ptrstructs = SMAStructArrayCreate(2, 100, sizeof(initval))
arraySize = SMAStructArraySize(2)
! Resize array 2 with initializer
ptrstructs = SMAStructArrayCreate(2, 200, sizeof(initval),
& initval)
arraySize = SMAStructArraySize(2)
! Deletion
call SMAStructArrayDelete(1)
call SMAStructArrayDelete(2)
C/C++:
#include <omi_for_types.h>
#include <SMAAspUserSubroutines.h>
// Include the definition of a user-defined type,
// for example, A
#include <A.h>
// Create an (optional) initializer for user structs
A init = { -1, -2, -3 };
// Creating arrays
// no initializer
SMAStructArrayCreate(1, 10, sizeof(A));
// with initializer
SMAStructArrayCreate(2, 10, sizeof(A), &init;);
// Accessing arrays (from another subroutine)
A* array = (A*) SMAStructArrayAccess(1);
// Modifying values in the array
A* s1 = &array[5]; // We use a pointer to modify the value in
// the array itself. Without a pointer, s1
// will contain a copy of the entry in
// the array, and any modifications to
// this copy will not affect the value in
// the original array.
s1->a = -111;
s1->b = -222;
s1->c = -333;
// Looping over the entries
size_t sz = SMAStructArraySize(1);
printf("Array 1: \n");
for (size_t i=0; i < sz; i++) {
PrintStruct(i, &array[i]);
}
// Deletion
SMAStructArrayDelete(1);
SMAStructArrayDelete(2);Variables to be provided to the utility routine
Variables returned from the utility routine
| |||||||||