コード例 #1
0
    def setOptimalValues(self, esM, pyM):
        """
        Set the optimal values of the components.

        :param esM: EnergySystemModel instance representing the energy system in which the component should be modeled.
        :type esM: EnergySystemModel class instance

        :param pyM: pyomo ConcreteModel which stores the mathematical formulation of the model.
        :type pyM: pyomo Concrete Model
        """

        super().setOptimalValues(esM, pyM)

        abbrvName = self.abbrvName
        discretizationPointVariables = getattr(
            pyM, 'discretizationPoint_' + abbrvName)
        discretizationSegmentConVariables = getattr(
            pyM, 'discretizationSegmentCon_' + abbrvName)
        discretizationSegmentBinVariables = getattr(
            pyM, 'discretizationSegmentBin_' + abbrvName)

        discretizationPointVariablesOptVal_ = utils.formatOptimizationOutput(
            discretizationPointVariables.get_values(), 'operationVariables',
            '1dim', esM.periodsOrder)
        discretizationSegmentConVariablesOptVal_ = utils.formatOptimizationOutput(
            discretizationSegmentConVariables.get_values(),
            'operationVariables', '1dim', esM.periodsOrder)
        discretizationSegmentBinVariablesOptVal_ = utils.formatOptimizationOutput(
            discretizationSegmentBinVariables.get_values(),
            'operationVariables', '1dim', esM.periodsOrder)

        self.discretizationPointVariablesOptimun = discretizationPointVariablesOptVal_
        self.discretizationSegmentConVariablesOptimun = discretizationSegmentConVariablesOptVal_
        self.discretizationSegmentBinVariablesOptimun = discretizationSegmentBinVariablesOptVal_
コード例 #2
0
ファイル: transmission.py プロジェクト: m-staggenborg/FINE
    def setOptimalValues(self, esM, pyM):
        """
        Set the optimal values of the components.

        :param esM: EnergySystemModel instance representing the energy system in which the component should be modeled.
        :type esM: esM - EnergySystemModel class instance

        :param pyM: pyomo ConcreteModel which stores the mathematical formulation of the model.
        :type pyM: pyomo ConcreteModel
        """
        compDict, abbrvName = self.componentsDict, self.abbrvName
        opVar = getattr(pyM, 'op_' + abbrvName)
        mapC = {loc1 + '_' + loc2: (loc1, loc2) for loc1 in esM.locations for loc2 in esM.locations}

        # Set optimal design dimension variables and get basic optimization summary
        optSummaryBasic = super().setOptimalValues(esM, pyM, mapC.keys(), 'commodityUnit')
        for compName, comp in compDict.items():
            for cost in ['invest', 'capexCap', 'capexIfBuilt', 'opexCap', 'opexIfBuilt']:
                data = optSummaryBasic.loc[compName, cost]
                optSummaryBasic.loc[compName, cost] = (0.5 * data * comp.distances).values

        # Set optimal operation variables and append optimization summary
        optVal = utils.formatOptimizationOutput(opVar.get_values(), 'operationVariables', '1dim', esM.periodsOrder)
        optVal_ = utils.formatOptimizationOutput(opVar.get_values(), 'operationVariables', '2dim', esM.periodsOrder,
                                                 compDict=compDict)
        self.operationVariablesOptimum = optVal_

        props = ['operation', 'opexOp']
        units = ['[-]', '[' + esM.costUnit + '/a]', '[' + esM.costUnit + '/a]']
        tuples = [(compName, prop, unit) for compName in compDict.keys() for prop, unit in zip(props, units)]
        tuples = list(map(lambda x: (x[0], x[1], '[' + compDict[x[0]].commodityUnit + '*h/a]')
                          if x[1] == 'operation' else x, tuples))
        mIndex = pd.MultiIndex.from_tuples(tuples, names=['Component', 'Property', 'Unit'])
        optSummary = pd.DataFrame(index=mIndex, columns=sorted(mapC.keys())).sort_index()

        if optVal is not None:
            opSum = optVal.sum(axis=1).unstack(-1)
            ox = opSum.apply(lambda op: op * compDict[op.name].opexPerOperation[op.index], axis=1)
            optSummary.loc[[(ix, 'operation', '[' + compDict[ix].commodityUnit + '*h/a]') for ix in opSum.index],
                            opSum.columns] = opSum.values/esM.numberOfYears
            optSummary.loc[[(ix, 'opexOp', '[' + esM.costUnit + '/a]') for ix in ox.index], ox.columns] = \
                ox.values/esM.numberOfYears * 0.5

        optSummary = optSummary.append(optSummaryBasic).sort_index()

        # Summarize all contributions to the total annual cost
        optSummary.loc[optSummary.index.get_level_values(1) == 'TAC'] = \
            optSummary.loc[(optSummary.index.get_level_values(1) == 'TAC') |
                           (optSummary.index.get_level_values(1) == 'opexOp')].groupby(level=0).sum().values

        # Split connection indices to two location indices
        optSummary = optSummary.stack()
        indexNew = []
        for tup in optSummary.index.tolist():
            loc1, loc2 = mapC[tup[3]]
            indexNew.append((tup[0], tup[1], tup[2], loc1, loc2))
        optSummary.index = pd.MultiIndex.from_tuples(indexNew)
        optSummary = optSummary.unstack(level=-1)

        self.optSummary = optSummary
コード例 #3
0
ファイル: conversion.py プロジェクト: passion4energy/FINE
    def setOptimalValues(self, esM, pyM):
        """
        Set the optimal values of the components.

        :param esM: EnergySystemModel instance representing the energy system in which the component should be modeled.
        :type esM: esM - EnergySystemModel class instance

        :param pyM: pyomo ConcreteModel which stores the mathematical formulation of the model.
        :type pyM: pyomo ConcreteModel
        """
        compDict, abbrvName = self.componentsDict, self.abbrvName
        opVar = getattr(pyM, 'op_' + abbrvName)

        # Set optimal design dimension variables and get basic optimization summary
        optSummaryBasic = super().setOptimalValues(esM, pyM, esM.locations,
                                                   'physicalUnit')

        # Set optimal operation variables and append optimization summary
        optVal = utils.formatOptimizationOutput(opVar.get_values(),
                                                'operationVariables',
                                                '1dim',
                                                esM.periodsOrder,
                                                esM=esM)
        self.operationVariablesOptimum = optVal

        props = ['operation', 'opexOp']
        units = ['[-]', '[' + esM.costUnit + '/a]']
        tuples = [(compName, prop, unit) for compName in compDict.keys()
                  for prop, unit in zip(props, units)]
        tuples = list(
            map(
                lambda x:
                (x[0], x[1], '[' + compDict[x[0]].physicalUnit + '*h/a]')
                if x[1] == 'operation' else x, tuples))
        mIndex = pd.MultiIndex.from_tuples(
            tuples, names=['Component', 'Property', 'Unit'])
        optSummary = pd.DataFrame(index=mIndex,
                                  columns=sorted(esM.locations)).sort_index()

        if optVal is not None:
            opSum = optVal.sum(axis=1).unstack(-1)
            ox = opSum.apply(
                lambda op: op * compDict[op.name].opexPerOperation[op.index],
                axis=1)
            optSummary.loc[[(ix, 'operation',
                             '[' + compDict[ix].physicalUnit + '*h/a]')
                            for ix in opSum.index],
                           opSum.columns] = opSum.values / esM.numberOfYears
            optSummary.loc[[(ix, 'opexOp', '[' + esM.costUnit + '/a]') for ix in ox.index], ox.columns] = \
                ox.values/esM.numberOfYears

        optSummary = optSummary.append(optSummaryBasic).sort_index()

        # Summarize all contributions to the total annual cost
        optSummary.loc[optSummary.index.get_level_values(1) == 'TAC'] = \
            optSummary.loc[(optSummary.index.get_level_values(1) == 'TAC') |
                           (optSummary.index.get_level_values(1) == 'opexOp')].groupby(level=0).sum().values

        self.optSummary = optSummary
コード例 #4
0
ファイル: sourceSink.py プロジェクト: l-welder/FINE
    def setOptimalValues(self, esM, pyM):
        compDict, abbrvName = self.componentsDict, self.abbrvName
        opVar = getattr(pyM, 'op_' + abbrvName)

        # Set optimal design dimension variables and get basic optimization summary
        optSummaryBasic = super().setOptimalValues(esM, pyM, esM.locations,
                                                   'commodityUnit')

        # Set optimal operation variables and append optimization summary
        optVal = utils.formatOptimizationOutput(opVar.get_values(),
                                                'operationVariables', '1dim',
                                                esM.periodsOrder)
        self.operationVariablesOptimum = optVal

        props = ['operation', 'opexOp', 'commodCosts']
        units = ['[-]', '[' + esM.costUnit + '/a]', '[' + esM.costUnit + '/a]']
        tuples = [(compName, prop, unit) for compName in compDict.keys()
                  for prop, unit in zip(props, units)]
        tuples = list(
            map(
                lambda x:
                (x[0], x[1], '[' + compDict[x[0]].commodityUnit + '*h/a]')
                if x[1] == 'operation' else x, tuples))
        mIndex = pd.MultiIndex.from_tuples(
            tuples, names=['Component', 'Property', 'Unit'])
        optSummary = pd.DataFrame(index=mIndex,
                                  columns=sorted(esM.locations)).sort_index()

        if optVal is not None:
            opSum = optVal.sum(axis=1).unstack(-1)
            ox = opSum.apply(
                lambda op: op * compDict[op.name].opexPerOperation[op.index],
                axis=1)
            cCost = opSum.apply(
                lambda op: op * compDict[op.name].commodityCost[op.index],
                axis=1)
            cRevenue = opSum.apply(
                lambda op: op * compDict[op.name].commodityRevenue[op.index],
                axis=1)
            optSummary.loc[[(ix, 'operation',
                             '[' + compDict[ix].commodityUnit + '*h/a]')
                            for ix in opSum.index],
                           opSum.columns] = opSum.values / esM.numberOfYears
            optSummary.loc[[(ix, 'opexOp', '[' + esM.costUnit + '/a]') for ix in ox.index], ox.columns] = \
                ox.values/esM.numberOfYears
            optSummary.loc[[(ix, 'commodCosts', '[' + esM.costUnit + '/a]') for ix in ox.index], ox.columns] = \
                (cCost-cRevenue).values/esM.numberOfYears

        optSummary = optSummary.append(optSummaryBasic).sort_index()

        # Summarize all contributions to the total annual cost
        optSummary.loc[optSummary.index.get_level_values(1) == 'TAC'] = \
            optSummary.loc[(optSummary.index.get_level_values(1) == 'TAC') |
                           (optSummary.index.get_level_values(1) == 'opexOp') |
                           (optSummary.index.get_level_values(1) == 'commodCosts')].groupby(level=0).sum().values

        self.optSummary = optSummary
コード例 #5
0
ファイル: lopf.py プロジェクト: l-welder/FINE
    def setOptimalValues(self, esM, pyM):

        super().setOptimalValues(esM, pyM)

        compDict, abbrvName = self.componentsDict, self.abbrvName
        phaseAngleVar = getattr(pyM, 'phaseAngle_' + abbrvName)

        optVal_ = utils.formatOptimizationOutput(phaseAngleVar.get_values(),
                                                 'operationVariables', '1dim',
                                                 esM.periodsOrder)
        self.operationVariablesOptimum = optVal_
コード例 #6
0
    def setOptimalValues(self, esM, pyM):
        optVal = utils.formatOptimizationOutput(pyM.cap_trans.get_values(),
                                                'designVariables', '1dim')
        self._capacityVariablesOptimum = optVal
        utils.setOptimalComponentVariables(optVal, '_capacityVariablesOptimum',
                                           self._componentsDict)

        optVal = utils.formatOptimizationOutput(
            pyM.designBin_trans.get_values(), 'designVariables', '1dim')
        self._isBuiltVariablesOptimum = optVal
        utils.setOptimalComponentVariables(optVal, '_isBuiltVariablesOptimum',
                                           self._componentsDict)

        optVal = utils.formatOptimizationOutput(pyM.op_trans.get_values(),
                                                'operationVariables', '1dim',
                                                esM._periodsOrder)
        self._operationVariablesOptimum = optVal
        utils.setOptimalComponentVariables(optVal,
                                           '_operationVariablesOptimum',
                                           self._componentsDict)
コード例 #7
0
ファイル: lopf.py プロジェクト: m-staggenborg/FINE
    def setOptimalValues(self, esM, pyM):
        """
        Set the optimal values of the components.

        :param esM: EnergySystemModel instance representing the energy system in which the component should be modeled.
        :type esM: EnergySystemModel class instance

        :param pyM: pyomo ConcreteModel which stores the mathematical formulation of the model.
        :type pyM: pyomo Concrete Model
        """

        super().setOptimalValues(esM, pyM)

        compDict, abbrvName = self.componentsDict, self.abbrvName
        phaseAngleVar = getattr(pyM, 'phaseAngle_' + abbrvName)

        optVal_ = utils.formatOptimizationOutput(phaseAngleVar.get_values(), 'operationVariables', '1dim',
                                                 esM.periodsOrder)
        self.operationVariablesOptimum = optVal_
コード例 #8
0
ファイル: DSM.py プロジェクト: t-gross/FINE
    def setOptimalValues(self, esM, pyM):
        """
        Set the optimal values of the components.

        :param esM: EnergySystemModel instance representing the energy system in which the component should be modeled.
        :type esM: esM - EnergySystemModel class instance

        :param pym: pyomo ConcreteModel which stores the mathematical formulation of the model.
        :type pym: pyomo ConcreteModel
        """
        compDict, abbrvName = self.componentsDict, self.abbrvName
        opVar = getattr(pyM, 'op_' + abbrvName)

        # Set optimal design dimension variables and get basic optimization summary
        optSummaryBasic = super(SourceSinkModel, self).setOptimalValues(esM, pyM, esM.locations, 'commodityUnit')

        # Set optimal operation variables and append optimization summary
        chargeOp = getattr(pyM, 'chargeOp_storExt')
        optVal = utils.formatOptimizationOutput(chargeOp.get_values(), 'operationVariables', '1dim', esM.periodsOrder)

        def groupStor(x):
            ix = optVal.loc[x].name
            for compName, comp in self.componentsDict.items():
                if ix[0] in [compName + '_' + str(i) for i in range(comp.tBwd+comp.tFwd+1)]:
                    return (compName, ix[1])

        optVal = optVal.groupby(lambda x: groupStor(x)).sum()
        optVal.index = pd.MultiIndex.from_tuples(optVal.index)

        self.operationVariablesOptimum = optVal

        props = ['operation', 'opexOp', 'commodCosts', 'commodRevenues']
        units = ['[-]', '[' + esM.costUnit + '/a]', '[' + esM.costUnit + '/a]', '[' + esM.costUnit + '/a]']
        tuples = [(compName, prop, unit) for compName in compDict.keys() for prop, unit in zip(props, units)]
        tuples = list(map(lambda x: (x[0], x[1], '[' + compDict[x[0]].commodityUnit + '*h/a]')
                          if x[1] == 'operation' else x, tuples))
        mIndex = pd.MultiIndex.from_tuples(tuples, names=['Component', 'Property', 'Unit'])
        optSummary = pd.DataFrame(index=mIndex, columns=sorted(esM.locations)).sort_index()

        if optVal is not None:
            opSum = optVal.sum(axis=1).unstack(-1)
            ox = opSum.apply(lambda op: op * compDict[op.name].opexPerOperation[op.index], axis=1)
            cCost = opSum.apply(lambda op: op * compDict[op.name].commodityCost[op.index], axis=1)
            cRevenue = opSum.apply(lambda op: op * compDict[op.name].commodityRevenue[op.index], axis=1)
            
            optSummary.loc[[(ix, 'operation', '[' + compDict[ix].commodityUnit + '*h/a]') for ix in opSum.index],
                            opSum.columns] = opSum.values/esM.numberOfYears
            optSummary.loc[[(ix, 'opexOp', '[' + esM.costUnit + '/a]') for ix in ox.index], ox.columns] = \
                ox.values/esM.numberOfYears
            
            # get empty datframe for resulting time dependent (TD) cost sum
            cRevenueTD = pd.DataFrame(0., index = list(compDict.keys()), columns = opSum.columns)
            cCostTD = pd.DataFrame(0., index = list(compDict.keys()), columns = opSum.columns)

            for compName in compDict.keys():
                if not compDict[compName].commodityCostTimeSeries is None:
                    # in case of time series aggregation rearange clustered cost time series
                    calcCostTD = utils.buildFullTimeSeries(compDict[compName].commodityCostTimeSeries, 
                                                           esM.periodsOrder, axis=0)
                    # multiply with operation values to get the total cost
                    cCostTD.loc[compName,:] = optVal.xs(compName, level=0).T.mul(calcCostTD).sum(axis=0)

                if not compDict[compName].commodityRevenueTimeSeries is None:
                    # in case of time series aggregation rearange clustered revenue time series
                    calcRevenueTD = utils.buildFullTimeSeries(compDict[compName].commodityRevenueTimeSeries,
                                                              esM.periodsOrder, axis=0)
                    # multiply with operation values to get the total revenue
                    cRevenueTD.loc[compName,:] = optVal.xs(compName, level=0).T.mul(calcRevenueTD).sum(axis=0)
                        
            optSummary.loc[[(ix, 'commodCosts', '[' + esM.costUnit + '/a]') for ix in ox.index], ox.columns] = \
                (cCostTD.values + cCost.values)/esM.numberOfYears

            optSummary.loc[[(ix, 'commodRevenues', '[' + esM.costUnit + '/a]') for ix in ox.index], ox.columns] = \
                (cRevenueTD.values + cRevenue.values)/esM.numberOfYears
        
        # get discounted investment cost as total annual cost (TAC)
        optSummary = optSummary.append(optSummaryBasic).sort_index()

        # add operation specific contributions to the total annual cost (TAC) and substract revenues
        optSummary.loc[optSummary.index.get_level_values(1) == 'TAC'] = \
            optSummary.loc[(optSummary.index.get_level_values(1) == 'TAC') |
                           (optSummary.index.get_level_values(1) == 'opexOp') |
                           (optSummary.index.get_level_values(1) == 'commodCosts')].groupby(level=0).sum().values \
            - optSummary.loc[(optSummary.index.get_level_values(1) == 'commodRevenues')].groupby(level=0).sum().values

        self.optSummary = optSummary
コード例 #9
0
ファイル: transmission.py プロジェクト: FZJ-IEK3-VSA/FINE
        def _setOptimalValues(self,
                              esM,
                              pyM,
                              indexColumns,
                              plantUnit,
                              unitApp=""):

            compDict, abbrvName = self.componentsDict, self.abbrvName
            capVar = getattr(esM.pyM, "cap_" + abbrvName)
            binVar = getattr(esM.pyM, "designBin_" + abbrvName)

            props = [
                "capacity",
                "isBuilt",
                "capexCap",
                "capexIfBuilt",
                "opexCap",
                "opexIfBuilt",
                "TAC",
                "invest",
            ]
            units = [
                "[-]",
                "[-]",
                "[" + esM.costUnit + "/a]",
                "[" + esM.costUnit + "/a]",
                "[" + esM.costUnit + "/a]",
                "[" + esM.costUnit + "/a]",
                "[" + esM.costUnit + "/a]",
                "[" + esM.costUnit + "]",
            ]
            tuples = [(compName, prop, unit) for compName in compDict.keys()
                      for prop, unit in zip(props, units)]
            tuples = list(
                map(
                    lambda x: (
                        x[0],
                        x[1],
                        "[" + getattr(compDict[x[0]], plantUnit) + unitApp +
                        "]",
                    ) if x[1] == "capacity" else x,
                    tuples,
                ))
            mIndex = pd.MultiIndex.from_tuples(
                tuples, names=["Component", "Property", "Unit"])
            optSummary = pd.DataFrame(
                index=mIndex, columns=sorted(indexColumns)).sort_index()

            # Get and set optimal variable values for expanded capacities
            values = capVar.get_values()
            optVal = utils.formatOptimizationOutput(values, "designVariables",
                                                    "1dim")
            optVal_ = utils.formatOptimizationOutput(values,
                                                     "designVariables",
                                                     self.dimension,
                                                     compDict=compDict)
            self.capacityVariablesOptimum = optVal_

            if optVal is not None:
                # Check if the installed capacities are close to a bigM value for components with design decision variables but
                # ignores cases where bigM was substituted by capacityMax parameter (see bigM constraint)
                for compName, comp in compDict.items():
                    if (comp.hasIsBuiltBinaryVariable
                            and (comp.capacityMax is None)
                            and optVal.loc[compName].max() >= comp.bigM * 0.9
                            and
                            esM.verbose < 2):  # and comp.capacityMax is None
                        warnings.warn(
                            "the capacity of component " + compName +
                            " is in one or more locations close " +
                            "or equal to the chosen Big M. Consider rerunning the simulation with a higher"
                            + " Big M.")

                # Calculate the investment costs i (proportional to capacity expansion)
                i = optVal.apply(
                    lambda cap: cap * compDict[cap.name].
                    processedInvestPerCapacity * compDict[cap.name].QPcostDev +
                    (compDict[cap.name].processedInvestPerCapacity * compDict[
                        cap.name].QPcostScale /
                     (compDict[cap.name].QPbound) * cap * cap),
                    axis=1,
                )
                # Calculate the annualized investment costs cx (CAPEX)
                cx = optVal.apply(
                    lambda cap:
                    (cap * compDict[cap.name].processedInvestPerCapacity *
                     compDict[cap.name].QPcostDev / compDict[cap.name].CCF) +
                    (compDict[cap.name].processedInvestPerCapacity / compDict[
                        cap.name].CCF * compDict[cap.name].QPcostScale /
                     (compDict[cap.name].QPbound) * cap * cap),
                    axis=1,
                )
                # Calculate the annualized operational costs ox (OPEX)
                ox = optVal.apply(
                    lambda cap: cap * compDict[cap.name].
                    processedOpexPerCapacity * compDict[cap.name].QPcostDev +
                    (compDict[cap.name].processedOpexPerCapacity * compDict[
                        cap.name].QPcostScale /
                     (compDict[cap.name].QPbound) * cap * cap),
                    axis=1,
                )

                # Fill the optimization summary with the calculated values for invest, CAPEX and OPEX
                # (due to capacity expansion).
                optSummary.loc[[(
                    ix,
                    "capacity",
                    "[" + getattr(compDict[ix], plantUnit) + unitApp + "]",
                ) for ix in optVal.index], optVal.columns, ] = optVal.values
                optSummary.loc[[(ix, "invest", "[" + esM.costUnit + "]")
                                for ix in i.index], i.columns, ] = i.values
                optSummary.loc[[(ix, "capexCap", "[" + esM.costUnit + "/a]")
                                for ix in cx.index], cx.columns, ] = cx.values
                optSummary.loc[[(ix, "opexCap", "[" + esM.costUnit + "/a]")
                                for ix in ox.index], ox.columns, ] = ox.values

            # Get and set optimal variable values for binary investment decisions (isBuiltBinary).
            values = binVar.get_values()
            optVal = utils.formatOptimizationOutput(values, "designVariables",
                                                    "1dim")
            optVal_ = utils.formatOptimizationOutput(values,
                                                     "designVariables",
                                                     self.dimension,
                                                     compDict=compDict)
            self.isBuiltVariablesOptimum = optVal_

            if optVal is not None:
                # Calculate the investment costs i (fix value if component is built)
                i = optVal.apply(lambda dec: dec * compDict[dec.name].
                                 processedInvestIfBuilt,
                                 axis=1)
                # Calculate the annualized investment costs cx (fix value if component is built)
                cx = optVal.apply(
                    lambda dec: dec * compDict[dec.name].processedInvestIfBuilt
                    / compDict[dec.name].CCF,
                    axis=1,
                )
                # Calculate the annualized operational costs ox (fix value if component is built)
                ox = optVal.apply(
                    lambda dec: dec * compDict[dec.name].processedOpexIfBuilt,
                    axis=1)

                # Fill the optimization summary with the calculated values for invest, CAPEX and OPEX
                # (due to isBuilt decisions).
                optSummary.loc[[(ix, "isBuilt", "[-]") for ix in optVal.index],
                               optVal.columns] = optVal.values
                optSummary.loc[[(ix, "invest", "[" + esM.costUnit + "]")
                                for ix in cx.index], cx.columns, ] += i.values
                optSummary.loc[[(ix, "capexIfBuilt",
                                 "[" + esM.costUnit + "/a]")
                                for ix in cx.index], cx.columns, ] = cx.values
                optSummary.loc[[(ix, "opexIfBuilt", "[" + esM.costUnit + "/a]")
                                for ix in ox.index], ox.columns, ] = ox.values

            # Summarize all annualized contributions to the total annual cost
            optSummary.loc[optSummary.index.get_level_values(1) == "TAC"] = (
                optSummary.loc[
                    (optSummary.index.get_level_values(1) == "capexCap")
                    | (optSummary.index.get_level_values(1) == "opexCap")
                    | (optSummary.index.get_level_values(1) == "capexIfBuilt")
                    | (optSummary.index.get_level_values(1) == "opexIfBuilt")].
                groupby(level=0).sum().values)

            return optSummary
コード例 #10
0
ファイル: transmission.py プロジェクト: FZJ-IEK3-VSA/FINE
    def setOptimalValues(self, esM, pyM):
        """
        Set the optimal values of the components.

        :param esM: EnergySystemModel instance representing the energy system in which the component should be modeled.
        :type esM: esM - EnergySystemModel class instance

        :param pyM: pyomo ConcreteModel which stores the mathematical formulation of the model.
        :type pyM: pyomo ConcreteModel
        """
        compDict, abbrvName = self.componentsDict, self.abbrvName
        opVar = getattr(pyM, "op_" + abbrvName)
        mapC = {
            loc1 + "_" + loc2: (loc1, loc2)
            for loc1 in esM.locations for loc2 in esM.locations
        }

        def _setOptimalValues(self,
                              esM,
                              pyM,
                              indexColumns,
                              plantUnit,
                              unitApp=""):

            compDict, abbrvName = self.componentsDict, self.abbrvName
            capVar = getattr(esM.pyM, "cap_" + abbrvName)
            binVar = getattr(esM.pyM, "designBin_" + abbrvName)

            props = [
                "capacity",
                "isBuilt",
                "capexCap",
                "capexIfBuilt",
                "opexCap",
                "opexIfBuilt",
                "TAC",
                "invest",
            ]
            units = [
                "[-]",
                "[-]",
                "[" + esM.costUnit + "/a]",
                "[" + esM.costUnit + "/a]",
                "[" + esM.costUnit + "/a]",
                "[" + esM.costUnit + "/a]",
                "[" + esM.costUnit + "/a]",
                "[" + esM.costUnit + "]",
            ]
            tuples = [(compName, prop, unit) for compName in compDict.keys()
                      for prop, unit in zip(props, units)]
            tuples = list(
                map(
                    lambda x: (
                        x[0],
                        x[1],
                        "[" + getattr(compDict[x[0]], plantUnit) + unitApp +
                        "]",
                    ) if x[1] == "capacity" else x,
                    tuples,
                ))
            mIndex = pd.MultiIndex.from_tuples(
                tuples, names=["Component", "Property", "Unit"])
            optSummary = pd.DataFrame(
                index=mIndex, columns=sorted(indexColumns)).sort_index()

            # Get and set optimal variable values for expanded capacities
            values = capVar.get_values()
            optVal = utils.formatOptimizationOutput(values, "designVariables",
                                                    "1dim")
            optVal_ = utils.formatOptimizationOutput(values,
                                                     "designVariables",
                                                     self.dimension,
                                                     compDict=compDict)
            self.capacityVariablesOptimum = optVal_

            if optVal is not None:
                # Check if the installed capacities are close to a bigM value for components with design decision variables but
                # ignores cases where bigM was substituted by capacityMax parameter (see bigM constraint)
                for compName, comp in compDict.items():
                    if (comp.hasIsBuiltBinaryVariable
                            and (comp.capacityMax is None)
                            and optVal.loc[compName].max() >= comp.bigM * 0.9
                            and
                            esM.verbose < 2):  # and comp.capacityMax is None
                        warnings.warn(
                            "the capacity of component " + compName +
                            " is in one or more locations close " +
                            "or equal to the chosen Big M. Consider rerunning the simulation with a higher"
                            + " Big M.")

                # Calculate the investment costs i (proportional to capacity expansion)
                i = optVal.apply(
                    lambda cap: cap * compDict[cap.name].
                    processedInvestPerCapacity * compDict[cap.name].QPcostDev +
                    (compDict[cap.name].processedInvestPerCapacity * compDict[
                        cap.name].QPcostScale /
                     (compDict[cap.name].QPbound) * cap * cap),
                    axis=1,
                )
                # Calculate the annualized investment costs cx (CAPEX)
                cx = optVal.apply(
                    lambda cap:
                    (cap * compDict[cap.name].processedInvestPerCapacity *
                     compDict[cap.name].QPcostDev / compDict[cap.name].CCF) +
                    (compDict[cap.name].processedInvestPerCapacity / compDict[
                        cap.name].CCF * compDict[cap.name].QPcostScale /
                     (compDict[cap.name].QPbound) * cap * cap),
                    axis=1,
                )
                # Calculate the annualized operational costs ox (OPEX)
                ox = optVal.apply(
                    lambda cap: cap * compDict[cap.name].
                    processedOpexPerCapacity * compDict[cap.name].QPcostDev +
                    (compDict[cap.name].processedOpexPerCapacity * compDict[
                        cap.name].QPcostScale /
                     (compDict[cap.name].QPbound) * cap * cap),
                    axis=1,
                )

                # Fill the optimization summary with the calculated values for invest, CAPEX and OPEX
                # (due to capacity expansion).
                optSummary.loc[[(
                    ix,
                    "capacity",
                    "[" + getattr(compDict[ix], plantUnit) + unitApp + "]",
                ) for ix in optVal.index], optVal.columns, ] = optVal.values
                optSummary.loc[[(ix, "invest", "[" + esM.costUnit + "]")
                                for ix in i.index], i.columns, ] = i.values
                optSummary.loc[[(ix, "capexCap", "[" + esM.costUnit + "/a]")
                                for ix in cx.index], cx.columns, ] = cx.values
                optSummary.loc[[(ix, "opexCap", "[" + esM.costUnit + "/a]")
                                for ix in ox.index], ox.columns, ] = ox.values

            # Get and set optimal variable values for binary investment decisions (isBuiltBinary).
            values = binVar.get_values()
            optVal = utils.formatOptimizationOutput(values, "designVariables",
                                                    "1dim")
            optVal_ = utils.formatOptimizationOutput(values,
                                                     "designVariables",
                                                     self.dimension,
                                                     compDict=compDict)
            self.isBuiltVariablesOptimum = optVal_

            if optVal is not None:
                # Calculate the investment costs i (fix value if component is built)
                i = optVal.apply(lambda dec: dec * compDict[dec.name].
                                 processedInvestIfBuilt,
                                 axis=1)
                # Calculate the annualized investment costs cx (fix value if component is built)
                cx = optVal.apply(
                    lambda dec: dec * compDict[dec.name].processedInvestIfBuilt
                    / compDict[dec.name].CCF,
                    axis=1,
                )
                # Calculate the annualized operational costs ox (fix value if component is built)
                ox = optVal.apply(
                    lambda dec: dec * compDict[dec.name].processedOpexIfBuilt,
                    axis=1)

                # Fill the optimization summary with the calculated values for invest, CAPEX and OPEX
                # (due to isBuilt decisions).
                optSummary.loc[[(ix, "isBuilt", "[-]") for ix in optVal.index],
                               optVal.columns] = optVal.values
                optSummary.loc[[(ix, "invest", "[" + esM.costUnit + "]")
                                for ix in cx.index], cx.columns, ] += i.values
                optSummary.loc[[(ix, "capexIfBuilt",
                                 "[" + esM.costUnit + "/a]")
                                for ix in cx.index], cx.columns, ] = cx.values
                optSummary.loc[[(ix, "opexIfBuilt", "[" + esM.costUnit + "/a]")
                                for ix in ox.index], ox.columns, ] = ox.values

            # Summarize all annualized contributions to the total annual cost
            optSummary.loc[optSummary.index.get_level_values(1) == "TAC"] = (
                optSummary.loc[
                    (optSummary.index.get_level_values(1) == "capexCap")
                    | (optSummary.index.get_level_values(1) == "opexCap")
                    | (optSummary.index.get_level_values(1) == "capexIfBuilt")
                    | (optSummary.index.get_level_values(1) == "opexIfBuilt")].
                groupby(level=0).sum().values)

            return optSummary

        # Set optimal design dimension variables and get basic optimization summary
        optSummaryBasic = _setOptimalValues(self, esM, pyM, mapC.keys(),
                                            "commodityUnit")

        for compName, comp in compDict.items():
            for cost in [
                    "invest",
                    "capexCap",
                    "capexIfBuilt",
                    "opexCap",
                    "opexIfBuilt",
                    "TAC",
            ]:
                data = optSummaryBasic.loc[compName, cost]
                optSummaryBasic.loc[compName, cost] = (data).values

        # Set optimal operation variables and append optimization summary
        optVal = utils.formatOptimizationOutput(opVar.get_values(),
                                                "operationVariables",
                                                "1dim",
                                                esM.periodsOrder,
                                                esM=esM)
        optVal_ = utils.formatOptimizationOutput(
            opVar.get_values(),
            "operationVariables",
            "2dim",
            esM.periodsOrder,
            compDict=compDict,
            esM=esM,
        )
        self.operationVariablesOptimum = optVal_

        props = ["operation", "opexOp"]
        # Unit dict: Specify units for props
        units = {
            props[0]: ["[-*h]", "[-*h/a]"],
            props[1]: ["[" + esM.costUnit + "/a]"]
        }
        # Create tuples for the optSummary's multiIndex. Combine component with the respective properties and units.
        tuples = [(compName, prop, unit) for compName in compDict.keys()
                  for prop in props for unit in units[prop]]
        # Replace placeholder with correct unit of component
        tuples = list(
            map(
                lambda x:
                (x[0], x[1], x[2].replace("-", compDict[x[0]].commodityUnit))
                if x[1] == "operation" else x,
                tuples,
            ))
        mIndex = pd.MultiIndex.from_tuples(
            tuples, names=["Component", "Property", "Unit"])
        optSummary = pd.DataFrame(index=mIndex,
                                  columns=sorted(mapC.keys())).sort_index()

        if optVal is not None:
            opSum = optVal.sum(axis=1).unstack(-1)
            ox = opSum.apply(
                lambda op: op * compDict[op.name].opexPerOperation, axis=1)
            optSummary.loc[[(ix, "operation",
                             "[" + compDict[ix].commodityUnit + "*h/a]")
                            for ix in opSum.index],
                           opSum.columns, ] = (opSum.values /
                                               esM.numberOfYears)
            optSummary.loc[[(ix, "operation",
                             "[" + compDict[ix].commodityUnit + "*h]")
                            for ix in opSum.index],
                           opSum.columns, ] = opSum.values
            optSummary.loc[[(ix, "opexOp", "[" + esM.costUnit + "/a]")
                            for ix in ox.index],
                           ox.columns, ] = (ox.values / esM.numberOfYears *
                                            0.5)

        optSummary = optSummary.append(optSummaryBasic).sort_index()

        # Summarize all contributions to the total annual cost
        optSummary.loc[optSummary.index.get_level_values(1) == "TAC"] = (
            optSummary.loc[
                (optSummary.index.get_level_values(1) == "TAC")
                | (optSummary.index.get_level_values(1) == "opexOp")].groupby(
                    level=0).sum().values)

        # Split connection indices to two location indices
        optSummary = optSummary.stack()
        indexNew = []
        for tup in optSummary.index.tolist():
            loc1, loc2 = mapC[tup[3]]
            indexNew.append((tup[0], tup[1], tup[2], loc1, loc2))
        optSummary.index = pd.MultiIndex.from_tuples(indexNew)
        optSummary = optSummary.unstack(level=-1)
        names = list(optSummaryBasic.index.names)
        names.append("LocationIn")
        optSummary.index.set_names(names, inplace=True)

        self.optSummary = optSummary
コード例 #11
0
    def setOptimalValues(self, esM, pyM):
        """
        Set the optimal values of the components.

        :param esM: EnergySystemModel instance representing the energy system in which the component should be modeled.
        :type esM: esM - EnergySystemModel class instance

        :param pyM: pyomo ConcreteModel which stores the mathematical formulation of the model.
        :type pyM: pyomo ConcreteModel
        """
        compDict, abbrvName = self.componentsDict, self.abbrvName
        opVar = getattr(pyM, "op_" + abbrvName)

        # Set optimal design dimension variables and get basic optimization summary
        optSummaryBasic = super().setOptimalValues(esM, pyM, esM.locations,
                                                   "physicalUnit")

        # Set optimal operation variables and append optimization summary
        optVal = utils.formatOptimizationOutput(opVar.get_values(),
                                                "operationVariables",
                                                "1dim",
                                                esM.periodsOrder,
                                                esM=esM)
        self.operationVariablesOptimum = optVal

        props = ["operation", "opexOp"]
        # Unit dict: Specify units for props
        units = {
            props[0]: ["[-*h]", "[-*h/a]"],
            props[1]: ["[" + esM.costUnit + "/a]"]
        }
        # Create tuples for the optSummary's multiIndex. Combine component with the respective properties and units.
        tuples = [(compName, prop, unit) for compName in compDict.keys()
                  for prop in props for unit in units[prop]]
        # Replace placeholder with correct unit of component
        tuples = list(
            map(
                lambda x:
                (x[0], x[1], x[2].replace("-", compDict[x[0]].physicalUnit))
                if x[1] == "operation" else x,
                tuples,
            ))
        mIndex = pd.MultiIndex.from_tuples(
            tuples, names=["Component", "Property", "Unit"])
        optSummary = pd.DataFrame(index=mIndex,
                                  columns=sorted(esM.locations)).sort_index()

        if optVal is not None:
            opSum = optVal.sum(axis=1).unstack(-1)
            ox = opSum.apply(
                lambda op: op * compDict[op.name].opexPerOperation[op.index],
                axis=1)
            optSummary.loc[[(ix, "operation",
                             "[" + compDict[ix].physicalUnit + "*h/a]")
                            for ix in opSum.index],
                           opSum.columns, ] = (opSum.values /
                                               esM.numberOfYears)
            optSummary.loc[[(ix, "operation",
                             "[" + compDict[ix].physicalUnit + "*h]")
                            for ix in opSum.index],
                           opSum.columns, ] = opSum.values
            optSummary.loc[[(ix, "opexOp", "[" + esM.costUnit + "/a]")
                            for ix in ox.index],
                           ox.columns, ] = (ox.values / esM.numberOfYears)

        optSummary = optSummary.append(optSummaryBasic).sort_index()

        # Summarize all contributions to the total annual cost
        optSummary.loc[optSummary.index.get_level_values(1) == "TAC"] = (
            optSummary.loc[
                (optSummary.index.get_level_values(1) == "TAC")
                | (optSummary.index.get_level_values(1) == "opexOp")].groupby(
                    level=0).sum().values)

        self.optSummary = optSummary
コード例 #12
0
ファイル: sourceSink.py プロジェクト: FZJ-IEK3-VSA/FINE
    def setOptimalValues(self, esM, pyM):
        """
        Set the optimal values of the components.

        :param esM: EnergySystemModel instance representing the energy system in which the component should be modeled.
        :type esM: esM - EnergySystemModel class instance

        :param pym: pyomo ConcreteModel which stores the mathematical formulation of the model.
        :type pym: pyomo ConcreteModel
        """
        compDict, abbrvName = self.componentsDict, self.abbrvName
        opVar = getattr(pyM, "op_" + abbrvName)

        # Set optimal design dimension variables and get basic optimization summary
        optSummaryBasic = super().setOptimalValues(
            esM, pyM, esM.locations, "commodityUnit"
        )

        # Set optimal operation variables and append optimization summary
        optVal = utils.formatOptimizationOutput(
            opVar.get_values(), "operationVariables", "1dim", esM.periodsOrder, esM=esM
        )
        self.operationVariablesOptimum = optVal

        props = ["operation", "opexOp", "commodCosts", "commodRevenues"]
        # Unit dict: Specify units for props
        units = {
            props[0]: ["[-*h]", "[-*h/a]"],
            props[1]: ["[" + esM.costUnit + "/a]"],
            props[2]: ["[" + esM.costUnit + "/a]"],
            props[3]: ["[" + esM.costUnit + "/a]"],
        }
        # Create tuples for the optSummary's multiIndex. Combine component with the respective properties and units.
        tuples = [
            (compName, prop, unit)
            for compName in compDict.keys()
            for prop in props
            for unit in units[prop]
        ]
        # Replace placeholder with correct unit of component
        tuples = list(
            map(
                lambda x: (x[0], x[1], x[2].replace("-", compDict[x[0]].commodityUnit))
                if x[1] == "operation"
                else x,
                tuples,
            )
        )
        mIndex = pd.MultiIndex.from_tuples(
            tuples, names=["Component", "Property", "Unit"]
        )
        optSummary = pd.DataFrame(
            index=mIndex, columns=sorted(esM.locations)
        ).sort_index()

        if optVal is not None:
            opSum = optVal.sum(axis=1).unstack(-1)
            ox = opSum.apply(
                lambda op: op * compDict[op.name].opexPerOperation[op.index], axis=1
            )
            cCost = opSum.apply(
                lambda op: op * compDict[op.name].commodityCost[op.index], axis=1
            )
            cRevenue = opSum.apply(
                lambda op: op * compDict[op.name].commodityRevenue[op.index], axis=1
            )
            optSummary.loc[
                [
                    (ix, "operation", "[" + compDict[ix].commodityUnit + "*h/a]")
                    for ix in opSum.index
                ],
                opSum.columns,
            ] = (
                opSum.values / esM.numberOfYears
            )
            optSummary.loc[
                [
                    (ix, "operation", "[" + compDict[ix].commodityUnit + "*h]")
                    for ix in opSum.index
                ],
                opSum.columns,
            ] = opSum.values
            optSummary.loc[
                [(ix, "opexOp", "[" + esM.costUnit + "/a]") for ix in ox.index],
                ox.columns,
            ] = (
                ox.values / esM.numberOfYears
            )

            # get empty datframe for resulting time dependent (TD) cost sum
            cRevenueTD = pd.DataFrame(0.0, index=opSum.index, columns=opSum.columns)
            cCostTD = pd.DataFrame(0.0, index=opSum.index, columns=opSum.columns)

            for compName in opSum.index:
                if not compDict[compName].processedCommodityCostTimeSeries is None:

                    # in case of time series aggregation rearange clustered cost time series
                    calcCostTD = utils.buildFullTimeSeries(
                        compDict[compName]
                        .processedCommodityCostTimeSeries.unstack(level=1)
                        .stack(level=0),
                        esM.periodsOrder,
                        esM=esM,
                        divide=False,
                    )
                    # multiply with operation values to get the total cost
                    cCostTD.loc[compName, :] = (
                        optVal.xs(compName, level=0).T.mul(calcCostTD.T).sum(axis=0)
                    )

                if not compDict[compName].processedCommodityRevenueTimeSeries is None:
                    # in case of time series aggregation rearange clustered revenue time series
                    calcRevenueTD = utils.buildFullTimeSeries(
                        compDict[compName]
                        .processedCommodityRevenueTimeSeries.unstack(level=1)
                        .stack(level=0),
                        esM.periodsOrder,
                        esM=esM,
                        divide=False,
                    )
                    # multiply with operation values to get the total revenue
                    cRevenueTD.loc[compName, :] = (
                        optVal.xs(compName, level=0).T.mul(calcRevenueTD.T).sum(axis=0)
                    )

            optSummary.loc[
                [(ix, "commodCosts", "[" + esM.costUnit + "/a]") for ix in ox.index],
                ox.columns,
            ] = (cCostTD.values + cCost.values) / esM.numberOfYears
            optSummary.loc[
                [(ix, "commodRevenues", "[" + esM.costUnit + "/a]") for ix in ox.index],
                ox.columns,
            ] = (cRevenueTD.values + cRevenue.values) / esM.numberOfYears

        # get discounted investment cost as total annual cost (TAC)
        optSummary = optSummary.append(optSummaryBasic).sort_index()

        # add operation specific contributions to the total annual cost (TAC) and substract revenues
        optSummary.loc[optSummary.index.get_level_values(1) == "TAC"] = (
            optSummary.loc[
                (optSummary.index.get_level_values(1) == "TAC")
                | (optSummary.index.get_level_values(1) == "opexOp")
                | (optSummary.index.get_level_values(1) == "commodCosts")
            ]
            .groupby(level=0)
            .sum()
            .values
            - optSummary.loc[(optSummary.index.get_level_values(1) == "commodRevenues")]
            .groupby(level=0)
            .sum()
            .values
        )

        self.optSummary = optSummary