From 65caae0b6cfb6aefd71d078860724c759f20a5c9 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 20:59:06 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=93=9D=20Add=20docstrings=20to=20`fea?= =?UTF-8?q?ture/312-improve-and-move-docstrings`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docstrings generation was requested by @FBumann. * https://github.com/flixOpt/flixopt/pull/316#issuecomment-3286800236 The following files were modified: * `flixopt/calculation.py` * `flixopt/components.py` * `flixopt/core.py` * `flixopt/effects.py` * `flixopt/elements.py` * `flixopt/flow_system.py` * `flixopt/interface.py` --- flixopt/calculation.py | 31 ++++++++++++++++++++ flixopt/components.py | 57 ++++++++++++++++++++++++++++++++++++ flixopt/core.py | 15 ++++++++++ flixopt/effects.py | 27 +++++++++++++++++ flixopt/elements.py | 35 ++++++++++++++++++++++ flixopt/flow_system.py | 12 ++++++++ flixopt/interface.py | 66 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 243 insertions(+) diff --git a/flixopt/calculation.py b/flixopt/calculation.py index 22577ef59..51d59da42 100644 --- a/flixopt/calculation.py +++ b/flixopt/calculation.py @@ -134,6 +134,16 @@ class FullCalculation(Calculation): """ def do_modeling(self) -> SystemModel: + """ + Builds and runs the SystemModel for this calculation using the Calculation's FlowSystem. + + Activates the configured time series, creates the SystemModel from the associated FlowSystem, + runs the model's modeling step, records the modeling duration in self.durations['modeling'], + and stores the created model on self.model. + + Returns: + SystemModel: The built and modeled system model. + """ t_start = timeit.default_timer() self._activate_time_series() @@ -218,6 +228,27 @@ def __init__( active_timesteps: Optional[pd.DatetimeIndex] = None, folder: Optional[pathlib.Path] = None, ): + """ + Initialize an AggregatedCalculation. + + Creates an AggregatedCalculation that extends FullCalculation with aggregation configuration. + Stores the provided aggregation parameters and optional component selection and initializes + the aggregation result placeholder. + + Parameters: + name: Human-readable name for the calculation. + flow_system: The FlowSystem to build the SystemModel from. + aggregation_parameters: AggregationParameters controlling clustering (e.g., hours_per_period, + nr_of_periods, weighting and peak-labeling options). + components_to_clusterize: Optional list of components to include in the clustering step; + if None, the default component selection (all eligible components) is used. + active_timesteps: Optional subset of timesteps to activate for modeling (delegated to base class). + folder: Optional results folder path (delegated to base class). + + Side effects: + Sets self.aggregation to None; this will be replaced by the produced Aggregation after + _perform_aggregation runs. + """ super().__init__(name, flow_system, active_timesteps, folder=folder) self.aggregation_parameters = aggregation_parameters self.components_to_clusterize = components_to_clusterize diff --git a/flixopt/components.py b/flixopt/components.py index 37f1da8b9..8a8941c71 100644 --- a/flixopt/components.py +++ b/flixopt/components.py @@ -164,6 +164,27 @@ def __init__( meta_data: Optional[Dict] = None, ): # TODO: fixed_relative_chargeState implementieren + """ + Create a storage element representing an energy/material buffer with charging and discharging flows. + + The storage has a capacity expressed in flow-hours (either a numeric scalar or InvestParameters), a bounded charge state (given as relative min/max fractions of capacity), optional initial and final charge-state constraints, separate charge/discharge efficiencies, and proportional hourly self-losses. Optionally prevents simultaneous charging and discharging by marking those flows as mutually exclusive. + + Parameters: + label: Human-readable identifier for the storage element. + charging: Flow used to charge the storage (input). + discharging: Flow used to discharge the storage (output). + capacity_in_flow_hours: Storage capacity expressed as flow × hours. Can be a numeric scalar for fixed capacity or an InvestParameters instance to enable investment sizing. + relative_minimum_charge_state: Minimum allowed state-of-charge expressed as a fraction of capacity (default 0). + relative_maximum_charge_state: Maximum allowed state-of-charge expressed as a fraction of capacity (default 1). + initial_charge_state: Initial state-of-charge at the first time step; a numeric value (absolute in flow-hours) or the special string 'lastValueOfSim' to reuse the last simulated value (default 0). + minimal_final_charge_state: Optional lower bound for the state-of-charge at the final time step (absolute in flow-hours). + maximal_final_charge_state: Optional upper bound for the state-of-charge at the final time step (absolute in flow-hours). + eta_charge: Charging efficiency factor (multiplicative, default 1). + eta_discharge: Discharging efficiency factor (multiplicative, default 1). + relative_loss_per_hour: Fractional relative loss per hour applied to the stored energy (default 0). + prevent_simultaneous_charge_and_discharge: If True, charging and discharging flows are forbidden to be active at the same time (default True). + meta_data: Optional dictionary with user-defined metadata. + """ super().__init__( label, inputs=[charging], @@ -686,6 +707,28 @@ def __init__( prevent_simultaneous_flow_rates: bool = False, **kwargs, ): + """ + Initialize a Source element that produces one or more output flows. + + If the deprecated `source` keyword argument is provided it is accepted for + backwards compatibility (emits a DeprecationWarning) and must not be used + together with `outputs`. + + Parameters: + label: Human-readable identifier for the element. + outputs: List of output Flow objects produced by this Source. If + `prevent_simultaneous_flow_rates` is True, these outputs are used to + determine which flows cannot operate simultaneously. + meta_data: Optional mapping of additional metadata stored with the element. + prevent_simultaneous_flow_rates: If True, prevents simultaneous nonzero + rates across the specified outputs by wiring them into the base + `prevent_simultaneous_flows` mechanism. + + Notes: + - Using the legacy `source` kwarg will convert it to a single-item + `outputs` list and raise a DeprecationWarning. Supplying both `source` + and `outputs` raises ValueError. + """ source = kwargs.pop('source', None) if source is not None: warnings.warn( @@ -737,6 +780,20 @@ def __init__( prevent_simultaneous_flow_rates: bool = False, **kwargs, ): + """ + Initialize a Sink (consumes flow from the system). + + Supports legacy `sink=` keyword for backward compatibility (deprecated): if `sink` is provided it is used as the single input flow and a DeprecationWarning is issued; specifying both `inputs` and `sink` raises ValueError. + + Parameters: + label (str): Unique element label. + inputs (List[Flow], optional): Input flows for the sink. + meta_data (dict, optional): Arbitrary metadata attached to the element. + prevent_simultaneous_flow_rates (bool, optional): If True, prevents simultaneous nonzero flow rates across the element's inputs by wiring that restriction into the base Component setup. + + Note: + The deprecated `sink` kwarg is accepted for compatibility but will be removed in future releases. + """ sink = kwargs.pop('sink', None) if sink is not None: warnings.warn( diff --git a/flixopt/core.py b/flixopt/core.py index 8b4be7ea3..348dc4204 100644 --- a/flixopt/core.py +++ b/flixopt/core.py @@ -127,6 +127,21 @@ class TimeSeriesData: # TODO: Move to Interface.py def __init__(self, data: NumericData, agg_group: Optional[str] = None, agg_weight: Optional[float] = None): + """ + Initialize a TimeSeriesData wrapper that holds time series input data and optional aggregation metadata. + + Parameters: + data: The time-series data in any supported NumericData form (scalar, ndarray, pandas/xarray, etc.). + agg_group: Optional name of an aggregation group; when set, this series' aggregation weight is derived from the group's weight. + agg_weight: Optional explicit aggregation weight for this series. Must not be provided together with `agg_group`. + + Notes: + - Exactly one of `agg_group` or `agg_weight` may be specified; providing both raises ValueError. + - A `label` attribute is initialized to None and may be set later (e.g., when the series is added to a collection). + + Raises: + ValueError: If both `agg_group` and `agg_weight` are provided. + """ self.data = data self.agg_group = agg_group self.agg_weight = agg_weight diff --git a/flixopt/effects.py b/flixopt/effects.py index 19cbeaa4a..65714df42 100644 --- a/flixopt/effects.py +++ b/flixopt/effects.py @@ -67,6 +67,33 @@ def __init__( minimum_total: Optional[Scalar] = None, maximum_total: Optional[Scalar] = None, ): + """ + Initialize an Effect representing a measurable impact (e.g., cost, emission, area). + + Args: + label: Unique identifier for the effect. + unit: Unit string for the effect values (e.g., "kg", "EUR"). + description: Human-readable description of the effect. + meta_data: Optional arbitrary metadata stored with the effect. + is_standard: If True this effect is treated as the collection's default (used when a scalar/default is supplied). + is_objective: If True this effect is marked as the optimization objective. + specific_share_to_other_effects_operation: Per-effect operation shares (user form). If omitted, defaults to an empty mapping. + specific_share_to_other_effects_invest: Per-effect investment shares (user form). If omitted, defaults to an empty mapping. + minimum_operation: Optional lower bound scalar for the aggregated operation contribution. + maximum_operation: Optional upper bound scalar for the aggregated operation contribution. + minimum_invest: Optional lower bound scalar for the aggregated investment contribution. + maximum_invest: Optional upper bound scalar for the aggregated investment contribution. + minimum_operation_per_hour: Optional time series providing per-timestep lower bounds for operation. + maximum_operation_per_hour: Optional time series providing per-timestep upper bounds for operation. + minimum_total: Optional lower bound scalar for the total (operation + invest). + maximum_total: Optional upper bound scalar for the total (operation + invest). + + Notes: + - Shares provided via `specific_share_to_other_effects_operation` and + `specific_share_to_other_effects_invest` are kept in user form and later + converted to internal time-series representations during model transformation. + - Bounds may be None to indicate unbounded in that direction. + """ super().__init__(label, meta_data=meta_data) self.label = label self.unit = unit diff --git a/flixopt/elements.py b/flixopt/elements.py index 283d0cef9..8de46a1ef 100644 --- a/flixopt/elements.py +++ b/flixopt/elements.py @@ -107,6 +107,17 @@ class Bus(Element): def __init__( self, label: str, excess_penalty_per_flow_hour: Optional[NumericDataTS] = 1e5, meta_data: Optional[Dict] = None ): + """ + Initialize a Bus element representing a nodal balance with optional excess-penalty. + + Parameters: + label: Unique identifier for the bus. + excess_penalty_per_flow_hour: Scalar or time series giving the monetary penalty applied per unit of excess flow-hour (inputs or outputs). If None, no excess variables/penalty are created. Defaults to 1e5. + meta_data: Optional mapping of user-provided metadata. + + Notes: + The constructor also initializes empty `inputs` and `outputs` lists for connected Flow objects. + """ super().__init__(label, meta_data=meta_data) self.excess_penalty_per_flow_hour = excess_penalty_per_flow_hour self.inputs: List[Flow] = [] @@ -197,6 +208,30 @@ def __init__( previous_flow_rate: Optional[NumericData] = None, meta_data: Optional[Dict] = None, ): + """ + Initialize a Flow element representing material/energy transfer between a Bus and a Component. + + Creates and stores sizing, bounds, profiles, operational constraints, effects and bookkeeping fields used later by the modeling layer. Important behaviors: + - If `size` is None, a large default (CONFIG.modeling.BIG) is used. + - Passing a Bus object to `bus` is deprecated: the Bus's full label is recorded and a UserWarning is emitted; prefer passing the bus label string. + - If `previous_flow_rate` is provided as a list, it is converted to a NumPy array. + + Parameters: + label: Unique flow identifier. + bus: Bus label string (preferred). If a Bus instance is passed, its label_full is used and a deprecation warning is emitted. + size: Fixed numeric size or InvestParameters to enable investment modeling. If omitted, a large default is used. + fixed_relative_profile: Optional time series that fixes the flow profile relative to `size`. + relative_minimum: Relative lower bound (fraction of size or profile); defaults to 0. + relative_maximum: Relative upper bound (fraction of size or profile); defaults to 1. + effects_per_flow_hour: Optional mapping of effect identifiers to per-hour effect factors applied to operation. + on_off_parameters: Optional OnOffParameters controlling on/off behavior for this flow. + flow_hours_total_max: Optional scalar upper bound for total flow-hours over the planning horizon. + flow_hours_total_min: Optional scalar lower bound for total flow-hours. + load_factor_min: Optional minimum capacity-factor (total flow-hours / (size * total_hours)). + load_factor_max: Optional maximum capacity-factor. + previous_flow_rate: Optional numeric time series (or list) with previous flow values; lists are converted to NumPy arrays. + meta_data: Optional dictionary of user metadata. + """ super().__init__(label, meta_data=meta_data) self.size = size or CONFIG.modeling.BIG # Default size self.relative_minimum = relative_minimum diff --git a/flixopt/flow_system.py b/flixopt/flow_system.py index e4887053c..96b5fd1de 100644 --- a/flixopt/flow_system.py +++ b/flixopt/flow_system.py @@ -48,6 +48,18 @@ def __init__( hours_of_last_timestep: Optional[float] = None, hours_of_previous_timesteps: Optional[Union[int, float, np.ndarray]] = None, ): + """ + Initialize a FlowSystem that manages components, buses, effects, and their time-series. + + Parameters: + timesteps: DatetimeIndex defining the primary timesteps for the system's TimeSeriesCollection. + hours_of_last_timestep: Duration (in hours) of the final timestep; if None, inferred from timesteps or defaults in TimeSeriesCollection. + hours_of_previous_timesteps: Scalar or array-like durations (in hours) for the preceding timesteps; used to configure non-uniform timestep lengths. + + Notes: + Creates an empty registry for components and buses, an empty EffectCollection, and a placeholder for a SystemModel. + The instance starts disconnected (self._connected == False) and with no active network visualization app. + """ self.time_series_collection = TimeSeriesCollection( timesteps=timesteps, hours_of_last_timestep=hours_of_last_timestep, diff --git a/flixopt/interface.py b/flixopt/interface.py index 1b240bc4b..e89753373 100644 --- a/flixopt/interface.py +++ b/flixopt/interface.py @@ -70,6 +70,13 @@ class Piece(Interface): """ def __init__(self, start: NumericData, end: NumericData): + """ + Create a linear segment defined by its start and end numeric values. + + Parameters: + start (NumericData): Value at the segment's start boundary. + end (NumericData): Value at the segment's end boundary. + """ self.start = start self.end = end @@ -158,9 +165,21 @@ class Piecewise(Interface): """ def __init__(self, pieces: List[Piece]): + """ + Initialize a piecewise linear function from an ordered list of Piece segments. + + Parameters: + pieces (List[Piece]): Ordered sequence of Piece objects representing consecutive segments of the piecewise linear function. The order of items defines the sequence of segments; no validation is performed. + """ self.pieces = pieces def __len__(self): + """ + Return the number of Piece segments in this Piecewise container. + + Returns: + int: Count of contained Piece objects. + """ return len(self.pieces) def __getitem__(self, index) -> Piece: @@ -338,9 +357,21 @@ class PiecewiseConversion(Interface): """ def __init__(self, piecewises: Dict[str, Piecewise]): + """ + Initialize a PiecewiseConversion mapping flow labels to their Piecewise conversions. + + Parameters: + piecewises (Dict[str, Piecewise]): Mapping from flow identifier (label) to its Piecewise object; used by transform_data to convert each flow's piecewise definition into time-series data. + """ self.piecewises = piecewises def items(self): + """ + Return an iterator over (flow_label, Piecewise) pairs stored in this PiecewiseConversion. + + This is a thin convenience wrapper around the internal mapping and yields the same view + as dict.items(), where each key is a flow label (str) and each value is a Piecewise. + """ return self.piecewises.items() def transform_data(self, flow_system: 'FlowSystem', name_prefix: str): @@ -477,6 +508,13 @@ class PiecewiseEffects(Interface): """ def __init__(self, piecewise_origin: Piecewise, piecewise_shares: Dict[str, Piecewise]): + """ + Initialize a PiecewiseEffects container linking a primary piecewise function to per-effect piecewise shares. + + Parameters: + piecewise_origin (Piecewise): The primary piecewise function that defines the base relationship. + piecewise_shares (Dict[str, Piecewise]): Mapping from effect name to a Piecewise that defines that effect's share of the origin (per-effect piecewise share). + """ self.piecewise_origin = piecewise_origin self.piecewise_shares = piecewise_shares @@ -686,6 +724,19 @@ def __init__( piecewise_effects: Optional[PiecewiseEffects] = None, divest_effects: Optional['EffectValuesUserScalar'] = None, ): + """ + Initialize investment parameter container. + + Parameters: + fixed_size: If set, investment is treated as a fixed (non-continuous) size and both minimum and maximum sizing will effectively be this value. + minimum_size: Lower bound for continuous sizing; if omitted defaults to CONFIG.modeling.EPSILON. Ignored when `fixed_size` is provided. + maximum_size: Upper bound for continuous sizing; if omitted defaults to CONFIG.modeling.BIG. Ignored when `fixed_size` is provided. + optional: If True, investment may be omitted (binary invest/not-invest behavior allowed). + fix_effects: Fixed effects (one-time or capacity-independent) incurred when the investment is made. + specific_effects: Effects that scale with installed size (per-unit investment effects). + piecewise_effects: Piecewise (nonlinear) effects mapping size to effect values. + divest_effects: Effects incurred if the investment is not made (opposite of `fix_effects`). + """ self.fix_effects: EffectValuesUser = fix_effects or {} self.divest_effects: EffectValuesUser = divest_effects or {} self.fixed_size = fixed_size @@ -895,6 +946,21 @@ def __init__( switch_on_total_max: Optional[int] = None, force_switch_on: bool = False, ): + """ + Initialize OnOffParameters controlling binary on/off behavior and associated costs. + + Parameters: + effects_per_switch_on: Mapping of effect identifiers to values applied each time the unit switches from off to on (startup costs/effects). Can be empty. + effects_per_running_hour: Mapping of effect identifiers to values applied per running hour while on (operating costs/impacts). Can be empty. + on_hours_total_min: Minimum total on-hours across the horizon (integer hours). + on_hours_total_max: Maximum total on-hours across the horizon (integer hours). + consecutive_on_hours_min: Minimum continuous on-hours after a start; may be a scalar or time-series (NumericData). + consecutive_on_hours_max: Maximum continuous on-hours after a start; may be a scalar or time-series (NumericData). + consecutive_off_hours_min: Minimum continuous off-hours between runs; may be a scalar or time-series (NumericData). + consecutive_off_hours_max: Maximum continuous off-hours between runs; may be a scalar or time-series (NumericData). + switch_on_total_max: Maximum number of switch-on (startup) events allowed across the horizon. + force_switch_on: If True, force creation of a switch-on variable even if no other switch-on constraints or effects are provided. + """ self.effects_per_switch_on: EffectValuesUser = effects_per_switch_on or {} self.effects_per_running_hour: EffectValuesUser = effects_per_running_hour or {} self.on_hours_total_min: Scalar = on_hours_total_min From 650eccd5648a4591a4f78d528cdcc25ad5271522 Mon Sep 17 00:00:00 2001 From: FBumann <117816358+FBumann@users.noreply.github.com> Date: Fri, 12 Sep 2025 23:01:34 +0200 Subject: [PATCH 2/4] ruff format and lint --- flixopt/calculation.py | 10 +++++----- flixopt/components.py | 16 ++++++++-------- flixopt/core.py | 6 +++--- flixopt/effects.py | 4 ++-- flixopt/elements.py | 8 ++++---- flixopt/flow_system.py | 4 ++-- flixopt/interface.py | 16 ++++++++-------- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/flixopt/calculation.py b/flixopt/calculation.py index 51d59da42..6b57c4cf3 100644 --- a/flixopt/calculation.py +++ b/flixopt/calculation.py @@ -136,11 +136,11 @@ class FullCalculation(Calculation): def do_modeling(self) -> SystemModel: """ Builds and runs the SystemModel for this calculation using the Calculation's FlowSystem. - + Activates the configured time series, creates the SystemModel from the associated FlowSystem, runs the model's modeling step, records the modeling duration in self.durations['modeling'], and stores the created model on self.model. - + Returns: SystemModel: The built and modeled system model. """ @@ -230,11 +230,11 @@ def __init__( ): """ Initialize an AggregatedCalculation. - + Creates an AggregatedCalculation that extends FullCalculation with aggregation configuration. Stores the provided aggregation parameters and optional component selection and initializes the aggregation result placeholder. - + Parameters: name: Human-readable name for the calculation. flow_system: The FlowSystem to build the SystemModel from. @@ -244,7 +244,7 @@ def __init__( if None, the default component selection (all eligible components) is used. active_timesteps: Optional subset of timesteps to activate for modeling (delegated to base class). folder: Optional results folder path (delegated to base class). - + Side effects: Sets self.aggregation to None; this will be replaced by the produced Aggregation after _perform_aggregation runs. diff --git a/flixopt/components.py b/flixopt/components.py index 8a8941c71..b790e5256 100644 --- a/flixopt/components.py +++ b/flixopt/components.py @@ -166,9 +166,9 @@ def __init__( # TODO: fixed_relative_chargeState implementieren """ Create a storage element representing an energy/material buffer with charging and discharging flows. - + The storage has a capacity expressed in flow-hours (either a numeric scalar or InvestParameters), a bounded charge state (given as relative min/max fractions of capacity), optional initial and final charge-state constraints, separate charge/discharge efficiencies, and proportional hourly self-losses. Optionally prevents simultaneous charging and discharging by marking those flows as mutually exclusive. - + Parameters: label: Human-readable identifier for the storage element. charging: Flow used to charge the storage (input). @@ -709,11 +709,11 @@ def __init__( ): """ Initialize a Source element that produces one or more output flows. - + If the deprecated `source` keyword argument is provided it is accepted for backwards compatibility (emits a DeprecationWarning) and must not be used together with `outputs`. - + Parameters: label: Human-readable identifier for the element. outputs: List of output Flow objects produced by this Source. If @@ -723,7 +723,7 @@ def __init__( prevent_simultaneous_flow_rates: If True, prevents simultaneous nonzero rates across the specified outputs by wiring them into the base `prevent_simultaneous_flows` mechanism. - + Notes: - Using the legacy `source` kwarg will convert it to a single-item `outputs` list and raise a DeprecationWarning. Supplying both `source` @@ -782,15 +782,15 @@ def __init__( ): """ Initialize a Sink (consumes flow from the system). - + Supports legacy `sink=` keyword for backward compatibility (deprecated): if `sink` is provided it is used as the single input flow and a DeprecationWarning is issued; specifying both `inputs` and `sink` raises ValueError. - + Parameters: label (str): Unique element label. inputs (List[Flow], optional): Input flows for the sink. meta_data (dict, optional): Arbitrary metadata attached to the element. prevent_simultaneous_flow_rates (bool, optional): If True, prevents simultaneous nonzero flow rates across the element's inputs by wiring that restriction into the base Component setup. - + Note: The deprecated `sink` kwarg is accepted for compatibility but will be removed in future releases. """ diff --git a/flixopt/core.py b/flixopt/core.py index 348dc4204..043880ccc 100644 --- a/flixopt/core.py +++ b/flixopt/core.py @@ -129,16 +129,16 @@ class TimeSeriesData: def __init__(self, data: NumericData, agg_group: Optional[str] = None, agg_weight: Optional[float] = None): """ Initialize a TimeSeriesData wrapper that holds time series input data and optional aggregation metadata. - + Parameters: data: The time-series data in any supported NumericData form (scalar, ndarray, pandas/xarray, etc.). agg_group: Optional name of an aggregation group; when set, this series' aggregation weight is derived from the group's weight. agg_weight: Optional explicit aggregation weight for this series. Must not be provided together with `agg_group`. - + Notes: - Exactly one of `agg_group` or `agg_weight` may be specified; providing both raises ValueError. - A `label` attribute is initialized to None and may be set later (e.g., when the series is added to a collection). - + Raises: ValueError: If both `agg_group` and `agg_weight` are provided. """ diff --git a/flixopt/effects.py b/flixopt/effects.py index 65714df42..81dcc3e30 100644 --- a/flixopt/effects.py +++ b/flixopt/effects.py @@ -69,7 +69,7 @@ def __init__( ): """ Initialize an Effect representing a measurable impact (e.g., cost, emission, area). - + Args: label: Unique identifier for the effect. unit: Unit string for the effect values (e.g., "kg", "EUR"). @@ -87,7 +87,7 @@ def __init__( maximum_operation_per_hour: Optional time series providing per-timestep upper bounds for operation. minimum_total: Optional lower bound scalar for the total (operation + invest). maximum_total: Optional upper bound scalar for the total (operation + invest). - + Notes: - Shares provided via `specific_share_to_other_effects_operation` and `specific_share_to_other_effects_invest` are kept in user form and later diff --git a/flixopt/elements.py b/flixopt/elements.py index 8de46a1ef..963880f9a 100644 --- a/flixopt/elements.py +++ b/flixopt/elements.py @@ -109,12 +109,12 @@ def __init__( ): """ Initialize a Bus element representing a nodal balance with optional excess-penalty. - + Parameters: label: Unique identifier for the bus. excess_penalty_per_flow_hour: Scalar or time series giving the monetary penalty applied per unit of excess flow-hour (inputs or outputs). If None, no excess variables/penalty are created. Defaults to 1e5. meta_data: Optional mapping of user-provided metadata. - + Notes: The constructor also initializes empty `inputs` and `outputs` lists for connected Flow objects. """ @@ -210,12 +210,12 @@ def __init__( ): """ Initialize a Flow element representing material/energy transfer between a Bus and a Component. - + Creates and stores sizing, bounds, profiles, operational constraints, effects and bookkeeping fields used later by the modeling layer. Important behaviors: - If `size` is None, a large default (CONFIG.modeling.BIG) is used. - Passing a Bus object to `bus` is deprecated: the Bus's full label is recorded and a UserWarning is emitted; prefer passing the bus label string. - If `previous_flow_rate` is provided as a list, it is converted to a NumPy array. - + Parameters: label: Unique flow identifier. bus: Bus label string (preferred). If a Bus instance is passed, its label_full is used and a deprecation warning is emitted. diff --git a/flixopt/flow_system.py b/flixopt/flow_system.py index 96b5fd1de..4c0b8eb17 100644 --- a/flixopt/flow_system.py +++ b/flixopt/flow_system.py @@ -50,12 +50,12 @@ def __init__( ): """ Initialize a FlowSystem that manages components, buses, effects, and their time-series. - + Parameters: timesteps: DatetimeIndex defining the primary timesteps for the system's TimeSeriesCollection. hours_of_last_timestep: Duration (in hours) of the final timestep; if None, inferred from timesteps or defaults in TimeSeriesCollection. hours_of_previous_timesteps: Scalar or array-like durations (in hours) for the preceding timesteps; used to configure non-uniform timestep lengths. - + Notes: Creates an empty registry for components and buses, an empty EffectCollection, and a placeholder for a SystemModel. The instance starts disconnected (self._connected == False) and with no active network visualization app. diff --git a/flixopt/interface.py b/flixopt/interface.py index e89753373..05939c333 100644 --- a/flixopt/interface.py +++ b/flixopt/interface.py @@ -72,7 +72,7 @@ class Piece(Interface): def __init__(self, start: NumericData, end: NumericData): """ Create a linear segment defined by its start and end numeric values. - + Parameters: start (NumericData): Value at the segment's start boundary. end (NumericData): Value at the segment's end boundary. @@ -167,7 +167,7 @@ class Piecewise(Interface): def __init__(self, pieces: List[Piece]): """ Initialize a piecewise linear function from an ordered list of Piece segments. - + Parameters: pieces (List[Piece]): Ordered sequence of Piece objects representing consecutive segments of the piecewise linear function. The order of items defines the sequence of segments; no validation is performed. """ @@ -176,7 +176,7 @@ def __init__(self, pieces: List[Piece]): def __len__(self): """ Return the number of Piece segments in this Piecewise container. - + Returns: int: Count of contained Piece objects. """ @@ -359,7 +359,7 @@ class PiecewiseConversion(Interface): def __init__(self, piecewises: Dict[str, Piecewise]): """ Initialize a PiecewiseConversion mapping flow labels to their Piecewise conversions. - + Parameters: piecewises (Dict[str, Piecewise]): Mapping from flow identifier (label) to its Piecewise object; used by transform_data to convert each flow's piecewise definition into time-series data. """ @@ -368,7 +368,7 @@ def __init__(self, piecewises: Dict[str, Piecewise]): def items(self): """ Return an iterator over (flow_label, Piecewise) pairs stored in this PiecewiseConversion. - + This is a thin convenience wrapper around the internal mapping and yields the same view as dict.items(), where each key is a flow label (str) and each value is a Piecewise. """ @@ -510,7 +510,7 @@ class PiecewiseEffects(Interface): def __init__(self, piecewise_origin: Piecewise, piecewise_shares: Dict[str, Piecewise]): """ Initialize a PiecewiseEffects container linking a primary piecewise function to per-effect piecewise shares. - + Parameters: piecewise_origin (Piecewise): The primary piecewise function that defines the base relationship. piecewise_shares (Dict[str, Piecewise]): Mapping from effect name to a Piecewise that defines that effect's share of the origin (per-effect piecewise share). @@ -726,7 +726,7 @@ def __init__( ): """ Initialize investment parameter container. - + Parameters: fixed_size: If set, investment is treated as a fixed (non-continuous) size and both minimum and maximum sizing will effectively be this value. minimum_size: Lower bound for continuous sizing; if omitted defaults to CONFIG.modeling.EPSILON. Ignored when `fixed_size` is provided. @@ -948,7 +948,7 @@ def __init__( ): """ Initialize OnOffParameters controlling binary on/off behavior and associated costs. - + Parameters: effects_per_switch_on: Mapping of effect identifiers to values applied each time the unit switches from off to on (startup costs/effects). Can be empty. effects_per_running_hour: Mapping of effect identifiers to values applied per running hour while on (operating costs/impacts). Can be empty. From 79c6871fbaeda046e6d4eb52bb0663fd43f8474d Mon Sep 17 00:00:00 2001 From: FBumann <117816358+FBumann@users.noreply.github.com> Date: Fri, 12 Sep 2025 23:20:36 +0200 Subject: [PATCH 3/4] Manual updates --- flixopt/calculation.py | 32 +--------------------- flixopt/components.py | 62 +++++++++++++----------------------------- flixopt/core.py | 15 ---------- flixopt/effects.py | 31 +++------------------ flixopt/elements.py | 46 ++++++++----------------------- flixopt/flow_system.py | 5 ++++ flixopt/interface.py | 48 -------------------------------- 7 files changed, 40 insertions(+), 199 deletions(-) diff --git a/flixopt/calculation.py b/flixopt/calculation.py index 6b57c4cf3..de62f47f9 100644 --- a/flixopt/calculation.py +++ b/flixopt/calculation.py @@ -134,16 +134,6 @@ class FullCalculation(Calculation): """ def do_modeling(self) -> SystemModel: - """ - Builds and runs the SystemModel for this calculation using the Calculation's FlowSystem. - - Activates the configured time series, creates the SystemModel from the associated FlowSystem, - runs the model's modeling step, records the modeling duration in self.durations['modeling'], - and stores the created model on self.model. - - Returns: - SystemModel: The built and modeled system model. - """ t_start = timeit.default_timer() self._activate_time_series() @@ -217,6 +207,7 @@ class AggregatedCalculation(FullCalculation): This equalizes variables in the components according to the typical periods computed in the aggregation active_timesteps: DatetimeIndex of timesteps to use for calculation. If None, all timesteps are used folder: Folder where results should be saved. If None, current working directory is used + aggregation: contains the aggregation model """ def __init__( @@ -228,27 +219,6 @@ def __init__( active_timesteps: Optional[pd.DatetimeIndex] = None, folder: Optional[pathlib.Path] = None, ): - """ - Initialize an AggregatedCalculation. - - Creates an AggregatedCalculation that extends FullCalculation with aggregation configuration. - Stores the provided aggregation parameters and optional component selection and initializes - the aggregation result placeholder. - - Parameters: - name: Human-readable name for the calculation. - flow_system: The FlowSystem to build the SystemModel from. - aggregation_parameters: AggregationParameters controlling clustering (e.g., hours_per_period, - nr_of_periods, weighting and peak-labeling options). - components_to_clusterize: Optional list of components to include in the clustering step; - if None, the default component selection (all eligible components) is used. - active_timesteps: Optional subset of timesteps to activate for modeling (delegated to base class). - folder: Optional results folder path (delegated to base class). - - Side effects: - Sets self.aggregation to None; this will be replaced by the produced Aggregation after - _perform_aggregation runs. - """ super().__init__(name, flow_system, active_timesteps, folder=folder) self.aggregation_parameters = aggregation_parameters self.components_to_clusterize = components_to_clusterize diff --git a/flixopt/components.py b/flixopt/components.py index b790e5256..1df7d7b92 100644 --- a/flixopt/components.py +++ b/flixopt/components.py @@ -164,27 +164,6 @@ def __init__( meta_data: Optional[Dict] = None, ): # TODO: fixed_relative_chargeState implementieren - """ - Create a storage element representing an energy/material buffer with charging and discharging flows. - - The storage has a capacity expressed in flow-hours (either a numeric scalar or InvestParameters), a bounded charge state (given as relative min/max fractions of capacity), optional initial and final charge-state constraints, separate charge/discharge efficiencies, and proportional hourly self-losses. Optionally prevents simultaneous charging and discharging by marking those flows as mutually exclusive. - - Parameters: - label: Human-readable identifier for the storage element. - charging: Flow used to charge the storage (input). - discharging: Flow used to discharge the storage (output). - capacity_in_flow_hours: Storage capacity expressed as flow × hours. Can be a numeric scalar for fixed capacity or an InvestParameters instance to enable investment sizing. - relative_minimum_charge_state: Minimum allowed state-of-charge expressed as a fraction of capacity (default 0). - relative_maximum_charge_state: Maximum allowed state-of-charge expressed as a fraction of capacity (default 1). - initial_charge_state: Initial state-of-charge at the first time step; a numeric value (absolute in flow-hours) or the special string 'lastValueOfSim' to reuse the last simulated value (default 0). - minimal_final_charge_state: Optional lower bound for the state-of-charge at the final time step (absolute in flow-hours). - maximal_final_charge_state: Optional upper bound for the state-of-charge at the final time step (absolute in flow-hours). - eta_charge: Charging efficiency factor (multiplicative, default 1). - eta_discharge: Discharging efficiency factor (multiplicative, default 1). - relative_loss_per_hour: Fractional relative loss per hour applied to the stored energy (default 0). - prevent_simultaneous_charge_and_discharge: If True, charging and discharging flows are forbidden to be active at the same time (default True). - meta_data: Optional dictionary with user-defined metadata. - """ super().__init__( label, inputs=[charging], @@ -601,6 +580,19 @@ def relative_charge_state_bounds(self) -> Tuple[NumericData, NumericData]: class SourceAndSink(Component): """ class for source (output-flow) and sink (input-flow) in one commponent + A SourceAndSink consumes AND provides energy or material flows from and to the system. + + Sources can represent markets where energy or material can be bought or sold. + + Args: + label: The label of the Element. Used to identify it in the FlowSystem + inputs: Input-flows into the SourceAndSink + outputs: Output-flows from the SourceAndSink + prevent_simultaneous_flow_rates: If True, only one output flow can be active at a time + meta_data: Used to store more information about the Element. Is not used internally, but saved in the results. Only use python native types. + + Deprecated: + The deprecated `sink` and `source` kwargs are accepted for compatibility but will be removed in future releases. """ def __init__( @@ -697,6 +689,9 @@ class Source(Component): outputs: Output-flows from the source meta_data: Used to store more information about the Element. Is not used internally, but saved in the results. Only use python native types. prevent_simultaneous_flow_rates: If True, only one output flow can be active at a time + + Deprecated: + The deprecated `source` kwarg is accepted for compatibility but will be removed in future releases. """ def __init__( @@ -707,28 +702,6 @@ def __init__( prevent_simultaneous_flow_rates: bool = False, **kwargs, ): - """ - Initialize a Source element that produces one or more output flows. - - If the deprecated `source` keyword argument is provided it is accepted for - backwards compatibility (emits a DeprecationWarning) and must not be used - together with `outputs`. - - Parameters: - label: Human-readable identifier for the element. - outputs: List of output Flow objects produced by this Source. If - `prevent_simultaneous_flow_rates` is True, these outputs are used to - determine which flows cannot operate simultaneously. - meta_data: Optional mapping of additional metadata stored with the element. - prevent_simultaneous_flow_rates: If True, prevents simultaneous nonzero - rates across the specified outputs by wiring them into the base - `prevent_simultaneous_flows` mechanism. - - Notes: - - Using the legacy `source` kwarg will convert it to a single-item - `outputs` list and raise a DeprecationWarning. Supplying both `source` - and `outputs` raises ValueError. - """ source = kwargs.pop('source', None) if source is not None: warnings.warn( @@ -770,6 +743,9 @@ class Sink(Component): inputs: Input-flows into the sink meta_data: Used to store more information about the Element. Is not used internally, but saved in the results. Only use python native types. prevent_simultaneous_flow_rates: If True, only one input flow can be active at a time + + Deprecated: + The deprecated `sink` kwarg is accepted for compatibility but will be removed in future releases. """ def __init__( diff --git a/flixopt/core.py b/flixopt/core.py index 043880ccc..8b4be7ea3 100644 --- a/flixopt/core.py +++ b/flixopt/core.py @@ -127,21 +127,6 @@ class TimeSeriesData: # TODO: Move to Interface.py def __init__(self, data: NumericData, agg_group: Optional[str] = None, agg_weight: Optional[float] = None): - """ - Initialize a TimeSeriesData wrapper that holds time series input data and optional aggregation metadata. - - Parameters: - data: The time-series data in any supported NumericData form (scalar, ndarray, pandas/xarray, etc.). - agg_group: Optional name of an aggregation group; when set, this series' aggregation weight is derived from the group's weight. - agg_weight: Optional explicit aggregation weight for this series. Must not be provided together with `agg_group`. - - Notes: - - Exactly one of `agg_group` or `agg_weight` may be specified; providing both raises ValueError. - - A `label` attribute is initialized to None and may be set later (e.g., when the series is added to a collection). - - Raises: - ValueError: If both `agg_group` and `agg_weight` are provided. - """ self.data = data self.agg_group = agg_group self.agg_weight = agg_weight diff --git a/flixopt/effects.py b/flixopt/effects.py index 81dcc3e30..8ed82a24c 100644 --- a/flixopt/effects.py +++ b/flixopt/effects.py @@ -46,6 +46,10 @@ class Effect(Element): minimum_total: Min sum of effect (invest+operation) maximum_total: Max sum of effect (invest+operation) meta_data: Used to store more information about the Element. Is not used internally, but saved in the results. Only use python native types. + + Notes: + - Bounds may be None to indicate unbounded in that direction. + - The unit of the effect is only informative and does not affect the optimization. """ def __init__( @@ -67,33 +71,6 @@ def __init__( minimum_total: Optional[Scalar] = None, maximum_total: Optional[Scalar] = None, ): - """ - Initialize an Effect representing a measurable impact (e.g., cost, emission, area). - - Args: - label: Unique identifier for the effect. - unit: Unit string for the effect values (e.g., "kg", "EUR"). - description: Human-readable description of the effect. - meta_data: Optional arbitrary metadata stored with the effect. - is_standard: If True this effect is treated as the collection's default (used when a scalar/default is supplied). - is_objective: If True this effect is marked as the optimization objective. - specific_share_to_other_effects_operation: Per-effect operation shares (user form). If omitted, defaults to an empty mapping. - specific_share_to_other_effects_invest: Per-effect investment shares (user form). If omitted, defaults to an empty mapping. - minimum_operation: Optional lower bound scalar for the aggregated operation contribution. - maximum_operation: Optional upper bound scalar for the aggregated operation contribution. - minimum_invest: Optional lower bound scalar for the aggregated investment contribution. - maximum_invest: Optional upper bound scalar for the aggregated investment contribution. - minimum_operation_per_hour: Optional time series providing per-timestep lower bounds for operation. - maximum_operation_per_hour: Optional time series providing per-timestep upper bounds for operation. - minimum_total: Optional lower bound scalar for the total (operation + invest). - maximum_total: Optional upper bound scalar for the total (operation + invest). - - Notes: - - Shares provided via `specific_share_to_other_effects_operation` and - `specific_share_to_other_effects_invest` are kept in user form and later - converted to internal time-series representations during model transformation. - - Bounds may be None to indicate unbounded in that direction. - """ super().__init__(label, meta_data=meta_data) self.label = label self.unit = unit diff --git a/flixopt/elements.py b/flixopt/elements.py index 963880f9a..1b444b11e 100644 --- a/flixopt/elements.py +++ b/flixopt/elements.py @@ -102,22 +102,15 @@ class Bus(Element): (none/ 0 -> no penalty). The default is 1e5. (Take care: if you use a timeseries (no scalar), timeseries is aggregated if calculation_type = aggregated!) meta_data: used to store more information about the Element. Is not used internally, but saved in the results. Only use python native types. + + Notes: + The constructor also initializes empty `inputs` and `outputs` lists for connected Flow objects. + The registration of connections is handled automatically by the FlowSystem. """ def __init__( self, label: str, excess_penalty_per_flow_hour: Optional[NumericDataTS] = 1e5, meta_data: Optional[Dict] = None ): - """ - Initialize a Bus element representing a nodal balance with optional excess-penalty. - - Parameters: - label: Unique identifier for the bus. - excess_penalty_per_flow_hour: Scalar or time series giving the monetary penalty applied per unit of excess flow-hour (inputs or outputs). If None, no excess variables/penalty are created. Defaults to 1e5. - meta_data: Optional mapping of user-provided metadata. - - Notes: - The constructor also initializes empty `inputs` and `outputs` lists for connected Flow objects. - """ super().__init__(label, meta_data=meta_data) self.excess_penalty_per_flow_hour = excess_penalty_per_flow_hour self.inputs: List[Flow] = [] @@ -161,6 +154,13 @@ class Flow(Element): A **Flow** moves energy (or material) between a [Bus][flixopt.elements.Bus] and a [Component][flixopt.elements.Component] in a predefined direction. The flow-rate is the main optimization variable of the **Flow**. + Notes: + - If `size` is None, a large default (CONFIG.modeling.BIG) is used. + - If `previous_flow_rate` is provided as a list, it is converted to a NumPy array. + + Deprecated: + - Passing a Bus object to `bus` is deprecated. Pass the bus label string instead. + Args: label: The label of the Flow. Used to identify it in the FlowSystem. Its `full_label` consists of the label of the Component and the label of the Flow. bus: Label of the bus the flow is connected to. @@ -208,30 +208,6 @@ def __init__( previous_flow_rate: Optional[NumericData] = None, meta_data: Optional[Dict] = None, ): - """ - Initialize a Flow element representing material/energy transfer between a Bus and a Component. - - Creates and stores sizing, bounds, profiles, operational constraints, effects and bookkeeping fields used later by the modeling layer. Important behaviors: - - If `size` is None, a large default (CONFIG.modeling.BIG) is used. - - Passing a Bus object to `bus` is deprecated: the Bus's full label is recorded and a UserWarning is emitted; prefer passing the bus label string. - - If `previous_flow_rate` is provided as a list, it is converted to a NumPy array. - - Parameters: - label: Unique flow identifier. - bus: Bus label string (preferred). If a Bus instance is passed, its label_full is used and a deprecation warning is emitted. - size: Fixed numeric size or InvestParameters to enable investment modeling. If omitted, a large default is used. - fixed_relative_profile: Optional time series that fixes the flow profile relative to `size`. - relative_minimum: Relative lower bound (fraction of size or profile); defaults to 0. - relative_maximum: Relative upper bound (fraction of size or profile); defaults to 1. - effects_per_flow_hour: Optional mapping of effect identifiers to per-hour effect factors applied to operation. - on_off_parameters: Optional OnOffParameters controlling on/off behavior for this flow. - flow_hours_total_max: Optional scalar upper bound for total flow-hours over the planning horizon. - flow_hours_total_min: Optional scalar lower bound for total flow-hours. - load_factor_min: Optional minimum capacity-factor (total flow-hours / (size * total_hours)). - load_factor_max: Optional maximum capacity-factor. - previous_flow_rate: Optional numeric time series (or list) with previous flow values; lists are converted to NumPy arrays. - meta_data: Optional dictionary of user metadata. - """ super().__init__(label, meta_data=meta_data) self.size = size or CONFIG.modeling.BIG # Default size self.relative_minimum = relative_minimum diff --git a/flixopt/flow_system.py b/flixopt/flow_system.py index 4c0b8eb17..657d30f87 100644 --- a/flixopt/flow_system.py +++ b/flixopt/flow_system.py @@ -40,6 +40,10 @@ class FlowSystem: If None, the first time increment of time_series is used. This is needed to calculate previous durations (for example consecutive_on_hours). If you use an array, take care that its long enough to cover all previous values! + + Notes: + - Creates an empty registry for components and buses, an empty EffectCollection, and a placeholder for a SystemModel. + - The instance starts disconnected (self._connected == False) and will be connected automatically when trying to solve a calculation. """ def __init__( @@ -59,6 +63,7 @@ def __init__( Notes: Creates an empty registry for components and buses, an empty EffectCollection, and a placeholder for a SystemModel. The instance starts disconnected (self._connected == False) and with no active network visualization app. + This can also be triggered manually with `_connect_network()`. """ self.time_series_collection = TimeSeriesCollection( timesteps=timesteps, diff --git a/flixopt/interface.py b/flixopt/interface.py index 05939c333..cdde7b3e0 100644 --- a/flixopt/interface.py +++ b/flixopt/interface.py @@ -70,13 +70,6 @@ class Piece(Interface): """ def __init__(self, start: NumericData, end: NumericData): - """ - Create a linear segment defined by its start and end numeric values. - - Parameters: - start (NumericData): Value at the segment's start boundary. - end (NumericData): Value at the segment's end boundary. - """ self.start = start self.end = end @@ -357,12 +350,6 @@ class PiecewiseConversion(Interface): """ def __init__(self, piecewises: Dict[str, Piecewise]): - """ - Initialize a PiecewiseConversion mapping flow labels to their Piecewise conversions. - - Parameters: - piecewises (Dict[str, Piecewise]): Mapping from flow identifier (label) to its Piecewise object; used by transform_data to convert each flow's piecewise definition into time-series data. - """ self.piecewises = piecewises def items(self): @@ -508,13 +495,6 @@ class PiecewiseEffects(Interface): """ def __init__(self, piecewise_origin: Piecewise, piecewise_shares: Dict[str, Piecewise]): - """ - Initialize a PiecewiseEffects container linking a primary piecewise function to per-effect piecewise shares. - - Parameters: - piecewise_origin (Piecewise): The primary piecewise function that defines the base relationship. - piecewise_shares (Dict[str, Piecewise]): Mapping from effect name to a Piecewise that defines that effect's share of the origin (per-effect piecewise share). - """ self.piecewise_origin = piecewise_origin self.piecewise_shares = piecewise_shares @@ -724,19 +704,6 @@ def __init__( piecewise_effects: Optional[PiecewiseEffects] = None, divest_effects: Optional['EffectValuesUserScalar'] = None, ): - """ - Initialize investment parameter container. - - Parameters: - fixed_size: If set, investment is treated as a fixed (non-continuous) size and both minimum and maximum sizing will effectively be this value. - minimum_size: Lower bound for continuous sizing; if omitted defaults to CONFIG.modeling.EPSILON. Ignored when `fixed_size` is provided. - maximum_size: Upper bound for continuous sizing; if omitted defaults to CONFIG.modeling.BIG. Ignored when `fixed_size` is provided. - optional: If True, investment may be omitted (binary invest/not-invest behavior allowed). - fix_effects: Fixed effects (one-time or capacity-independent) incurred when the investment is made. - specific_effects: Effects that scale with installed size (per-unit investment effects). - piecewise_effects: Piecewise (nonlinear) effects mapping size to effect values. - divest_effects: Effects incurred if the investment is not made (opposite of `fix_effects`). - """ self.fix_effects: EffectValuesUser = fix_effects or {} self.divest_effects: EffectValuesUser = divest_effects or {} self.fixed_size = fixed_size @@ -946,21 +913,6 @@ def __init__( switch_on_total_max: Optional[int] = None, force_switch_on: bool = False, ): - """ - Initialize OnOffParameters controlling binary on/off behavior and associated costs. - - Parameters: - effects_per_switch_on: Mapping of effect identifiers to values applied each time the unit switches from off to on (startup costs/effects). Can be empty. - effects_per_running_hour: Mapping of effect identifiers to values applied per running hour while on (operating costs/impacts). Can be empty. - on_hours_total_min: Minimum total on-hours across the horizon (integer hours). - on_hours_total_max: Maximum total on-hours across the horizon (integer hours). - consecutive_on_hours_min: Minimum continuous on-hours after a start; may be a scalar or time-series (NumericData). - consecutive_on_hours_max: Maximum continuous on-hours after a start; may be a scalar or time-series (NumericData). - consecutive_off_hours_min: Minimum continuous off-hours between runs; may be a scalar or time-series (NumericData). - consecutive_off_hours_max: Maximum continuous off-hours between runs; may be a scalar or time-series (NumericData). - switch_on_total_max: Maximum number of switch-on (startup) events allowed across the horizon. - force_switch_on: If True, force creation of a switch-on variable even if no other switch-on constraints or effects are provided. - """ self.effects_per_switch_on: EffectValuesUser = effects_per_switch_on or {} self.effects_per_running_hour: EffectValuesUser = effects_per_running_hour or {} self.on_hours_total_min: Scalar = on_hours_total_min From 22c21cc58b579ac25df93a3ac176528c254e7713 Mon Sep 17 00:00:00 2001 From: FBumann <117816358+FBumann@users.noreply.github.com> Date: Fri, 12 Sep 2025 23:21:45 +0200 Subject: [PATCH 4/4] Manual updates --- flixopt/interface.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/flixopt/interface.py b/flixopt/interface.py index cdde7b3e0..78a50f181 100644 --- a/flixopt/interface.py +++ b/flixopt/interface.py @@ -158,12 +158,6 @@ class Piecewise(Interface): """ def __init__(self, pieces: List[Piece]): - """ - Initialize a piecewise linear function from an ordered list of Piece segments. - - Parameters: - pieces (List[Piece]): Ordered sequence of Piece objects representing consecutive segments of the piecewise linear function. The order of items defines the sequence of segments; no validation is performed. - """ self.pieces = pieces def __len__(self):