Building with HOOPS Solve

After the package is unpacked and the license is activated, this page describes how to compile and link a program against HOOPS Solve.

Pick the tab that matches your situation. Building Your Own Application is the recommended route for any new project; the legacy tab is kept for projects that were link against the old obfuscated source distribution.

The package is a binary distribution. You only compile your code, and then link it to the pre-compiled libraries.

Package Contents

The HoopsSAM library is designed to link against the third-party packages bundled with the distribution. These packages are tested with HOOPS SAM to ensure compatibility. The distribution includes libraries such as Abaqus, Ansys DPF, Blosc, CGNS, GKLib, HDF5, Intel MKL, Intel OpenMP, and METIS. The exact versions are listed in the corresponding third-party folders and are documented in the release notes for the package. Each third-party software is redistributed under its respective license terms. Tech Soft 3D is not the author of those packages, and redistribution is subject to the license terms included with the distribution. See the appropriate release note page to find a list of the provided packages with their versions. This information is only available starting HOOPS SAM 2.5.0.

The extracted package root is named according to the platform it was generarted on, for example HOOPS_Solve_Access_Mesh_<version>_Windows_x86-64_v142\ on Windows and HOOPS_Solve_Access_Mesh_<version>_Linux_x86-64_glibc235/ on Linux. The HOOPS SAM releases use the Semantic Versioning scheme. The include file base.h defines two macros that can be used to retrieve version information:

  • SYS_VERSION defines a hexadecimal value built up from the major, minor, and patch version numbers. This value is guaranteed to be monotonically increasing for each new release.
  • SYS_VERSIONSTR defines a string built up from the major, minor, and patch version numbers. It may also contain pre-release or other supplemental information if available.
HOOPS_Solve_Access_Mesh_<version>_Windows_x86-64_v142\
│
├── include\                                <- the HEADER files + source files for bindings of FORTRAN, C++, and C#
│   ├── sam\                                <- C API:   base, vis, vdm, vfe, vfs, vfx, msh
│   └── samcpp\                             <- C++ API: core, access
│
├── lib\                                    <- IMPORT libraries, used by the LINKER
│   ├── HoopsSAM_core.lib                   <- Foundation.
│   ├── HoopsSAM_access.lib                 <- Access library: reading and writing CAE files.
│   ├── HoopsSAM_mesh.lib                   <- Mesh library: meshing functionality.
│   ├── HoopsSAM_solve.lib                  <- Solve library: solving functionality.
│   ├── HoopsSAM_linearAlgebraCore.lib      <- linear algebra core functionality used by solve and mesh (internally)
│   ├── HoopsSAM_static_MD.lib              <- static variant, /MD runtime
│   ├── HoopsSAM_static_MT.lib              <- static variant, /MT runtime
│   ├── DataProviderHostLib.lib             <- data provider host library
│   ├── DataProviderPluginHeaders.lib       <- data provider plugin headers library
│   └── zlibstatic.lib                      <- static variant of zlib

│
├── bin\                                    <- the DLLs, loaded by the PROGRAM at run time
│   ├── HoopsSAM_core.dll
│   ├── HoopsSAM_access.dll
│   ├── HoopsSAM_mesh.dll
│   ├── HoopsSAM_solve.dll
│   ├── HoopsSAM_linearAlgebraCore.dll
│   ├── HoopsSAMcs.dll                      <- C# wrapper DLL for HoopsSAM
│   ├── exchangePlugin\                     <- plugin for exchange library
│   ├── openfoamPlugin\                     <- plugin for OpenFOAM reader
│   ├── vtkPlugin\                          <- plugin for VTK readers
│   └── dynamicLoadingLibraries\            <- wrapper libraries for Abaqus, AutoDyn and SAMCEF readers
│
├── thirdparty\                             <- helper libraries/ vendor SDKS
│   ├── intelopenmp-<version>-win64\
│   ├── intelmkl.win-x64\
│   ├── hdf5-<version>-win64\
│   ├── abaqus-odb_api-<year>-win64\
│   └── ...
│
├── Examples\                               <- ready-made sample programs (sam, legacy)
├── cmake\                                  <- helper modules used by the examples
├── DataProviderFramework\                  <- plugin SDKs framework
├── dynamicLoadingWrapperSource\            <- source of the reader wrappers
├── migration_scripts\                      <- scripts to help with migrating between major versions
├── VersionInfo.json
└── README.txt

Important

The files in lib are primarily import libraries used during linking, while the DLLs in bin are loaded at runtime. The only exceptions are the two static libraries.

The next step is to focus on building the program and connecting it to the required components:

Folder Job
include
#include "sam/base/base.h"
#include "sam/vis/vis.h"
#include "sam/vfx/vfx.h"
#include "sam/vfe/vfe.h" # To use the built-in element api
#include "sam/vfs/vfs.h" # To use the built-in linear algebra/matrix api
lib
HoopsSAM_access.lib  # if access functionality needed
HoopsSAM_solve.lib
HoopsSAM_core.lib
thirdparty Dependency libraries (Intel OpenMP, Intel MKL, HDF5, METIS, GKLib, Zlib and Vendor SDKs are optional)

Step 1 - Create Your Project Folder

Create an empty folder named SolveExample for the project. It does not need to live next to the distribution. The project consists of two files:

SolveExample/
├── CMakeLists.txt      <- the recipe (Step 3)
└── main.cpp            <- your program (Step 2)

Step 2 - Write A Very Small Program

Create main.cpp. The program below builds a single hexahedral element, fixes its bottom face, puts a pressure on its top face and runs a linear static analysis.

#include "sam/base/base.h"
#include "sam/base/license.h"
#include "sam/hoops_license.h"
#include "sam/vis/vis.h"
#include "sam/vfx/vfx.h"

#include <cstdio>

/* One unit cube: fixed at the bottom, pressed on the top. */
static Vdouble coords[8][3] = {
    {0., 0., 0.}, {1., 0., 0.}, {1., 1., 0.}, {0., 1., 0.},
    {0., 0., 1.}, {1., 0., 1.}, {1., 1., 1.}, {0., 1., 1.},
};
static Vint conn[8] = {1, 2, 3, 4, 5, 6, 7, 8};

int
main(void)
{
    /* Always validate the license before calling anything else. */
    vsy_LicenseValidate(HOOPS_LICENSE);

    vis_Model* model = vis_ModelBegin();

    /* --- the mesh --- */
    vis_Connect* connect = vis_ConnectBegin();
    vis_ConnectPre(connect, SYS_DOUBLE);
    vis_ConnectDef(connect, 8, 1);
    for (Vint i = 0; i < 8; i++) {
        vis_ConnectSetCoordsdv(connect, i + 1, coords[i]);
    }
    vis_ConnectSetTopology(connect, 1, VIS_SHAPEHEX, 2, 0, 0);
    vis_ConnectSetElemNode(connect, 1, conn);
    vis_ConnectSetElemAssoc(connect, VIS_FEATYPE, 1, VIS_ELEM_SOLID);
    vis_ConnectSetElemAssoc(connect, VIS_PROPID, 1, 1);
    vis_ModelSetObject(model, VIS_CONNECT, connect);

    vis_GridFun* gf = vis_GridFunBegin();
    vis_ConnectGridFun(connect, gf);

    /* --- material and element property --- */
    vsy_HashTable* mphash = vsy_HashTableBegin();
    vis_MProp* mprop = vis_MPropBegin();
    vis_MPropDef(mprop, SYS_MAT_ISOTROPIC);
    vis_MPropSetValued(mprop, MPROP_E, 1.0e+7);
    vis_MPropSetValued(mprop, MPROP_NU, 0.3);
    vsy_HashTableInsert(mphash, 1, mprop);
    vis_ModelSetHashTable(model, VIS_MPROP, mphash);

    vsy_HashTable* ephash = vsy_HashTableBegin();
    vis_EProp* eprop = vis_EPropBegin();
    vis_EPropDef(eprop, VIS_ELEM_SOLID);
    vis_EPropSetValuei(eprop, EPROP_MID, 1);
    vsy_HashTableInsert(ephash, 1, eprop);
    vis_ModelSetHashTable(model, VIS_EPROP, ephash);

    /* --- restraint: the bottom face is fully fixed --- */
    vsy_HashTable* rchash = vsy_HashTableBegin();
    vis_RCase* rcase = vis_RCaseBegin();
    for (Vint n = 1; n <= 4; n++) {
        vis_RCaseSetSPC(rcase, n, SYS_DOF_TX, RCASE_FIXED, NULL, 0);
        vis_RCaseSetSPC(rcase, n, SYS_DOF_TY, RCASE_FIXED, NULL, 0);
        vis_RCaseSetSPC(rcase, n, SYS_DOF_TZ, RCASE_FIXED, NULL, 0);
    }
    vsy_HashTableInsert(rchash, 1, rcase);
    vis_ModelSetHashTable(model, VIS_RCASE, rchash);

    /* --- load: pressure on the top face --- */
    vsy_HashTable* lchash = vsy_HashTableBegin();
    vis_LCase* lcase = vis_LCaseBegin();
    vis_LCaseSetObject(lcase, VIS_GRIDFUN, gf);
    Vdouble pres[4] = {50., 50., 50., 50.};
    vis_LCaseSetDistdv(lcase, SYS_FACE, 1, 2, LCASE_PRES, pres);
    vsy_HashTableInsert(lchash, 1, lcase);
    vis_ModelSetHashTable(model, VIS_LCASE, lchash);

    /* --- the solution to perform --- */
    vsy_List* splist = vsy_ListBegin();
    vis_SProp* sprop = vis_SPropBegin();
    vis_SPropDef(sprop, SYS_SOL_STATIC);
    vis_SPropSetValuei(sprop, SPROP_ANALYSIS, SYS_ANALYSIS_STRUCTURAL);
    vis_SPropSetValuei(sprop, SPROP_CASEID, 1);
    vis_SPropSetValuei(sprop, SPROP_RCASE, 1);
    vis_SPropSetValued(sprop, SPROP_RCASE_FACTOR, 1.);
    vis_SPropSetValuei(sprop, SPROP_LCASE_NUM, 1);
    vis_SPropSetValuei(sprop, SPROP_LCASE, 1);
    vis_SPropSetValued(sprop, SPROP_LCASE_FACTOR, 1.);
    vsy_ListInsert(splist, 1, sprop);
    vis_ModelSetList(model, VIS_SPROP, splist);

    /* --- solve --- */
    vfx_ProSolve* prosolve = vfx_ProSolveBegin();
    vfx_ProSolveSetObject(prosolve, VIS_MODEL, model);
    vfx_ProSolveExec(prosolve);

    Vint ierr = vfx_ProSolveError(prosolve);
    std::printf("Solver finished, error = %d\n", (int)ierr);

    vfx_ProSolveEnd(prosolve);
    vis_ModelDelete(model);

    return ierr ? 1 : 0;
}

Warning

The HOOPS_LICENSE must be validated before any calls to the HOOPS Solve API functions. Please refer to Installing HOOPS Solve for more details.

Step 3 - Write The CMakeLists.txt

Create CMakeLists.txt next to main.cpp (Step 2). Pick the flavour you want: link against the shared libraries (the usual choice), or link everything into one self-contained executable. The library names differ per platform, so there is one tab per combination.

cmake_minimum_required(VERSION 3.21)

project(SolveExample LANGUAGES CXX)

# --- 1. Path to unpacked distribution------------------------------
set(SAM_ROOT "" CACHE PATH "Root of the HOOPS Solve, Access & Mesh distribution")

set(SAM_INCLUDE_DIR "${SAM_ROOT}/include")
set(SAM_LIB_DIR     "${SAM_ROOT}/lib")

# --- 2. executable --------------------------------------------------------
add_executable(solve_example main.cpp)
target_compile_features(solve_example PRIVATE cxx_std_17)

# --- 3. Headers -------------------------------------------------------------
target_include_directories(solve_example PRIVATE "${SAM_INCLUDE_DIR}")

# --- 4. Libraries -----------------------------------------------------------
target_link_libraries(solve_example PRIVATE
    "${SAM_LIB_DIR}/HoopsSAM_access.lib"  # if access functionality needed
    "${SAM_LIB_DIR}/HoopsSAM_solve.lib"
    "${SAM_LIB_DIR}/HoopsSAM_core.lib")

install(TARGETS solve_example RUNTIME DESTINATION bin)

Note

The transitive dependencies of the main libraries (HoopsSAM_solve and HoopsSAM_core) are not automatically found at runtime. They are available in the thirdparty folders, so you need to add them to PATH - see Dependencies.

Step 4 - Configure And Build

The Visual Studio generator is multi-configuration: you do not choose the build type when you configure, you choose it when you build.

cmake -S . -B SolveExample ^
      -G "Visual Studio 16 2019" -A x64 ^
      -DSAM_ROOT=C:\path\to\HOOPS_Solve_Access_Mesh_<version>_Windows_x86-64_v142

cmake --build SolveExample --config Release

Step 5 - Run It

Compilation and linking alone are not sufficient. At runtime, the program must locate the shared libraries, and the build-time search paths are not retained. HOOPS Solve relies on Intel MKL and Intel OpenMP for linear algebra, so both dependency folders must remain accessible. The required locations are provided through environment variables: PATH on Windows and LD_LIBRARY_PATH on Linux.

Note

This step is still needed even if linked statically. Only the HoopsSAM_* libraries (plus METIS, GKlib and zlib) end up inside the executable; Intel MKL, Intel OpenMP and HDF5 remain shared libraries, so the thirdparty folders below have to be reachable either way.

set SAM_ROOT=C:\path\to\HOOPS_Solve_Access_Mesh_<version>_Windows_x86-64_v142

set PATH=%SAM_ROOT%\bin;%PATH%
set PATH=%SAM_ROOT%\thirdparty\intelopenmp-2023.1.0-win64\bin;%PATH%
set PATH=%SAM_ROOT%\thirdparty\intelmkl.win-x64\bin;%PATH%

SolveExample\Release\solve_example.exe

Congratulations, your first program is built with HOOPS Solve.

Dependencies

A HOOPS Solve requires some shared libraries to be loaded at run time. Environment variables define the search paths used to locate these components.

For shared linking, the program must also locate HoopsSAM_linearAlgebraCore, which is a transitive dependency of HoopsSAM_Solve. This library is provided in the same folder as HoopsSAM_Solve. In addition, HOOPS Solve depends on two libraries from the thirdparty folder: Intel OpenMP and Intel MKL, which provide the linear algebra layer used by the solver.

Add the HOOPS SAM bin folder and the two third party bin folders to PATH:

set PATH=%SAM_ROOT%\bin;%PATH%                            :: the folder containing HoopsSAM_linearAlgebraCore.dll
set PATH=%SAM_ROOT%\thirdparty\intelopenmp-2023.1.0-win64\bin;%PATH%
set PATH=%SAM_ROOT%\thirdparty\intelmkl.win-x64\bin;%PATH%
set PATH=%SAM_ROOT%\thirdparty\hdf5-1.14.5-win64\bin;%PATH% :: if access functionality is used

For Static linking, in addition to the above libraries, HOOPS Solve needs Metis, GKLib, Zlib and HDF5 libraries from the thirdparty folder. (Zlib and HDF5 are required only if your program performs file I/O with HOOPS Access.)

When HOOPS Access Is Also Used

The preceding information applies to HOOPS Solve used independently, where the model is created, solved, and retained in memory. If the application also reads or writes CAE files, it uses HOOPS Access (HoopsSAM_Access), which introduces additional run-time requirements. These requirements are documented on the Dependencies page of the HOOPS Access documentation; use that page as the reference whenever a file format is involved.

Important

Separate license is required for Access functionality when used together with Solver.

Need Help ?

The project is now ready for use with HOOPS Solve. For additional support, refer to the support resources or the forum.