HyperWorks Solvers

User Subroutine Guidelines

User Subroutine Guidelines

Previous topic Next topic Expand/collapse all hidden text  

User Subroutine Guidelines

Previous topic Next topic JavaScript is required for expanding text JavaScript is required for the print function  

User subroutines are created for various reasons.  Some include:

To describe a physical phenomenon that is determined by non-trivial logical conditions.
When it is unpractical to formulate a complicated expression in an explicit form.
To take full advantage of a programming language like C/C++ or Fortran or a scripting language like Python or MATLAB.
NoteUsing user subroutines adds a level of complexity to your multi-body model. We recommend using the built-in functions to model your system before using subroutines unless it is necessary or more convenient to use subroutines.

To use your own subroutines in MotionSolve, follow these steps:

1.Create a Python, MATLAB, C/C++ or FORTRAN source file that contains the user defined modeling entity.
2.Obtain a Dynamic-Link Library (DLL) or Shared Object (SO) by compiling and linking your user subroutine(s) – only for C/C++ or FORTRAN source code.  No compiling is required for Python or MATLAB source code.  Python routines are automatically compiled, and you can use compiled Python files with MotionSolve without the source files.
3.Modify the corresponding entity in your multi-body model to be "user defined" and to point to your DLL/SO or script file.
4.Run MotionSolve, verifying that it picks up the appropriate DLL/SO or script file during simulation.

The above steps are described in detail in the sections below.

hmtoggle_plus1greyWriting Solver Subroutines

To write a user subroutine, you first have to determine which user subroutine you need to use and select a programming language.

Listed below are supported solver subroutines and the corresponding user defined entity.

Subroutine Name

Corresponding MotionSolve XML Element

ARYSUB

<Reference_Array>

CNFSUB

<Force_Contact> - Normal force only

CFFSUB

<Force_Contact> - Friction force only

CONSUB

<UserProgramControl>

CONTACTPOST

<Force_Contact> - Custom processing of contact results

COUSUB/COUXX/COUXX2

<Constraint_Coupler>

CURSUB

<Reference_ParamCurve>

DIFSUB

<Control_Diff>

DMPSUB

<Body_Flexible>

FIESUB

<Force_Field>

GCOSUB

<Constraint_General>

GFOSUB

<Force_Vector_OneBody|TwoBody> - when type is ForceAndTorque

GRASUB

<Post_Graphic>

GSESUB/GSEXX/GSEXU/GSEYU/GSEYX

<Control_StateEqn>

MARKER_READ

<Reference_Marker>

MATRIX_READ

<Reference_Matrix>

MESSAGE_SUB

<Messaging>

MFOSUB

<Force_FlexModal>

MOTSUB

<Motion_Joint|Marker>

NFOSUB

<Force_MultiPoint>

PFOSUB

<Force_Penalty>

PINSUB

<Control_PlantOutput>

POST_SUB

<Post_UserAPI>

POUTSUB

<Control_PlantOutput>

PTDSFSUB

<Force_PTdSF>

RELSUB

<Load_Model>

REQSUB

<Post_Request>

SAVSUB

<Save>

SENSUB

<Sensor_Event>

SEVSUB

<Sensor_Evaluate>

SFOSUB

<Force_Scalar_TwoBody>

SPLINE_READ

<Reference_Spline>

STRING_READ

<Reference_String>

SURSUB

<Reference_ParamSurface>

TUNSUB

<Param_Simulation>

UCOSUB

<Constraint_UserConstr>

VARSUB

<Reference_Variable>

VFOSUB

<Force_Vector_OneBody|TwoBody> - when type is ForceOnly

VTOSUB

<Force_Vector_OneBody|TwoBody> - when type is TorqueOnly

YFOSUB/YFOXU/YFOXX/YFOYU/YFOYX

<Force_StateEqn>

To help you create a user subroutine, included in the installation is a series of simple routine templates (one for each supported routine) in FORTRAN, C/C++, Python and MATLAB programming/scripting languages. These templates are located in the following installation directories:

<install-path>\hwsolvers\motionsolve\usersub\f_src

<install-path>\hwsolvers\motionsolve\usersub\c_src

<install-path>\hwsolvers\motionsolve\usersub\mex

<install-path>\hwsolvers\motionsolve\usersub\py_src

Also included in the installation directory is a Microsoft Visual Studio Project file that can be optionally used to create your user library (DLL, Dynamic-Link Library).

The C/C++ simple routine templates included in the installation contain the required include statements:

msolvsub_c_include.h for C/C++ code.

This external file is used to resolve the symbols of the various utility functions that can be invoked.  They contain the function prototypes of utility functions like SYSFNC, AKISPL, and all other utility functions that can be used to access system states (displacement, velocity, acceleration, forces, and so on) and MotionSolve states (current simulation time, solver mode, and so on).

You can simplify the process of creating the DLL by using Microsoft Visual Studio with the supplied project file which contains all compiler and linker options, the name of the generated DLL, and the pointers to all source files used for generating the DLL. Below is an example of how to do this with the FORTRAN or C/C++ projects.

hmtoggle_plus1greyBuilding Subroutines in Windows
1.Double-click ms_fsubdll.vfproj in <install-path>\hwsolvers\motionsolve\usersub\f_project.

Note: Based on your installation of Microsoft Visual Studio, the project may be converted to a compatible version automatically.

This contains a list of all FORTRAN subroutines that can be called by MotionSolve.  You may remove any from the project that are not needed.  To remove subroutines, simply right-click on one or more subroutines and click Remove.

solution_explorer_remove

2.Edit the FORTRAN subroutine(s).
3.From the Build menu, select Build.

Your subroutine(s) will be compiled and built as ms_fsubdll.dll and placed in the folder
<install-path>\hwsolvers\motionsolve\usersub\f_project\x64\Release

or

<install-path>\hwsolvers\motionsolve\usersub\f_project\x64\Debug

depending on the build settings.

1.Double-click ms_csubdll.vcproj in <install-path>\hwsolvers\motionsolve\usersub\c_project.

Note: Based on your installation of Microsoft Visual Studio, the project may be converted to a compatible version automatically.

This contains a list of all C/C++ subroutines that can be called by MotionSolve.  You may remove any from the project that are not needed.  To remove subroutines, simply right-click on one or more subroutines and click Remove.

visual_c_remove

2.Edit the C/C++ subroutine(s).
3.From the Build menu, select Build.

Your subroutine(s) will be compiled and built as
ms_csubdll.dll and placed in the folder <install-path>\hwsolvers\motionsolve\usersub\c_project\x64\Release\

or

<install-path>\hwsolvers\motionsolve\usersub\c_project\x64\Debug\

depending on the build settings.

hmtoggle_plus1greyBuilding Subroutines in Linux
1.User subroutines can be built in Linux using the MakeFile that is provided in the installation at <install-path>\hwsolvers\motionsolve\usersub\Makefile. Navigate to the above path in a shell window.  Locate the file "Makefile".
2.Make changes to the FOTRAN or C/C++ source code in <install-path>\hwsolvers\motionsolve\usersub\f_src or
<install-path>\hwsolvers\motionsolve\usersub\c_src.
3.To compile and link a C/C++ source code shared object, enter "make csub=1".  To compile and link a FORTRAN source code shared object, enter "make fsub=1".  This command creates the shared object in a folder titled "exec\Linux_g64\usercsub.so" or "exec\Linux_g64\userfsub.so".
4.The table below lists some other options that can be used with the make file:

Command

Description

make help

Prints out help text for different options available with the make file.

make csub=1

Compile and link all C/C++ source files located in
<install-path>\hwsolvers\motionsolve\usersub\c_src

make fsub=1

Compile and link all FORTRAN source files located in
<install-path>\hwsolvers\motionsolve\usersub\f_src

make clean

Clean object files and shared libraries only for the current platform.

make realclean

Clean all object files and shared libraries for all platforms.

When editing the FORTRAN or C/C++ subroutine(s), you have to observe certain guidelines regarding assigning arguments, variable declarations, and calls to utility functions.

User written subroutines have input and output arguments.  Typically, the output arguments are the result of the computation performed in your routine, while input arguments provide a communication between the multi-body model (and its solver representation, the MotionSolve XML file) and the routine itself.

You can use parameters as input arguments to make subroutines more general.  In other words, do not use hard coded entity IDs, but instead use them as input parameters to your routine.

To make sure that your subroutine(s) are effectively interfaced with MotionSolve, you need to accurately declare the input and output variables according to the guidelines provided in the subroutine templates.  In other words, you should use the supplied routine templates where variables are already declared directly in the subroutine declaration (C/C++):

void STDCALL REQSUB(int *id, double *time, double *par, int *npar, int *iflag, double *results)

Or, declared shortly after the subroutine declaration (FORTRAN):

SUBROUTINE REQSUB (ID, TIME, PAR, NPAR, IFLAG, RESULTS)

DOUBLE PRECISION STATES(6)

INTEGER ITYPE, IPAR(10), NSTATES

LOGICAL ERRFLG

In addition to subroutine templates, MotionSolve also offers utility subroutines if you need to call them from your routines.  These utility subroutines provide system states like displacement, velocity, acceleration, and force on various entities of your mechanical multi-body system, allowing your routine(s) to accurately define and compute outputs based on system states.

For information about the available utility functions and how to call them from your subroutine(s), please refer to Utility Subroutines in the XML Format Reference Guide.

hmtoggle_plus1greyUsing a Dynamically Linked Library (DLL) or Shared Object (SO)

MotionSolve supports two separate levels of user DLLs/SOs and the algorithm attempts to resolve the symbols, starting from the most specific library.  It is possible to specify an Element Level DLL/SO (most specific) and a Machine Level DLL/SO.  They can be defined as follows:

1.Element level – Specify the name of the DLL/SO in the element definition. For example:

<Constraint_Coupler

    id                  = "1"

    label               = "TwoJoint"

    joint1_id           = "30603030"

    joint2_id           = "30602031"

    freedom_1           = "T"

    freedom_2           = "T"

    usrsub_param_string = "USER(-8.5)"

    usrsub_dll_name     = "C:/work/testsub.dll"

   usrsub_fnc_name     = “coupler_function” >

</Constraint_Coupler>

The usrsub_dll_name argument defines C:/work/testsub.dll as the element level DLL/SO for this coupler element.  Any element can be defined pointing to a different DLL/SO.

2.Machine-level DLL/SO

You can create an environment variable called MS_USERSUBDLL and set it to the DLL/SO file.  This environment variable is not defined automatically when MotionSolve is installed.  However, FORTRAN and C/C++ DLLs/SOs are provided in the installation in folder <install-path>\hwsolvers\usersub\subdll\<platform>. This is so you can run some of the test models that use user subroutine DLLs.

The selection of what DLL/SO is loaded and used is based on the "most specific" rule: number one overrides number two.

hmtoggle_plus1greySetting Up User-Defined Modeling Elements

In addition to writing your solver subroutine, you also have to modify the corresponding modeling element in your multi-body model so that it receives output value(s) from the user subroutine.

This can be done in two ways:

1.By editing the MotionSolve XML file.
2.By modifying the entity in the MotionView interface and producing a new XML file.

Regardless of the method you select, you will end up with an XML file where one or more entities are now user defined.

For example, the following motion entity:

 <Motion_Joint

    id                  = "101001"

    type                = "EXPRESSION"

    val_type            = "D"

    expr                = "-.2*TIME"

    joint_id            = "101002"

    joint_type          = "R"

    motion_type         = "R"

    ic_disp             = "0."

    ic_vel              = "0.">

 </Motion_Joint>

can be modified in the following manner to indicate that the motion value is computed in a user subroutine, as opposed to an explicit function expression.

 <Motion_Joint

    id                  = "101001"

    type                = "USERSUB"

    val_type            = "D"

    usrsub_param_string = "USER(5,2)"

    usrsub_dll_name     = “C:/work/testsub.dll"

    joint_id            = "101002"

    joint_type          = "R"

    motion_type         = "R"

    ic_disp             = "0."

    ic_vel              = "0.">

 </Motion_Joint>

hmtoggle_plus1greyRunning User Solver Libraries

At runtime, MotionSolve loads the appropriate user DLL/SO, according to the rules described above (most specific among "element" and "machine level" DLL/SO).

For verification purposes, MotionSolve outputs the DLL/SO that loaded at runtime immediately after the initialization of the model.

User Subroutine DLL [C:/work/testsub.dll] Loaded

The above message is displayed in the analysis log file.

After the analysis is completed, a similar message informs the user that MotionSolve has unloaded the user subroutine DLL/SO.

Unloading User Subroutine DLL [C:/work/testsub.dll]

See Also:

Compiler and System Requirements

Solver-Neutral Routines