254 lines
9.8 KiB
Markdown
254 lines
9.8 KiB
Markdown
<!-- source-page: 671 -->
|
||
|
||
```c
|
||
// 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
|
||
|
||
# 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 items. The maximum size is INT\_MAX (2,147,483,647).
|
||
|
||
# INITVAL
|
||
|
||
Initial value for each item of the array. If the argument is not supplied, zero is used as the initial value.
|
||
|
||
<!-- source-page: 672 -->
|
||
|
||
# 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 a native C/C++ array. These arrays are global. All threads will see and access exactly the same global array with a given ID.
|
||
|
||
# Allocatable global arrays of user-defined types
|
||
|
||
The 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.
|
||
|
||
# Interface
|
||
|
||
# Fortran:
|
||
|
||
```gradle
|
||
! Include a user module called, for example, 'mod', ! which defines some user structure 'UserStruct'
|
||
```
|
||
|
||
use mod
|
||
|
||
```cpp
|
||
#include <aba_param.inc> ! include this for Abaqus/Standard
|
||
#include <vaba_param.inc> ! include this for Abaqus/Explicit
|
||
```
|
||
|
||
```txt
|
||
#include <SMAAspUserSubroutines.hdr>
|
||
```
|
||
|
||
```cpp
|
||
type(UserStruct):: us(10)
|
||
type(UserStruct):: structs(10)
|
||
type(UserStruct):: initval,s
|
||
```
|
||
|
||
<!-- source-page: 673 -->
|
||
|
||
```fortran
|
||
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
|
||
```
|
||
|
||
<!-- source-page: 674 -->
|
||
|
||
```txt
|
||
write(*,*) '### Array 2 does not exist'
|
||
end if
|
||
```
|
||
|
||
! Use as a native array in Fortran
|
||
```txt
|
||
structs(5).a = -51
|
||
structs(5).b = -52
|
||
structs(5).c = -53
|
||
```
|
||
|
||
```txt
|
||
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)
|
||
```objectivec
|
||
arraySize = SMAStructArraySize(2)
|
||
```
|
||
! Deletion call SMAStructArrayDelete(1)
|
||
|
||
<!-- source-page: 675 -->
|
||
|
||
```c
|
||
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;
|
||
```
|
||
|
||
<!-- source-page: 676 -->
|
||
|
||
```c
|
||
// 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
|
||
|
||
# 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.
|
||
|
||
# NUM\_ITEMS
|
||
|
||
Size of the array as the number of items. The maximum size is INT\_MAX (2,147,483,647).
|
||
|
||
# ITEM\_SIZE
|
||
|
||
Size of one item (struct) in bytes.
|
||
|
||
# INITVAL
|
||
|
||
Initial value for each item (struct) in the array. If this value is not supplied, the memory is simply zeroed out.
|
||
|
||
# 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 a native C/C++ array. These arrays are global. All threads will see and access exactly the same global array with a given ID.
|
||
|
||
<!-- source-page: 677 -->
|
||
|
||
# Appendix A: Index
|
||
|
||
• “User subroutines index,” Section A.1
|
||
• “User subroutine functions listing,” Section A.2
|
||
|
||
<!-- source-page: 678 -->
|
||
|
||
<!-- source-page: 679 -->
|
||
|
||
# A.1 User subroutines index
|
||
|
||
The following tables categorize each user subroutine according to its primary function. The topics are listed alphabetically.
|
||
|
||
Table A–1 Abaqus/Standard user subroutines.
|
||
|
||
<table><tr><td>Function</td><td>Related user subroutines</td></tr><tr><td>Amplitudes, User-defined</td><td>UAMP</td></tr><tr><td>Boundary Conditions</td><td>DISP, UDEMPOTENTIAL</td></tr><tr><td>Constraints</td><td>MPC</td></tr><tr><td>Contact Behavior</td><td>FRIC, FRIC_COEF, GAPCON, GAPELECTR, UINTER</td></tr><tr><td>Contact Surfaces</td><td>RSURFU</td></tr><tr><td>Element Output</td><td>UVARM</td></tr><tr><td>Elements, User-defined</td><td>UEL, UELMAT</td></tr><tr><td>Fields, Predefined</td><td>UFIELD, UMASFL, UPRESS, USDFLD, UTEMP</td></tr><tr><td>Fluid Pipe Section Behavior</td><td>UFLUIDCONNECTORLOSS, UFLUIDCONNECTORVALVE, UFLUIDPIPEFRICTION</td></tr><tr><td>Initial Conditions</td><td>HARDINI, SDVINI, SIGINI, UPOREP, VOIDRI</td></tr><tr><td>Interfacing with External Resources</td><td>UETERNALDB, URDFIL</td></tr><tr><td>Loads, Distributed</td><td>DLOAD, UTRACLOAD</td></tr><tr><td>Loads, Thermal</td><td>FILM, HETVAL</td></tr><tr><td>Loads, Electromagnetic</td><td>UDECURRENT, UDSECURRENT</td></tr><tr><td>Material Properties</td><td>CREEP, UANISOHYPER_INV, UANISOHYPER_STRAIN, UCREEPNETWORK, UDMGINI, UEXPAN, UFLUID, UFLUIDLEAKOFF, UHARD, UHYPEL, UHYPER, UMULLINS, UTRS, UTRSNETWORK, UXFEMNONLOCALWEIGHT</td></tr><tr><td>Materials, User-defined</td><td>UMAT, UMATHT</td></tr><tr><td>Motion, Prescribed</td><td>UMESHMOTION, UMOTION</td></tr><tr><td>Orientation</td><td>ORIENT</td></tr><tr><td>Pore Fluid Flow</td><td>DFLOW, DFLUX, FLOW</td></tr><tr><td>Random Response</td><td>UCORR, UPSD</td></tr></table>
|
||
|
||
<!-- source-page: 680 -->
|
||
|
||
<table><tr><td>Function</td><td>Related user subroutines</td></tr><tr><td>Shell Section Behavior</td><td>UGENS</td></tr><tr><td>Wave Kinematics</td><td>UWAVE</td></tr></table>
|
||
|
||
Table A–2 Abaqus/Explicit user subroutines.
|
||
|
||
<table><tr><td>Function</td><td>Related user subroutines</td></tr><tr><td>Amplitudes, User-defined</td><td>VUAMP</td></tr><tr><td>Boundary Conditions</td><td>VDISP</td></tr><tr><td>Contact Behavior</td><td>VFRIC, VFRIC_COEF, VFRICTION, VUINTER, VUINTERACTION</td></tr><tr><td>Elements, User-defined</td><td>VUEL</td></tr><tr><td>Fields, Predefined</td><td>VUFIELD, VUSDFLD</td></tr><tr><td>Fluid Exchange, User-defined</td><td>VUFLUIDEXCH, VUFLUIDEXCHEFFAREA</td></tr><tr><td>Interfacing with External Resources</td><td>VEXTERNALDB</td></tr><tr><td>Loads, Distributed</td><td>VDLOAD</td></tr><tr><td>Loads, Thermal</td><td>VDFLUX</td></tr><tr><td>Material Properties</td><td>VFABRIC, VUANISOHYPER_INV, VUANISOHYPER_STRAIN, VUCHARLENGTH, VUCREEPNETWORK, VUEOS, VUHARD, VUMULLINS, VUTRS, VUVISCOSITY</td></tr><tr><td>Materials, User-defined</td><td>VUMAT</td></tr><tr><td>Wave Kinematics</td><td>VWAVE</td></tr></table>
|
||
|
||
Table A–3 Abaqus/CFD user subroutines.
|
||
|
||
<table><tr><td>Function</td><td>Related user subroutines</td></tr><tr><td>Boundary Conditions</td><td>SMACfdUserPressureBC, SMACfdUserVelocityBC</td></tr></table>
|