Reference#

This module allows a portion of an EMTDC simulation to be run in a Python process.

Example:

import mhi.cosim

with mhi.cosim.cosimulation("config.cfg") as cosim:
   channel = cosim.channel(1)

   time = 0
   time_step = 0.001
   run_time = 1.0

   x = ...
   y = ...
   z = ...

   while time <= run_time:

       a = ...
       b = ...
       c = ...
       d = ...

       time += time_step
       channel.set_values(a, b, c, d)
       channel.send(time)

       if time <= run_time:
           x, y, z = channel.get_values(time)

Context Management#

mhi.cosim.initialize_cfg(config_file)#

Call this function to start the Co-Simulation Process. Only call this function once per process. This function accepts the host and port specified in a configuration file.

mhi.cosim.finalize()#

Call this function to end the Co-Simulation process.

mhi.cosim.cosimulation(config_file)#

This function returns a context managed object suitable for use in a with statement.

Parameters:

config_file – the cosimulation configuration file.

Instead of writing:

try:
    mhi.cosim.initialize_cfg(config_file)
    channel = mhi.cosim.Channel(1)
    ...
finally:
    mhi.cosim.finalize()

A with statement may be used:

with mhi.cosim.cosimulation(config_file) as cosim:
    channel = cosim.find_channel(1)
    ...

Cosimulation#

class mhi.cosim.Cosimulation#

A shim class to support a with statement that returns an object that manages intialization and finalization of the cosimulation library.

channel(channel_id: int) Channel#

Return a channel object identified by channel_id

Parameters:

channel_id (int) – channel identifier

named_channel(channel_id: int, recv_names, send_names) NamedChannel#

Return a channel object identified by channel_id, with the given named recv and send subchannels.

Parameters:
  • channel_id (int) – channel identifier

  • recv_names – a sequence of strings such as ['a', 'b']. Alternatively, recv_names can be a single string with each name separated by whitespace and/or commas, for example 'a b' or 'a, b'.

  • send_names – a sequence of strings such as ['x', 'y']. Alternatively, send_names can be a single string with each name separated by whitespace and/or commas, for example 'x y' or 'x, y'.

Channel#

class mhi.cosim.Channel#

A channel object for a given channel_id

Example:

channel = mhi.cosim.Channel(1)
get_value(time, index)#

Retrieve the value on the given index of the channel for the time indicated.

This call will block until the sender publishes the channel values for the requested time.

0 <= index < Channel.recv_size

get_values(time)#

Retrieve all values of the channel for the time indicated.

This call will block until the sender publishes the channel values for the requested time.

Returns Channel.recv_size values.

id#

The channel id (read-only)

recv_size#

Number of channel values received from the remote end. (read-only)

send(time)#

Send the stored values to the remote end, indicating these values become valid when the remote end reaches the given time.

send_size#

Number of channel values sent to the remote end. (read-only)

set_value(value, index)#

Store a value in the given index for sending to the remote end. 0 <= index < Channel.send_size

set_values(*values)#

Set all values of the channel.

Raise an error if the number of values given is not Channel.send_size.

NamedChannel#

class mhi.cosim.NamedChannel(channel_id, recv_names, send_names)#

A communication channel with subchannels identified usings names instead of numeric indices.

Parameters:
  • channel_id (int) – channel identifier

  • recv_names – a sequence of strings such as ['a', 'b']. Alternatively, recv_names can be a single string with each name separated by whitespace and/or commas, for example 'a b' or 'a, b'.

  • send_names – a sequence of strings such as ['x', 'y']. Alternatively, send_names can be a single string with each name separated by whitespace and/or commas, for example 'x y' or 'x, y'.

The following code, using subchanel indices 0 & 1:

with mhi.cosim.cosimulation(config_file) as cosim:
    channel = cosim.channel(1)

    time = 0.0
    time_step = 0.001
    run_time = 1.0

    r_speed = 0

    while time <= run_time:
        torque = ...
        wind_speed = ...

        time += time_step;

        channel.set_value(torque, 0)
        channel.set_value(wind_speed, 1)
        channel.send(time)

        if time <= run_time:
            r_speed = channel.get_value(time, 0)

could become:

with mhi.cosim.cosimulation(config_file) as cosim:
    channel = cosim.named_channel(1, "r_speed", "torque, wind_speed")

    time = 0.0
    time_step = 0.001
    run_time = 1.0

    r_speed = 0

    while time <= run_time:
        channel.torque = ...
        channel.wind_speed = ...

        time += time_step;
        channel.send(time)

        if time <= run_time:
            channel.get_values(time)
            r_speed = channel.r_speed
get_values(time: float) None#

Wait for simulation to reach time, and update the named subchannels with the values received from the remote end.

This function blocks until the remote end has reached and transmitted value for the given time.

Parameters:

time (float) – next simulation time

send(time: float) None#

Send to the remote end stored subchannel values, indicating they are valid up to the given time.

Parameters:

time (float) – time stored values are valid until.