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:
The
gridsim.core.AbstractSimulationModule
that provides a simple way to add features to Gridsim.and
The
gridsim.core.AbstractSimulationElement
that provides a simple way to a features in already implementedgridsim.core.AbstractSimulationModule
.
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:
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.
- time (time, see
-
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.
- time (time, see
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 elementfriendly_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 busfriendly_name
.If there is interest for the geographical
position
of the element, defined by thegridsim.util.Position
class. Apart from the methods provided by the superclassAbstractElectricalElement
, this class provides the methodposition
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-portfriendly_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 powerQi
flowing into the branch at branch start, and active power Po and reactive powerQo
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 superclassAbstractElectricalElement
in giving access to the propertydelta_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 methodsgridsim.core.AbstractSimulationElement.reset()
to set thedelta_energy
property to 0 andgridsim.core.AbstractSimulationElement.update()
to update thedelta_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.
- time (time, see
-
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 thewrite_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 valueReturns: 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 allCallable
retrieve values, data are aggregated throughWriteParam.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 thisWriteParam
to return the next value. All the values are aggregated throughAggregator.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 theReadParam
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 allCallable
retrieve values, data are aggregated throughWriteParam.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 theThermalSimulator
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. SeeMaterial
. - 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