Skip to content
Snippets Groups Projects
Commit cec05aa2 authored by Pedro L. Magalhães's avatar Pedro L. Magalhães
Browse files

Reivsed PT simplification. Solver issues pending.

parent 7130cff9
No related branches found
No related tags found
1 merge request!5Revised ResourcePrice class and methods. Added tests for problem...
Showing with 5728 additions and 13165 deletions
......@@ -6,6 +6,7 @@ import numpy as np
# local libraries, internal
from .dynsys import DynamicSystem
from .signal import Signal, FixedSignal
from .time import TimeFrame
# *****************************************************************************
# *****************************************************************************
......@@ -16,10 +17,16 @@ from .signal import Signal, FixedSignal
class Converter:
"""A class for modular dynamic systems in an integrated energy system."""
# input options:
# 1) DynamicSystem object
# 2) Matrices
def __init__(
self,
# system information
sys: DynamicSystem,
# time frame
time_frame: TimeFrame,
# initial conditions
initial_states: np.array,
# optimisation-relevant parameters
......
# -*- coding: utf-8 -*-
"""
Created on Wed Nov 17 13:04:53 2021
@author: pmede
"""
# standard libraries
# local libraries, external
import numpy as np
from scipy.linalg import expm, inv
# local libraries, internal
......@@ -22,11 +13,14 @@ from scipy.linalg import expm, inv
# TODO: ensure it is compatible with stateless systems
class DynamicSystem:
"""A class for dynamic systems described using A, B, C and D matrices."""
# use cases:
# 1) simulate
# 2) optimise
# input options:
# 1) the A, B, C and D matrices are provided: inputs, states and outputs (general case)
# 2) the A and B matrices are provided: inputs and states (no outputs)
# 3) the D matrix is provided: inputs and outputs (no states)
......@@ -1192,6 +1186,25 @@ class OutputlessSystem(DynamicSystem):
return DynamicSystem.simulate(self, U=U, X0=X0)
# *****************************************************************************
# *****************************************************************************
class DiscretisedDynamicSystem(DynamicSystem):
# workflow:
# 1) define the system
# 2) discretise
# 3) simulate response
# what should it do?
# 1) discretise based on (q,k) tuples
# 2) simulate response
#
def __init__(self):
pass
# *****************************************************************************
# *****************************************************************************
......@@ -22,7 +22,6 @@ from .resource import are_prices_time_invariant
# *****************************************************************************
# *****************************************************************************
class Arcs:
"""A class for arc technologies in a network."""
......@@ -134,7 +133,7 @@ class Arcs:
"""Returns True if the arc has a constant efficiency."""
if self.has_proportional_losses():
# proportional losses
# has proportional losses
if self.is_isotropic():
# is isotropic
if len(set(self.efficiency.values())) == 1:
......
This diff is collapsed.
......@@ -227,11 +227,26 @@ class ResourcePrice:
# *************************************************************************
# *************************************************************************
def __eq__(self, o) -> bool:
"""Returns True if a given ResourcePrice is equivalent to another."""
return self.is_equivalent(o)
def __hash__(self):
return hash(
tuple((
self.number_segments(),
tuple(self.prices),
tuple(self.volumes)
))
)
# *************************************************************************
# *************************************************************************
# *****************************************************************************
# *****************************************************************************
# TODO: method to determine if qpk-keyed dict is time-invariant per q and p
def are_prices_time_invariant(resource_prices_qpk: dict) -> bool:
"""Returns True if all prices are identical per time interval."""
# check if there is only one or no (q,p,k) entry
......
......@@ -307,3 +307,14 @@ class EconomicTimeFrame(TimeFrame):
# *****************************************************************************
# *****************************************************************************
def entries_are_invariant(data: dict, keys: tuple = None) -> bool:
"Returns True if all (identified) entries in the dict are identical."
return set(
value for key, value in data.items()
) if type(keys) == type(None) else set(
value for key, value in data.items() if key in keys
)
# *****************************************************************************
# *****************************************************************************
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -5,9 +5,6 @@ import random
from topupheat.pipes.single import StandardisedPipeDatabase
from topupheat.common.fluids import FluidDatabase # , Fluid
from examples_esipp_network import examples as examples_esipp_network
from examples_esipp_problem import examples as examples_esipp_problem
from examples_esipp import examples as examples_esipp
from examples_signal import examples as examples_signal
# ******************************************************************************
......@@ -17,17 +14,6 @@ from examples_signal import examples as examples_signal
def test_suite():
test_examples_dynsys = True
# test_examples_dynsys = False
test_examples_esipp_network = True
# test_examples_esipp_network = False
test_examples_esipp_problem = True
# test_examples_esipp_problem = False
test_examples_esipp = True
# test_examples_esipp = False
test_examples_signal = True
# test_examples_signal = False
......@@ -124,44 +110,6 @@ def test_suite():
# load osm/osmnx data
# **************************************************************************
# **************************************************************************
# esipp-network
if test_examples_esipp_network:
print("'esipp-network': testing about to start...")
examples_esipp_network()
print("'esipp-network': testing complete.")
# **************************************************************************
# esipp-problem
if test_examples_esipp_problem:
print("'esipp-problem': testing about to start...")
examples_esipp_problem(solver, solver_options, init_aux_sets=False)
examples_esipp_problem(solver, solver_options, init_aux_sets=True)
print("'esipp-problem': testing complete.")
# **************************************************************************
# esipp
if test_examples_esipp:
print("'esipp': testing about to start...")
examples_esipp(solver, solver_options, seed_number, init_aux_sets=False)
examples_esipp(solver, solver_options, seed_number, init_aux_sets=True)
print("'esipp-problem': testing complete.")
# **************************************************************************
# signal
......
......@@ -273,6 +273,7 @@ def method_full_converter(time_step_durations: list):
# create a converter
cvn1 = cvn.Converter(
sys=ds,
time_frame=None,
initial_states=x0,
turn_key_cost=3,
inputs=inputs,
......@@ -281,9 +282,7 @@ def method_full_converter(time_step_durations: list):
)
# get the dictionaries
(a_innk, b_inmk, c_irnk, d_irmk, e_x_ink, e_y_irk) = cvn1.matrix_dictionaries(
"cvn1"
)
(a_innk, b_inmk, c_irnk, d_irmk, e_x_ink, e_y_irk) = cvn1.matrix_dictionaries()
# TODO: check the dicts
......
......@@ -15,157 +15,6 @@ import src.topupopt.problems.esipp.dynsys as dynsys
class TestDynsys:
# *************************************************************************
# *************************************************************************
# seed_number = random.randint(1,int(1e5))
# print_outputs = True
# # with states and outputs
# # test multi-ODE, multi-output dynamic systems while integrating outputs
# examples_dynsys_multiode_multiout(True, print_outputs, seed_number)
# # test multi-ODE, multi-output dynamic systems without integrating outputs
# examples_dynsys_multiode_multiout(False, print_outputs, seed_number)
# # test single ODE, multi-output dynamic systems while integrating outputs
# examples_dynsys_singleode_multiout(True, print_outputs, seed_number)
# # test single ODE, multi-output dynamic systems without integrating outputs
# examples_dynsys_singleode_multiout(False, print_outputs, seed_number)
# # test multi-ODE, single-output dynamic systems while integrating outputs
# examples_dynsys_multiode_multiout(True, print_outputs, seed_number, 1)
# # test multi-ODE, single-output dynamic systems without integrating outputs
# examples_dynsys_multiode_multiout(False, print_outputs, seed_number, 1)
# # test single-ODE, single-output dynamic systems while integrating outputs
# examples_dynsys_singleode_multiout(True, print_outputs, seed_number, 1)
# # test single-ODE, single-output dynamic systems without integrating outputs
# examples_dynsys_singleode_multiout(False, print_outputs, seed_number, 1)
# # *************************************************************************
# # outputless
# # test single-ODE, outputless dynamic systems while integrating outputs
# examples_dynsys_singleode_multiout(True, print_outputs, seed_number, 0)
# # test multi-ODE, outputless dynamic systems while integrating outputs
# examples_dynsys_multiode_multiout(True, print_outputs, seed_number, 0)
# # test single-ODE, outputless dynamic systems without integrating outputs
# examples_dynsys_singleode_multiout(False, print_outputs, seed_number, 0)
# # test multi-ODE, outputless dynamic systems without integrating outputs
# examples_dynsys_multiode_multiout(False, print_outputs, seed_number, 0)
# # outputless system via dynsys subclass
# example_outputless_system_object()
# # *************************************************************************
# # stateless
# # test stateless, single-output dynamic systems while integrating outputs
# examples_dynsys_stateless_multiout(True, print_outputs, seed_number, 1)
# # test stateless, multi-output dynamic systems without integrating outputs
# examples_dynsys_stateless_multiout(False, print_outputs, seed_number, 2)
# # stateless system via dynsys subclass
# example_stateless_system_object(True)
# example_stateless_system_object(False)
# # *************************************************************************
# # *************************************************************************
# # trigger errors
# # test stateless, outputless dynamic systems while integrating outputs
# number_errors = 0
# try:
# examples_dynsys_stateless_multiout(True, False, seed_number, 0)
# except Exception:
# number_errors += 1
# assert number_errors == 1
# # test stateless, outputless dynamic systems without integrating outputs
# number_errors = 0
# try:
# examples_dynsys_stateless_multiout(False, False, seed_number, 0)
# except Exception:
# number_errors += 1
# assert number_errors == 1
# # test negative time duration
# example_incorrect_time_step_durations()
# # test unrecognised matrix formats
# example_unrecognised_matrix_formats()
# # different matrix sizes for the same problem, all other things being equal
# example_varying_matrix_sizes(True)
# example_varying_matrix_sizes(False)
# # test multiple A matrices and multiple non-matching time intervals
# example_nonmatching_time_steps_and_matrices()
# # test non-square A matrices
# example_nonsquare_A_matrices()
# # test incompatible A and B matrices (different number of rows)
# example_incompatible_AB_matrices()
# # test incompatible C and D matrices (different number of rows)
# example_incompatible_CD_matrices()
# # test incompatible A and C matrices (different number of columns)
# example_incompatible_AC_matrices()
# # test incompatible B and D matrices (different number of columns)
# example_incompatible_BD_matrices()
# # trigger incorrect input signal format error when simulating
# example_single_time_step_model_incorrect_inputs()
# # TODO: test only some matrices as being time invariant
# *************************************************************************
# *************************************************************************
......@@ -1642,11 +1491,8 @@ def method_dynsys_singleode_multiout(integrate_outputs: bool, number_outputs: in
# generate time invariant problem
# data
Ci, Ria, Aw, min_rel_heat, x0 = get_single_ode_model_data()
# matrices
(A_matrix, B_matrix, C_matrix, D_matrix) = single_node_model(
Ci, Ria, Aw, min_rel_heat
)
......
......@@ -26,39 +26,6 @@ from src.topupopt.data.misc.utils import generate_pseudo_unique_key
# TODO: add test for directed arcs between import and export nodes with static losses
class TestNetwork:
# *************************************************************************
# *************************************************************************
def test_tree_topology(self):
# create a network object with a tree topology
tree_network = binomial_tree(3, create_using=MultiDiGraph)
network = Network(tree_network)
for edge_key in network.edges(keys=True):
arc = ArcsWithoutLosses(
name=str(edge_key),
capacity=[5, 10],
minimum_cost=[3, 6],
specific_capacity_cost=0,
capacity_is_instantaneous=False,
)
network.add_edge(*edge_key, **{Network.KEY_ARC_TECH: arc})
# assert that it does not have a tree topology
assert not network.has_tree_topology()
# select all the nodes
for edge_key in network.edges(keys=True):
network.edges[edge_key][Network.KEY_ARC_TECH].options_selected[0] = True
# assert that it has a tree topology
assert network.has_tree_topology()
# *************************************************************************
# *************************************************************************
......@@ -1931,7 +1898,6 @@ class TestNetwork:
# *************************************************************************
def test_network_disallowed_cases(self):
# *********************************************************************
net = Network()
......@@ -2035,7 +2001,6 @@ class TestNetwork:
error_triggered = True
assert error_triggered
# *********************************************************************
# *********************************************************************
# trigger errors using non-identified nodes
......@@ -2199,6 +2164,40 @@ class TestNetwork:
# *************************************************************************
# *************************************************************************
def test_tree_topology(self):
# create a network object with a tree topology
tree_network = binomial_tree(3, create_using=MultiDiGraph)
network = Network(tree_network)
for edge_key in network.edges(keys=True):
arc = ArcsWithoutLosses(
name=str(edge_key),
capacity=[5, 10],
minimum_cost=[3, 6],
specific_capacity_cost=0,
capacity_is_instantaneous=False,
)
network.add_edge(*edge_key, **{Network.KEY_ARC_TECH: arc})
# assert that it does not have a tree topology
assert not network.has_tree_topology()
# select all the nodes
for edge_key in network.edges(keys=True):
network.edges[edge_key][Network.KEY_ARC_TECH].options_selected[0] = True
# assert that it has a tree topology
assert network.has_tree_topology()
# *************************************************************************
# *************************************************************************
def test_pseudo_unique_key_generation(self):
# create network
......@@ -2251,5 +2250,81 @@ class TestNetwork:
error_triggered = True
assert error_triggered
# *************************************************************************
# *************************************************************************
def test_imp_exp_static_losses(self):
# assessment
q = 0
# 4 nodes: one import, one export, two supply/demand nodes
mynet = Network()
# import node
imp_node_key = generate_pseudo_unique_key(mynet.nodes())
imp_prices = {
qpk: ResourcePrice(
prices=0.5,
volumes=None,
)
for qpk in [(0,0,0),(0,0,1),(0,1,0),(0,1,1)]
}
mynet.add_import_node(
node_key=imp_node_key,
prices=imp_prices
)
# export node
exp_node_key = generate_pseudo_unique_key(mynet.nodes())
exp_prices = {
qpk: ResourcePrice(
prices=1.5,
volumes=None,
)
for qpk in [(0,0,0),(0,0,1),(0,1,0),(0,1,1)]
}
mynet.add_export_node(
node_key=exp_node_key,
prices=exp_prices,
)
# add arc with fixed losses from import node to export
arc_tech_IE_fix = Arcs(
name="IE_fix",
# efficiency=[1, 1, 1, 1],
efficiency={(q, 0): 1, (q, 1): 1},
efficiency_reverse=None,
validate=False,
capacity=[0.5, 1.0, 2.0],
minimum_cost=[5, 5.1, 5.2],
specific_capacity_cost=1,
capacity_is_instantaneous=False,
# static_losses=[
# [0.10, 0.15, 0.20, 0.25],
# [0.15, 0.20, 0.25, 0.30],
# [0.20, 0.25, 0.30, 0.35]]
static_loss={
(0, q, 0): 0.10,
(0, q, 1): 0.15,
(1, q, 0): 0.15,
(1, q, 1): 0.20,
(2, q, 0): 0.20,
(2, q, 1): 0.25,
},
)
mynet.add_directed_arc(
node_key_a=imp_node_key, node_key_b=exp_node_key, arcs=arc_tech_IE_fix
)
error_raised = False
try:
# identify node types
mynet.identify_node_types()
except ValueError:
error_raised = True
assert error_raised
# *****************************************************************************
# *****************************************************************************
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment