Preparing Your Code for Co-Simulation with Simcenter STAR-CCM+

Your program couples with Simcenter STAR-CCM+ through the Simcenter STAR-CCM+ API server, which is a Simcenter STAR-CCM+ simulation that represents your program. You set up and communicate with the Simcenter STAR-CCM+ API server through the Co-Simulation API library. The Simcenter STAR-CCM+ API server couples with other Simcenter STAR-CCM+ simulations using Simcenter STAR-CCM+ to Simcenter STAR-CCM+ Co-Simulation.

To set up and communicate with the Simcenter STAR-CCM+ API server, prepare your code following the steps below. Each step includes a code example that uses the latest version of the API.

  1. Include one of the Co-Simulation API header files in your program.
    See Header Files. API versions based on the function suite structure are not suitable for coupling with versions of Simcenter STAR-CCM+ prior to v11.04.
  2. For dynamic loading of the Co-Simulation API library, also include the LibraryLoader.h and LibraryLoader.cpp files that are provided with the SpindleValve example program.
    • If your program is written in C++, you can directly use the LibraryLoader.h and LibraryLoader.cpp files in your program.
    • If your program is written in Fortran or C, you can use these files with a C wrapper.
  3. Define pointers to the API structure and the function suites:
    StarccmplusCoSimulationApiStruct const * apiStruct;
    StarccmplusApiSuiteV8 const * apiSuite;
    StarccmplusFactorySuiteV8 const * factorySuite;
    StarccmplusPropertiesSuiteV8 const * propertiesSuite;
  4. Define the messageHandler and fillContainerHandler callback functions that Simcenter STAR-CCM+ uses to call back into your program:
    void messageHandler(StarccmplusMessageType const msgType, char const* message)
    {see SpindleValve program for example message handler};
    
    void fillContainerHandler(int containerIndex, char const* requirement)
    {see SpindleValve program for example fill container handler};
    
    StarccmplusHandlerSuiteV8 handlerSuite ={
      messageHandler,  
      fillContainerHandler};
  5. Load the Co-Simulation API library.
    apiLib.load();
  6. Get a pointer to the API structure defined in StarccmplusCoSimulationApiStruct.h.
    apiLib.getApiStruct(&apiStruct)
  7. Verify that the Co-Simulation API version in use is supported.
    The Simcenter STAR-CCM+ version that is launched is a user choice, that is, your program cannot use the API to load specific versions of Simcenter STAR-CCM+. Typically, your program verifies whether the version of Simcenter STAR-CCM+ that the user launches is compatible with the API version in use, and issues an error when it is not compatible.
    apiStruct->isApiVersionSupported(
      API_VERSION,
      &versionsArray, 
      &versionsArraySize);
      
    The API queries Simcenter STAR-CCM+ for a list of supported API versions, then matches the input API_VERSION against this list:
    • If there is no match, the API call returns 1. In this case, unless your program can handle falling back to a different version of the API, you cannot couple with this version of Simcenter STAR-CCM+.
    • If there is a match, the API call returns 0. In this case, your program can couple with this version of Simcenter STAR-CCM+.
    Although you cannot use the API to load specific versions of Simcenter STAR-CCM+, you can take into account the Simcenter STAR-CCM+ version in order to determine the capabilities available in Simcenter STAR-CCM+ (for example, to determine whether implicit coupling is available).
  8. Get pointers to the function suites.
    apiStruct->setExternalCodeFunctions(
      API_VERSION, 
      StarccmplusCoSimulationHandlerSuiteName, 
      &handlerSuite);
    apiStruct->getStarccmplusFunctions(
      API_VERSION, 
      StarccmplusCoSimulationApiSuiteName, 
      (void const * *)&apiSuite);
    apiStruct->getStarccmplusFunctions(
      API_VERSION,
      StarccmplusCoSimulationFactorySuiteName,
      (void const * *)&factorySuite);
    apiStruct->getStarccmplusFunctions(
      API_VERSION, 
      StarccmplusCoSimulationPropertiesSuiteName, 
      (void const * *)&propertiesSuite);
    After these calls, you make all subsequent calls using the function suites.
  9. Initialize the library.
    apiSuite->initialize(argc,argv);
  10. Set up the Simcenter STAR-CCM+ API Server:
    1. Create a physics continuum on the Simcenter STAR-CCM+ API Server. The continuum requires you to specify a material model and a time discretization model.
      int continuumId = factorySuite->createContinuum(
        "Solid Continuum", 
        StarccmplusSingleComponentSolid, 
        StarccmplusSingleSurfacePolyMesh,
        StarccmplusImplicitUnsteady, 
        propertiesSuite->create());
    2. Create a region on the Simcenter STAR-CCM+ API server. As the region requires you to specify a continuum ID, make sure that you create the physics continuum first.
      int regionId = factorySuite->createRegion(
        continuumId, 
        "Spindle Ball",
        StarccmplusSurfaceRegion,
        StarccmplusSolidRegion);
    3. Create the region boundaries. As you create boundaries within regions, make sure that you create a region first.
      int boundaryId = factorySuite->createBoundary(
        regionId, 
        "Spindle Ball Surface",
        StarccmplusWallBoundary);
    4. Create and set up a co-simulation link. At this stage, you also specify the coupling scheme (implicit or explicit).
      int coSimulationId = factorySuite->createCoSimulation( 
        "Link 1",
        propertiesSuite->create();
      int coSimulationId = factorySuite->setupCoSimulation(
        coSimulationId,
        StarccmplusImplicitCoupling,
        propertiesSuite->create();
    5. Create a co-simulation zone of appropriate type (either surface, for surface-to-surface coupling, or volume, for volume-to-volume coupling). As you create co-simulation zones within the co-simulation link, you require the co-simulation link ID.
      int zoneId = factorySuite->createCoSimulationZone(
        coSimulationId, 
        "zoneName",
        StarccmplusSurfaceZone,
        propertiesSuite->create();
    6. To couple a model part (either boundary or region) with Simcenter STAR-CCM+, assign it to a co-simulation zone. Assign coupled boundaries to surface zones and coupled regions to volume zones.
      factorySuite->addModelPartToZone(
      zoneId, 
      boundaryId);
    7. Provide a mesh to the Simcenter STAR-CCM+ API server that conforms to the Simcenter STAR-CCM+ polyhedral mesh format (see Polyhedral Mesh Reference). To register the mesh, you require the region ID.
      int meshId = factorySuite->registerOutgoingMesh(
        regionId, 
        StarccmplusSurfacePolyMesh);
    8. Register data fields that your program sends to Simcenter STAR-CCM+ through the co-simulation zone.
      int displId = factorySuite->registerOutgoingField(
        zoneId,
        StarccmplusVertexFieldLocation,
        StarccmplusDisplacementSpecification, 
        StarccmplusDisplacements, 
        propertiesSuite->create());
    9. Register data fields that your program receives from Simcenter STAR-CCM+ through the co-simulation zone.
      int pressureId = factorySuite->registerIncomingField(
        zoneId,
        StarccmplusFaceFieldLocation,
        StarccmplusPressureSpecification,
        StarccmplusPressure,
        propertiesSuite->create());
  11. Notify Simcenter STAR-CCM+ that the mesh is ready for use:
    apiSuite->notifyOutgoingMeshesReady();
  12. Specify the solver settings and run loop. Include the solver time-step and either the coupling time (for explicit coupling) or the number of inner iterations per exchange (for implicit coupling).
    1. Set the solver time-step. You can specify a fixed time-step or query the Simcenter STAR-CCM+ simulation to get the time-step and coupling time interval. You can only query Simcenter STAR-CCM+ after the initial connection negotiation. To check:
      apiSuite->waitForUpdate();
      To get the Simcenter STAR-CCM+ simulation time-step and the coupling frequency:
      int propId = factorySuite->getConditionValueProperties( 
        coSimulationId,
        StarccmplusPropIdPartnerCouplingParameters);
      double timeStep = propertiesSuite->getDouble(
         propId,
         StarccmplusPropNameTimeStep);
      apiSuite->setTimeStep(t, timeStep);
    2. Specify the data exchange frequency:
      Explicit Loop Implicit Loop
      Specify the coupling time, which must be equal to, or greater than, the solver target time (current time + time-step).
      apiSuite->setCouplingTime(couplingTime);
      Set the number of inner iterations per exchange.
      apiSuite->setNumberOfInnerIterationsPerExchange(
        inner_iterations_per_exchange);
    3. Wait for incoming fields.
      apiSuite->waitForIncomingFields();
    4. If the return value of the waitForIncomingFields call is non-zero, a data exchange occurred. In this case, retrieve the registered incoming fields.
      propertiesSuite->addDouble(
        pressureId,"Time",t); 
           
      propertiesSuite->fill(pressureId,"FieldValues"); 
           
      propertiesSuite->getDoubleArray(
        pressureId, "Pressure", &pressField[0], pressField.size());
    5. Solve for partner solution and prepare the solution data for export.
    6. At every iteration or time-step, notify Simcenter STAR-CCM+ that outgoing fields are ready.
      apiSuite->notifyOutgoingFieldsReady();
    7. At the end of a solution loop, notify Simcenter STAR-CCM+ that the time-step is complete.
      apiSuite->notifyTimeStepComplete();
    8. Repeat the solution loop until done.
  13. When complete, finalize the Co-Simulation API library.
    apiSuite->finalize();
  14. Terminate the API library.
    apiLib.close();