Tutorial for integrating the CoSimIO using C++ interface
Table of Contents
- What you need
 - Building the CoSimIO
 - Hello CosimIO
 - Connecting and Disconnecting
 - Data Exchange
 - Mesh Exchange
 - Next steps
 
This tutorial helps you to integrate the CoSimIO into a solver/software-tool using the C++ interface.
What you need
- Downloading the CosimIO from the repository:
    
git clone https://github.com/KratosMultiphysics/CoSimIO.git - 
    
A C++11 compatible compiler. This includes most of the major CPP compilers in Windows, Linux, and Mac. You may find a detailed list of C++11 compatible compilers here
 - CMake
 
Building the CoSimIO
The C++ version of the CoSimIO is implemented in co_sim_io.hpp. It can be used after compiling CoSimIO into a shared library and linking against it. Check here for the available build options.
Several options for using/integrating the CoSimIO exist:
- Using CMake:
    
- Integrating CoSimIO as a subproject into the host with CMake:
  Here the CoSimIO is directly integrated into the host code and added with 
add_subdirectory(CoSimIO). CMake then takes care of compiling and installing the CoSimIO. Kratos uses this way to integrate the CoSimIO, check theCMakeLists.txtof the CoSimulationApplication for details - 
        
Compiling CoSimIO outside the host project: One can use build_cpp.sh or build_cpp.bat for compiling it.
- For GNU/Linux or MacOS:
            
$ bash scripts/build_cpp.sh - 
            
For Windows OS:
$ scripts/build_cpp.bat 
 - For GNU/Linux or MacOS:
            
 
After compiling, the headers need to be included (e.g. with
include_directories) and theco_sim_ioshared library needs to be linked (e.g withtarget_link_libraries).include_directories(path/to/CoSimIO/co_sim_io) target_link_libraries(my_executable co_sim_io) - Integrating CoSimIO as a subproject into the host with CMake:
  Here the CoSimIO is directly integrated into the host code and added with 
 - 
    
Compiling CoSimIO outside the host and manually integrating it: One can use build_cpp.sh or build_cpp.bat for compiling it.
- For GNU/Linux or MacOS:
        
$ bash scripts/build_cpp.sh - 
        
For Windows OS:
$ scripts/build_cpp.bat 
Is important that the compiler can find the header files of the CoSimIO. For this, one can add the folder
co_sim_ioto the include path. Example:export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/path/to/CoSimIO/co_sim_ioFurthermore it is required to link against the
co_sim_ioshared library. - For GNU/Linux or MacOS:
        
 
The shared library co_sim_io will be installed in the bin/ folder. After building CoSimIO, is necessary to add the path where the shared library co_sim_io was installed to (bin/) to the library path of the system such that the it can be linked against. Depending on the operating system this can be e.g. PATH or LD_LIBRARY_PATH. This also needs to be available at runtime, otherwise errors when strating the execution will occur. In linux this can be achieved with the following:
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH$:$HOME/path/to/CoSimIO/bin"
After building and linking it to your project, you may use the interface defined in co_sim_io.hpp:
// CoSimulation includes
#include "co_sim_io.hpp"
int main()
{
    return 0;
}
Hello CosimIO
After integrating the CoSimIO in your code now it’s time to say hello
CoSimIO::Info info = CoSimIO::Hello();
Please note that this method like other methods in CoSimIO returns a CoSimIO::Info object. This object is a versatile container holding important information about the operation that has been done. See here for the documentation. In this case, it contains the version of the CoSimIO library which can be queried:
std::cout << info << std::endl;
The Info class also provides the Get method for retrieving certain values knowing their type:
int major_version = info.Get<int>("major_version");
int minor_version = info.Get<int>("minor_version");
std::string patch_version = info.Get<std::string>("patch_version");
This example can be found in integration_tutorials/cpp/hello.cpp.
Connecting and Disconnecting
The first step to establish a connection to Kratos CoSimulation is to use the Connect method:
// The connect must be called before any CosimIO method
auto info = CoSimIO::Connect(settings);
First of all, you may notice that Connect method takes a CoSimIO::Info as its argument. This container can be used to pass additional information about the solver/software-tool or connection settings to the CoSimIO:
CoSimIO::Info settings;
settings.Set("my_name", "cpp_connect_disconnect_a");    // my name
settings.Set("connect_to", "cpp_connect_disconnect_b"); // to whom I want to connect to
settings.Set("echo_level", 1);
settings.Set("version", "1.25");
It is very important that the settings for my_name and connect_to are set correctly, otherwise the connection cannot be established!
E.g in the above example one code sets my_name as cpp_connect_disconnect_a and connect_to as cpp_connect_disconnect_b. This means that the other code has to use the same settings but reversed: my_name must be cpp_connect_disconnect_b and connect_to must be cpp_connect_disconnect_a.
This method returns a Info object containing information about the connection which can be queried using Get method. For further calls to CoSimIO it is necessary to get the connection_name:
std::string connection_name = info.Get<std::string>("connection_name");
Similar things work for the Disconnect method.
Now putting together everything:
// CoSimulation includes
#include "co_sim_io.hpp"
int main()
{
    CoSimIO::Info settings;
    settings.Set("my_name", "cpp_connect_disconnect_a");    // my name
    settings.Set("connect_to", "cpp_connect_disconnect_b"); // to whom I want to connect to
    settings.Set("echo_level", 1);
    settings.Set("version", "1.25");
    auto info = CoSimIO::Connect(settings);
    std::string connection_name = info.Get<std::string>("connection_name"); // getting name of connection for future calls
    if (info.Get<int>("connection_status") != CoSimIO::ConnectionStatus::Connected)
        return 1;
    // Now you may call any CoSimIO methods like ImportData, ExportData, etc.
    // ...
    CoSimIO::Info disconnect_settings;
    disconnect_settings.Set("connection_name", connection_name);
    info = CoSimIO::Disconnect(disconnect_settings); // disconnect afterwards
    // Here you may use the info but cannot call any CoSimIO method anymore
    if (info.Get<int>("connection_status") != CoSimIO::ConnectionStatus::Disconnected)
        return 1;
    return 0;
}
This example can be found in integration_tutorials/cpp/connect_disconnect_a.cpp and integration_tutorials/cpp/connect_disconnect_b.cpp.
Data Exchange
Make sure to connect (refer Connecting and Disconnecting) before Data Exchange.
One of the important missions of the CoSimIO is to send and recieve data between different solvers/software tools. The ExportData method can be used to send data to the Kratos or directly to another solver/software-tool:
std::vector<double> data_to_send(4, 3.14);
CoSimIO::Info info;
info.Set("identifier", "vector_of_pi");
info.Set("connection_name", connection_name); // connection_name is obtained from calling "Connect"
info = CoSimIO::ExportData(info, data_to_send);
The ImportData should be used on the other side to recieve data:
std::vector<double> receive_data;
CoSimIO::Info info;
info.Set("identifier", "vector_of_pi");
info.Set("connection_name", connection_name); // connection_name is obtained from calling "Connect"
info = CoSimIO::ImportData(info, receive_data);
It is important to mention that ImportData will clear and resize the vector if needed.
This example can be found in integration_tutorials/cpp/export_data.cpp and integration_tutorials/cpp/import_data.cpp.
Mesh Exchange
Make sure to connect (refer Connecting and Disconnecting) before Mesh Exchange.
After seeing how we transfer raw data between solvers/software-tools, it is time to see how we can export and import meshes. For exporting the mesh one may use the ExportMesh method:
CoSimIO::Info info;
info.Set("identifier", "fluid_mesh");
info.Set("connection_name", connection_name); // connection_name is obtained from calling "Connect"
CoSimIO::ModelPart model_part("name_of_model_part_to_export");
export_info = CoSimIO::ExportMesh(info, model_part);
The argument model_part is of type CoSimIO::ModelPart and contains a mesh. Its usage is explained here.
On the other side one can use the ImportMesh() method to get the mesh sent by the export:
info.Clear();
info.Set("identifier", "fluid_mesh");
info.Set("connection_name", connection_name); // connection_name is obtained from calling "Connect"
CoSimIO::ModelPart model_part("name_of_imported_model_part");
import_info = CoSimIO::ImportMesh(info, model_part);
This example can be found in integration_tutorials/cpp/export_mesh.cpp and integration_tutorials/cpp/import_mesh.cpp.
Next steps
In the next tutorial, a connection to Kratos is established and basic data exchange with Kratos is done.