UT-SIM
  • Home
  • Architecture
    • Communication
    • Integration Modules
    • Substructure Modules
  • Users
    • Get Started with UT-SIM >
      • OpenSees
      • Abaqus
      • S-Frame
      • VecTor Suite
      • NICON-NIO
      • NICON-AIO
    • Download
  • Developers
    • Source Code
    • Communication Examples >
      • C/C++
      • Fortran
      • Matlab
      • Python
    • Download
  • Hybrid Simulation
  • Numerical Simulation
  • Application Examples
  • Workshop
  • News
  • Collaborators
  • Contact
  • References

matlab module development

matlab

To develop an integration model or an substructure model in Matlab for communication, the developer needs to provide the explicit linkage to the DataExchange DLL in the code. This document assumes that the develoepr is familiar with Matlab.

Link with DataExchange library (Matlab)¶

To explicitly link with the DLL in Matlab, the DataExchange.dll and corresponding header file (DataExchange.h) should be loaded to Matlab using the following command.

% load DataExchange library
    loadlibrary('./DataExchange.dll', './DataExchange.h');

Then use the following calllib function to call the DLL functions in the matlab script.

Syntax: [x1,...,xN] = calllib(libname,function,arg1,...,argN)

where

  • x1,...,xN: return variables of the DLL function
  • libname: the name of the dll file
  • function: the name of the DLL function
  • arg1,...,argN: input variables of the DLL function

For example, the way to use the setupconnection() function to establish the connection is shown below

iResult = calllib('DataExchange', 'setupconnection', PortNumber, sockfdPtr, flag, machineInetAddr, TCP_IP);

Integration Model (Matlab)¶

In addition to the above code to link with the DataExchange.dll, the integration model starts with declaring variables required for communication.

PortNumber = 8090;                                           % port number
    machineInetAddr = libpointer('cstring','127.0.0.1');         % IP address

    sockfd = 0;                                                  % initialize socket number
    flag = 1;                                                    % 1 - integration module; 2 - substructure module
    numdofs = 3;                                                 % total interface DOFs

where

  • PortNumber: port number. This number should be consistent with the port number specified in the substructure model below.
  • machineInetAddr - IP address of machine with the substructure model. For the case that the integration and substructure models are modelled in the same Windows machine, the standard IP address of "127.0.0.1" can be used.
  • sockfd: a SOCKET type variable for a newly generated socket
  • flag: a variable to be used in the DataExchange.dll functions to indicate the model is a integration model or a substructure model.
  • numdofs: a variable defines the total number of degrees of freedom at the interface nodes.

Communication Initialization¶

Then, three DLL functions are called to initialize the data exchange format, set up the connection with the substructure model, and send the initialized data exchange format to the substructure model.

% initialize data exchange format
    calllib('DataExchange', 'updatemessageheader', 2, 0, Software_only, 1, Double_precision, numdofs);

    % setup connection
    sockfdPtr = libpointer('uint64Ptr', sockfd);                               % pointer to sockfd
    iResult = calllib('DataExchange', 'setupconnection', PortNumber, sockfdPtr, flag, machineInetAddr, TCP_IP);
    if iResult ~= 0
        disp('Connection failed.');
    else
        disp('Connection done');
    end

    % send the data exchange format to the substructure model
    sockfd1 = get(sockfdPtr, 'value');
    iResult = calllib('DataExchange', 'initialization', sockfd1, flag, TCP_IP);
    if iResult ~= 0
        disp('Initialization failed.');
    else
        disp('Initialization done');
    end

where UpdateMessageHeader(version, command, testtype, subtype, precision, numdofs) function is used to initialize the following information defined in the header block of the data exchanged through UTNP (see here for more details).

  • version: this parameter corresponds to the Version parameter in the data exchange format. It is 2 for the current release version.
  • command: this parameter corresponds to the Command parameter in the data exchange format. It can be defined as zero at this initialization stage.
  • testtype: this parameter corresponds to thie Test type parameter in the data exchange format. Depending on the simulation methods, one of the following values can be used to initialize the parameter.
    • 1 - Pseudo-dynamic (ramp-hold) simulation
    • 2 - Pseudo-dynamic (continuous) simulation
    • 4 - Numerical multi-platform simulation
  • subtype: this parameter corresponds to the Substructure type parameter in the data exchange format. Depending on the substructure modules, one of the following values can be used to initialize the parameter
    • 1 - OpenSees
    • 2 - Zeus-NL
    • 3 - ABAQUS
    • 4 - VecTor2
    • 5 - NICON-AIO or NICON-NIO
    • 6 - VecTor4
    • 7 - LS-Dyna
  • precision: this parameter corresponds to the Precision parameter in the data exchange format. It can be defined as 1 for single precision and 2 for double precision
  • numdofs: this parameter corresponds to the Number of DOFs parameter in the data exchange format. It is equal to the total number of effective DOFs at the interface nodes for communication.

Sending Data¶

Once communication is established and the data format parameters are initialized, the integration module starts with sending displacement command to the substructure.

%------------------------------------------------------------------------------------
    %   send trial displacement to substructure module 
    %------------------------------------------------------------------------------------
    % update the command in the message header block for imposing target displacement   
    calllib('DataExchange', 'updatecommand', Impose_TargetValues);

    % define the type of data to be appended to the message header 
    % updatesubtype (disp, vel, accel, force, stiff, mass,temperature)
    % use 1 and 0 to enable and disable the data in the function.
    calllib('DataExchange', 'updatesubtype', 1, 0, 0, 0, 0, 0, 0);

    % send the updated data header to the substructure module
    action = calllib('DataExchange', 'command', sockfd1, flag, TCP_IP);

    % calculate the data size to be appended to the message header
    lens = calllib('DataExchange', 'indicator');

    % send trial disp to substructure module
    sdata = unn(:,i);

    sdataPtr = libpointer('doublePtr', sdata);

    iResult = calllib('DataExchange', 'senddata', sockfd1, sdataPtr, lens, TCP_IP);
    if iResult ~= 0
        disp('Failed to send disp.');
    else
        disp('Disp sent');
    end

Receiving Data¶

Once the restoring force is computed in the substructure module, the integration module sends another command to receive the computed force from the substructure module.

%------------------------------------------------------------------------------------
    %   receive restoring force from substructure module 
    %------------------------------------------------------------------------------------ 
    % update the command in the message header for receiving data from the substructure module
    calllib('DataExchange', 'updatecommand', Report_Values);

    % define the type of data to be appended to the message header 
    % UpdateSubtype (disp, vel, accel, force, stiff, mass,temperature)
    % use 1 and 0 to enable and disable the data in the function.
    calllib('DataExchange', 'updatedatatype', 0, 0, 0, 1, 0, 0, 0);

    % send the updated message header to the substructure module
    action = calllib('DataExchange', 'command', sockfd1, flag, TCP_IP);

    % calculate the data size to be appended to the message header
    lens = calllib('DataExchange', 'indicator');

    % receive the computed restoring force from substructure module
    forcePtr = libpointer('doublePtr', zeros(1,lens));

    iResult = calllib('DataExchange', 'recvdata', sockfd1, forcePtr, lens, TCP_IP);
    if iResult ~= 0
        disp('Failed to receive force.');
    else
        disp('Force received');
    end

    %Formulate the equivalent force to solve the system's motion equation 
    force = get(forcePtr,'value');
    Pe = P(:,i) - force';

The above sending and receving data steps are repeated until the end of the simulation.

Disconnection¶

Once the simulation is done, the following is included in the code to disconnect the integration module from the substructure module.

%------------------------------------------------------------------------------------
    %   terminate communication
    %------------------------------------------------------------------------------------
    %update the command in the message header 
    calllib('DataExchange', 'updatecommand', Terminate);

    % send the updated message header to the substructure module
    action = calllib('DataExchange', 'command', sockfd1, flag, TCP_IP);

    % disconnect and close socket
    iResult = calllib('DataExchange', 'close', sockfdPtr);

    disp('Simulation done.')

    % unload dataexchange library
    unloadlibrary DataExchange;

Substructure Model (C/C++)¶

Similar to the above integration module, the variables for port number, IP address, socket number, and indicator of module type should be defined after the program is linked with the DataExchange.dll.

PortNumber = 8090;                                           % port number
    machineInetAddr = libpointer('cstring','0.0.0.0');           % IP address

    sockfd = 0;                                                  % variable for new created socket id
    flag = 2;                                                    % 1 - integration module; 2 - substructure module

Communication Initialization¶

The same updatemessageheader, setupconnection, initialization are used in the substructure module to initialize the message header and connect with the integration module. The only difference is the value of flag which indicates that the dll functions are being called by a substructure module.

%------------------------------------------------------------------------------------
    %   Initialize data exchange format and setup connection  
    %------------------------------------------------------------------------------------

    % declare data exchange format          
    calllib('DataExchange', 'updatemessageheader', 2, 0, 0, 0, Double_precision, 0);

    % setup connection
    sockfdPtr = libpointer('uint64Ptr', sockfd);                               % pointer to sockfd
    iResult = calllib('DataExchange', 'setupconnection', PortNumber, sockfdPtr, flag, machineInetAddr, TCP_IP);
    if iResult ~= 0
        disp('Connection failed.');
    else
        disp('Connection done');
    end

    % receive data exchange format from the integration module
    sockfd1 = get(sockfdPtr, 'value');
    iResult = calllib('DataExchange', 'initialization', sockfd1, flag, TCP_IP);
    if iResult ~= 0
        disp('Initialization failed.');
    else
        disp('Initialization done');
    end

After the connection is built, a switch statement is included, which defines different actions based on the received command values in the message header.

% receive data format from integration module
    action = calllib('DataExchange', 'command', sockfd1, flag, TCP_IP);

    switch action

        case Impose_TargetValues

            % // code to receive data from the integration module (see below)

        case Report_Values

            % // code to send computed data to the integration module (see below)

        case Terminate

            % // exit the switch statement
            exitFlag = 0;

        otherwise

            disp('Invalid action received');

    end

Receiving Data¶

In the above case of Impose_TargetValues, the substructure module receives the displacement from the integration module. Detailed code is shown below:

% calculate the size to be appended to the message header
    lens = calllib('DataExchange', 'indicator');

    % receive displacement from the integration module
    TdispPtr = libpointer('doublePtr', zeros(1,lens));

    iResult = calllib('DataExchange', 'recvdata', sockfd1, TdispPtr, lens, TCP_IP);
    if iResult ~= 0
        disp('Failed to receive trial displacement.');
    else
        disp('Trial displacement received');
    end

    % save the displacement for analysis
    Tdisp = get(TdispPtr,'value');

Sending Data¶

In the case of Report_Values, the substructure module sends the computed restoring force back to the integration module. Detailed code is shown below:

% calculate the size to be appended to the message header
    lens = calllib('DataExchange', 'indicator');

    % calculate the restoring force with respect to the received displacement
    RF = K * Tdisp';

    RFPtr = libpointer('doublePtr', RF);

    % send the computed force to integration module
    iResult = calllib('DataExchange', 'senddata', sockfd1, RFPtr, lens, TCP_IP);
    if iResult ~= 0
        disp('Failed to send restoring force.');
    else
        disp('Restoring force sent');
    end

Disconnection¶

At the end of the simulation, the communication is disconnected.

%------------------------------------------------------------------------------------
    %   Disconnect communication and close socket
    %------------------------------------------------------------------------------------
    % disconnect and close socket   
    iResult = calllib('DataExchange', 'close', sockfdPtr);

    disp('Simulation done.')

    % unload DataExchcange library
    unloadlibrary DataExchange;

Source Code Downloading¶

The source code the above communication example in Matlab can be downloaded from here.

Proudly powered by Weebly
  • Home
  • Architecture
    • Communication
    • Integration Modules
    • Substructure Modules
  • Users
    • Get Started with UT-SIM >
      • OpenSees
      • Abaqus
      • S-Frame
      • VecTor Suite
      • NICON-NIO
      • NICON-AIO
    • Download
  • Developers
    • Source Code
    • Communication Examples >
      • C/C++
      • Fortran
      • Matlab
      • Python
    • Download
  • Hybrid Simulation
  • Numerical Simulation
  • Application Examples
  • Workshop
  • News
  • Collaborators
  • Contact
  • References