Skip to content

Commit fab9368

Browse files
authored
Merge pull request #171 from flixOpt/next/patch
Next/patch
2 parents 424ddb7 + cd181c9 commit fab9368

3 files changed

Lines changed: 66 additions & 20 deletions

File tree

flixOpt/elements.py

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,6 @@ def do_modeling(self, system_model: SystemModel):
307307
'flow_rate',
308308
self,
309309
system_model.nr_of_time_steps,
310-
fixed_value=self.fixed_relative_flow_rate,
311310
lower_bound=self.absolute_flow_rate_bounds[0] if self.element.on_off_parameters is None else 0,
312311
upper_bound=self.absolute_flow_rate_bounds[1] if self.element.on_off_parameters is None else None,
313312
previous_values=self.element.previous_flow_rate,
@@ -328,7 +327,9 @@ def do_modeling(self, system_model: SystemModel):
328327
self.element.size,
329328
self.flow_rate,
330329
self.relative_flow_rate_bounds,
331-
fixed_relative_profile=self.fixed_relative_flow_rate,
330+
fixed_relative_profile=(None
331+
if self.element.fixed_relative_profile is None
332+
else self.element.fixed_relative_profile.active_data),
332333
on_variable=self._on.on if self._on is not None else None,
333334
)
334335
self._investment.do_modeling(system_model)
@@ -392,35 +393,25 @@ def with_investment(self) -> bool:
392393
"""Checks if the element's size is investment-driven."""
393394
return isinstance(self.element.size, InvestParameters)
394395

395-
@property
396-
def fixed_relative_flow_rate(self) -> Optional[np.ndarray]:
397-
"""Returns a fixed flow rate if defined by the element."""
398-
if self.element.fixed_relative_profile is not None:
399-
return self.element.fixed_relative_profile.active_data
400-
return None
401-
402396
@property
403397
def absolute_flow_rate_bounds(self) -> Tuple[Numeric, Numeric]:
404-
"""Returns absolute flow rate bounds. Iportant for OnOffModel"""
398+
"""Returns absolute flow rate bounds. Important for OnOffModel"""
405399
rel_min, rel_max = self.relative_flow_rate_bounds
406400
size = self.element.size
407-
if self.with_investment:
408-
if size.fixed_size is not None:
409-
return rel_min * size.fixed_size, rel_max * size.fixed_size
410-
return rel_min * size.minimum_size, rel_max * size.maximum_size
411-
else:
401+
if not self.with_investment:
412402
return rel_min * size, rel_max * size
403+
if size.fixed_size is not None:
404+
return rel_min * size.fixed_size, rel_max * size.fixed_size
405+
return rel_min * size.minimum_size, rel_max * size.maximum_size
406+
413407

414408
@property
415409
def relative_flow_rate_bounds(self) -> Tuple[Numeric, Numeric]:
416410
"""Returns relative flow rate bounds."""
417411
fixed_profile = self.element.fixed_relative_profile
418412
if fixed_profile is None:
419413
return self.element.relative_minimum.active_data, self.element.relative_maximum.active_data
420-
return (
421-
np.minimum(fixed_profile.active_data, self.element.relative_minimum.active_data),
422-
np.maximum(fixed_profile.active_data, self.element.relative_maximum.active_data),
423-
)
414+
return fixed_profile.active_data, fixed_profile.active_data
424415

425416

426417
class BusModel(ElementModel):

flixOpt/features.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ def _add_on_constraints(self, system_model: SystemModel, time_indices: Union[lis
309309
# eq: sum( Leistung(t,i)) - sum(Leistung_max(i)) * On(t) <= 0
310310
# --> damit Gleichungswerte nicht zu groß werden, noch durch nr_of_flows geteilt:
311311
# eq: sum( Leistung(t,i) / nr_of_flows ) - sum(Leistung_max(i)) / nr_of_flows * On(t) <= 0
312-
absolute_maximum: Numeric = 0
312+
absolute_maximum: Numeric = 0.0
313313
for variable, bounds in zip(self._defining_variables, self._defining_bounds, strict=False):
314314
eq_on_2.add_summand(variable, 1 / nr_of_defining_variables, time_indices)
315315
absolute_maximum += bounds[

tests/test_functional.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,61 @@ def test_optional_invest(self):
370370
err_msg='"Boiler__Q_th__IsInvested" does not have the right value',
371371
)
372372

373+
def test_fixed_relative_profile(self):
374+
self.flow_system = self.create_model(self.datetime_array)
375+
self.flow_system.add_elements(
376+
fx.linear_converters.Boiler(
377+
'Boiler',
378+
0.5,
379+
Q_fu=fx.Flow('Q_fu', bus=self.get_element('Gas')),
380+
Q_th=fx.Flow(
381+
'Q_th',
382+
bus=self.get_element('Fernwärme'),
383+
size=fx.InvestParameters(optional=True, minimum_size=40, fix_effects=10, specific_effects=1),
384+
),
385+
),
386+
fx.linear_converters.Boiler(
387+
'Boiler_optional',
388+
0.5,
389+
Q_fu=fx.Flow('Q_fu', bus=self.get_element('Gas')),
390+
Q_th=fx.Flow(
391+
'Q_th',
392+
bus=self.get_element('Fernwärme'),
393+
size=fx.InvestParameters(optional=True, minimum_size=50, fix_effects=10, specific_effects=1),
394+
),
395+
),
396+
)
397+
self.flow_system.add_elements(
398+
fx.Source(
399+
'Wärmequelle',
400+
source=fx.Flow('Q_th',
401+
bus=self.get_element('Fernwärme'),
402+
fixed_relative_profile=np.linspace(0, 5, len(self.datetime_array)),
403+
size=fx.InvestParameters(optional=False, minimum_size=2, maximum_size=5),
404+
)
405+
)
406+
)
407+
self.get_element('Fernwärme').excess_penalty_per_flow_hour = 1e5
408+
409+
self.solve_and_load(self.flow_system)
410+
source = self.get_element('Wärmequelle')
411+
assert_allclose(
412+
source.source.model.flow_rate.result,
413+
np.linspace(0, 5, len(self.datetime_array)) * source.source.model._investment.size.result,
414+
rtol=self.mip_gap,
415+
atol=1e-10,
416+
err_msg='The total costs does not have the right value',
417+
)
418+
assert_allclose(
419+
source.source.model._investment.size.result,
420+
2,
421+
rtol=self.mip_gap,
422+
atol=1e-10,
423+
err_msg='The total costs does not have the right value',
424+
)
425+
426+
427+
373428

374429
class TestOnOff(BaseTest):
375430
"""

0 commit comments

Comments
 (0)