AmesimKnowledge

Hybrid Co-simulation with the usercosim interface > Use of the usercosim interface

How do you create the master model?

Write your own master

The three main tasks are as follows:

  • Load the dynamic library generated by Simcenter Amesim. To access the dll generated by Simcenter Amesim, you have to load it. The example provided is based on functions defined in file import_dll_utils.c which is provided in the Simcenter Amesim demo.

  • Initialize the slave solver and set options with initmodel() Once you have gained access to the model DLL, you have to initialize the model, calling AMEInitModel(). Refer to API Documentation for more information.

  • Set slave inputs, make it compute outputs at a given date with doAStep() The core of the example provided consists of a loop of iterations. An iteration is made of three steps:

    The inputs of Simcenter Amesim models are set.
    
    
    Simcenter Amesim models then compute their outputs at a given date.
    
    
    These outputs are finally processed by the master to compute the new inputs of the model.
    

Code example

The following c code is available as a Simcenter Amesim demo as well as the makefile required to compile it.

Copy

/** This is a simple example of a code that loads a Simcenter Amesim DLL (shared library)
 * created for Co-simulation and use this DLL for doing some simple simulation
 * COPYRIGHT 2018 Siemens Industry Software NV
*/

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "import_dll_utils.h"

/* A simple example of a program that loads a DLL 
 * (name provided by argument list) and calls the functions
 * in this DLL to do a simple simulation */
int main(int argc, char *argv[])
{
  double samptime = 0.1;      /* Sample interval */
  double printinter = samptime/5.0; /* How often will Simcenter Amesim model write the result file */
  double tol = 1e-5;        /* Solver tolerance */

  /* The following parameter values should be kept at their default values. */
  const int errtype = 0;      /* Error check type : mixed */
  const int writelevel = 2;     /* Don't output the time for every step taken */
  const int disconpr = 0;      /* No extra discontinuity printouts */
  const int runstats = 0;      /* No Runstats after the simulation */
  const int runtype = 8;      /* Dynamic run */
  const int thesolvertype = 0;   /* The default solver config */

  double time = 0;
  int numinputs_to_model=-1;
  int numoutputs_from_model=-1;
  double *inputs=NULL;
  double *outputs=NULL;

  int i;
  int model_initialised=0;
  static AME_DLL amedll;

  char tmpfullname[1024];
  char *dirsep;

  /* ********************************************* */
  if(argc <= 1)
  {
   fprintf(stderr,"Need the name of the DLL used as slave Simcenter Amesim model\n");
   fprintf(stderr,"EXIT\n");
   exit(1);
  }

  /* The DLL (or shared library) is loaded. If it fails to load we exit. */
  if( !loadamesimdll(argv[1], &amedll) )
  {
   fprintf(stderr,"failed to load DLL %s\n",argv[1]);
   exit(1);
  }
  else
  {
   fprintf(stdout,"Simcenter Amesim model '%s' loaded OK\n", argv[1]);
  }

  /* set model directory */
  strcpy(tmpfullname, argv[1]);
  dirsep = strrchr(tmpfullname,'/');
  if(dirsep)
  {
   dirsep++;
   *dirsep = '\0';
   fprintf(stdout, "MASTER> Setting model directory to %s\n", tmpfullname);
   amedll.AMEWorkingDir(tmpfullname);
  }

  {
   /* Check that the Simcenter Amesim model have the same number of inputs
    * and outputs as we expect. */
   int ame_says_numinputs;
   int ame_says_numoutputs;
   int ame_says_numstates;
   int ame_says_numimplicit;
   amedll.AMEInitSizes(&ame_says_numinputs, &ame_says_numoutputs, &ame_says_numstates, &ame_says_numimplicit);
   fprintf(stdout, "MASTER> Simcenter Amesim model have \n %d inputs \n %d outputs \n %d state variables \n %d implicit variables\n", ame_says_numinputs, ame_says_numoutputs, ame_says_numstates, ame_says_numimplicit);

   /* In this case we only accept systems with two inputs and three outputs. */
   if (ame_says_numinputs != 2)
   {
     fprintf(stderr,"Expected model with 2 inputs. Got %d.\n", ame_says_numinputs);
     exit(1);
   }
   if (ame_says_numoutputs != 3)
   {
     fprintf(stderr,"Expected model with 3 outputs. Got %d.\n", ame_says_numoutputs);
     exit(1);
   }
   numinputs_to_model = ame_says_numinputs;
   numoutputs_from_model = ame_says_numoutputs;
  }

  /* Create the input/output arrays */
  inputs = calloc(1,numinputs_to_model*sizeof(double));
  outputs = calloc(1,numoutputs_from_model*sizeof(double));

  /* Do a simple run up till 10 seconds */
  while (time <= 10.0)
  {
   /* SET THE INPUTS TO THE AMESIM MODEL HERE */
   for (i=0 ; i<numinputs_to_model ; i++)
   {
     if(i == 0)
     {
      inputs[i] = 1450.0; /* Pumpspeed */
     }
     else if(i == 1)
     {
      inputs[i] = 40.0*sin(time); /* Valve input signal */
     }
     else
     {
      inputs[i] = (i+1)*sin(time); /* Any other signal */ 
     }
   }

   if(!model_initialised)
   {
     /* InitModel loads the Simcenter Amesim model data, set up the model
      (with an init call) and checks that number of
      inputs/outputs agree. We do the init in the loop since it
      will also do a call to the model and it needs to have the
      inputs set properly. */
     fprintf(stdout,"MASTER> Starting simulation with a call to InitModel.\n\n");
     amedll.AMEInitModel(time, printinter, samptime, tol, errtype, writelevel, 
             disconpr, runstats, runtype, thesolvertype, 
             numinputs_to_model, numoutputs_from_model, inputs, outputs);
     model_initialised = 1;
   }

   /* Here we do a call to the Simcenter Amesim model and asks it to
     calculate its outputs up to time="time" using the inputs sent. */
   amedll.AMEdoAStep2(time, numinputs_to_model, numoutputs_from_model, inputs, outputs);

   /* The vector "outputs" now contains the outputs from 
    * the Simcenter Amesim model at time "time". 
    * In this simple example we only print the values. */
   fprintf(stdout,"time = %.3f\t",time);
   for (i=0; i<numoutputs_from_model; i++)
   {
     fprintf(stdout,"out%d = %.3f\t", i, outputs[i]);
   }
   fprintf(stdout,"\n");

   /* Update the time for the next step */
   time += samptime;
  }

  /* Allow for a "clean" end of the Simceter Amesim model with Terminate. */
  amedll.AMETerminate();

  /* Tell the operating system we no longer use the DLL
   (freeamesimdll). This will normally unload the DLL. In this
   example it does not matter, but if one wants to perform several
   simulations without leaving this program it is important to do
   this since unloading the DLL will ensure for it to be properly
   (re-)initialized when loading it. After the call to
   freeamesimdll it is not possible to use the model until a
   loadamesimdll has been done.*/
  unloadamesimdll(&amedll);

 

  /* Return 0 - to indicate success */
  return 0;
}

Use libcosim DLL Import submodel to import a model built with the usercosim interface

Figure 31: "libcosim" DLL import submodel

The shared library made with the "usercosim" interface can be loaded by a Simcenter Amesim model with a submodel from the library "libcosim". Importing a model DLL into Simcenter Amesim is a very easy task. Just select the "import" submodel from libcosim. You will be asked to set the number of input/output variables.

Figure 32: Setting the number of input/output variables

The "import" submodel of libcosim performs Hybrid Co-simulation. As described in Simcenter Amesim co-simulation types and features, this means that the imported model will be launched when the master model starts. This "import" submodel makes it possible to import a Simcenter Amesim model into another Simcenter Amesim model (called the master). The master model will pilot the imported model. It will decide when data exchange will take place.

In our example, since the slave has 2 inputs and 3 outputs, we create a block with 2 inputs and 3 outputs:

Figure 33: Creating a block

Be careful when working with the input/output of the "import" submodel. Inputs are counted from top to bottom, outputs from bottom to top.

The slave variable order can be displayed through the Modeling > Interface Block > Display Interface status menu.

  • Parameter mode

    Set up the master in Parameter mode: Figure 34: Setting up the master

    Error type: select the error control method from mixed, relative or absolute.
    
    
    Write level: select the write level method from time or no output.
    
    
    Discontinuity printouts: this option activates the discontinuity printout.
    
    
    Runstats: this option displays the runstats at the end of a simulation.
    
    
    Sample time: this is the time interval between two consecutive data exchanges between slave and master.
    
    
    Slave print interval: this is the interval between points saved in the Simcenter Amesim result file of the slave model.
    
    
    Slave tolerance: this is the tolerance level for the Simcenter Amesim solver (see the Simcenter Amesim manual for details).
    
    
    Slave dynamic library: this is the name of the dynamic library that corresponds to the slave model. The slave model must be open in Simcenter Amesim.
    
    
    Output variable: initial value of outputs.
    
  • Simulation mode

    Both slave and master must be open in Simcenter Amesim in order to simulate the whole system. You may access the variables of both the imported and the slave model. In Simulation mode, every variable of the "imported" model can be observed as usual, its inputs come from the master and its outputs go to the master. Figure 35: Hybrid Co-simulation master and slave

Source: https://docs.sw.siemens.com/en-US/doc/254352342/PL20250521841123434.amesim_collection.lib-cosim/xid1852771 · retrieved 2026-07-17