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
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