Source code for energia.components.operations.process

"""Process"""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING

from ...modeling.parameters.conversions import Production
from ...utils.decorators import timer
from .operation import Operation

logger = logging.getLogger("energia")

if TYPE_CHECKING:
    from ..spatial.location import Location
    from ..temporal.periods import Periods


[docs] class Process(Operation): """ Process converts one Resource to another Resource at some Location :param label: An optional label for the component. Defaults to None. :type label: str, optional :param citations: An optional citation or description for the component. Defaults to None. :type citations: str | list[str] | dict[str, str | list[str]], optional :ivar model: The model to which the component belongs. :vartype model: Model :ivar name: Set when the component is assigned as a Model attribute. :vartype name: str :ivar constraints: List of constraints associated with the component. :vartype constraints: list[str] :ivar domains: List of domains associated with the component. :vartype domains: list[Domain] :ivar aspects: Aspects associated with the component with domains. :vartype aspects: dict[Aspect, list[Domain]] :ivar conversion: Operational conversion associated with the operation. Defaults to None. :vartype conversion: Conversion, optional :ivar _conv: True if the operational conversion has been set. Defaults to False. :vartype _conv: bool :ivar fab: Material conversion associated with the operation. Defaults to None. :vartype fab: Conversion, optional :ivar _fab_balanced: True if the material conversion has been balanced. Defaults to False. :vartype _fab_balanced: bool :ivar locations: Locations at which the process is balanced. Defaults to []. :vartype locations: list[Location] :ivar charges: If the Process is Storage charging. Defaults to None. :vartype charges: Storage, optional :ivar discharges: If the Process is Storage discharging. Defaults to None. :vartype discharges: Storage, optional """ def __init__(self, *args, label: str = "", citations: str = "", **kwargs): Operation.__init__(self, *args, label=label, citations=citations, **kwargs) self.primary_conversion = Production( operation=self, ) # at which locations the process is balanced # Note that we do not need a conversion at every temporal scale. # once balanced at a location for a particular time, # if time != horizon, the individual streams are summed up anyway self.locations: list[Location] = [] @property def spaces(self) -> list[Location]: """Locations at which the process is balanced""" return self.locations @property def production(self): """Alias for primary_conversion""" return self.primary_conversion @production.setter def production(self, value): """Set primary_conversion""" self.primary_conversion = value
[docs] @timer(logger, kind="production") def write_primary_conversion(self, space_times: list[tuple[Location, Periods]]): """Write the production constraints for the process""" # This makes the production consistent # check conv_test.py in tests for examples self.production.balancer() #! PWL # if self.conversion.pwl: # if there are piece-wise linear conversions # here we assume that the same resources appear in all piece-wise segments # this is a reasonable assumption for conversion in processes # but not if process modes involve different resources # TODO: # make the statement eff = [conv[res] for conv in self.conversion.values()] # into try # if that fails, create a consistent dict, see: # {0: {r1: 10, r2: -5}, 1: {r1: 8, r2: -4, r3: -2}} # transforms to {0: {r1: 10, r2: -5, r3: 0}, 1: {r1: 8, r2: -4, r3: -2}} # the r3: 0 will ensure that r3 is considered in all modes # the zero checks will prevent unnecessary constraints # there is a problem though, because I am only checking for the elements in the first dict # in the multi conversion dict # conversion = self.balance[list(self.balance)[0]] # else: for space, time in space_times: if space in self.locations: # if the process is already balanced for the space , Skip continue self.primary_conversion.write(space, time) # update the locations at which the process exists self.locations.append(space) self.space_times.append((space, time)) return self, self.locations