EXTERNAL_OUTPUT

Specifies parameters to enable an external code or user-defined function to collect data from AcuSolve.

Type

AcuSolve Command

Syntax

EXTERNAL_OUTPUT("name") {parameters...}

Qualifier

User-given name.

Parameters

type (enumerated) [=socket]
Type of the communication.
socket
Socket communication. Requires socket_host, socket_port and launch.
user
User-defined function is called periodically, which may itself communicate with an external code. Requires user_function.
output_frequency or out_freq (integer) >=0 [=0]
Time step frequency at which to allow an external code or user-defined function to collect data from AcuSolve. If zero, this option is ignored.
output_time_interval or out_intv (real) >=0 [=0]
Time frequency at which to allow an external code or user-defined function to collect data from AcuSolve. If zero, this option is ignored.
socket_host or host (string) [no default]
User-given name of the host that runs the external code. Used with socket type.
socket_port or port (integer) >0 [=20000]
Socket port for communication with the external code. Used with socket type.
user_function or user (string) [no default]
Name of the user-defined function. Used with user type.
user_values (array) [={}]
Array of values to be passed to the user-defined function. Used with user type.
user_strings (list) [={}]
Array of strings to be passed to the user-defined function. Used with user type.
launch (boolean) [=off]
Flag specifying whether or not AcuSolve should launch the external code. Used with socket type.
launch_command (string) [no default]
Command to launch the external code. Used with launch=on and socket type.

Description

This command specifies the parameters to enable an external code or user-defined function to extract data from a running AcuSolve instance. For an external code this extraction is done via the socket type and the External Code Output (ECO) library. The ECO library is documented in the file doc/external_output.txt, which can be found in the AcuSolve distribution. The ECO functions are listed below. Once this library is linked to an external code, the external code is able to collect data from AcuSolve, process it, and store it in any desirable form.

For example, the following command may be used to notify AcuSolve that external output is to be used from an external code:
EXTERNAL_OUTPUT( "test" ) {
   type                 = socket
   output_frequency     = 1
   output_time_interval = 0
   socket_host          = "hostname"
   socket_port          = 20000
   launch               = off 
}

By default both output frequencies are zero, which means that this output mechanism is turned off. If either is non-zero, then socket_host gives the name of the machine where the external code will run and socket_port is the port that the external code will be listening to. Run times may not coincide with output_time_interval. In this case, at every time step which passes through a multiple of output_time_interval, output to the external code is enabled.

When AcuSolve encounters this command, it will connect to the socket with the given host and port. Every AcuSolve subdomain will establish connection with the external code. The external code must be listening at that port and establish connection to each of the AcuSolve processors. It will then communicate with each processor in order to get the needed information. You can launch the EXTERNAL_OUTPUT command, for example, extOut 20000, directly from the AcuSolve input file. For example,
EXTERNAL_OUTPUT( "test" ) {
   ...
   launch         = on
   launch_command = "extOut 20000"
   ...
}
A user type is an advanced feature that allows access to AcuSolve data at a fine granularity. One purpose is for a user-defined function to act as an interface to an external visualizer. As such, this function will be able to traverse much of the data contained in AcuSolve using most of the user-defined function support routines. See the AcuSolve User-Defined Functions Manual for a detailed description of these routines. For example,
EXTERNAL_OUTPUT( "test" ) {
   type              = user
   output_frequency  = 1
   user_function     = "usrParaView"
   user_values       = { 1., 2., 3. }
   user_strings      = { "visualizer" }
}
The following is an example of an external code for type=socket written in C:
/* Include necessary header files */
#include "acusim.h"
#include "eco.h"
#include "ver.h"
/* Main function */
int main( int, char** ) ;
int
main( int argc,
    char* argv[] )
{
    char*         funcName = "main" ;    /* function name                   */
    EcoHd         ecoHd ;                /* an ECO handle                   */
    Integer       nNodes ;               /* No. nodes                       */
    Integer*      usrIds ;               /* user ids                        */
    Integer*      elemIds ;              /* user ids                        */
    Integer*      cnn ;                  /* cnns                            */
    Real*         crd ;                  /* coordinates                     */
    Real*         vec ;                  /* output vector                   */
    Integer       port ;                 /* port number                     */
    Integer       verbose ;              /* verbose level                   */
    Integer       waitTime ;             /* wait time                       */
    Integer       i ;                    /* temporary integer               */
    Integer       iElm ;                 /* temporary integer               */
    Integer       iVar ;                 /* temporary integer               */
    Integer       tsId ;                 /* time step Id                    */
    Real          time ;                 /* time level                      */
    Real          timeInc ;              /* time increment                  */
    Integer       nElms ;                /* No. element sets                */
    Integer       nElems ;               /* No. elements                    */
    Integer       nElemNodes ;           /* No. nodes per element           */
    Integer       nVars ;                /* No. variables                   */
    Integer       nDims ;                /* Variable dimension              */
    Integer       iTmp ;                 /* temporay integer                */
    Integer       medium ;               /* medium type                     */
    char          buff[SYS_BUFF_SIZE] ;  /* a temporary buffer              */
    IopHd         iopHd ;                /* output handle                   */
/* Set the program name and version */
    sysSetProgName( argv[0] ) ;
    sysSetVersion( VER_VERSION ) ;
    sysSetMessFile( "ECO.txt" ) ;
    sysLineBuffMess( ) ;
/* Get the options */
    if ( argc != 2 ) {
       sysMess( "Usage: %s port", argv[0] ) ;
       sysExit( 1 ) ;
   }
/* Initialize ECO */
    sscanf( argv[1], "%i", &port ) ;
    waitTime      = 3600 ;
    verbose       = 1 ;
    nNodes        = 60 ;
    usrIds        = memNew( Integer, nNodes ) ;
    crd           = memNew( Real, 3*nNodes ) ;
    iopReadFileArrays(      "channel.crd",    nNodes,          2,
                             usrIds,          IOP_ARRAY_INT,   1, 
                             crd,             IOP_ARRAY_REAL,  3,           ) ;
ecoHd             = ecoNew( "oriole",         port,            waitTime,
                             usrIds,          nNodes,          verbose      ) ;
/* Process */
   ecoGetUsrIds(                      ecoHd,  usrIds                        ) ;
   ecoGetCrd(                         ecoHd,  crd                           ) ;
/* Time related output */
   tsId           = ecoGetTimeStep(   ecoHd                                 ) ;
   time           = ecoGetTime(       ecoHd                                 ) ;
   timeInc        = ecoGetTimeInc(    ecoHd                                 ) ;
/* Variables output */
   nVars          = ecoGetNOutVars(   ecoHd                                 ) ;
   for ( iVar = 0 ; iVar < nVars ; iVar++ ) {
       nDims      = ecoGetOutVarDim(  ecoHd,  iVar                          ) ;
       vec        = memNew(           Real,   nDims*nNodes
       ecoGetOutVarName(              ecoHd,  iVar,            buff         ) ;
       sysMess("variable=%s", buff)
       ecoGetOutValues(               ecoHd,  iVar,            vec          ) ;
       for ( i = 0 ; i < nNodes ; i++ ) {
           sysMess("%s @ node %d=%lf", buff, i, vec[i]                      ) ;
   }
}
/* Element output */
   nElms          = ecoGetNElms( ecoHd                                      ) ;
   nElems         = 0 ;
   for ( iElm = 0 ; iElm < nElms ; iElm++ ) {
       iTmp       = ecoGetNElems(     ecoHd,  iElm                          ) ;
       nElems += iTmp ;
       nElemNodes = ecoGetNElemNodes( ecoHd,  iElm                          ) ;
       medium     = ecoGetElmMedium ( ecoHd,  iElm                          ) ;
   }
   cnn            = memNew(          Integer, nElemNodes*nElems             ) ;
   for ( iElm = 0 ; iElm < nElms ; iElm++ ) {
   ecoGetCnn(                         ecoHd,  iElm,            cnn          ) ;
   }
   sprintf( buff, "eco_cnn.txt" ) ;
   sysMess( "%26s = %s", "Writing cnn file", buff ) ;
   iopHd          = iopOpenFile( buff, IOP_WRITE | IOP_ASCII ) ;
   iopWriteInts(                      iopHd,  "cnn",  nElemNodes, nElems,
                                      cnn                                    ) ;
   ecoContinue(                       ecoHd                                  ) ;
/* Cleanup */
   ecoFree(                           ecoHd                                  ) ;
   free(                              usrIds                                 ) ;
   free(                              crd                                    ) ;
   free(                              vec                                    ) ;
   free(                              cnn                                    ) ;
} /* end of main() */
This Python example is similar to the above. However, memory management is done by Python.
# Import utilities
import acueco
import acudb
import numarray
# Call graphics utility
problem            = "channel"
port               = 20004
codeName           = "test"
waitTime           = 3600
verbose            = 1
matchInputIds      = False                 # use condensed node numbers
matchInputIds      = True               # match input node numbers
if not matchInputIds:
   eco             = acueco.Acueco( port, codeName, waitTime, None, verbose)
else:
   adb             = acudb.Acudb( problem, 'ACUSIM.DIR', 0 )
   adb.openRun( 0 )
   usrIds          = adb.get( 'usrIds' )
   usrIds          = numarray.array( usrIds )
   eco             = acueco.Acueco( port, codeName, waitTime, usrIds, verbose)
# Extract nodal data
nSds               = eco.getNSds()
nNodes             = eco.getNNodes()
usrIds             = eco.getUsrIds()
# Extract element data
# Alternative: the elements may be obtained from acudb
nElms              = eco.getNElms( )
cnns               = []
for i in range(nElms):
   cnn             = eco.getCnn( i )
   cnns.append     ( cnn )
# Get the velocity index
nVars              = eco.getNVars()
velId              = -1
for i in 
range(nVars):
   varName         = eco.getVarName( i )
   if varName      == "velocity": velId = i
# Get the velocity field at each time step
while True:
   step            = eco.getTimeStep()
   time            = eco.getTime()
   timeInc         = eco.getTimeInc()
   vel             = eco.getOutValues( velId )
   last            = eco.getLastStepFlag()
   print "Step     =", step
   print "Time     =", time
   print "TimeInc  =", timeInc
   print "Max Vel  =", vel.max()
   eco.continueRun()
   if last: break
The functions available in the ECO library are:
ecoNew
Initialize external output.
ecoGetNSds
Return the number of subdomains in the problem.
ecoGetNNodes
Return the number of nodes in the problem.
ecoGetUsrIds
Get the user-prescribed nodal IDs of the problem.
ecoGetCrd
Get the coordinates of the domain.
ecoGetNElms
Get the number of element sets in the domain.
ecoGetNElems
Get the number of elements in the domain.
ecoGetNElemNodes
Get the number of nodes per element.
ecoGetCnn
Output the element connectivity table.
ecoGetElmMedium
Output the medium type (fluid, solid, or shell) of the element set.
ecoGetNOutVars
Output the number of variables in the problem.
ecoGetOutVarName
Output the name of variables in the problem.
ecoGetOutVarDim
Output the dimension of variables.
ecoGetOutValues
Get the values of variables in the domain.
ecoGetTimeStep
Get the time step ID during run time.
ecoGetTime
Get the current time level during simulation.
ecoGetTimeInc
Get the time-step increment.
ecoGetLastStepFlag
Obtain the flag for the last time-step.
ecoContinue
Get the command for the continuation of simulation.
ecoStop
Get the termination command for the run.
ecoFree
Deallocate all the arrays, close all file descriptors and sockets, disconnect from AcuSolve.