2.12. Memory-Management Subroutines

The program uses a dynamic memory manager that overlays the system malloc and free functions and provides a mechanism for accessing the memory from FORTRAN as well as C and C++. The memory manager library for Windows and Linux are:

Windows: The memory manager is in a dynamic linked library, \Program Files\ANSYS Inc\V242\ansys\bin\<platform>\ansMemManager.dll, where <platform> is a directory that uniquely identifies the hardware platform version.
Linux: The memory manager is a shared library in /ansys_inc/242/ansys/lib/<platform>/libansMemManager.so

You may use the system malloc and free functions or, for FORTRAN, the allocate system function. However, you may end up competing with the program for memory, and for large problems there may be insufficient system memory to perform the function.

Alternatively, you can use Ansys, Inc. provided subroutines for memory management.

2.12.1. Using the Memory Manager in a FORTRAN UPF

In FORTRAN, dynamic memory is done through Cray-style pointers, where a dynamically allocated array is defined via the construct

pointer (piArray,Array)
integer Array(*)

and memory space for the array is allocated by assigning the pointer, in this case piArray, to the allocated memory space:

piArray = fAnsMemAlloc (size,...)

or

piArray = fAnsMemAllocL (sizeL,...)

where size in an integer (4-byte) length variable, and sizeL is a long integer (8-byte) length variable.

To use the memory manager in a FORTRAN UPF, follow these steps:

  1. Define the dynamically allocated arrays:

    pointer (piArray,Array), (pdArray,dArray)
    integer Array(*)
    double precision dArray(*)
    

  2. Initialize the pointers as follows:

    piArray = PTRFTNNULL 
    pdArray = PTRFTNNULL
    

  3. Allocate space for an array or arrays, as follows:

    For integer (4-byte) numbers:

    piArray = fAnsMemAlloc(ileng,MEM_INTEGER,C16Label)

    For long integer (8-byte) numbers:

    piArray = fAnsMemAlloc(ileng,MEM_LONGINT,C16Label)

    For double-precision numbers:

    pdArray = fAnsMemAlloc(dleng,MEM_DOUBLE,C16Label)

    For complex numbers:

    pcArray = fAnsMemAlloc(cleng,MEM_COMPLEX,C16Label)

    For real numbers:

    prArray = fAnsMemAlloc(rleng,MEM_REAL,C16Label)

    Where the arguments are:

    • xleng is the desired size of the array (use fAnsMemAllocL when this size exceeds 2e31 in value)

    • MEM_xxx is the keyword indicating the type of data

    • C16Label is a character*16 name of the memory block

    You must include the ansysdef.inc include file to get the parameter values of MEM_INTEGER, MEM_LONGINT, MEM_DOUBLE, MEM_COMPLEX, and MEM_REAL. The parameter value PTRFTNNULL is defined in impcom.inc.


    Note:  If there is insufficient memory, fAnsMemAlloc and fAnsMemAllocL return "PTRFTNNULL".


  4. Use the arrays.

  5. If necessary, you may either shrink or grow the allocated memory space by using the reallocation routine. In this case, the original pointer and new length must be passed in as follows:

    piArray = fAnsMemRealloc(piArray,ileng,MEM_INTEGER,C16Label)

    or

    piArray = fAnsMemReallocL(piArray,ilengL,MEM_INTEGER,C16Label)
  6. Deallocate the space using the fAnsMemFree subroutine, as follows:

    call fAnsMemFree (piArray)

The next sections provide Input and output listings for the memory management subroutines in FORTRAN.

For an example using the memory management functions, see: Function user03 (Demonstrates Using Memory) discussed in Defining Your Own Commands.

2.12.1.1. Function fAnsMemAlloc (Allocating Space and Returning a Pointer)

*deck,fAnsMemAlloc
      function fAnsMemAlloc (iLeng, key, c16Label)

c primary function:    Get A Block of Space from mem manager and Return Pointer

c object/library:  mem
                                       
c *** Notice - This file contains ANSYS Confidential information ***

c  input arguments:
c     iLeng        (int,sc,in)       - length of the block (in data elements)
c     c16Label     (chr*16,sc,in)    - 16 character name for the Block
c     key          (int,sc,in)       - type of data for this block (see ansysdef.inc)

c  output arguments:
c     fAnsMemAlloc (PTRFTN,sc,out)   - Pointer to this data block -- needs to be
c                                      tied to a local variable in the calling 
c                                      routine


2.12.1.2. Function fAnsMemAllocL (Allocating Space and Returning a Pointer - long integer)

*deck,fAnsMemAllocL
      function fAnsMemAllocL (iLengL, key, c16Label)

c primary function:    Get A Block of Space from mem manager and Return Pointer

c object/library:  mem
                                       
c *** Notice - This file contains ANSYS Confidential information ***

c  input arguments:
c     iLengL        (LONG,sc,in)      - length of the block (in data elements)
c     c16Label      (chr*16,sc,in)    - 16 character name for the Block
c     key           (int,sc,in)       - type of data for this block (see ansysdef.inc)

c  output arguments:
c     fAnsMemAllocL (PTRFTN,sc,out)   - Pointer to this data block -- needs to be
c                                       tied to a local variable in the calling 
c                                       routine


2.12.1.3. Function fAnsMemRealloc (Reallocating Space and Returning a Pointer)

*deck,fAnsMemRealloc
      function fAnsMemRealloc (memPtr, iLeng, key, c16Label)

c primary function:    Modify a Block of Space from mem manager and 
c                      Return Pointer 

c object/library:  mem

c *** Notice - This file contains ANSYS Confidential information ***

c  input arguments:
c     memPtr         (PTRFTN,sc,in)    - pointer of block being reallocated
c     iLeng          (int,sc,in)       - new length of the block (in data elements)
c     key            (int,sc,in)       - type of data needed (see ansysdef.inc)
c     c16Label       (ch*16,sc,in)     - name for this block

c  output arguments:
c     fAnsMemRealloc (PTRFTN,sc,out)   - Pointer to the new block location


2.12.1.4. Functional fAnsMemReallocL (Reallocating Space and Returning a Pointer - long integer)

*deck,fAnsMemReallocL
      function fAnsMemReallocL (memPtr, iLengL, key, c16Label)

c primary function:    Modify a Block of Space from mem manager and 
c                      Return Pointer 

c object/library:  mem

c *** Notice - This file contains ANSYS Confidential information ***

c  input arguments:
c     memPtr          (PTRFTN,sc,in)    - pointer of block being reallocated
c     iLengL          (LONG,sc,in)      - new length of the block (in data elements)
c     key             (int,sc,in)       - type of data needed (see ansysdef.inc)
c     c16Label        (ch*16,sc,in)     - name for this block

c  output arguments:
c     fAnsMemReallocL (PTRFTN,sc,out)   - Pointer to the new block location


2.12.1.5. Subroutine fAnsMemFree (Deallocating Space)

*deck,fAnsMemFree
      subroutine fAnsMemFree (memPtr)

c primary function:   Free a Data Block, given a pointer

c object/library:  mem
                                       
c *** Notice - This file contains ANSYS Confidential information ***

c  input arguments:
c     ptr   (PTRFTN,sc,inout)  - pointer for this block

c  output arguments:  
c     ptr   (PTRFTN,sc,inout)  - pointer will be set to PTRFTNNULL


2.12.2. Using the Memory Manager in a C or C++ UPF

To use the memory manager In C or C++, follow these steps:

  1. Define the dynamically allocated arrays:

    int *iArray;
    double *dArray;
  2. Initialize the pointers as follows:

    iArray = (int*) NULL; 
    dArray = (double*) NULL;
  3. Allocate space for an array or arrays, as follows:

    For integer (4-byte) numbers:

    numBytes = leng*sizeof(int);
    iArray = cAnsMemAlloc(numBytes,0,__FILE__,__LINE__);

    For double-precision numbers:

    numBytes = leng*sizeof(double);
    dArray = cAnsMemAlloc(numBytes,0,__FILE__,__LINE__);

    Where the arguments are:

    • numBytes is the desired amount of memory to allocate (NOTE: this length can be a 64-bit integer)

    • The __FILE__ and __LINE__ arguments are used to create a string for naming the memory block


      Note:  If there is insufficient memory, cAnsMemAlloc will return a NULL pointer.


  4. Use the arrays.

  5. If necessary, you may either shrink or grow the allocated memory space by using the reallocation routine. In this case, the original pointer and new length must be passed in as follows:

    iArray = cAnsMemRealloc(iArray,newNumBytes,0,__FILE__,__LINE__);
  6. Deallocate the space using the cAansMemFree subroutine, as follows:

    call cAnsMemFree (iArray,__FILE__,__LINE__);

    Note:  the pointer passed into cAnsMemFree is untouched upon leaving this routine.


The next sections provide Input and output listings for the memory management subroutines in C or C++.

2.12.2.1. Function cAnsMemAlloc (Allocating Space and Returning a Pointer)

void *cAnsMemAlloc(size_t iLen, INT key, CHAR *cName, INT cLineNum)
/*
 * Allocate a block of memory from the memory manager and return pointer
 *
 * PARAMETER LIST:
 *  iLen     - length of block to allocate (in bytes)
 *  key      - bit patterned descriptive key to be passed to lower level manager
 *             =0, get memory any way possible
 *             &MEM_INITIAL, get memory only from initial heap block
 *             &MEM_GROWTH, get memory only outside of initial heap block
 *
 *             also stores bit patterns (in bits 17-23) representing various 
 *              allocation groups (solvers, etc)
 *  cName    - name of calling routine (should be gotten from __FILE__)
 *  cLineNum - line number of calling routines (gotten from __LINE__)
 *
 * RETURN VALUE:
 *  a pointer to the memory space
 */

2.12.2.2. Function cAnsMemRealloc (Reallocating Space and Returning a Pointer)

void *cAnsMemRealloc(void *memPtr, size_t iLen, INT key, CHAR *cName, INT cLineNum)
/*
 * Modify a block of memory from the memory manager and return pointer
 *
 * PARAMETER LIST:
 *  memPtr   - pointer to the memory block being reallocated
 *  iLen     - length of block to reallocate (in bytes)
 *  key      - bit patterned descriptive key to be passed to lower level manager
 *             =0, get memory any way possible
 *             &MEM_INITIAL, get memory only from initial heap block
 *             &MEM_GROWTH, get memory only outside of initial heap block
 *
 *             also stores bit patterns (in bits 17-23) representing various
 *              allocation groups (solvers, etc)
 *  cName    - name of calling routine (should be gotten from __FILE__)
 *  cLineNum - line number of calling routines (gotten from __LINE__)
 *
 * RETURN VALUE:
 *  a pointer to the memory space
 */

2.12.2.3. Subroutine cAnsMemFree (Deallocating Space)

void cAnsMemFree(void *memPtr, CHAR *cName, INT cLineNum)
/*
 * Free a block of memory, given a pointer
 *
 * PARAMETER LIST:
 *  memPtr   - pointer to the memory block being deallocated
 *  cName    - name of calling routine (should be gotten from __FILE__)
 *  cLineNum - line number of calling routines (gotten from __LINE__)
 *
 * RETURN VALUE:
 *  a pointer to the memory space (will be set to NULL)
 */