# 7. OMSimulatorPython3

This section documents the new oms3 Python API, designed to improve modularity and reduce overhead, while providing tighter integration with Python. The updated architecture separates the simulation core from the SSP (System Structure and Parameterization) standards, offering greater flexibility, interoperability and efficient model management.

## 7.1. Core Capabilities

The oms3 Python API provides an extensive set of commands for building, configuring, and validating SSP models. The following table summarizes the main functionalities provided by the package.

Category | Functionality
--- | ---
Model Management | Create new SSP models Create, activate, and duplicate variants Add or delete resources, components, systems, connectors Create nested systems Set parameters and solvers Swap SSV references
Connectivity | Add components and connectors Define and manage connections
SSP Standards | Import and export SSP models Create SSV and SSM descriptions Export SSV and SSM templates Validate SSP, SSV, and SSM
FMU Integration | Import and validate FMUs as components
Utilities | Error handling, logging, and debugging support

## 7.2. Command Line Interface

In addition to the Python API, the oms3 Python package installs a `OMSimulatorPython3` command line entry point that can run a `.ssp` or `.fmu` file directly, without having to write a driver script:

    OMSimulatorPython3 model.ssp
    OMSimulatorPython3 model.fmu

All simulation settings (start/stop time, tolerance, …) are taken from the model itself; use the flags below to override them. Both file types are validated against their schema (FMI for `.fmu`, SSP for `.ssp`) before simulation.

The full list of command line arguments can also be printed at any time with:

    OMSimulatorPython3 --help

OMSimulatorPython3 command line flags
Flag | Value | Description
--- | --- | ---
`--result-file` | `FILE` | Override the result file name.
`--start-time` | `TIME` | Override the simulation start time.
`--stop-time` | `TIME` | Override the simulation stop time.
`--tolerance` | `TOL` | Override the solver tolerance (`.fmu` only).
`--step-size` | `SIZE` | Override the (maximum) simulation step size (`.fmu` only).
`--mode` | `cs` | `me` | Force co-simulation or model exchange for FMUs that export both kinds (`.fmu` only).
`--solver` | `euler` | `cvode` | Set the ODE solver for model-exchange FMUs (`.fmu`, requires `--mode me`).
`--stripRoot` | — | Remove the root system prefix from exported signal names (applies to both `.fmu` and `.ssp`).
`--validate` | `.fmu` | `.ssp` | Only validate the file against its schema; do not simulate.

### 7.2.1. Examples

    # Simulate an FMU using its own declared defaults
    OMSimulatorPython3 model.fmu

    # Force model-exchange mode with the Euler solver and a custom step size
    OMSimulatorPython3 model.fmu --mode me --solver euler --step-size 1e-3

    # Only validate an FMU or SSP against its schema, without simulating
    OMSimulatorPython3 model.fmu --validate
    OMSimulatorPython3 model.ssp --validate

    # Override the stop time and result file of an SSP
    OMSimulatorPython3 model.ssp --stop-time 10 --result-file out.mat

    # Drop the "model.root" prefix from exported signal names (.fmu or .ssp)
    OMSimulatorPython3 model.fmu --stripRoot
    OMSimulatorPython3 model.ssp --stripRoot

## 7.3. Quick start Example

The following example demonstrates how to

- Create a new SSP model

- Add FMU components as resources

- Establish connections between components

- Export the model to an SSP file

- Re-import the exported SSP file

- Instantiate the model, set parameter values, and run a simulation

    from OMSimulator import SSP, CRef, Settings
    Settings.suppressPath = True

    # This example creates a new SSP file with an FMU instantiated as a component.
    # It then exports the SSP file and re-imports and set run time value on the instantiated model and the simulates the model.

    model = SSP()
    model.addResource('../resources/Modelica.Blocks.Math.Add.fmu', new_name='resources/Add.fmu')
    model.addResource('../resources/Modelica.Blocks.Math.Gain.fmu', new_name='resources/Gain.fmu')

    component1 = model.addComponent(CRef('default', 'Add1'), 'resources/Add.fmu')
    component3 = model.addComponent(CRef('default', 'Gain1'), 'resources/Gain.fmu')

    model.addConnection(CRef('default', 'Gain1', 'y'), CRef('default', 'Add1', 'u1'))

    #model.list()
    model.export('SimpleSimulation5.ssp')
    ## import the exported SSP file
    model2 = SSP('SimpleSimulation5.ssp')

    instantiated_model = model2.instantiate()
    instantiated_model.setResultFile("SimpleSimulation5_res.mat")
    instantiated_model.setValue(CRef('default', 'Gain1', 'k'), 2.0)
    instantiated_model.setValue(CRef('default', 'Gain1', 'u'), 6.0)

    print(f"info: After instantiation:")
    print(f"info:    default.Gain1.k: {instantiated_model.getValue(CRef('default', 'Gain1', 'k'))}", flush=True)
    print(f"info:    default.Gain1.u: {instantiated_model.getValue(CRef('default', 'Gain1', 'u'))}", flush=True)
    print(f"info:    default.Gain1.y: {instantiated_model.getValue(CRef('default', 'Gain1', 'y'))}", flush=True)
    print(f"info:    default.Add1.u1: {instantiated_model.getValue(CRef('default', 'Add1', 'u1'))}", flush=True)

    instantiated_model.initialize()
    instantiated_model.simulate()
    print(f"info: After simulation:")
    print(f"info:    default.Gain1.k: {instantiated_model.getValue(CRef('default', 'Gain1', 'k'))}", flush=True)
    print(f"info:    default.Gain1.u: {instantiated_model.getValue(CRef('default', 'Gain1', 'u'))}", flush=True)
    print(f"info:    default.Gain1.y: {instantiated_model.getValue(CRef('default', 'Gain1', 'y'))}", flush=True)
    print(f"info:    default.Add1.u1: {instantiated_model.getValue(CRef('default', 'Add1', 'u1'))}", flush=True)

    instantiated_model.terminate()
    instantiated_model.delete()

## 7.4. SSP

The `ssp` module provides a high-level interface for creating, importing, and managing SSP (System Structure and Parameterization) models. SSP models are used to describe complex system architectures by connecting multiple components and defining their parameters, enabling seamless simulation and co-simulation workflows.

    from OMSimulator import SSP, Settings
    Settings.suppressPath = True

    # Create a new, empty SSP model instance
    model = SSP()

    # Load an existing SSP model from a file
    model = SSP("PIController.ssp")

    # list the ssp components
    model.list()

Once created or loaded, an `SSP` model instance allows you to:

- Add and configure components.

- Connect signals between components.

- Define parameters and experiment settings.

- Export the model for simulation or further analysis.

## 7.5. SSD

The SSV class provides a high-level interface for importing, and managing SSD (System Structure Description) models which are unpacked from SSP files. We can use the SSD class to load an SSD file, inspect its structure, and manipulate its elements programmatically.

    from OMSimulator import SSD, Settings
    Settings.suppressPath = True
    ssd = SSD.importFromFile('../resources/LOC/SystemStructure.ssd')
    ssd.list()

## 7.6. SSV

The SSV class provides an interface for creating and managing System Structure Parameter Values (SSV) files. These files are used to define parameter values, units, and variability information for components within an SSP model.

Typical use cases include:

  - Defining scalar variables and their default values

  - Assigning units and data types to parameters

  - Storing both numeric and string-based parameter values

  - Exporting parameter sets to .ssv files for reuse across simulations

Key Methods

- `setValue(name, value, unit=None)` Assigns a parameter value. Optionally, a unit can be specified.

- `export(filename)` Writes the defined parameters to an external .ssv file.

Example

    from OMSimulator import SSV, Settings

    Settings.suppressPath = True

    # Create a new SSV file and define parameters
    ssv1 = SSV()
    ssv1.setValue("k1", 2.0, "m")
    ssv1.setValue("k2", 3.0)
    ssv1.setValue("k3", 3)
    ssv1.setValue("k4", False)
    ssv1.setValue("param3", "hello")

    # Export to file
    ssv1.export("myfile1.ssv")

## 7.7. SSM

The SSM class provides an interface for creating and managing System Structure and Mapping (SSM) files. These files define how parameters declared in an SSV file are mapped to component parameters within an SSP model. This enables separation of parameter definitions from their usage, improving reusability and modularity.

Typical use cases include:

  - Linking global parameter definitions (from SSV files) to component parameters in an SSP model.

  - Supporting multiple parameter mappings for the same input across different components.

  - Creating flexible configurations by swapping or updating parameter mappings without modifying the model structure.

Key Methods

- `mapParameter(source, target)` Creates a mapping between a parameter defined in an SSV file (`source`) and a component parameter or input signal (`target`).

- `export(filename)` Writes the defined parameter mappings to an external .ssm file.

Example

    from OMSimulator import SSV, SSM, Settings

    Settings.suppressPath = True

    # Define parameters in SSV
    ssv1 = SSV()
    ssv1.setValue("Input1", 2.0)
    ssv1.setValue("param1", 3.0)
    ssv1.setValue("param2", 3)
    ssv1.export("mapping1.ssv")

    # Create parameter mappings in SSM
    ssm1 = SSM()
    ssm1.mapParameter("Input1", "Add1.u1")
    ssm1.mapParameter("Input1", "u2")
    ssm1.mapParameter("Input1", "u3")
    ssm1.mapParameter("param1", "k1")
    ssm1.mapParameter("param2", "k2")
    ssm1.export("mapping2.ssm")

## 7.8. FMU

The FMU class provides an interface for loading and inspecting Functional Mock-up Units (FMUs).This class allows users to access key metadata, states, and variables of an FMU directly from Python, enabling integration, validation and simulation.

Typical use cases include:

  - Loading an FMU into memory for inspection or simulation.

  - Accessing FMU metadata such as name, GUID, and FMI version.

  - Iterating through state variables and retrieving their properties.

  - Using variable metadata (signal type, causality, variability, value references) for analysis or parameter mapping.

  - set default experiment settings such as start time, stop time, step size, and tolerance.

  - set parameters and inputs before simulation.

Syntax

  fmu = FMU(fmuPath: str, instanceName: str = “”)

Arguments

  - fmuPath: Path to the FMU file.

  - instanceName: Optional name for the FMU instance. If not provided, it defaults to the model name of the FMU. The instance name is used in the result file as prefix for the variable names.

Example

    from OMSimulator import FMU

    # Load FMU
    fmu = FMU('../resources/Modelica.Electrical.Analog.Examples.CauerLowPassAnalog.fmu')

    # Print metadata
    print("name:", fmu.modelName)
    print("guid:", fmu.guid)
    print("fmi version:", fmu.fmiVersion)

    # Inspect state variables
    print("States:")
    for var in sorted(fmu.states, key=lambda x: x.name):
        print({
            'name': var.name,
            'signal_type': var.signal_type.name,
            'valueReference': var.valueReference,
            'variability': var.variability,
            'causality': var.causality.name
        })
    ## instantiate the FMU
    fmu.instantiate()
    ## set result file
    fmu.setResultFile('CauerLowPass_res.mat')
    ## set parameter and input values
    fmu.setValue('R1', 1000.0)
    fmu.setValue('C1.u', 1e-6)
    ## initialize the FMU
    fmu.initialize()
    ## simulate the FMU
    fmu.simulate()
    fmu.terminate()
    fmu.delete()

## 7.9. Component

The Component class provides a flexible interface for defining modular building blocks in an SSP model. It supports architectural modeling, allowing components to represent actual FMUs or “dummy fmus” with expected connectors and parameter values. This makes it possible to design and validate system architectures before all FMUs are available.

Key Features:

  - Flexible instantiation — create a component from an FMU or as a dummy placeholder.

  - Connector support — define inputs, outputs, and parameters with explicit causality and signal type.

  - Parameter management — assign values to parameters or inputs directly within the component.

  - SSV integration — link components to SSV files to define and manage parameter sets externally.

  - System integration — add the component to SSP models for hierarchical or flat system architectures.

    from OMSimulator import CRef, Connector, Causality, SignalType, SSV
    from OMSimulator.component import Component

    # Create a dummy component
    component = Component(CRef('add'), 'dummy.fmu')

    # Add connectors
    component.addConnector(Connector('input', Causality.input, SignalType.Real))
    component.addConnector(Connector('output', Causality.output, SignalType.Real))
    component.addConnector(Connector('parameter', Causality.parameter, SignalType.Real))

    # Set parameter values
    component.setValue('parameter', 1.0)
    component.setValue('input', 2.0)

    # Create an SSV file for parameter initialization
    ssv = SSV()
    ssv.setValue('parameter', 1.0)
    ssv.setValue('input', 2.0)
    ssv.export('dummy.ssv')

    # Link SSV file to component
    component.addSSVReference('dummy.ssv')

    # List component details
    component.list()

## 7.10. addSystem

The addSystem method creates a new system within an SSP model. Systems serve as containers for components and connectors, and can be organized hierarchically to support nested-system architectures. This enables modular, scalable, and reusable system designs.

Key Features:

  - System instantiation — create new systems within the SSP model.

  - Hierarchical modeling — use structured `CRef` paths to create nested systems (e.g., a subsystem inside another subsystem).

  - Organization — group related components, connectors, and resources within a defined subsystem for clarity and reusability.

  - Scalability — build complex system hierarchies with multiple levels.

Syntax

    addSystem(cref)

Parameters:

  - `cref` (CRef): The system reference, specifying the hierarchical path and system name within the SSP model.

Example

    from OMSimulator import SSP, CRef

    model = SSP()

    # Create systems
    model.addSystem(CRef('default', 'sub-system'))
    model.addSystem(CRef('default', 'sub-system2'))

    # Create a nested subsystem inside 'sub-system2'
    model.addSystem(CRef('default', 'sub-system2', 'sub-sub-system'))

## 7.11. addConnector

The addConnector API is used to define external interfaces for systems and components within an SSP model. A connector specifies the signal type and causality (e.g., input, output, or parameter) of a variable, allowing subsystems and components to communicate through well-defined ports.

Connectors can be added at different hierarchy levels:

  - Top-level system connectors, which expose inputs, outputs, and parameters of the entire SSP model.

  - Subsystem connectors, which define interaction points within nested systems and enable modular system design.

Syntax:

    addConnector(Connector(name, causality, signal_type))

Parameters:

  - `name` (str): Name of the connector.

  - `causality` (Causality): Role of the connector (`input`, `output`, or `parameter`).

  - `signal_type` (SignalType): Type of signal (e.g., `Real`, `Integer`,``Boolean``, `String`).

Example:

    from OMSimulator import SSP, CRef, Connector, Causality, SignalType

    model = SSP()
    # Add a top-level system connector
    model.activeVariant.system.addConnector(Connector('input1', Causality.input, SignalType.Real))
    # Add a connector to a subsystem
    model.addSystem(CRef('default', 'sub-system'))
    model.activeVariant.system.elements[CRef('sub-system')].addConnector(Connector('output', Causality.output, SignalType.Real))

## 7.12. addConnection

The addConnection API is used to link the output of one component to the input of another within an SSP model. Connections define the signal flow between components, ensuring that data is transmitted correctly during simulation.

Connections are defined using source and target references:

  - Source: Specifies the output variable of a component.

  - Target: Specifies the input variable of another component.

Syntax:

    addConnection(source: CRef, target: CRef)

Parameters:

  - `source` (CRef): Reference to the output variable of the source component.

  - `target` (CRef): Reference to the input variable of the target component.

Example:

    from OMSimulator import SSP, CRef, Settings

    model = SSP()
    model.addResource('../resources/Modelica.Blocks.Math.Add.fmu', new_name='resources/Add.fmu')
    model.addResource('../resources/Modelica.Blocks.Math.Gain.fmu', new_name='resources/Gain.fmu')

    model.addComponent(CRef('default', 'Add1'), 'resources/Add.fmu')
    model.addComponent(CRef('default', 'Gain1'), 'resources/Gain.fmu')
    ## add a connection from Gain1.y to Add1.u1
    model.addConnection(CRef('default', 'Gain1', 'y'), CRef('default', 'Add1', 'u1'))
    ## list the components in the model and connections
    model.list()

## 7.13. addResource

The addResource method allows you to add external files, such as FMUs, SSV, SSM, SRMD etc.. to an SSP model’s resource directory. This ensures that all required model files are bundled with the SSP package and can be referenced consistently during simulation.

Key Features:

  - File management — copy or rename external FMUs and resources into the SSP project structure only once and use the instances multiple times in the model.

  - Integration with components — added resources can then be used to instantiate components within the SSP model.

Syntax

    addResource(source_path, new_name=None)

Parameters:

  - `source_path` (str): Path to the external resource file (e.g., FMU)

  - `new_name` (str, optional): New name for the resource within the SSP project structure. If not provided, the original filename is used.

Example

    from OMSimulator import SSP, CRef, Settings

    # Add an FMU to the SSP model's resources folder
    model.addResource('../resources/Modelica.Blocks.Math.Add.fmu', new_name='resources/Add.fmu')
    model.addResource('../resources/Modelica.Blocks.Math.Gain.fmu', new_name='resources/Gain.fmu')

## 7.14. addComponent

The addComponent method allows you to instantiate a component within an SSP model. Components can be FMUs or dummy placeholders, enabling flexible system architecture design and simulation.

Key Features:

  - Component instantiation — create components based on FMU resources or dummy placeholders.

  - Hierarchical modeling — components can be placed in nested systems using a structured CRef path.

  - Flexible integration — components can later be connected via connectors, linked to SSV files, or assigned custom solver settings.

  - Supports multiple components — multiple instances of the same FMU can be added with unique identifiers.

Syntax

    addComponent(cref, resource_path)

Parameters:

  - `cref` (CRef): The component reference, specifying the hierarchical path and component name within the SSP model.

  - `resource_path` (str): Path to the FMU or model resource that the component should instantiate.

Returns:

  - The newly created Component object.

Example

    from OMSimulator import SSP, CRef, Settings

    Settings.suppressPath = True

    model = SSP()

    # Add resources to the SSP model
    model.addResource('../resources/Modelica.Blocks.Math.Add.fmu', new_name='resources/Add.fmu')
    model.addResource('../resources/Modelica.Blocks.Math.Gain.fmu', new_name='resources/Gain.fmu')

    # Instantiate components
    component1 = model.addComponent(CRef('default', 'Add1'), 'resources/Add.fmu')
    # instantiate multiple instances of the same FMU
    component2 = model.addComponent(CRef('default', 'Add2'), 'resources/Add.fmu')
    component3 = model.addComponent(CRef('default', 'Gain1'), 'resources/Gain.fmu')
    component4 = model.addComponent(CRef('default', 'Gain2'), 'resources/Gain.fmu')
    # list the components in the model
    model.list()

## 7.15. addSSVReference

The addSSVReference API is used to associate an SSV (System Structure Parameterer and values) file with a specific component in an SSP model. This allows parameter values defined in the SSV file to be applied directly to the component, enabling flexible configuration and reuse of parameter sets.

The API also supports an optional third argument for specifying a parameter mapping file (.ssm), which defines how the variables in the SSV file map to the parameters of the component.

Syntax:

    addSSVReference(cref, ssv_path: str, ssm_path: str = None)

Parameters:

  - `cref` (CRef): Reference to a system, sub-system or component to which the SSV file should be applied.

  - `ssv_path` (str): Path to the SSV file relative to the SSP model resources.

  - `ssm_path` (str, optional): Path to a parameter mapping file (.ssm) that defines how SSV variables correspond to component parameters.

Example:

    from OMSimulator import SSP, CRef, Settings, SSV, SSM, Connector, Causality, SignalType

    Settings.suppressPath = True

    # This example creates a new SSP file with an FMU instantiated as a component and
    # set parameter values to ssv file and map some parameters to ssm file

    model = SSP()
    model.addResource('../resources/Modelica.Blocks.Math.Add.fmu', new_name='resources/Add.fmu')
    component1 = model.addComponent(CRef('default', 'Add1'), 'resources/Add.fmu')
    component2 = model.addComponent(CRef('default', 'Add2'), 'resources/Add.fmu')

    ## create a ssv file
    ssv1 = SSV()
    ssv1.setValue("connector_param", 2.0)
    ssv1.setValue("connector_input", 3.0)
    ssv1.export("myfile3.ssv")

    ## create a ssm file
    ssm = SSM()
    ssm.mapParameter("connector_param", "u1")
    ssm.mapParameter("connector_input", "u2")
    ssm.export("myfile4.ssm")

     ## Add  SSV resource to the model
     model.addResource("myfile3.ssv", "resources/myfile3.ssv")
     ## Add ssm resources to the model
     model.addResource("myfile3.ssv", "resources/myfile4.ssm")

     # Reference the SSV to a specific component
     model.addSSVReference(CRef('default', 'Add1'), 'resources/myfile3.ssv')

     # With an optional SSM mapping file
     model.addSSVReference(CRef('default', 'Add2'), 'resources/myfile4.ssv', 'resources/myfile4.ssm')

## 7.16. removeSSVReference

Removes the reference to a given SSV (System Structure parameter and values) file from a specific component or subsystem within the SSP model.This method is useful when a component or subsystem should no longer be associated with a parameter set defined in an SSV file.

> Notes:

>   - The SSV file itself remains in the `resources/` folder of the SSP.

>   - Only the reference from the specified component is removed.

>   - If a parameter mapping file (.ssm) is associated with the SSV, it is also removed.

>   - If the component had multiple SSV references, only the matching one is cleared.

Syntax:

    removeSSVReference(cref, ssv_path)

Parameters:

  - `cref` (CRef): Reference to a system, sub-system or component to which the SSV file should be applied.

  - `ssv_path` (str): Path to the SSV file relative to the SSP model resources.

Example usage:

>     # Load an existing SSP model
>     model = SSP("swapSSV1.ssp")

>     # Remove SSV reference from top-level component Add1
>     model.removeSSVReference(CRef("default", "Add1"), "resources/swap1.ssv")

>     # Remove SSV reference from Add3 inside the subsystem
>     model.removeSSVReference(CRef("default", "sub-system", "Add3"), "resources/swap1.ssv")
>     # List the model details to verify removal
>     model.list()

## 7.17. swapSSVReference

Swaps the reference to an existing SSV (System Structure parameter and values) file with a new one for a specific component or subsystem within the SSP model.

This method is essentially a combination of `removeSSVReference` and `addSSVReference`. It ensures that the old SSV reference is removed and replaced with the new SSV reference in a single step, reducing the risk of leaving the system without any SSV mapping during the transition.

> Notes:

>   - The old SSV file remains in the `resources/` folder of the SSP model.

>   - Only the reference is swapped — no SSV files are deleted.

>   - If a parameter mapping file (.ssm) is associated with the old SSV, it will also be swapped accordingly.

>   - This method is equivalent to calling:

>         model.removeSSVReference(cref, old_ssv)
>         model.addSSVReference(cref, new_ssv)

Syntax:

    swapSSVReference(cref, old_ssv, new_ssv)

Parameters:

  - `cref` (CRef): Reference to a system, sub-system, or component where the SSV file should be swapped.

  - `old_ssv` (str): Path to the currently referenced SSV file relative to the SSP model resources.

  - `new_ssv` (str): Path to the new SSV file relative to the SSP model resources.

Example usage:

>     # Load an existing SSP model
>     model = SSP("swapSSV3.ssp")

>     # Swap SSV reference from default system (swap5.ssv → swap6.ssv)
>     model.swapSSVReference(CRef("default"), "resources/swap5.ssv", "resources/swap6.ssv")

>     # Swap SSV reference from sub-system (swap6.ssv → swap5.ssv)
>     model.swapSSVReference(CRef("default", "sub-system"), "resources/swap6.ssv", "resources/swap5.ssv")

>     print("After swapping swap6.ssv to default and swap5.ssv to sub-system")
>     print("===============================================================")
>     model.list()

## 7.18. listSSVReference

Retrieves the list of SSV (System Structure parameter and values) files currently referenced by a system, sub-system, or component within the SSP model.

> Notes:

>   - Only the references are listed — the method does not open or parse the SSV files.

>   - If no SSV file is associated with the given scope, an empty list is returned.

>   - The returned paths are relative to the `resources/` directory of the SSP archive.

Syntax:

    listSSVReference(cref) -> list[dict]

Parameters:

  - `cref` (CRef): Reference to a system, sub-system, or component for which SSV references should be listed.

Returns:

  - (list[dict]): A list of dict referenced by the given system, sub-system, or component. - Each dict contains:

    > - `ssv` (str): Path to the referenced SSV file relative to the SSP model resources.

    > - `ssm` (str | None): Path to the associated SSM file if one exists; otherwise, `None`.

Example usage:

    model = SSP("listSSVReference1.ssp")
    model.list()

    print("List of SSV references")
    print("=======================")
    print(f"Top level system SSV resources    : {model.listSSVReference(CRef('default'))}")
    print(f"Top level sub-system SSV resources: {model.listSSVReference(CRef('default', 'sub-system'))}")
    print(f"Component Add1 SSV resources      : {model.listSSVReference(CRef('default', 'Add1'))}")
    print(f"Component Add2 SSV resources      : {model.listSSVReference(CRef('default', 'Add2'))}")
    print(f"Component Add3 SSV resources      : {model.listSSVReference(CRef('default', 'sub-system', 'Add3'))}")

## 7.19. exportSSVTemplate

Exports a template SSV (System Structure Parameter Values) file for a given system, sub-system, or component within the SSP model.

The generated SSV template contains all parameters that can be configured for the referenced scope (system or component), but without assigned values. This is useful for creating new parameter sets, preparing configuration files, or documenting the available tunable parameters in a model.

> Notes:

>   - The exported SSV file contains parameter definitions but not their actual values.

>   - The scope of the export depends on the provided CRef

>       - Root system → exports all parameters for the entire SSP.

>       - Sub-system → exports parameters for that sub-system and its components.

>       - Component → exports only the parameters of the selected component.

>   - The output file is always written to the specified path; existing files will be overwritten.

Syntax:

    exportSSVTemplate(cref, ssv_path)

Parameters:

  - `cref` (CRef): Reference to a system, sub-system, or component for which the SSV template should be generated.

  - `ssv_path` (str): Path where the exported SSV template will be saved.

Example usage:

>     from OMSimulator import SSP, CRef

>     # Load an existing SSP model
>     model = SSP("exportSSVTemplate1.ssp")

>     # Export template for the entire SSP
>     model.exportSSVTemplate(CRef("default"), "exportSSVTemplate1.ssv")

>     # Export template for a sub-system
>     model.exportSSVTemplate(CRef("default", "sub-system"), "exportSSVTemplate2.ssv")

>     # Export template for a single component (Add1)
>     model.exportSSVTemplate(CRef("default", "Add1"), "exportSSVTemplate3.ssv")

>     # Export template for another component (Add2)
>     model.exportSSVTemplate(CRef("default", "Add2"), "exportSSVTemplate4.ssv")

Example usage with fmu component:

      from OMSimulator import FMU
      fmu = FMU('../resources/Modelica.Blocks.Math.Add.fmu')
      ## export the start values in fmu to ssv template
      fmu.exportSSVTemplate('startValuesSSVTemplate.ssv')

## 7.20. exportSSVTemplate

Exports a template SSM (System Structure Parameter mapping) file for a given system, sub-system, or component within the SSP model.

The generated SSM template contains all parameters that can be configured for the referenced scope (system or component), with source and target variables. The source attribute in ssm template will be empty and should be set by user to map to the desired variable in the SSV file. This is useful for creating new parameter mapping files, preparing configuration files.

> Notes:

>   - The exported SSM file contains source and target definitions but source attribute will be empty.

>   - The scope of the export depends on the provided CRef

>       - Root system → exports all parameters for the entire SSP.

>       - Sub-system → exports parameters for that sub-system and its components.

>       - Component → exports only the parameters of the selected component.

>   - The output file is always written to the specified path; existing files will be overwritten.

Syntax:

    exportSSMTemplate(cref, ssm_path)

Parameters:

  - `cref` (CRef): Reference to a system, sub-system, or component for which the SSV template should be generated.

  - `ssm_path` (str): Path where the exported SSV template will be saved.

Example usage:

>     from OMSimulator import SSP, CRef

>     # Load an existing SSP model
>     model = SSP("exportSSMTemplate1.ssp")

>     # Export template for the entire SSP
>     model.exportSSMTemplate(CRef("default"), "exportSSMTemplate1.ssm")

>     # Export template for a sub-system
>     model.exportSSMTemplate(CRef("default", "sub-system"), "exportSSMTemplate2.ssm")

>     # Export template for a single component (Add1)
>     model.exportSSMTemplate(CRef("default", "Add1"), "exportSSMTemplate3.ssm")

>     # Export template for another component (Add2)
>     model.exportSSMTemplate(CRef("default", "Add2"), "exportSSMTemplate4.ssm")

Example usage with fmu component:

>     from OMSimulator import FMU
>     fmu = FMU('../resources/Modelica.Blocks.Math.Add.fmu')
>     ## export the start values in fmu to ssv template
>     fmu.exportSSMTemplate('startValuesSSVTemplate.ssm')

## 7.21. setValue

Assigns a numerical value to a parameter of a component within the SSP model.

This method is used to directly set start values or parameter values of model variables defined in an FMU component. The values are stored in the SSP model and will be applied when the model is simulated or exported.

> Notes:

>   - The parameter must exist in the referenced FMU/component or a top level system connectors; otherwise, an error will be raised.

>   - Values are stored at the SSP level and exported together with the model structure.

>   - Supported data types are numerical (`float`, `int`, `str`, `bool`).

>   - Special FMI-3.0 data types like `Float64`, `Float32`, `Int8`, `Int16`, `Int32`, `Int64`, `UInt8`, `UInt16`, `UInt32`, `UInt64` are handled via special classes in OMSimulator like `Float64`, `Int32`, etc. These classes can be imported from OMSimulator and used to set parameter values with specific fmi3 data types.

>   - Parameters can be set before or after instantation.

Syntax:

    setValue(cref, value)

Parameters:

  - `cref` (CRef): Reference to the parameter variable within a component. The `CRef` must specify the system, component, and parameter name (e.g., `CRef("default", "Add1", "k1")`).

  - `value` (float | int | str | bool | Float64 | Float32 | Int8 | Int16 | Int32 | Int64 | UInt8 | UInt16 | UInt32 | UInt64): The value to assign to the parameter.

Example usage:

    from OMSimulator import SSP, CRef, Settings

    Settings.suppressPath = True

    # Create a new SSP model
    model = SSP()

    # Add FMU resource
    model.addResource("../resources/Modelica.Blocks.Math.Add.fmu", new_name="Add.fmu")

    # Add two components
    model.addComponent(CRef("default", "Add1"), "Add.fmu")
    model.addComponent(CRef("default", "Add2"), "Add.fmu")

    # Set parameter values for Add1
    model.setValue(CRef("default", "Add1", "k1"), 2.0)
    model.setValue(CRef("default", "Add1", "k2"), 3.0)

    # Set parameter values for Add2
    model.setValue(CRef("default", "Add2", "k1"), 100.0)
    model.setValue(CRef("default", "Add2", "k2"), 300.0)

    # Display model details
    model.list()

    # Export the SSP with parameter values applied
    model.export("setValue2.ssp")

Example of setting FMI-3.0 specific data types:

    from OMSimulator import SSP, CRef, Settings, Float64, Int32, UInt16, Float32, Int8, Int16, Int64, UInt8, UInt32, UInt64

    model = SSP()
    model.addResource("../resources/Feedthrough3.fmu", new_name="resources/Feedthrough3.fmu")
    model.addComponent(CRef("default", "Feedthrough1"), "resources/Feedthrough3.fmu")

    model.setValue(CRef("default", "Feedthrough1", "Float64_continuous_input"), Float64(3.5))
    model.setValue(CRef("default", "Feedthrough1", "Int64_input"), Int64(7))
    model.setValue(CRef("default", "Feedthrough1", "Float32_continuous_input"), Float32(1.5))
    model.setValue(CRef("default", "Feedthrough1", "Int8_input"), Int8(3))
    model.setValue(CRef("default", "Feedthrough1", "Boolean_input"), True)

    model.setValue(CRef("default", "Feedthrough1", "Float32_discrete_input"), Float32(2.5))
    model.setValue(CRef("default", "Feedthrough1", "Enumeration_input"), 2)

    model.setValue(CRef("default", "Feedthrough1", "Int16_input"), Int16(1000))
    model.setValue(CRef("default", "Feedthrough1", "UInt16_input"), UInt16(2000))
    model.setValue(CRef("default", "Feedthrough1", "UInt32_input"), UInt32(3000))
    model.setValue(CRef("default", "Feedthrough1", "UInt64_input"), UInt64(4000))

## 7.22. getValue

Retrieves the current value of a parameter or variable from a system, sub-system, or component within the SSP model.

This method is typically used to query parameter values that have been set using `setValue`, or to inspect default values provided by FMUs or the SSP model. It can be applied both before and after simulation, depending on whether the SSP has been instantiated and executed.

> Notes:

>   - If called before instantiation, it will return the value stored in the SSP model (either default or set explicitly by the user).

>   - If called after instantation, it return the updated value depending on the FMU state.

>   - Works for system-level, sub-system, and component parameters.

>   - Returns a Python type corresponding to the variable type (`float` for Real, `int` for Integer, `bool` for Boolean, etc.).

Syntax:

    getValue(cref) -> value

Parameters:

  - `cref` (CRef): Reference to the parameter or variable whose value should be retrieved. For example, `CRef("default", "Add1", "k1")` refers to parameter `k1` of component `Add1`.

Returns:

  - (float | int | bool | str): The current value of the requested parameter or variable.

Example usage:

    from OMSimulator import SSP, CRef, Settings

    Settings.suppressPath = True

    # Load an existing SSP model
    model = SSP("setValue2.ssp")

    # Retrieve values from top-level system parameter
    print(f"info:    default.param1 : {model.getValue(CRef('default', 'param1'))}", flush=True)

    # Retrieve values from FMU components
    print(f"info:    Add1.k1 : {model.getValue(CRef('default', 'Add1', 'k1'))}", flush=True)
    print(f"info:    Add2.k2 : {model.getValue(CRef('default', 'Add2', 'k2'))}", flush=True)

## 7.23. mapParameter

Creates a parameter mapping between a connector and one or more parameters within the SSP model.

> Notes:

>   - Parameter mapping enables hierarchical parameterization of systems and sub-systems.

>   - A single connector can be mapped to multiple parameters (fan-out mapping).

>   - Mappings can be stored inline or in the associated SSM (System Structure Mapping) file.

Syntax:

    mapParameter(cref, connector, parameter)

Parameters:

  - `cref` (CRef): Reference to the system, sub-system, or component where the mapping is applied. Typically, this is the root system (e.g., `CRef("default")`).

  - `connector` (str): Name of the connector providing the source value.

  - `parameter` (str): Name of the target parameter or input to be mapped to the connector.

Example usage:

    from OMSimulator import SSP, CRef, Connector, Causality, SignalType

    # Create a new SSP model
    model = SSP()

    # Add top-level system connectors
    model.activeVariant.system.addConnector(Connector("param1", Causality.parameter, SignalType.Real))
    model.activeVariant.system.addConnector(Connector("param2", Causality.parameter, SignalType.Real))
    model.activeVariant.system.addConnector(Connector("param3", Causality.parameter, SignalType.Real))
    model.activeVariant.system.addConnector(Connector("input1", Causality.input, SignalType.Real))
    model.activeVariant.system.addConnector(Connector("input2", Causality.input, SignalType.Real))

    # Assign values to virtual connectors
    model.setValue(CRef("default", "connector_param"), 2.0)
    model.setValue(CRef("default", "connector_input"), 3.0)

    # Map top-level parameters
    model.mapParameter(CRef("default"), "connector_param", "param1")
    model.mapParameter(CRef("default"), "connector_param", "param2")
    model.mapParameter(CRef("default"), "connector_param", "param3")

    # Map inputs
    model.mapParameter(CRef("default"), "connector_input", "input1")
    model.mapParameter(CRef("default"), "connector_input", "input2")

## 7.24. duplicate and activate Variant

Creates a copy of an existing variant (SSD file) within an SSP model and assigns it a new name.

A variant in SSP represents a specific configuration of a system (stored as an SSD file). By duplicating a variant, users can create an alternative configuration without modifying the original one. This is particularly useful for scenario testing, parameter studies, or creating multiple versions of a system with different inputs, parameters, or components.

> Notes:

>   - The duplicate is a deep copy of the variant — all systems, components, and parameter values are copied.

>   - The duplicate can be modified independently of the original (e.g., by adding components, changing parameter values).

>   - Duplicated variants must be explicitly added back to the model using `model.add(variant)`.

>   - The active variant of a model can be switched using `model.activeVariantName = "VariantName"`.

Syntax:

    variant_copy = model.variants['Variant-Name'].duplicate(new_name)

Parameters:

  - `new_name` (str): Name for the duplicated variant.

Returns:

  - (SSD): A new `SSD` object representing the duplicated variant.

Example usage:

    from OMSimulator import SSD, SSP, Settings, CRef

    Settings.suppressPath = True

    # Create a new SSP model with a default variant
    model = SSP(temp_dir="./tmp-duplicateVariant2/")
    model.addResource("../resources/Modelica.Blocks.Math.Add.fmu")
    model.addComponent(CRef("default", "Add1"), "resources/Modelica.Blocks.Math.Add.fmu")

    # Set parameter values in default variant
    model.setValue(CRef("default", "Add1", "u1"), 10.0)
    model.setValue(CRef("default", "Add1", "u2"), 20.0)
    model.setValue(CRef("default", "Add1", "k1"), 30.0)

    # Duplicate the default variant as "Variant-B"
    variantB = model.variants["default"].duplicate("Variant-B")
    model.add(variantB)

    # Modify parameter values in Variant-B
    variantB.setValue(CRef("default", "Add1", "u1"), 100.0)
    variantB.setValue(CRef("default", "Add1", "u2"), 200.0)

    # Export SSP with both variants
    model.export("duplicateVariant2.ssp")

    # Load the model again and duplicate Variant-B as Variant-C
    model2 = SSP("duplicateVariant2.ssp")
    variantC = model2.variants["Variant-B"].duplicate("Variant-C")
    model2.add(variantC)

    # Modify Variant-C independently
    variantC.setValue(CRef("default", "Add1", "u1"), -100.0)
    variantC.addComponent(CRef("default", "Add2"), "resources/Modelica.Blocks.Math.Add.fmu")

    # Switch active variant to Variant-C
    model2.activeVariantName = "Variant-C"

    # Add new component only to Variant-C
    model2.addComponent(CRef("default", "Add3"), "resources/Modelica.Blocks.Math.Add.fmu")
    variantC.setValue(CRef("default", "Add3", "u1"), -200.0)
    variantC.setValue(CRef("default", "Add3", "k1"), -30.0)

    # Print the structure of the model
    model2.list()

## 7.25. getVariant

Get the list of available variants for a given system or sub-system within the SSP model.

Syntax:

    getVariant(cref : None | str) -> SSD | None

Parameters:

  - `cref` : variant name (e.g) SystemStructure, VarA, VarB, if None is given then it will return the current active variant.

Example usage:

>     from OMSimulator import SSP, CRef

>     # Load an existing SSP model
>     model = SSP("exportSSMTemplate1.ssp")
>     ## get list of available variants
>     model.getAllVariantNames()
>     ## get current active variant
>     varA = model.getVariant("varA")

## 7.26. listResource

Lists all resource files stored in the `resources/` folder of the SSP model.

This method is useful for inspecting the files available in the model, including FMUs, SSV parameter files, SSM mapping files, and other artifacts. It provides a quick overview of which resources are packaged inside the SSP archive.

Syntax:

    listResource() -> list[str]

Returns:

  - (list[str]): A list of resource file paths contained in the SSP model.

Example usage:

    model = SSP("deleteResources1.ssp")
    model.list()

    print("list of Resources in SSP:")
    print("==========================")
    print(model.listResource())

## 7.27. deleteResource

Removes a resource file from the `resources/` folder of the SSP model.

This method deletes the specified resource file from the model archive and updates the SSP structure accordingly. It is useful for cleaning up unused parameter sets, mapping files, or FMUs.

> Notes:

>   - The file is physically removed from the SSP archive — it cannot be recovered unless re-added.

>   - If the resource is still referenced by components, connectors, or mappings, those references will become invalid and may cause errors.

>   - Can be used for any type of resource (e.g., FMU, SSV, SSM, or custom files).

Syntax:

    deleteResource(resource_path)

Parameters:

  - `resource_path` (str): Path to the resource file to be deleted, relative to the SSP `resources/` directory.

Example usage:

    model = SSP("deleteResources1.ssp")
    model.list()

    # Delete a parameter set file
    model.deleteResource("resources/delete3.ssv")
    print("After deleting delete3.ssv:")
    model.list()

    # Delete another SSV file
    model.deleteResource("resources/delete4.ssv")
    print("After deleting delete4.ssv:")
    model.list()

    # Delete an FMU resource
    model.deleteResource("resources/Add.fmu")
    print("After deleting resources/Add.fmu:")
    model.list()

## 7.28. delete

Deletes a connector, component, or subsystem from the SSP model.

This method removes the specified element from the model hierarchy. It can be used to: - Remove individual connectors (parameters or inputs/outputs) from a system or component. - Remove components from a subsystem or top-level system. - Remove entire subsystems, including all their child components and connectors.

> Notes:

>   - Deleting a connector removes it from the system/component, but does not affect other connectors or components.

>   - Deleting a component removes all its connectors and any associated parameter values.

>   - Deleting a subsystem removes the subsystem and all nested components and connectors.

>   - Any SSV/SSM references pointing to deleted elements may become invalid.

>   - The operation modifies the active variant; other variants are unaffected unless explicitly modified.

Syntax:

    delete(cref)

Parameters:
  - `cref` (CRef): Reference to the element to delete. Can point to a connector, component, or subsystem. Examples:

      - Connector: `CRef("default", "param1")`

      - Component: `CRef("default", "Add1")`

      - Subsystem: `CRef("default", "sub-system")`

Example usage:

    from OMSimulator import SSP, CRef

    # Load an existing SSP model
    model2 = SSP("deleteConnector1.ssp")

    # Delete individual connectors
    model2.delete(CRef("default", "param1"))
    model2.delete(CRef("default", "sub-system", "input"))
    model2.delete(CRef("default", "sub-system", "Add2", "u1"))
    model2.delete(CRef("default", "Add1", "u1"))

    print("## After deleting connectors:")
    model2.list()

    # Delete an entire component
    model2.delete(CRef("default", "sub-system", "Add2"))
    print("## After deleting component Add2 from sub-system:")
    model2.list()
    # Delete an entire sub-system
    model2.delete(CRef('default', 'sub-system'))
    print("## After deleting sub-system:")
    model2.list()
    # Delete the entire system
    model2.delete(CRef('default'))
    print("## After deleting full system:")
    model2.list()

## 7.29. instantiate

Instantiates an SSP model for simulation by creating an internal runtime representation. After instantiation, users can modify parameter values on the instantiated model and specify the simulation result file before running the simulation.

> Notes:

>   - All start values from SSV files and inline SSP `setValue` calls are applied initially.

>   - Values set via `setValue` on the instantiated model override the initial values.

>   - The instantiated model is independent of the SSP file on disk

>   - After instantiation, simulation methods such as `initialize()`, `simulate()`, `terminate()`, and `delete()` can be used.

>   - The instantiated model should be deleted using `delete()` to free resources after simulation.

>   - `setResultFile()` should be called before simulation to define the output file for logged results.

Syntax:

    instantiated_model = model.instantiate() -> InstantiatedSSP

Returns:

  - (InstantiatedSSP): A runtime object representing the SSP model, ready for simulation.

Example usage:

    from OMSimulator import SSP, CRef, Settings

    # import SSP
    model2 = SSP("SimpleSimulation2.ssp")
    model2.list()

    # Instantiate the model for simulation
    instantiated_model = model2.instantiate()  # Start values from SSV and inline setValue are applied

    # Set result file
    instantiated_model.setResultFile("SimpleSimulation6_res.mat")

    # Override parameter values at runtime
    instantiated_model.setValue(CRef("default", "Gain1", "k"), 2.0)
    instantiated_model.setValue(CRef("default", "Gain1", "u"), 6.0)

## 7.30. setResultFile

Specifies the file where simulation results of an instantiated SSP model will be stored.

> Notes:

>   - The file path can be relative or absolute.

>   - Supported formats depend on the simulator backend (commonly .mat or .csv files).

>   - Must be called before simulate() to ensure proper logging of results.

Syntax:

    setResultFile(file_path)

Parameters:

  - `file_path` (str): Path to the simulation result file.

Example usage:

    from OMSimulator import SSP, CRef, Settings

    Settings.suppressPath = True

    # Load SSP and instantiate model
    model = SSP("SimpleSimulation2.ssp")
    instantiated_model = model.instantiate()

    # Specify the result file
    instantiated_model.setResultFile("SimpleSimulation6_res.mat")

## 7.31. initialize

Initializes an instantiated SSP model and prepares it for simulation.

> Notes:

>   - Must be called after instantiate() and before simulate().

>   - Applies all parameter and connector start values at runtime.

>   - Performs consistency checks on component connections and initial conditions.

>   - Initializes all FMU components and sets the model to a “ready-to-simulate” state.

>   - Does not perform the actual simulation; only prepares the model for it.

Syntax:

    initialize()

Example usage:

    from OMSimulator import SSP, CRef, Settings

    Settings.suppressPath = True

    # Load SSP and instantiate model
    model = SSP("SimpleSimulation2.ssp")
    instantiated_model = model.instantiate()

    # Apply result file and runtime parameters
    instantiated_model.setResultFile("SimpleSimulation6_res.mat")
    instantiated_model.setValue(CRef("default", "Gain1", "k"), 2.0)
    instantiated_model.setValue(CRef("default", "Gain1", "u"), 6.0)

    # Initialize the model before simulation
    instantiated_model.initialize()

## 7.32. Solver

OMSimulator supports different solver methods depending on the FMI kind of the components in the system. Solvers are configured by name in the Simulation Setup dialog and assigned to individual FMU components.

Co-Simulation (CS) Solvers

Co-simulation solvers act as masters that drive the co-simulation protocol. They are used for FMUs that implement the co-simulation interface (CS FMUs).

Method | Description
--- | ---
`oms_ma` | Master Algorithm — fixed-step co-simulation master. The step size is controlled by the `fixedStepSize` setting.
`oms_mav` | Master Algorithm with Variable Step — variable-step co-simulation master. Uses `initialStepSize`, `minimumStepSize`, and `maximumStepSize` to control the step size, and `relativeTolerance` for error control.
`oms_mav2` | Master Algorithm with Variable Step (v2) — an improved variable-step co-simulation master with enhanced error estimation. Supports the same settings as `oms_mav`.

Model-Exchange (ME) Solvers

Model-exchange solvers are ODE integrators used for FMUs that implement the model-exchange interface (ME FMUs). They integrate the continuous-time equations provided by the FMU.

Method | Description
--- | ---
`cvode` | CVODE — variable-step, variable-order ODE solver from the SUNDIALS suite. Suitable for stiff and non-stiff systems. Supports `initialStepSize`, `minimumStepSize`, `maximumStepSize`, and `relativeTolerance`.
`euler` | Explicit Euler — simple fixed-step explicit Euler integrator. Suitable for non-stiff systems. Controlled by `fixedStepSize`.

The following settings can be configured for each named solver:

Setting | Applies to | Description
--- | --- | ---
`relativeTolerance` | `oms_mav`, `oms_mav2`, `cvode` | Relative error tolerance used for step-size control.
`fixedStepSize` | `oms_ma`, `euler` | The fixed communication / integration step size.
`initialStepSize` | `oms_mav`, `oms_mav2`, `cvode` | The initial step size at the start of simulation.
`minimumStepSize` | `oms_mav`, `oms_mav2`, `cvode` | The minimum allowed step size.
`maximumStepSize` | `oms_mav`, `oms_mav2`, `cvode` | The maximum allowed step size.

Each FMU component in a system can be assigned one named solver configuration. The available solvers are filtered based on the FMI kind of the component:

- CS FMUs — only co-simulation solvers (`oms_ma`, `oms_mav`, `oms_mav2`) are available.

- ME FMUs — only model-exchange solvers (`cvode`, `euler`) are available.

- me+cs FMUs — all solvers are available.

If no solver is assigned to a component, the system default `oms_ma` is applied.

Example

The following example creates two named solver configurations — one using the fixed-step Euler method and one using the variable-step CVODE solver — and assigns them to individual components.

    from OMSimulator import SSP, CRef, Settings

    Settings.suppressPath = True

    model = SSP()

    # Add FMU resources
    model.addResource('../resources/Modelica.Blocks.Math.Add.fmu', new_name='resources/Add.fmu')
    model.addResource('../resources/Modelica.Blocks.Math.Gain.fmu', new_name='resources/Gain.fmu')

    # Instantiate components
    model.addComponent(CRef('default', 'Add1'), 'resources/Add.fmu')
    model.addComponent(CRef('default', 'Add2'), 'resources/Add.fmu')
    model.addComponent(CRef('default', 'Gain1'), 'resources/Gain.fmu')
    model.addComponent(CRef('default', 'Gain2'), 'resources/Gain.fmu')

    # Define solver configurations
    solver1 = {'name': 'solver1', 'method': 'euler', 'fixedStepSize': 1e-3}
    model.newSolver(solver1)

    solver2 = {'name': 'solver2', 'method': 'cvode', 'relativeTolerance': 1e-4,
               'initialStepSize': 1e-6, 'minimumStepSize': 1e-12, 'maximumStepSize': 0.001}
    model.newSolver(solver2)

    # Assign solvers to components
    model.setSolver(CRef('default', 'Add1'), 'solver1')
    model.setSolver(CRef('default', 'Add2'), 'solver2')
    model.setSolver(CRef('default', 'Gain1'), 'solver1')
    model.setSolver(CRef('default', 'Gain2'), 'solver2')

## 7.33. simulate

Runs the simulation of an instantiated SSP model.

> Notes:

>   - Must be called after initialize().

>   - Simulation uses start values from SSV files and any parameters overridden via setValue.

>   - Logged results are saved in the format defined by `setResultFile()` (commonly .mat).

>   - Simulation is performed on the active variant of the SSP model.

Syntax:

    simulate()

Example usage:

    from OMSimulator import SSP, CRef, Settings

    Settings.suppressPath = True

    # Load SSP and instantiate model
    model = SSP("SimpleSimulation2.ssp")
    instantiated_model = model.instantiate()

    # Apply result file and runtime parameters
    instantiated_model.setResultFile("SimpleSimulation6_res.mat")
    instantiated_model.setValue(CRef("default", "Gain1", "k"), 2.0)
    instantiated_model.setValue(CRef("default", "Gain1", "u"), 6.0)

    # Initialize before simulation
    instantiated_model.initialize()

    # Run the simulation
    instantiated_model.simulate()

## 7.34. terminate and delete

Terminates the simulation of an instantiated SSP model.It releases internal simulation resources, closes loggers, and ensures that the model state is marked as terminated.

Syntax:

    terminate()
    delete()

Example usage:

    from OMSimulator import SSP, CRef, Settings

    Settings.suppressPath = True

    # Load SSP and instantiate model
    model = SSP("SimpleSimulation2.ssp")
    instantiated_model = model.instantiate()

    # Apply result file and runtime parameters
    instantiated_model.setResultFile("SimpleSimulation6_res.mat")
    instantiated_model.setValue(CRef("default", "Gain1", "k"), 2.0)
    instantiated_model.setValue(CRef("default", "Gain1", "u"), 6.0)

    # Initialize and run simulation
    instantiated_model.initialize()
    instantiated_model.simulate()

    # Terminate the simulation
    instantiated_model.terminate()
    # Clean up resources
    instantiated_model.delete()