spine-tools / Spine-Toolbox

Spine Toolbox is an open source Python package to manage data, scenarios and workflows for modelling and simulation. You can have your local workflow, but work as a team through version control and SQL databases.
https://www.tools-for-energy-system-modelling.org/
GNU Lesser General Public License v3.0
66 stars 17 forks source link

Relationships between relationships (or multi dimensional entities where dimensions are multi dimensional entities) #2070

Open DillonJ opened 1 year ago

DillonJ commented 1 year ago

In SpineOpt we create a flow from a unit to a node by specifiying a unit__to_node relationship. Also, we create a flow to a unit from a node by specifiying a unit__from_node relationship. These relationships are multidimensional entities and correspond directly to a flow variable in the optimisation model.

To create a constraint between two flows (for example an efficiency or a heat rate, or an emission production rate, for example) we define a unit__node__node relationship and then create a parameter value for that relationship (e.g fix_ratio_out_in_unit_flow). When the user goes to create this relationship they will have to select each node from the full list of nodes available in the model whereas ideally the user should be able to select only from the nodes already related to a unit via unit__from_node or unit__to_node. The underlying issue is that we have used a three dimensional relationship to represent what is really a relationhip between two entities. In this case the entities are unit__from_node or unit__from_node entities.

The question is, does the current data structure support multi-dimensional entities where each of the entities are themselves multi-dimensional?

It would be nice to think this through a little - some questions:

jkiviluo commented 1 year ago

As far as I can see, this would introduce recursive structure into Spine Toolbox. One could then have an entity_class inside an entity_class inside an entity_class... Naturally we could choose to limit to just doing it once. Even in that case, database queries would probably need to fetch the first layer first, interpret that and then have an another query to get the second layer. The same would probably apply for interfaces too? I don't know how difficult that would be, @manuelma?

manuelma commented 1 year ago

If we do it this way, we'd need to create unit__from_node__to_node, unit__from_node__from_node, unit__to_node__to_node, and unit__to_node__from_node - so I don't think it's a very good idea. Or am I missing something?

DillonJ commented 1 year ago

If we do it this way, we'd need to create unit__from_node__to_node, unit__from_node__from_node, unit__to_node__to_node, and unit__to_node__from_node - so I don't think it's a very good idea. Or am I missing something?

Yes, but there would be fewer parameters since the unit__to_node/from_node relationship already has the information about whether the flow is an input or an output, we wouldn't need to have every combination of directions (in/out in/in out/out out/in)) and at least the relationships are more explicit.

Also, quite significantly, it would allow us to create constraints between flows of different units without having to use user constraints