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

Revised classes for investments in generic arcs and in district heating...

Revised classes for investments in generic arcs and in district heating trenches. Updated converter and dynsys tests.
parent bd660a80
No related branches found
No related tags found
1 merge request!5Revised ResourcePrice class and methods. Added tests for problem...
...@@ -10,9 +10,12 @@ from numbers import Real ...@@ -10,9 +10,12 @@ from numbers import Real
from topupheat.pipes.trenches import SupplyReturnPipeTrench from topupheat.pipes.trenches import SupplyReturnPipeTrench
# local, internal imports # local, internal imports
from ...data.finance.invest import Investment
from ...problems.esipp.network import ArcsWithoutProportionalLosses from ...problems.esipp.network import ArcsWithoutProportionalLosses
# TODO: add way to define polarity of cash flows
from ...data.finance.utils import ArcInvestments
#****************************************************************************** #******************************************************************************
#****************************************************************************** #******************************************************************************
...@@ -31,6 +34,7 @@ KEY_HHT_STD_PIPES = 'pipe_tuple' ...@@ -31,6 +34,7 @@ KEY_HHT_STD_PIPES = 'pipe_tuple'
# ***************************************************************************** # *****************************************************************************
class PipeTrenchOptions(ArcsWithoutProportionalLosses): class PipeTrenchOptions(ArcsWithoutProportionalLosses):
"A class for defining investments in district heating trenches."
def __init__( def __init__(
self, self,
...@@ -207,146 +211,197 @@ class PipeTrenchOptions(ArcsWithoutProportionalLosses): ...@@ -207,146 +211,197 @@ class PipeTrenchOptions(ArcsWithoutProportionalLosses):
# ***************************************************************************** # *****************************************************************************
# ***************************************************************************** # *****************************************************************************
class ExistingPipeTrench(PipeTrenchOptions): class PipeTrenchInvestments(ArcInvestments, PipeTrenchOptions):
"A class for defining investments in district heating trenches."
def __init__(self, option_selected: int, **kwargs):
PipeTrenchOptions.__init__(
self,
minimum_cost=[0 for i in range(kwargs['trench'].number_options())],
**kwargs)
# define the option that already exists
self.options_selected[option_selected] = True
# *****************************************************************************
# *****************************************************************************
# TODO: add way to define polarity of cash flows
class PipeTrenchInvestmentOptions(PipeTrenchOptions):
def __init__( def __init__(
self, self,
discount_rates: list, # 1 per period trench: SupplyReturnPipeTrench,
# extra name: str,
investment_besides_pipes: float or list, # length: float,
investment_period: float or list, investments: tuple,
investment_longevity: float or list, static_loss: dict = None,
commissioning_delay_after_investment: float or list, specific_capacity_cost: float or list = None,
fixed_operational_cash_flows: float or list = None, capacity_is_instantaneous: bool = False,
start_operational_cash_flows: float or list = None, unit_conversion_factor: float = 1.0,
salvage_value_method: str = 'other',
**kwargs):
# prepare the instance as usual: minimum cost = cost of pipes
PipeTrenchOptions.__init__(
self,
**kwargs **kwargs
):
# store the unit conversion
self.unit_conversion_factor = unit_conversion_factor
# keep the trench object
self.trench = trench
# keep the trench length
self.length = (
[length for i in range(trench.number_options())]
if trench.vector_mode else
length
)
# determine the rated heat capacity
rhc = trench.rated_heat_capacity(
unit_conversion_factor=unit_conversion_factor
) )
# investments # initialise the object using the mother class
self.invs = [ ArcInvestments.__init__(
Investment(discount_rates=discount_rates) self,
for i in range(self.number_options()) investments=investments,
] name=name,
# add cost of pipes (self.minimum cost) and other items efficiency=None,
self.add_investment( efficiency_reverse=None,
investment=list( static_loss=static_loss,
map(sum,zip(self.minimum_cost, investment_besides_pipes)) capacity=[rhc] if isinstance(rhc, Real) else rhc,
specific_capacity_cost=(
0
if type(specific_capacity_cost) == type(None) else
specific_capacity_cost
), ),
investment_period=investment_period, capacity_is_instantaneous=False,
investment_longevity=investment_longevity, validate=False
commissioning_delay_after_investment=(
commissioning_delay_after_investment),
salvage_value_method=salvage_value_method
) )
# define the minimum cost as the net present value of the investments
self.update_minimum_cost()
# ************************************************************************* # # *************************************************************************
# ************************************************************************* # # *************************************************************************
# def set_minimum_cost(self, minimum_cost = None):
# # minimum arc cost
# # if no external minimum cost list was provided, calculate it
# if type(minimum_cost) == type(None):
# # use the specific pipe cost that features in the database
# if self.trench.vector_mode:
# # multiple options
# self.minimum_cost = tuple(
# (pipe.sp*length # twin pipes: one twin pipe
# if self.trench.twin_pipes else
# pipe.sp*length*2) # single pipes: two single pipes
# for pipe, length in zip(
# self.trench.supply_pipe,
# self.length
# )
# )
# else: # only one option
# self.minimum_cost = (self.trench.supply_pipe.sp*self.length,)
# else: # use an external minimum cost
# self.minimum_cost = tuple(minimum_cost)
# # *************************************************************************
# # *************************************************************************
# def set_capacity(self, **kwargs):
# # retrieve the rated heat capacity
# rhc = self.trench.rated_heat_capacity(**kwargs)
# if self.trench.vector_mode:
# # multiple options, rhc is already a list of values
# self.capacity = rhc
# else:
# # one option, rhc is one value
# self.capacity = (rhc,)
# # *************************************************************************
# # *************************************************************************
# def set_static_losses(
# self,
# scenario_key,
# ground_thermal_conductivity: float or list,
# ground_air_heat_transfer_coefficient: float or list,
# time_interval_duration: float or list,
# temperature_surroundings: float or list,
# length: float or list = None,
# unit_conversion_factor: float = None,
# **kwargs):
# hts = self.trench.heat_transfer_surroundings(
# ground_thermal_conductivity=ground_thermal_conductivity,
# ground_air_heat_transfer_coefficient=(
# ground_air_heat_transfer_coefficient),
# time_interval_duration=time_interval_duration,
# temperature_surroundings=temperature_surroundings,
# length=(
# self.length
# if type(length) == type(None) else
# length
# ),
# unit_conversion_factor=(
# self.unit_conversion_factor
# if type(unit_conversion_factor) == type(None) else
# unit_conversion_factor
# ),
# **kwargs)
# if self.trench.vector_mode:
# # multiple options: hts is a vector
# if (hasattr(self, "static_loss") and
# type(self.static_loss) != type(None)):
# # update the static loss dictionary
# if type(hts[0]) == list:
# # multiple time intervals
# self.static_loss.update({
# (h, scenario_key, k): hts[h][k]
# for h, hts_h in enumerate(hts)
# for k, hts_hk in enumerate(hts_h)
# })
# else: # not a list: one time interval
# self.static_loss.update({
# (h, scenario_key, 0): hts[h]
# for h, hts_h in enumerate(hts)
# })
# else:
# # no static loss dictionary, create it
# if type(hts[0]) == list:
# # multiple time intervals
# self.static_loss = {
# (h, scenario_key, k): hts[h][k]
# for h, hts_h in enumerate(hts)
# for k, hts_hk in enumerate(hts_h)
# }
# else: # not a list: one time interval
# self.static_loss = {
# (h, scenario_key, 0): hts[h]
# for h, hts_h in enumerate(hts)
# }
# else:
# # one option: hts might be a number
# if (hasattr(self, "static_loss") and
# type(self.static_loss) != type(None)):
# # update the static loss dictionary
# if not isinstance(hts, Real):
# # multiple time intervals
# self.static_loss.update({
# (0, scenario_key, k): hts[k]
# for k, hts_k in enumerate(hts)
# })
# else: # not a list: one time interval
# self.static_loss.update({
# (0, scenario_key, 0): hts
# })
# else:
# # no static loss dictionary, create it
# if not isinstance(hts, Real):
# # multiple time intervals
# self.static_loss = {
# (0, scenario_key, k): hts_k
# for k, hts_k in enumerate(hts)
# }
# else: # not a list: one time interval
# self.static_loss = {
# (0, scenario_key, 0): hts
# }
def update_minimum_cost(self): # *****************************************************************************
"""Sets the minimum cost as each investment\'s net prevent value.""" # *****************************************************************************
# define the minimum cost
self.minimum_cost = tuple(inv.net_present_value() for inv in self.invs)
# ************************************************************************* class ExistingPipeTrench(PipeTrenchOptions):
# ************************************************************************* "A class for existing pipe trenches."
def add_investment( def __init__(self, option_selected: int, **kwargs):
# initialise
PipeTrenchOptions.__init__(
self, self,
investment: float or list, # minimum_cost=[0 for i in range(kwargs['trench'].number_options())],
investment_period: float or list, **kwargs)
investment_longevity: float or list, # define the option that already exists
commissioning_delay_after_investment: float or list, self.options_selected[option_selected] = True
salvage_value_method: str = 'other',
update_minimum_cost: bool = False
):
# check the inputs
if (isinstance(investment, Real) and
isinstance(investment_period, Real) and
isinstance(investment_longevity, Real) and
isinstance(commissioning_delay_after_investment, Real)):
# real numbers as inputs: normal mode
vector_mode = False
# store the details
# self.investment = investment
# self.investment_period = investment_period
# self.investment_longevity = investment_longevity
# self.commissioning_delay_after_investment = (
# commissioning_delay_after_investment)
elif (type(investment) == list and
type(investment_period) == list and
type(investment_longevity) == list and
type(commissioning_delay_after_investment) == list):
# lists as inputs: vector mode
vector_mode = True
# # store the details
# self.investment = investment
# self.investment_period = investment_period
# self.investment_longevity = investment_longevity
# self.commissioning_delay_after_investment = (
# commissioning_delay_after_investment)
else:
raise TypeError('Incompatible inputs.')
# make sure the investment and trench details are consistent
if vector_mode != self.trench.vector_mode:
raise TypeError('Inconsistent input types.')
if vector_mode and self.number_options() != len(investment):
raise ValueError('Inconsistent inputs.')
# add the investment
if vector_mode:
# multiple options
for inv, ii, ip, il, cdai in zip(
self.invs,
investment,
investment_period,
investment_longevity,
commissioning_delay_after_investment
):
inv.add_investment(
investment=ii,
investment_period=ip,
investment_longevity=il,
commissioning_delay_after_investment=cdai,
salvage_value_method=salvage_value_method
)
else:
# single option
self.invs[0].add_investment(
investment=investment,
investment_period=investment_period,
investment_longevity=investment_longevity,
commissioning_delay_after_investment=(
commissioning_delay_after_investment),
salvage_value_method=salvage_value_method
)
# update the minimum cost if desired
if update_minimum_cost:
self.update_minimum_cost()
# *************************************************************************
# *************************************************************************
# ***************************************************************************** # *****************************************************************************
# ***************************************************************************** # *****************************************************************************
\ No newline at end of file
...@@ -13,14 +13,78 @@ import numpy as np ...@@ -13,14 +13,78 @@ import numpy as np
from ...problems.esipp.network import Network from ...problems.esipp.network import Network
from .network import PipeTrenchOptions from .network import PipeTrenchOptions
from topupheat.pipes.trenches import SupplyReturnPipeTrench
from numbers import Real
# ***************************************************************************** # *****************************************************************************
# ***************************************************************************** # *****************************************************************************
def summarise_network_by_arc_technology( def cost_pipes(trench: SupplyReturnPipeTrench,
length: float or tuple) -> tuple:
"""
Returns the costs of each trench option for a given trench length.
Parameters
----------
trench : SupplyReturnPipeTrench
The object describing the trench options.
length : float or tuple
The trench length in meters.
Raises
------
ValueError
This error is raised if unrecognised inputs are inserted.
Returns
-------
tuple
A tuple of the pipe costs for each option.
"""
# use the specific pipe cost that features in the database
if trench.vector_mode:
# multiple options
if (type(length) == tuple and
len(length) == trench.number_options()):
# multiple trench lengths
return tuple(
(pipe.sp*length # twin pipes: one twin pipe
if trench.twin_pipes else
pipe.sp*length*2) # single pipes: two single pipes
for pipe, length in zip(trench.supply_pipe, length)
)
elif isinstance(length, Real):
# one trench length
return tuple(
(pipe.sp*length # twin pipes: one twin pipe
if trench.twin_pipes else
pipe.sp*length*2) # single pipes: two single pipes
for pipe in trench.supply_pipe
)
else:
raise ValueError('Unrecognised input combination.')
elif (not trench.vector_mode and isinstance(length, Real)):
# only one option
return (trench.supply_pipe.sp*length,)
else: # only one option
raise ValueError('Unrecognised input combination.')
# # keep the trench length
# self.length = (
# [length for i in range(trench.number_options())]
# if trench.vector_mode else
# length
# )
# *****************************************************************************
# *****************************************************************************
def summarise_network_by_pipe_technology(
network: Network, network: Network,
print_output: bool = False print_output: bool = False
) -> dict: ) -> dict:
"A method to summarise a network by pipe technology."
# ************************************************************************* # *************************************************************************
# ************************************************************************* # *************************************************************************
...@@ -189,7 +253,7 @@ def plot_network_layout(network: Network, ...@@ -189,7 +253,7 @@ def plot_network_layout(network: Network,
# add base map # add base map
if include_basemap: if include_basemap:
# TODO: reach this statement in tests
cx.add_basemap(ax, cx.add_basemap(ax,
zoom=basemap_zoom_level, zoom=basemap_zoom_level,
source=cx.providers.OpenStreetMap.Mapnik, source=cx.providers.OpenStreetMap.Mapnik,
......
...@@ -8,6 +8,8 @@ from statistics import mean ...@@ -8,6 +8,8 @@ from statistics import mean
#****************************************************************************** #******************************************************************************
#****************************************************************************** #******************************************************************************
# TODO: enable swapping the polarity
class Investment: class Investment:
"""This class is meant to enable analysis of specific investments.""" """This class is meant to enable analysis of specific investments."""
...@@ -174,6 +176,7 @@ class Investment: ...@@ -174,6 +176,7 @@ class Investment:
cash_flow: float or int, cash_flow: float or int,
start_period: int, start_period: int,
longevity: int = None): longevity: int = None):
"""Adds a sequence of cash flows to the analysis."""
if type(longevity) == type(None): if type(longevity) == type(None):
......
...@@ -37,31 +37,20 @@ class Arcs: ...@@ -37,31 +37,20 @@ class Arcs:
validate: bool): # one number validate: bool): # one number
# initialise # initialise
self.name = name self.name = name
self.efficiency = efficiency self.efficiency = efficiency
self.efficiency_reverse = efficiency_reverse self.efficiency_reverse = efficiency_reverse
self.static_loss = static_loss self.static_loss = static_loss
self.capacity = capacity self.capacity = capacity
self.minimum_cost = minimum_cost self.minimum_cost = minimum_cost
self.specific_capacity_cost = specific_capacity_cost self.specific_capacity_cost = specific_capacity_cost
self.capacity_is_instantaneous = capacity_is_instantaneous self.capacity_is_instantaneous = capacity_is_instantaneous
# results (for simulation or post-optimisation analysis) # results (for simulation or post-optimisation analysis)
self.options_selected = [False for element in self.capacity] self.options_selected = [False for element in self.capacity]
# validate # validate
if validate: if validate:
Arcs.validate(self) Arcs.validate(self)
# ************************************************************************* # *************************************************************************
...@@ -148,6 +137,28 @@ class Arcs: ...@@ -148,6 +137,28 @@ class Arcs:
# ************************************************************************* # *************************************************************************
# ************************************************************************* # *************************************************************************
def has_constant_efficiency(self) -> bool:
"""Returns True if the arc has a constant efficiency."""
if self.has_proportional_losses():
# proportional losses
if self.is_isotropic():
# is isotropic
if len(set(self.efficiency.values())) == 1:
# is isotropic and has constant eta = True
return True
else:
# is isotropic but does not have constant eta = False
return False
else: # is not isotropic
return False # not isotropic = efficiency can change
else:
# no proportional losses: always equal to 1 = has constant eta
return True
# *************************************************************************
# *************************************************************************
def has_proportional_losses(self) -> bool: def has_proportional_losses(self) -> bool:
"""Returns False if the efficiency is always one, otherwise True.""" """Returns False if the efficiency is always one, otherwise True."""
......
...@@ -29,6 +29,9 @@ from .resource import ResourcePrice ...@@ -29,6 +29,9 @@ from .resource import ResourcePrice
# ***************************************************************************** # *****************************************************************************
# ***************************************************************************** # *****************************************************************************
# TODO: allow users to define how fixed components in the objective function
# are handled (using a variable equal to one or by excluding them altogether)
class InfrastructurePlanningProblem(EnergySystem): class InfrastructurePlanningProblem(EnergySystem):
"""A class for optimisation of infrastructure planning problems.""" """A class for optimisation of infrastructure planning problems."""
...@@ -4225,7 +4228,8 @@ def is_peak_total_problem(problem: InfrastructurePlanningProblem) -> bool: ...@@ -4225,7 +4228,8 @@ def is_peak_total_problem(problem: InfrastructurePlanningProblem) -> bool:
# conditions: # conditions:
# 1) maximum congestion occurs simultaneously across the network # 1) maximum congestion occurs simultaneously across the network
# - corollary: there are no dynamic behaviours in the network # - corollary: dynamic behaviours do not change the peaks
# - corollary: arc efficiencies are constant
# - simplifying assumption: no proportional losses in the network # - simplifying assumption: no proportional losses in the network
# 2) the time during which maximum congestion occurs can be determined # 2) the time during which maximum congestion occurs can be determined
# 3) energy prices are constant in time and volume # 3) energy prices are constant in time and volume
......
This diff is collapsed.
...@@ -5,9 +5,6 @@ import random ...@@ -5,9 +5,6 @@ import random
from topupheat.pipes.single import StandardisedPipeDatabase from topupheat.pipes.single import StandardisedPipeDatabase
from topupheat.common.fluids import FluidDatabase#, Fluid from topupheat.common.fluids import FluidDatabase#, Fluid
from examples_converter import examples as examples_converter
# from examples_dhn import examples as examples_dhn
from examples_dynsys import examples as examples_dynsys
from examples_esipp_network import examples as examples_esipp_network from examples_esipp_network import examples as examples_esipp_network
from examples_esipp_problem import examples as examples_esipp_problem from examples_esipp_problem import examples as examples_esipp_problem
from examples_esipp import examples as examples_esipp from examples_esipp import examples as examples_esipp
...@@ -20,9 +17,6 @@ from examples_signal import examples as examples_signal ...@@ -20,9 +17,6 @@ from examples_signal import examples as examples_signal
def test_suite(): def test_suite():
test_examples_converter = True
# test_examples_converter = False
test_examples_dynsys = True test_examples_dynsys = True
# test_examples_dynsys = False # test_examples_dynsys = False
...@@ -135,30 +129,6 @@ def test_suite(): ...@@ -135,30 +129,6 @@ def test_suite():
#************************************************************************** #**************************************************************************
#************************************************************************** #**************************************************************************
# converter
if test_examples_converter:
print('\'converter\': testing about to start...')
examples_converter()
print('\'converter\': testing complete.')
#**************************************************************************
# dynsys
if test_examples_dynsys:
print('\'dynsys\': testing about to start...')
examples_dynsys()
print('\'dynsys\': testing complete.')
#**************************************************************************
# esipp-network # esipp-network
if test_examples_esipp_network: if test_examples_esipp_network:
......
# imports
# standard
import random
# local, external
import numpy as np
# local, internal
import src.topupopt.problems.esipp.dynsys as dynsys
import src.topupopt.problems.esipp.converter as cvn
import src.topupopt.problems.esipp.signal as sgn
# *****************************************************************************
# *****************************************************************************
class TestConverter:
# test converters
# 1) regular and irregular time steps
# 2) time invariant and time varying models
# 3) integrate and do not integrate outputs
# 4) generate coefficients
# test creating a stateless converter without outputs
# test creating a stateless converter with 1 output
# test creating a stateless converter with 2 output
# test creating a converter based on a single ODE system without outputs
# test creating a converter based on a single ODE system with 1 output
# test creating a converter based on a single ODE system with 2 output
# test creating a converter based on a multiple ODE system without outputs
# test creating a converter based on a multiple ODE system with 1 output
# test creating a converter based on a multiple ODE multi-output system
def test_converter_regular_timesteps(self):
time_step_durations = [1,1,1,1]
self.example_full_converter(time_step_durations)
def test_converter_irregular_timesteps(self):
time_step_durations = [1,1.5,0.5,1]
self.example_full_converter(time_step_durations)
# *************************************************************************
# *************************************************************************
def get_stateless_model_data(relative_amplitude_variation: float = 0.0):
mrh_deviation = random.random() - 0.5
Aw = 6.22 # original: 6.22 m2
min_rel_heat = 0.2*(1+relative_amplitude_variation*mrh_deviation)
return Aw, min_rel_heat
# *************************************************************************
# *************************************************************************
def get_single_ode_model_data(relative_amplitude_variation: float = 0.0):
# define how the coefficients change
Ria_deviation = random.random() - 0.5
# define the (A, B, C and D) matrices
# A: n*n
# B: n*m
# C: r*n
# D: r*m
Ci = 1.360*3600000
Ria = (
(1+relative_amplitude_variation*Ria_deviation)*5.31/3600000
)
Aw = 6.22
min_rel_heat = 0.2
x0 = np.array([20])
return Ci, Ria, Aw, min_rel_heat, x0
# *************************************************************************
# *************************************************************************
def get_multi_ode_model_data(
self,
relative_amplitude_variation: float = 0.0):
# define how the coefficients change
Rih_deviation = random.random() - 0.5
Ria_deviation = random.random() - 0.5
# define the (A, B, C and D) matrices
# A: n*n
# B: n*m
# C: r*n
# D: r*m
# from Bacher and Madsen (2011): model TiTh
Ci = 1.360*3600000 # original: 1.36 kWh/ºC
Ch = 0.309*3600000 # original: 0.309 kWh/ºC
Ria = (
(1+relative_amplitude_variation*Ria_deviation)*5.31/3600000
) # original: 5.31 ºC/kWh
Rih = (
(1+relative_amplitude_variation*Rih_deviation)*0.639/3600000
) # original: 0.639 ºC/kWh
Aw = 6.22 # original: 6.22 m2
Pw = 5000 # 5 kW
min_rel_heat = 0.2
x0 = np.array([20, 20])
return Ci, Ch, Ria, Rih, Aw, min_rel_heat, Pw, x0
# *************************************************************************
# *************************************************************************
def stateless_model(self, Aw, min_rel_heat):
# inputs: Ta, phi_s, phi_h above the minimum, phi_h status
# outputs: solar irradiance, heat
d = np.array([[0, Aw, 0, 0],
[0, 0, (1-min_rel_heat), min_rel_heat]])
return None, None, None, d
# *************************************************************************
# *************************************************************************
def single_node_model(self, Ci, Ria, Aw, min_rel_heat, Pw):
# states: Ti and Th
# inputs: Ta, phi_s, phi_h above the minimum, phi_h status
# outputs: solar irradiance, heat
a = np.array([[-1/(Ria*Ci)]])
b = np.array([[1/(Ci*Ria), Aw/Ci, Pw*(1-min_rel_heat)/Ci, Pw*min_rel_heat/Ci]])
c = np.array([[0],[0]])
d = np.array([[0, Aw, 0, 0],
[0, 0, Pw*(1-min_rel_heat), Pw*min_rel_heat]])
return a, b, c, d
# *************************************************************************
# *************************************************************************
def two_node_model(self, Ci, Ch, Ria, Rih, Aw, min_rel_heat, Pw):
# states: Ti and Th
# inputs: Ta, phi_s, phi_h above the minimum, phi_h status
# outputs: solar irradiance, heat
a = np.array([[-(1/Rih+1/Ria)/Ci, 1/(Ci*Rih)],
[1/(Ch*Rih), -1/(Ch*Rih)]])
b = np.array([[1/(Ci*Ria), Aw/Ci, 0, 0],
[0, 0, Pw*(1-min_rel_heat)/Ch, Pw*min_rel_heat/Ch]])
c = np.array([[0, 0],
[0, 0]])
d = np.array([[0, Aw, 0, 0],
[0, 0, Pw*(1-min_rel_heat), Pw*min_rel_heat]])
return a, b, c, d
# *************************************************************************
# *************************************************************************
def get_two_node_model_signals(self, number_samples):
# signals
# inputs:
# 1) ambient temperature (real, can be fixed later)
# 2) solar irradiation (real, can be fixed later)
# 3) relative heat above minimum (nnr)
# 4) heater status (binary)
list_inputs = [
sgn.FreeUnboundedSignal(number_samples),
sgn.FreeUnboundedSignal(number_samples),
sgn.NonNegativeRealSignal(number_samples),
sgn.BinarySignal(number_samples)
]
# states
# 1) indoor temperature (real)
# 2) heater temperature (real)
list_states = [
sgn.FreeUnboundedSignal(number_samples),
sgn.FreeUnboundedSignal(number_samples)
]
# outputs:
# 1) solar gain (nnr)
# 2) heat input (nnr)
list_outputs = [
sgn.NonNegativeRealSignal(number_samples),
sgn.NonNegativeRealSignal(number_samples)
]
return list_inputs, list_states, list_outputs
# *************************************************************************
# *************************************************************************
def example_full_converter(self, time_step_durations: list):
# number of samples
number_time_steps = len(time_step_durations)
# get the coefficients
(Ci,
Ch,
Ria,
Rih,
Aw,
min_rel_heat,
Pw,
x0) = self.get_multi_ode_model_data()
# get the model
(a,
b,
c,
d) = self.two_node_model(Ci, Ch, Ria, Rih, Aw, min_rel_heat, Pw)
# get the signals
inputs, states, outputs = self.get_two_node_model_signals(
number_time_steps)
# create a dynamic system
ds = dynsys.DynamicSystem(
time_interval_durations=time_step_durations,
A=a,
B=b,
C=c,
D=d)
# create a converter
cvn1 = cvn.Converter(
'cvn1',
sys=ds,
initial_states=x0,
turn_key_cost=3,
inputs=inputs,
states=states,
outputs=outputs)
# get the dictionaries
(a_innk,
b_inmk,
c_irnk,
d_irmk,
e_x_ink,
e_y_irk) = cvn1.matrix_dictionaries()
# check the dicts
#**************************************************************************
#**************************************************************************
#******************************************************************************
#******************************************************************************
\ No newline at end of file
# imports # imports
# local, internal # local, internal
from src.topupopt.data.finance.invest import Investment, discount_factor, npv from src.topupopt.data.finance.invest import Investment, discount_factor, npv
from src.topupopt.data.finance.invest import salvage_value_linear_depreciation from src.topupopt.data.finance.invest import salvage_value_linear_depreciation
from src.topupopt.data.finance.invest import present_salvage_value_annuity from src.topupopt.data.finance.invest import present_salvage_value_annuity
from src.topupopt.data.finance.invest import salvage_value_annuity from src.topupopt.data.finance.invest import salvage_value_annuity
from src.topupopt.data.finance.utils import ArcInvestments
# local, external # local, external
import math import math
#****************************************************************************** #******************************************************************************
#****************************************************************************** #******************************************************************************
class TestArcInvestments:
def test_object_creation(self):
discount_rate = 0.035
analysis_period = 20
discount_rates = tuple(
discount_rate for i in range(analysis_period)
)
cash_flows_npv = [
3.673079208612225,
1.5610827143687658,
17,
117,
1842
]
abs_cash_flows_npv = [
1e-1,
1e-1,
1e-1,
0.5,
1
]
investments = []
# limited longevity operation, does not go beyond planning horizon
cash_flow = 1
cash_flow_start = 1
myinv = Investment(discount_rates=discount_rates)
myinv.add_operational_cash_flows(
cash_flow=cash_flow,
start_period=cash_flow_start,
longevity=4
)
investments.append(myinv)
# limited longevity operation, goes beyond planning horizon
cash_flow = 1
cash_flow_start = 18
myinv = Investment(discount_rates=discount_rates)
myinv.add_operational_cash_flows(
cash_flow=cash_flow,
start_period=cash_flow_start,
longevity=4
)
investments.append(myinv)
# D&V omkostninger kundeanlæg: Sengeløse Skole
cash_flow = 1.2
cash_flow_start = 1
myinv = Investment(discount_rates=discount_rates)
myinv.add_operational_cash_flows(
cash_flow=cash_flow,
start_period=cash_flow_start,
longevity=None
)
investments.append(myinv)
# D&V omkostninger kundeanlæg: Større forbrugere
cash_flow = 6/10
myinv = Investment(discount_rates=discount_rates)
myinv.add_operational_cash_flows(
cash_flow=10*cash_flow,
start_period=1,
longevity=None
)
myinv.add_operational_cash_flows(
cash_flow=3*cash_flow,
start_period=2,
longevity=None
)
myinv.add_operational_cash_flows(
cash_flow=1*cash_flow,
start_period=3,
longevity=None
)
investments.append(myinv)
# D&V omkostninger kundeanlæg: Mindre forbrugere
cash_flow = 0.320
myinv = Investment(discount_rates=discount_rates)
myinv.add_operational_cash_flows(
cash_flow=197*cash_flow,
start_period=1,
longevity=None
)
myinv.add_operational_cash_flows(
cash_flow=(233-197)*cash_flow,
start_period=2,
longevity=None
)
myinv.add_operational_cash_flows(
cash_flow=(269-233)*cash_flow,
start_period=3,
longevity=None
)
myinv.add_operational_cash_flows(
cash_flow=(305-269)*cash_flow,
start_period=4,
longevity=None
)
myinv.add_operational_cash_flows(
cash_flow=(341-305)*cash_flow,
start_period=5,
longevity=None
)
myinv.add_operational_cash_flows(
cash_flow=(377-341)*cash_flow,
start_period=6,
longevity=None
)
myinv.add_operational_cash_flows(
cash_flow=(413-377)*cash_flow,
start_period=7,
longevity=None
)
myinv.add_operational_cash_flows(
cash_flow=(449-413)*cash_flow,
start_period=8,
longevity=None
)
myinv.add_operational_cash_flows(
cash_flow=(488-449)*cash_flow,
start_period=9,
longevity=None
)
investments.append(myinv)
# check
for inv, true_npv, _abs in zip(
investments,
cash_flows_npv,
abs_cash_flows_npv
):
assert math.isclose(inv.net_present_value(), true_npv, abs_tol=_abs)
# create object
number_options = 5
static_loss = {
(h, q, k): 1+q*0.25+h*0.15+k*0.05
for h in range(number_options)
for q in range(2)
for k in range(3)
}
arc_invs = ArcInvestments(
investments=investments,
name='any',
efficiency=None,
efficiency_reverse=None,
capacity=tuple(1+o for o in range(number_options)),
#minimum_cost=tuple(1+o for o in range(number_options)),
specific_capacity_cost=1,
capacity_is_instantaneous=False,
static_loss=static_loss,
validate=True
)
# check the costs
for _npv, true_npv, _abs in zip(
arc_invs.minimum_cost,
cash_flows_npv,
abs_cash_flows_npv
):
assert math.isclose(_npv, true_npv, abs_tol=_abs)
# change something in the investments
for inv in arc_invs.investments:
inv.add_investment(
investment=1,
investment_period=0,
investment_longevity=10
)
# update the minimum costs
arc_invs.update_minimum_cost()
# make sure the comparison fails
for _npv, true_npv, _abs in zip(
arc_invs.minimum_cost,
cash_flows_npv,
abs_cash_flows_npv
):
error_raised = False
try:
assert math.isclose(_npv, true_npv, abs_tol=_abs)
except AssertionError:
error_raised = True
assert error_raised
# new true values
new_true_npv = [
4.673079208612225,
2.561082714368766,
18.054883962342764,
117.50524073646935,
1843.1804103901486
]
# print([inv.net_present_value() for inv in arc_invs])
for _npv, true_npv, _abs in zip(
arc_invs.minimum_cost,
new_true_npv,
abs_cash_flows_npv
):
assert math.isclose(_npv, true_npv, abs_tol=_abs)
# *****************************************************************************
# *****************************************************************************
class TestDataFinance: class TestDataFinance:
# TODO: make sure that all methods work with variable discount rates # TODO: make sure that all methods work with variable discount rates
......
...@@ -11,21 +11,17 @@ from math import inf, isclose ...@@ -11,21 +11,17 @@ from math import inf, isclose
# local, internal # local, internal
# topupopt # topupopt
# import src.topupopt.problems.esipp as tuo
from src.topupopt.data.dhn.network import PipeTrenchOptions, ExistingPipeTrench from src.topupopt.data.dhn.network import PipeTrenchOptions, ExistingPipeTrench
# from src.topupopt.data.dhn.network import from src.topupopt.data.dhn.network import PipeTrenchInvestments
from src.topupopt.data.finance.invest import Investment
# topupheat # topupheat
from topupheat.pipes.single import StandardisedPipe, StandardisedPipeDatabase from topupheat.pipes.single import StandardisedPipe, StandardisedPipeDatabase
import topupheat.pipes.trenches as trenches import topupheat.pipes.trenches as trenches
from topupheat.common.fluids import FluidDatabase#, Fluid from topupheat.common.fluids import FluidDatabase
#****************************************************************************** # *****************************************************************************
#****************************************************************************** # *****************************************************************************
class TestDistrictHeatingNetwork: class TestDistrictHeatingNetwork:
...@@ -147,6 +143,9 @@ class TestDistrictHeatingNetwork: ...@@ -147,6 +143,9 @@ class TestDistrictHeatingNetwork:
# ********************************************************************* # *********************************************************************
# *************************************************************************
# *************************************************************************
def test_creating_single_arcs(self): def test_creating_single_arcs(self):
# fluid data # fluid data
...@@ -284,8 +283,156 @@ class TestDistrictHeatingNetwork: ...@@ -284,8 +283,156 @@ class TestDistrictHeatingNetwork:
] ]
) )
# *************************************************************************
# *************************************************************************
def test_creating_single_arcs_investment(self):
# fluid data
waterdata_file = 'tests/data/incropera2006_saturated_water.csv'
phase = FluidDatabase.fluid_LIQUID
fluid_db = FluidDatabase(
fluid='fluid',
phase=phase,
source=waterdata_file
)
singlepipedata_files = ['tests/data/isoplus_singlepipes_s1.csv']
pipedb = StandardisedPipeDatabase(source=singlepipedata_files)
pipe = StandardisedPipe(
pipe_tuple=pipedb.pipe_tuples[0],
#e_eff=pipe_e_eff,
#sp=pipe_specific_price,
db=pipedb)
# network details
supply_temperature = 85+273.15
return_temperature = 45+273.15
pressure = 1e5
# trench
pipe_distance = 0.52 # m
pipe_depth = 0.66 # m
# environmental
outdoor_temperature = 6+273.15 # K
h_gs = inf # 14.6 # W/m2K
soil_k = 1.5 # W/mK
# more information
max_specific_pressure_loss = 100 # Pa/m
mytrench = trenches.SupplyReturnPipeTrench(
pipe_center_depth=pipe_depth,
pipe_center_distance=pipe_distance,
fluid_db=fluid_db,
phase=phase,
pressure=pressure,
supply_temperature=supply_temperature,
return_temperature=return_temperature,
max_specific_pressure_loss=max_specific_pressure_loss,
supply_pipe=pipe
)
# investments
number_periods = 20
discount_rate = 0.035
discount_rates = tuple([discount_rate for p in range(number_periods)])
inv = Investment(discount_rates=discount_rates)
# PipeTrenchOptions
myarcs = PipeTrenchInvestments(
trench=mytrench,
name='hellotrench',
length=50,
investments=(inv,),
)
# add static loss scenario
myarcs.set_static_losses(
scenario_key='scenario0',
ground_thermal_conductivity=soil_k,
ground_air_heat_transfer_coefficient=h_gs,
time_interval_duration=3600,
temperature_surroundings=outdoor_temperature
)
# add another static loss scenario
myarcs.set_static_losses(
scenario_key='scenario1',
ground_thermal_conductivity=soil_k+1,
ground_air_heat_transfer_coefficient=h_gs+1,
time_interval_duration=3600+100,
temperature_surroundings=outdoor_temperature+1
)
number_steps = 3
myarcs.set_static_losses(
scenario_key='scenario2',
ground_thermal_conductivity=[soil_k for i in range(number_steps)
],
ground_air_heat_transfer_coefficient=[
h_gs for i in range(number_steps)
],
time_interval_duration=[3600 for i in range(number_steps)],
temperature_surroundings=[
outdoor_temperature for i in range(number_steps)
]
)
# test arcs
n = myarcs.number_options()
assert not myarcs.has_been_selected()
assert len(myarcs.capacity) == n
assert len(myarcs.minimum_cost) == n
assert isinstance(myarcs.specific_capacity_cost, Real)
assert type(myarcs.efficiency) == type(None)
assert type(myarcs.efficiency_reverse) == type(None)
assert type(myarcs.static_loss) == dict
assert len(myarcs.static_loss) != 0
for (h, q, k), sl in myarcs.static_loss.items():
assert isinstance(sl, Real)
assert sl >= 0
# redefine the capacity
capacity = tuple(myarcs.capacity)
myarcs.set_capacity(
max_specific_pressure_loss=max_specific_pressure_loss+100
)
assert len(capacity) == len(myarcs.capacity)
for _c1, _c2 in zip(capacity, myarcs.capacity):
assert _c1 != _c2
# redefine the minimum costs
min_cost = tuple(myarcs.minimum_cost)
myarcs.set_minimum_cost(minimum_cost=[_mc+1 for _mc in min_cost])
assert len(min_cost) == len(myarcs.minimum_cost)
for _mc1, _mc2 in zip(min_cost, myarcs.minimum_cost):
assert _mc1+1 == _mc2
# ********************************************************************* # *********************************************************************
# create arcs object with multiple static loss values as a first case
# PipeTrenchOptions
myarcs = PipeTrenchOptions(
trench=mytrench,
name='hellotrench',
length=50
)
number_steps = 3
myarcs.set_static_losses(
scenario_key='scenario2',
ground_thermal_conductivity=[soil_k for i in range(number_steps)],
ground_air_heat_transfer_coefficient=[
h_gs for i in range(number_steps)
],
time_interval_duration=[3600 for i in range(number_steps)],
temperature_surroundings=[
outdoor_temperature for i in range(number_steps)
]
)
# *************************************************************************
# *************************************************************************
def test_creating_multiple_arcs(self): def test_creating_multiple_arcs(self):
# fluid data # fluid data
...@@ -444,7 +591,8 @@ class TestDistrictHeatingNetwork: ...@@ -444,7 +591,8 @@ class TestDistrictHeatingNetwork:
] ]
) )
# ********************************************************************* # *************************************************************************
# *************************************************************************
# ***************************************************************************** # *****************************************************************************
# ***************************************************************************** # *****************************************************************************
......
...@@ -19,6 +19,220 @@ from topupheat.common.fluids import FluidDatabase#, Fluid ...@@ -19,6 +19,220 @@ from topupheat.common.fluids import FluidDatabase#, Fluid
class TestDistrictHeatingNetworkUtils: class TestDistrictHeatingNetworkUtils:
# *************************************************************************
# *************************************************************************
def test_cost_pipes_single_arc(self):
# fluid data
waterdata_file = 'tests/data/incropera2006_saturated_water.csv'
phase = FluidDatabase.fluid_LIQUID
fluid_db = FluidDatabase(
fluid='fluid',
phase=phase,
source=waterdata_file
)
singlepipedata_files = ['tests/data/isoplus_singlepipes_s1.csv']
pipedb = StandardisedPipeDatabase(source=singlepipedata_files)
pipe = StandardisedPipe(
pipe_tuple=pipedb.pipe_tuples[0],
#e_eff=pipe_e_eff,
#sp=pipe_specific_price,
db=pipedb)
# network details
supply_temperature = 85+273.15
return_temperature = 45+273.15
pressure = 1e5
# trench
pipe_distance = 0.52 # m
pipe_depth = 0.66 # m
# environmental
outdoor_temperature = 6+273.15 # K
h_gs = inf # 14.6 # W/m2K
soil_k = 1.5 # W/mK
# more information
max_specific_pressure_loss = 100 # Pa/m
mytrench = trenches.SupplyReturnPipeTrench(
pipe_center_depth=pipe_depth,
pipe_center_distance=pipe_distance,
fluid_db=fluid_db,
phase=phase,
pressure=pressure,
supply_temperature=supply_temperature,
return_temperature=return_temperature,
max_specific_pressure_loss=max_specific_pressure_loss,
supply_pipe=pipe
)
# create arcs object with multiple static loss values as a first case
trench_length = 50
# PipeTrenchOptions
myarcs = PipeTrenchOptions(
trench=mytrench,
name='hellotrench',
length=trench_length
)
number_steps = 3
myarcs.set_static_losses(
scenario_key='scenario2',
ground_thermal_conductivity=[soil_k for i in range(number_steps)],
ground_air_heat_transfer_coefficient=[
h_gs for i in range(number_steps)
],
time_interval_duration=[3600 for i in range(number_steps)],
temperature_surroundings=[
outdoor_temperature for i in range(number_steps)
]
)
mypipecosts = utils.cost_pipes(mytrench, trench_length)
assert mypipecosts == (50.0,)
# unrecognised input: using a string for the trench length
error_raised = False
try:
mypipecosts = utils.cost_pipes(mytrench, '50')
except ValueError:
error_raised = True
assert error_raised
# *************************************************************************
# *************************************************************************
def test_cost_pipes_multiple_arcs(self):
# fluid data
waterdata_file = 'tests/data/incropera2006_saturated_water.csv'
phase = FluidDatabase.fluid_LIQUID
fluid_db = FluidDatabase(
fluid='fluid',
phase=phase,
source=waterdata_file
)
singlepipedata_files = ['tests/data/isoplus_singlepipes_s1.csv']
pipedb = StandardisedPipeDatabase(source=singlepipedata_files)
pipe = StandardisedPipe(
pipe_tuple=pipedb.pipe_tuples[0],
db=pipedb)
# network details
supply_temperature = 85+273.15
return_temperature = 45+273.15
pressure = 1e5
# trench
pipe_distance = 0.52 # m
pipe_depth = 0.66 # m
# environmental
outdoor_temperature = 6+273.15 # K
h_gs = inf # 14.6 # W/m2K
soil_k = 1.5 # W/mK
# more information
max_specific_pressure_loss = 100 # Pa/m
number_options = 2
mytrench = trenches.SupplyReturnPipeTrench(
pipe_center_depth=[pipe_depth for i in range(number_options)],
pipe_center_distance=[
pipe_distance for i in range(number_options)
],
fluid_db=fluid_db,
phase=phase,
pressure=[pressure for i in range(number_options)],
supply_temperature=[
supply_temperature for i in range(number_options)
],
return_temperature=[
return_temperature for i in range(number_options)
],
max_specific_pressure_loss=[
max_specific_pressure_loss for i in range(number_options)
],
supply_pipe=[pipe for i in range(number_options)]
)
# PipeTrenchOptions
myarcs = PipeTrenchOptions(
trench=mytrench,
name='hellotrench',
length=50
)
# add static loss scenario
myarcs.set_static_losses(
scenario_key='scenario0',
ground_thermal_conductivity=soil_k,
ground_air_heat_transfer_coefficient=h_gs,
time_interval_duration=3600,
temperature_surroundings=outdoor_temperature
)
# add another static loss scenario
myarcs.set_static_losses(
scenario_key='scenario1',
ground_thermal_conductivity=soil_k+1,
ground_air_heat_transfer_coefficient=h_gs+1,
time_interval_duration=3600+100,
temperature_surroundings=outdoor_temperature+1
)
# add static loss scenario
number_steps = 3
myarcs.set_static_losses(
scenario_key='scenario2',
ground_thermal_conductivity=[soil_k for i in range(number_steps)
],
ground_air_heat_transfer_coefficient=[
h_gs for i in range(number_steps)
],
time_interval_duration=[3600 for i in range(number_steps)],
temperature_surroundings=[
outdoor_temperature for i in range(number_steps)
]
)
trench_length = 50
# PipeTrenchOptions
myarcs = PipeTrenchOptions(
trench=mytrench,
name='hellotrench',
length=trench_length
)
number_steps = 3
myarcs.set_static_losses(
scenario_key='scenario2',
ground_thermal_conductivity=[soil_k for i in range(number_steps)
],
ground_air_heat_transfer_coefficient=[
h_gs for i in range(number_steps)
],
time_interval_duration=[3600 for i in range(number_steps)],
temperature_surroundings=[
outdoor_temperature for i in range(number_steps)
]
)
mypipecosts = utils.cost_pipes(mytrench, trench_length)
assert mypipecosts == (100.0, 100.0)
mypipecosts = utils.cost_pipes(mytrench, (trench_length, trench_length))
assert mypipecosts == (100.0, 100.0)
# unrecognised input: using a list for the trench lengths
error_raised = False
try:
mypipecosts = utils.cost_pipes(mytrench, [trench_length])
except ValueError:
error_raised = True
assert error_raised
# *************************************************************************
# *************************************************************************
def test_plotting_heating_demand(self): def test_plotting_heating_demand(self):
# g = 'dh' # g = 'dh'
...@@ -272,11 +486,13 @@ class TestDistrictHeatingNetworkUtils: ...@@ -272,11 +486,13 @@ class TestDistrictHeatingNetworkUtils:
# ********************************************************************* # *********************************************************************
out = utils.summarise_network_by_arc_technology(mynet, False) out = utils.summarise_network_by_pipe_technology(mynet, False)
assert 'DN20' in out and out['DN20'] == 25 assert 'DN20' in out and out['DN20'] == 25
assert 'DN32' in out and out['DN32'] == 50 assert 'DN32' in out and out['DN32'] == 50
utils.summarise_network_by_pipe_technology(mynet, True)
# ************************************************************************* # *************************************************************************
# ************************************************************************* # *************************************************************************
...@@ -427,13 +643,18 @@ class TestDistrictHeatingNetworkUtils: ...@@ -427,13 +643,18 @@ class TestDistrictHeatingNetworkUtils:
# ********************************************************************* # *********************************************************************
utils.summarise_network_by_arc_technology(network, False) utils.summarise_network_by_pipe_technology(network, False)
utils.plot_network_layout( utils.plot_network_layout(
network=network, network=network,
include_basemap=False) include_basemap=False)
utils.plot_network_layout(
network=network,
include_basemap=True)
# ************************************************************************* # *************************************************************************
# ************************************************************************* # *************************************************************************
#****************************************************************************** #******************************************************************************
#****************************************************************************** #******************************************************************************
\ No newline at end of file
...@@ -19,7 +19,7 @@ import src.topupopt.problems.esipp.signal as sgn ...@@ -19,7 +19,7 @@ import src.topupopt.problems.esipp.signal as sgn
#****************************************************************************** #******************************************************************************
#****************************************************************************** #******************************************************************************
def examples(): class TestConverter():
#************************************************************************** #**************************************************************************
#************************************************************************** #**************************************************************************
...@@ -47,10 +47,23 @@ def examples(): ...@@ -47,10 +47,23 @@ def examples():
# test creating a converter based on a multiple ODE system with 1 output # test creating a converter based on a multiple ODE system with 1 output
# test creating a converter based on a multiple ODE multi-output system # test creating a converter based on a multiple ODE multi-output system
#**************************************************************************
#**************************************************************************
def test_full_converter_regular(self):
time_step_durations = [1,1,1,1] time_step_durations = [1,1,1,1]
example_full_converter(time_step_durations) method_full_converter(time_step_durations)
#**************************************************************************
#**************************************************************************
def test_full_converter_irregular(self):
time_step_durations = [1,1.5,0.5,1] time_step_durations = [1,1.5,0.5,1]
example_full_converter(time_step_durations) method_full_converter(time_step_durations)
#************************************************************************** #**************************************************************************
#************************************************************************** #**************************************************************************
...@@ -95,8 +108,8 @@ def get_single_ode_model_data(relative_amplitude_variation: float = 0.0): ...@@ -95,8 +108,8 @@ def get_single_ode_model_data(relative_amplitude_variation: float = 0.0):
return Ci, Ria, Aw, min_rel_heat, x0 return Ci, Ria, Aw, min_rel_heat, x0
#****************************************************************************** # *****************************************************************************
#****************************************************************************** # *****************************************************************************
def get_multi_ode_model_data(relative_amplitude_variation: float = 0.0): def get_multi_ode_model_data(relative_amplitude_variation: float = 0.0):
...@@ -225,26 +238,21 @@ def get_two_node_model_signals(number_samples): ...@@ -225,26 +238,21 @@ def get_two_node_model_signals(number_samples):
#****************************************************************************** #******************************************************************************
#****************************************************************************** #******************************************************************************
def example_full_converter(time_step_durations: list): def method_full_converter(time_step_durations: list):
# number of samples # number of samples
number_time_steps = len(time_step_durations) number_time_steps = len(time_step_durations)
# get the coefficients # get the coefficients
Ci, Ch, Ria, Rih, Aw, min_rel_heat, Pw, x0 = get_multi_ode_model_data() Ci, Ch, Ria, Rih, Aw, min_rel_heat, Pw, x0 = get_multi_ode_model_data()
# get the model # get the model
a, b, c, d = two_node_model(Ci, Ch, Ria, Rih, Aw, min_rel_heat, Pw) a, b, c, d = two_node_model(Ci, Ch, Ria, Rih, Aw, min_rel_heat, Pw)
# get the signals # get the signals
inputs, states, outputs = get_two_node_model_signals(number_time_steps) inputs, states, outputs = get_two_node_model_signals(number_time_steps)
# create a dynamic system # create a dynamic system
ds = dynsys.DynamicSystem( ds = dynsys.DynamicSystem(
time_interval_durations=time_step_durations, time_interval_durations=time_step_durations,
A=a, A=a,
...@@ -253,7 +261,6 @@ def example_full_converter(time_step_durations: list): ...@@ -253,7 +261,6 @@ def example_full_converter(time_step_durations: list):
D=d) D=d)
# create a converter # create a converter
cvn1 = cvn.Converter( cvn1 = cvn.Converter(
'cvn1', 'cvn1',
sys=ds, sys=ds,
...@@ -264,11 +271,14 @@ def example_full_converter(time_step_durations: list): ...@@ -264,11 +271,14 @@ def example_full_converter(time_step_durations: list):
outputs=outputs) outputs=outputs)
# get the dictionaries # get the dictionaries
(a_innk,
a_innk, b_inmk, c_irnk, d_irmk, e_x_ink, e_y_irk = cvn1.matrix_dictionaries() b_inmk,
c_irnk,
# check the dicts d_irmk,
e_x_ink,
e_y_irk) = cvn1.matrix_dictionaries()
# TODO: check the dicts
#****************************************************************************** #******************************************************************************
#****************************************************************************** #******************************************************************************
\ No newline at end of file
This diff is collapsed.
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