Source code for optihood.constraints

from pyomo import environ as pyo
from oemof.solph.plumbing import sequence
from math import pi

[docs]def dailySHStorageConstraint(om): """ Function to limit the SH storage capacity to 2 days :param om: optimization model :return: om: optimization model """ for s in om.NODES: if "shStorage" in s.label: constr = s.label.replace("__Building","") + "_constraint_" for t in om.TIMESTEPS: if t % 48 == 0 and t!=0: setattr( om, constr + str(t), pyo.Constraint(expr=(om.GenericInvestmentStorageBlock.storage_content[s, t] == 0)), ) return om
[docs]def connectInvestmentRule(om): """Constraint to equate the investment objects of all the output flows of a Link""" elLinkOutputFlows = [(i, o) for (i, o) in om.flows if (i.label == "electricityLink" or i.label == "elLink")] shLinkOutputFlows = [(i, o) for (i, o) in om.flows if i.label == "shLink"] dhwLinkOutputFlows = [(i, o) for (i, o) in om.flows if i.label == "dhwLink"] if elLinkOutputFlows: first = om.InvestmentFlow.invest[next(iter(elLinkOutputFlows))] for (i, o) in elLinkOutputFlows: expr = (first == om.InvestmentFlow.invest[i, o]) setattr( om, "elLinkConstr_" + o.label, pyo.Constraint(expr=expr), ) if shLinkOutputFlows: first = om.InvestmentFlow.invest[next(iter(shLinkOutputFlows))] for (i, o) in shLinkOutputFlows: expr = (first == om.InvestmentFlow.invest[i, o]) setattr( om, "shLinkConstr_" + o.label, pyo.Constraint(expr=expr), ) if dhwLinkOutputFlows: first = om.InvestmentFlow.invest[next(iter(dhwLinkOutputFlows))] for (i, o) in dhwLinkOutputFlows: expr = (first == om.InvestmentFlow.invest[i, o]) setattr( om, "dhwLinkConstr_" + o.label, pyo.Constraint(expr=expr), ) return om
[docs]def environmentalImpactlimit(om, keyword1, keyword2, limit=None): """ Based on: oemof.solph.constraints.emission_limit Function to limit the environmental impacts during the multi-objective optimization :param om: model :param keyword1: keyword for environmental impacts per flow, placed in a solph.Flow() object :param keyword2: keyword for environmental impacts per capacity installed, placed in a solph.Investment() object :param limit: limit not to be reached :return: """ flows = {} transformerFlowCapacityDict = {} storageCapacityDict = {} for (i, o) in om.flows: if hasattr(om.flows[i, o], keyword1): flows[(i, o)] = om.flows[i, o] if hasattr(om.flows[i, o].investment, keyword2): transformerFlowCapacityDict[(i, o)] = om.flows[i, o].investment for x in om.GenericInvestmentStorageBlock.INVESTSTORAGES: if hasattr(x.investment, keyword2): storageCapacityDict[x] = om.GenericInvestmentStorageBlock.invest[x] envImpact = "totalEnvironmentalImpact" setattr( om, envImpact, pyo.Expression( expr=sum( # Environmental inpact of input flows om.flow[inflow, outflow, t] * om.timeincrement[t] * sequence(getattr(flows[inflow, outflow], keyword1))[t] for (inflow, outflow) in flows for t in om.TIMESTEPS ) # fix Environmental impact per transformer capacity + sum(om.InvestmentFlow.invest[inflow, outflow] * getattr(transformerFlowCapacityDict[inflow, outflow], keyword2) for (inflow, outflow) in transformerFlowCapacityDict) # fix Environmental impact per storage capacity + sum(om.GenericInvestmentStorageBlock.invest[x] * getattr(x.investment, keyword2) for x in storageCapacityDict) ), ) setattr( om, envImpact + "_constraint", pyo.Constraint(expr=(getattr(om, envImpact) <= limit)), ) return om, flows, transformerFlowCapacityDict, storageCapacityDict
[docs]def roof_area_limit(model, keyword1, keyword2, nb): r""" Based on: oemof.solph.constraints.additional_investment_flow_limit Constraint to limit the capacity of solar panels installed considering the roof area available Parameters ---------- model : oemof.solph.Model Model to which constraints are added. keyword1 : attribute to consider Coefficient representing the area used by one unit of capacity of a solar panel keyword2 : attribute to consider Total roof area available for panels. nb : int Number of buildings in the neighbourhood Note ---- The Investment attribute of the considered (Investment-)flows requires an attribute named like keyword! """ for b in range(1, nb+1): limit = 0 invest_flows = {} for (i, o) in model.flows: if str(b) in str(i): if hasattr(model.flows[i, o].investment, keyword1): invest_flows[(i, o)] = model.flows[i, o].investment limit = getattr(model.flows[i, o].investment, keyword2) limit_name = "invest_limit_" + keyword1 + "_building" + str(b) setattr( model, limit_name, pyo.Expression( expr=sum( model.InvestmentFlow.invest[inflow, outflow] * getattr(invest_flows[inflow, outflow], keyword1) for (inflow, outflow) in invest_flows ) ), ) setattr( model, limit_name + "_constraint", pyo.Constraint(expr=(getattr(model, limit_name) <= limit)), ) return model
[docs]def electricRodCapacityConstaint(om, numBuildings): """constraint to set the total capacity of electric rod equal to sum of total capacity selected for HP""" electricRodInputFlows = [(i, o) for (i, o) in om.flows if ("ElectricRod" in o.label)] airHeatPumpInputFlows = [(i, o) for (i, o) in om.flows if ("HP" in o.label and "CHP" not in o.label and "GWHP" not in o.label)] groundHeatPumpInputFlows = [(i, o) for (i, o) in om.flows if ("GWHP" in o.label and not any([c.isdigit() for c in o.label.split("__")[0]]))] groundHeatPumpOutFlows = [(i, o) for (i, o) in om.flows if ("GWHP" in i.label and any([c.isdigit() for c in i.label.split("__")[0]]))] # for splitted GSHPs elRodCapacityTotal = 0 airHeatPumpCapacityTotal = 0 groundHeatPumpCapacityTotal = 0 for b in range(1,numBuildings+1): elRodCapacity = [om.InvestmentFlow.invest[i, o] for (i, o) in electricRodInputFlows if ((f'__Building{b}') in o.label)] airHeatPumpCapacity = [om.InvestmentFlow.invest[i, o] for (i, o) in airHeatPumpInputFlows if ((f'__Building{b}') in o.label)] if groundHeatPumpInputFlows: groundHeatPumpCapacity = [om.InvestmentFlow.invest[i, o] for (i, o) in groundHeatPumpInputFlows if ((f'__Building{b}') in o.label)] else: groundHeatPumpCapacity = [om.InvestmentFlow.invest[i, o] for (i, o) in groundHeatPumpOutFlows if ((f'__Building{b}') in i.label)] if elRodCapacity: elRodCapacity = elRodCapacity[0] airHeatPumpCapacity = airHeatPumpCapacity[0] if airHeatPumpCapacity else 0 if groundHeatPumpInputFlows: groundHeatPumpCapacity = groundHeatPumpCapacity[0] if groundHeatPumpCapacity else 0 else: groundHeatPumpCapacity = groundHeatPumpCapacity[0] + groundHeatPumpCapacity[1] if groundHeatPumpCapacity else 0 elRodCapacityTotal = elRodCapacityTotal + elRodCapacity airHeatPumpCapacityTotal = airHeatPumpCapacityTotal + airHeatPumpCapacity groundHeatPumpCapacityTotal = groundHeatPumpCapacityTotal + groundHeatPumpCapacity expr = (elRodCapacityTotal <= (airHeatPumpCapacityTotal + groundHeatPumpCapacityTotal)) setattr( om, "electricRodSizeConstr", pyo.Constraint(expr=expr), ) return om
[docs]def totalPVCapacityConstraint(om, numBuildings): pvOutFlows = [(i, o) for (i, o) in om.flows if ("pv" in i.label)] pvCapacityTotal = 0 for b in range(1,numBuildings+1): pvCapacity = [om.InvestmentFlow.invest[i, o] for (i, o) in pvOutFlows if ((f'__Building{b}') in o.label)] if pvCapacity: pvCapacity = pvCapacity[0] pvCapacityTotal = pvCapacityTotal + pvCapacity expr = (pvCapacityTotal <= 205) setattr( om, "PVSizeConstr", pyo.Constraint(expr=expr), ) return om