3. The Simulation Core

Warning

This section will be only interesting for Gridsim module developers, if you just use the library, you should be more interested by The Simulator General Use.

The following section describes the core of Gridsim hidden to the user but useful for developers. It consists into three parts :

Note

This part is the low level of the simulator, Gridsim also provides tools to help the development of modules or elements: The Simulation Tools.

3.1. The core module

Module author: Michael Clausen <clm@hevs.ch>

Code author: Michael Clausen <clm@hevs.ch>

Gridsim core module. Defines the interface to the different simulation modules and controls the sequence of the whole simulation.

This core module provides 2 interesting classes to add new features to Gridsim:

Despite the fact that the simulation module is completely free how to organize its internal simulation behavior, the normal case is shown in the following sequence diagram:

_images/model-sequence2.png

The gridsim.simulation.Simulator is simply an aggregator of several gridsim.core.AbstractSimulationModule. When the user calls the gridsim.simulation.Simulator.reset() the simulator simply calls the gridsim.core.AbstractSimulationModule.reset() of every loaded modules. Likewise, when the user calls the gridsim.simulation.Simulator.step() the simulator calls first the gridsim.core.AbstractSimulationModule.calculate() of every loaded modules then their gridsim.core.AbstractSimulationModule.update().

Finally the gridsim.simulation.Simulator.run() function of the simulator is only a set of sequential calls of gridsim.simulation.Simulator.step() incrementing the time.

class gridsim.core.AbstractSimulationModule(self)

Interface for simulation modules. Gridsim groups different simulation aspects into different Python modules in oder to separate and organize the implementations.

All Gridsim simulation modules have to implement the pure abstract methods of this interface class.

Example of a minimal simulation module:

from gridsim.unit import units
from gridsim.core import AbstractSimulationModule, AbstractSimulationElement
from gridsim.simulation import Simulator


# A very simple simulation element of the minimal simulation module example:
# tracks only the time.
class MinimalSimulationElement(AbstractSimulationElement):
    def __init__(self, friendly_name):
        # It is important to call the base class constructor with the
        # friendly name!
        super(MinimalSimulationElement, self).__init__(friendly_name)

        # Initialize all attributes within the __init__ method. Python standard
        # rules apply.
        self.val = None
        self._val = None

    # Called by the simulation module to reset this element.
    def reset(self):
        self.val = 0.
        self._val = 0.

    # Calculates the next state of the element. Note that we do not make the new
    # state public. This will be done in the update() method.
    def calculate(self, time, delta_time):
        self._val += delta_time

    # When all elements have been calculated the simulation is calling this
    # method on all elements in order to put their internal state outside.
    def update(self, time, delta_time):
        self.val = self._val


# A simulation module has to derive from AbstractSimulationModule and has to
# implement all methods.
class MinimalGridsimModuleAbstract(AbstractSimulationModule):

    # It is important that the module has an __init__() method without
    # parameters, as the modules were instantiated by the core simulator using
    # constructors without parameters.
    def __init__(self):
        # Prepare list of all contained elements. Here we have just one type
        # of elements.
        self.elements = []
        super(MinimalGridsimModuleAbstract, self).__init__()

    # This is a custom method of our minimal simulation module.
    def say_hello(self):
        print 'Hello'

    # Each module has to offer its own methods to add elements to the control
    # of the module.
    def add(self, element):
        # To avoid errors from library users we
        if not isinstance(element, MinimalSimulationElement):
            raise TypeError
        element.id = len(self.elements)
        self.elements.append(element)
        return element

    def attribute_name(self):
        return 'minimal'

    def reset(self):
        #print 'reset'
        for element in self.elements:
            element.reset()

    def calculate(self, time, delta_time):
        #print 'calculate, time=' + str(time) + ', delta_time=' + str(delta_time)
        for element in self.elements:
            element.calculate(time, delta_time)

    def update(self, time, delta_time):
        #print 'update, time=' + str(time) + ', delta_time=' + str(delta_time)
        for element in self.elements:
            element.update(time, delta_time)

Simulator.register_simulation_module(MinimalGridsimModuleAbstract)

sim = Simulator()
sim.minimal.say_hello()
el = sim.minimal.add(MinimalSimulationElement('test'))
sim.reset()
sim.run(1*units.seconds, 250*units.milliseconds)

attribute_name(self)

This method should return the module’s attribute name which can be used in order to get the reference to the module at the main simulation level. If for example this string is “electrical”, the reference to the simulation module can be retrieved using this name as the attribute passed to the simulation object.

If the user wants a reference to the simulation’s module, he uses:

sim = Simulation()
sim.<attribute_name>
Returns:Attribute name under which the module should be accessible on the main simulator object.
Return type:str
all_elements(self)

This method should return a list of all element contained in the module. The core simulator will use these lists in order to be able to retrieve objects or list of objects by certain criteria.

find(self, uid=None, friendly_name=None, element_class=None, instance_of=None, has_attribute=None)

Convenience method, already implemented for all modules in Gridsim.core. Finds all AbstractSimulationElement derived objects matching the given criteria by searching this Gridsim simulation module. Note that the method returns always a list of element, even if only a single instance is found. All parameters are optional, if find() will be called without any parameters, the list of all element in the actual simulation module will be returned.

Parameters:
  • uid (int) – ID of the element. Note that these ID’s are only unique for a given class , so you should never search just for an ID without specifying the class.
  • friendly_name (str) – The friendly name to search for.
  • element_class (type) – The exact class the element has to be an instance of. Superclasses are not considered.
  • instance_of (type) – The object has to be an instance of the given class, whereas this can be the superclass of the object too.
  • has_attribute (str) – The object should have an attribute with the given name. This can be used in order to find all objects that have a ‘power’ attribute.
Returns:

a list of all AbstractThermalElement

Return type:

list

reset(self)

The module has to reset/initialize his internal variables and to call the reset method of all simulation element it owns/manages.

update(self, time, delta_time)

The master simulation object executes this method on all registered simulation modules in order to finish a simulation step. The module has to update its external state/variables and/or call the update() method on all simulation element it owns/manages.

Parameters:
  • time (int or float in in second) – The actual simulation time.
  • delta_time (int or float in second) – The time period for which the update has to be done.
calculate(self, time, delta_time)

The master simulation object executes this method on all registered simulation modules in order to calculate a step during the simulation process. The module has to calculate its internal state and/or call the update() method on all simulation element it owns/manages.

Parameters:
  • time (int or float in in second) – The actual simulation time.
  • delta_time (int or float in second) – The time period for which the calculation has to be done.
end(self, time)

Inform all the module of the simulation that the simulation has reached the end

Parameters:time – end time
class gridsim.core.AbstractSimulationElement(self, friendly_name, element_id=None)

This class is the base for all element that can be part of the simulation. It basically defines the ‘friendly_name’ and the ‘id’ properties and all abstract methods an element should provide for to be part of a simulation in Gridsim.

Parameters:
  • friendly_name (str) – Friendly name for the element. Should be unique within the simulation module.
  • element_id (int) – ID of the element. Has to be unique per module and element class. Defaults to None.
You find an example of an AbstractSimulationElement in the
description of AbstractSimulationModule.
id = None
ID of the simulation element. Note that the ID has not to be unique
simulation wide, it has just to be unique in order a simulation module can retrieve the element using the ID and the class (base-class) information.
friendly_name = None
User friendly name of the simulation element. Note that the name has not
to be unique simulation wide, it has just to be unique in order a simulation module can retrieve the element using the friendly name and the class (base-class) information.
reset(self)

This method is called by the core simulator or the simulator module in order to reset the element internal data and state to initial values. Each simulation element has to implement this method without exception.

calculate(self, time, delta_time)

This method is called by the core simulator or the simulator module in order to calculate the element’s next state. Each element should have an internal and an external representation of its state and data. During the calculation step (this method) an element should only update its internal state and data, another method update() will be used to copy these values to the public properties/attributes.

Parameters:
  • time (time, see gridsim.unit) – The actual time of the simulator.
  • delta_time (time, see gridsim.unit) – The delta time for which the calculation has to be done.
update(self, time, delta_time)

This method will be called after all simulation element have done their calculation step. Each element should copy its internal state and data to the external accessible locations.

Parameters:
  • time (time, see gridsim.unit) – The actual time of the simulator.
  • delta_time (time, see gridsim.unit) – The delta time for which the update has to be done.

3.2. The electrical module

Module author: Gilbert Maitre <gilbert.maitre@hevs.ch>

class gridsim.electrical.core.AbstractElectricalElement(self, friendly_name)

This class is the base for all element that can take place in the electrical simulator. It is based on the general gridsim.core.AbstractSimulationElement. At initialization the user has to give the element friendly_name.

Parameters:friendly_name (str) – Friendly name for the element. Should be unique within the simulation module.
class gridsim.electrical.core.ElectricalBus(self, friendly_name, bus_type, position=Position())

This class is the base for all type of buses (i.e. nodes) in the considered electrical network. It is based on the general AbstractElectricalElement class. At initialization the user has to give the bus friendly_name.

If there is interest for the geographical position of the element, defined by the gridsim.util.Position class. Apart from the methods provided by the superclass AbstractElectricalElement, this class provides the method position for getting the position property of the object.

The chosen representation for bus electrical values is : active power (P), reactive power (Q), voltage amplitude (V), and voltage phase (Th). Their default values are None.

Parameters:
  • friendly_name (str) – Friendly name for the element. Should be unique within the simulation module.
  • bus_type (ElectricalBus.Type) – The type of the bus. Note that Slack Bus is automatically added to the simulation
  • position (Position) – Bus geographical position. Defaults to Position default value.
class Type
SLACK_BUS = <Type.SLACK_BUS: 0>

Type for slack (or swing) bus, i.e. the bus insuring that produced power is balanced to consumed power. Since it is unique, there is no input parameter for the slack bus.

PV_BUS = <Type.PV_BUS: 1>

Type for bus of type PV, i.e. bus where active power (P) and voltage amplitude (V) are given by the element(s) (generator) attached to the bus. Reactive power (Q) and voltage angle (Th) are then fixed by the network.

PQ_BUS = <Type.PQ_BUS: 2>

Type for bus of type PQ, i.e. bus where active power (P) and reactive power (Q) are given by the element(s) (load) attached to the bus. Voltage amplitude (V) and voltage angle (Th) are then fixed by the network.

ElectricalBus.type = None

The type of the electrical bus (in Slack, PV, PQ)

ElectricalBus.position = None

The bus geographical position.

ElectricalBus.P = None

The bus active power.

ElectricalBus.Q = None

The bus reactive power.

ElectricalBus.V = None

The bus voltage amplitude.

ElectricalBus.Th = None

The bus voltage angle.

ElectricalBus.reset(self)

Reset bus electrical values to their default values: None

class gridsim.electrical.core.AbstractElectricalTwoPort(self, friendly_name, X, R=0*units.ohm)

This class is the base for all electrical element that can be placed on a network branch, e.g. transmission lines, transformers, phase shifters,... It is based on the general AbstractElectricalElement class. At initialization the user has to give the two-port friendly_name.

Parameters:
  • friendly_name (str) – Friendly name for the element. Should be unique within the simulation module.
  • X (ohm, see gridsim.unit) – reactance of the element
  • R (ohm, see gridsim.unit) – resistance of the element
X = None

The reactance.

R = None

The resistance.

class gridsim.electrical.core.ElectricalNetworkBranch(self, friendly_name, from_bus, to_bus, two_port)

Class for a branch of an electrical network, i.e. connection between two buses (or nodes). It is oriented from one bus to the other. It is based on the general AbstractElectricalElement class. At initialization, in addition to the ‘friendly_name’, the bus it is starting from, and the bus it is going to, have to be given, together with the two-port, e.g. transmission line, transformer,... it is made of.

The chosen representation for branch electrical values is: active power Pi and reactive power Qi flowing into the branch at branch start, and active power Po and reactive power Qo flowing out of the branch at branch end. Their default values are None.

Parameters:
  • friendly_name (str) – Friendly name for the branch. Should be unique within the simulation module, i.e. different for example from the friendly name of a bus
  • from_bus (ElectricalBus) – Electrical bus from which branch is starting.
  • to_bus (ElectricalBus) – Electrical bus to which branch is going.
  • two_port (AbstractElectricalTwoPort) – Electrical two-port on the branch, e.g. transmission line, transformer, ...
Pij = None

Active power flowing into the branch from the from-bus terminal.

Qij = None

Reactive power flowing into the branch from the from-bus terminal.

Pji = None

Active power flowing into the branch from the to-bus terminal.

Qji = None

Reactive power flowing into the branch from the to-bus terminal.

from_bus_id

Gets the id of the bus the branch is starting from.

Returns:id of the bus the branch is starting from.
Return type:int
to_bus_id

Gets the id of the bus the branch is going to.

Returns:id of the bus the branch is going to.
Return type:int
reset(self)

Reset branch electrical values to their default : None

class gridsim.electrical.core.AbstractElectricalCPSElement(self, friendly_name)

CPS stands for “Consuming-Producing-Storing”.

This class is based on the AbstractElectricalElement class. It has the same initialization parameters : friendly_name. It differs from the superclass AbstractElectricalElement in giving access to the property delta_energy, which is the amount of energy consumed or stored (if positive), produced or un-stored (if negative) during a simulation step. The class also implements the methods gridsim.core.AbstractSimulationElement.reset() to set the delta_energy property to 0 and gridsim.core.AbstractSimulationElement.update() to update the delta_energy property to its current value.

Parameters:friendly_name (str) – Friendly name for the element. Should be unique within the simulation module.
delta_energy

Gets the element consumed energy during last simulation step. Getting a negative value means that. the element has produced energy.

Returns:energy consumed by element during last simulation step.
Return type:time, see gridsim.unit
reset(self)

Resets the element to its initial state.

update(self, time, delta_time)

Updates delta_energy property to ist current value.

Parameters:
  • time (time, see gridsim.unit) – The actual time of the simulator.
  • delta_time (time, see gridsim.unit) – The delta time for which the update has to be done.

3.3. The cyberphysical module

Module author: Dominique Gabioud <dominique.gabioud@hevs.ch>

Module author: Gillian Basso <gillian.basso@hevs.ch>

Module author: Yann Maret <yann.maret@hevs.ch>

Code author: Yann Maret <yann.maret@hevs.ch>

class gridsim.cyberphysical.core.Converter(self)

Converts the data to an other that is comprehensible by the physical device. Check the limit after conversion with de limit data passed in parameters.

call(self, datadict)

Converts the data before the writing system function

Parameters:datadict – data to convert for the physical device
Returns:the converted value (dict)
class gridsim.cyberphysical.core.Aggregator(self, limit_min, limit_max, default)

This interface aggregates a list of data passed in parameter. Check the limit after aggregation with de limit data passed in parameters.

Parameters:
  • limit_min – down limit
  • limit_max – upper limit
  • default – default value on conversion failure
call(self, datalist)

Aggregates all the value passed in datalist and return a single represented value

Parameters:datalist – list of value to be aggregated
Returns:a single represented value (list)
class gridsim.cyberphysical.core.Callable(self)

This interface is used to get the value requested by a cyberphysical system on Callable.get_value() function with the write_param type specified in parameter.

Warning

This interface does not extend object class. As its implementation should implements another class (e.g. ParamListener), a diamond problem could arise.

get_value(self, write_param)

This function is called by the simulation each time a new value is required with the write_param id.

Parameters:write_param – The id of the WriteParam associated with the return value
Returns:value that correspond to the given WriteParam
class gridsim.cyberphysical.core.WriteParam(self, write_param, info=None, aggregator=None)

It asks its Callable to provide data. When all Callable retrieve values, data are aggregated through WriteParam.aggregate().

Parameters:
  • write_param – single id for the write param
  • info – full id for the write param, same data passed on Callable.get_value() function.
  • aggregator – aggregate function call when
add_callable(self, callable)

Adds the given Callable.

Parameters:callable – callable to add to the list
get_value(self)

Asks all Callable added to this WriteParam to return the next value. All the values are aggregated through Aggregator.call() function.

Returns:aggregated value (int, float)
class gridsim.cyberphysical.core.ParamListener(self)

This interface is used to notify the data read on the cyberphysical system on ParamListener.notify_read_param() function with the ReadParam type specified in parameter.

Note

Implementations of this class also usually implement Callable.

See also

Callable for more information.

notify_read_param(self, read_param, data)

Notifies the listener that a new value from the simulator has been updated.

Parameters:
  • read_param – ParamType id of the data notified
  • data – data updated itself
class gridsim.cyberphysical.core.ReadParam(self, read_param, info)

This class holds the properties of a write param. It asks its Callable to provide data. When all Callable retrieve values, data are aggregated through WriteParam.aggregate().

Parameters:
  • read_param
  • info
add_listener(self, listener)

Adds the listener.

Parameters:listener – listener to add to list
notify_read_param(self, data)

Informs all ParamListener that a new data has been updated.

Parameters:data – updated data published to all listener register in the list

3.4. The thermal module

Module author: Gillian Basso (gillian.basso@hevs.ch)

Code author: Michael Clausen (clm@hevs.ch)

class gridsim.thermal.core.AbstractThermalElement(self, friendly_name, position=Position())

Base class of all AbstractSimulationElement that have to be in the ThermalSimulator

Parameters:
  • friendly_name (str) – User friendly name to give to the element.
  • position (Position) – The position of the thermal element. Defaults to [0,0,0].
position

Returns the thermal simulation element’s position.

Returns:Position of the element.
class gridsim.thermal.core.ThermalProcess(*args, **keywords)

__init__(self, friendly_name, thermal_capacity, initial_temperature, mass=1*units.kilogram, position=Position()):

The very basic element of a thermal simulation. A thermal process represents a closed thermal envelope like a room or a amount of matter which has an uniform thermal capacity and and stores an amount of thermal energy resulting in a temperature. Those thermal processes can be coupled by ThermalCoupling element.

Parameters:
  • friendly_name (str) – The name to give to the thermal process.
  • thermal_capacity (heat_capacity, see gridsim.unit) – The thermal capacity of the process. See Material.
  • initial_temperature (kelvin, see gridsim.unit) – The initial temperature of the process in degrees.
  • mass (mass, see gridsim.unit) – the mass of the element
  • position (Position) – The position of the process.
temperature = None

The temperature of the process.

thermal_energy = None

The thermal energy stored inside the thermal process.

add_energy(self, delta_energy)

Adds a given amount of energy to the thermal process.

Parameters:delta_energy (joule, see gridsim.unit) – The energy to add to the thermal process.
reset(self)

AbstractSimulationElement implementation

calculate(self, time, delta_time)

AbstractSimulationElement implementation

Parameters:
  • time (float in second) – The actual time of the simulator.
  • delta_time (float in second) – The delta time for which the calculation has to be done.
update(self, time, delta_time)

AbstractSimulationElement implementation

Parameters:
  • time (float in second) – The actual time of the simulator.
  • delta_time (float in second) – The delta time for which the calculation has to be done.
static room(*args, **keywords)

room(friendly_name, surface, height, initial_temperature=293.15, position=Position()):

Returns the thermal process of a room filled with air and the given surface, height and initial temperature.

Parameters:
  • friendly_name (str) – Friendly name to give to the returned object.
  • surface (square_meter, see gridsim.unit) – The room’s surface.
  • height (meter, see gridsim.unit) – The room’s height.
  • initial_temperature (kelvin, see gridsim.unit) – The initial temperature inside the room.
  • position (Position) – The position of the process.
Returns:

A new thermal process object representing the room or None on error.

static solid(*args, **keywords)

solid(friendly_name, specific_thermal_capacity, mass, initial_temperature=293.15, position=Position()):

Returns the thermal process of a solid body and the given mass, initial temperature.

Parameters:
  • friendly_name (str) – Friendly name to give to the returned object.
  • specific_thermal_capacity (thermal_capacity, see gridsim.unit) – The thermal capacity.
  • mass (mass, see gridsim.unit) – The solid’s mass.
  • initial_temperature (temperature, see gridsim.unit) – The initial temperature of the solid.
  • position (Position) – The position of the solid.
Returns:

A new thermal process object representing the solid or None on error.

class gridsim.thermal.core.ThermalCoupling(self, friendly_name, thermal_conductivity, from_process, to_process, contact_area=1*units.metre**2, thickness=1*units.metre)

A thermal coupling connects two thermal processes allowing them to exchange thermal energy.

Parameters:
  • friendly_name (str) – The friendly name to identify the element.
  • thermal_conductivity (thermal conductivity, see gridsim.unit) – The thermal conductivity of the thermal element.
  • from_process (ThermalProcess) – The first process coupled process.
  • to_process (ThermalProcess) – The second process coupled process.
  • contact_area (square_meter, see gridsim.unit) – The size of the contact area process.
  • thickness (meter, see gridsim.unit) – the thickness of the contact area process.
thermal_conductivity = None

The thermal conductivity of the coupling in W/K.

power = None

Thermal power that gets conducted by the thermal coupling.

contact_area
thickness
reset(self)

AbstractSimulationElement implementation

calculate(self, time, delta_time)

AbstractSimulationElement implementation

update(self, time, delta_time)

AbstractSimulationElement implementation