Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Until here -->
## [Unreleased]

### Added
- Extra Check for HeatPumpWithSource.COP to be strictly > 1 to avoid division by zero

### Changed
- Greatly improved docstrings and documentation of all public classes
Expand All @@ -45,6 +46,9 @@ Until here -->
- Fix error handling in network visualization if networkx is not installed.
- Fix broken links in docs.
- Fix missing args in docstrings in `plotting.py`, `solvers.py`, and `core.py`.
- Fix COP getter and setter of `HeatPumpWithSource` returning and setting wrong conversion factors.
- Fix custom compression levels in `io.save_dataset_to_netcdf`
- Fix `total_max` did not work when total min was not used.

### Known Issues

Expand Down
4 changes: 2 additions & 2 deletions flixopt/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ def compute_consecutive_hours_in_state(
if len(hours_per_timestep) < nr_of_indexes_with_consecutive_ones:
raise ValueError(
f'When trying to calculate the consecutive duration, the length of the last duration '
f'({len(nr_of_indexes_with_consecutive_ones)}) is longer than the provided hours_per_timestep ({len(hours_per_timestep)}), '
f'({nr_of_indexes_with_consecutive_ones}) is longer than the provided hours_per_timestep ({len(hours_per_timestep)}), '
f'as {binary_values=}'
)

Expand Down Expand Up @@ -945,7 +945,7 @@ def __init__(

# Parameters
self._shares_are_time_series = shares_are_time_series
self._total_max = total_max if total_min is not None else np.inf
self._total_max = total_max if total_max is not None else np.inf
self._total_min = total_min if total_min is not None else -np.inf
self._max_per_hour = max_per_hour if max_per_hour is not None else np.inf
self._min_per_hour = min_per_hour if min_per_hour is not None else -np.inf
Expand Down
2 changes: 1 addition & 1 deletion flixopt/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def save_dataset_to_netcdf(
path,
encoding=None
if not apply_encoding
else {data_var: {'zlib': True, 'complevel': 5} for data_var in ds.data_vars},
else {data_var: {'zlib': True, 'complevel': compression} for data_var in ds.data_vars},
)


Expand Down
15 changes: 12 additions & 3 deletions flixopt/linear_converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -570,15 +570,24 @@ def __init__(
self.Q_ab = Q_ab
self.Q_th = Q_th

if np.any(np.asarray(self.COP) <= 1):
raise ValueError(f'{self.label_full}.COP must be strictly > 1 for HeatPumpWithSource.')

@property
def COP(self): # noqa: N802
return self.conversion_factors[0][self.Q_th.label]
return self.conversion_factors[0][self.P_el.label]

@COP.setter
def COP(self, value): # noqa: N802
check_bounds(value, 'COP', self.label_full, 1, 20)
self.conversion_factors[0][self.Q_th.label] = value
self.conversion_factors[1][self.Q_th.label] = value / (value - 1)
if np.any(np.asarray(self.COP) <= 1):
raise ValueError(f'{self.label_full}.COP must be strictly > 1 for HeatPumpWithSource.')
# electricity equation: COP * P_el == 1 * Q_th
self.conversion_factors[0][self.P_el.label] = value
self.conversion_factors[0][self.Q_th.label] = 1
# heat source equation: (COP/(COP-1)) * Q_ab == 1 * Q_th -> Q_ab = Q_th*(COP-1)/COP
self.conversion_factors[1][self.Q_ab.label] = value / (value - 1)
self.conversion_factors[1][self.Q_th.label] = 1


def check_bounds(
Expand Down
4 changes: 2 additions & 2 deletions tests/test_on_hours_computation.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def test_compute_duration(self, binary_values, hours_per_timestep, expected):
)
def test_compute_duration_raises_error(self, binary_values, hours_per_timestep):
"""Test error conditions."""
with pytest.raises(TypeError):
with pytest.raises(ValueError):
ConsecutiveStateModel.compute_consecutive_hours_in_state(binary_values, hours_per_timestep)


Expand All @@ -67,7 +67,7 @@ class TestComputePreviousOnStates:
([np.array([0.1, 0, 0.3]), None, np.array([0, 0, 0])], np.array([1, 0, 1])),
([np.array([0, 0, 0]), np.array([0, 1, 0])], np.array([0, 1, 0])),
([np.array([0.1, 0, 0]), np.array([0, 0, 0.2])], np.array([1, 0, 1])),
# Case 6: Mix of None, 1D and 2D arrays
# Case 6: Mix of None and 1D arrays
([None, np.array([0, 0, 0]), np.array([0, 1, 0]), np.array([0, 0, 0])], np.array([0, 1, 0])),
([np.array([0, 0, 0]), None, np.array([0, 0, 0]), np.array([0, 0, 0])], np.array([0, 0, 0])),
],
Expand Down