Commit 987ac3ce authored by ZZH's avatar ZZH

update inv eval 2024-12-31 11:45

parent e5638b51
......@@ -3,14 +3,22 @@
DATE:2024/12/30 10:16
"""
import numpy_financial as npf
from gurobipy import Model, GRB
def calculate_irr(revenue_year, investment_cost, max_invest_year):
cash_flows = [-investment_cost] + [revenue_year] * max_invest_year
irr = npf.irr(cash_flows)
return irr
class EnergyModel:
def __init__(self, d_params):
self.load_year = d_params["load_year"]
self.imp_load_year = d_params["imp_load_year"]
self.cg_cost = d_params["cg_cost"]
self.cg_cost = d_params["cg_cost"] + d_params["cg_fuel_cost"]
self.es_cost = d_params["es_cost"]
self.cg_eff = d_params["cg_eff"]
self.es_eff = d_params["es_eff"]
......@@ -22,14 +30,14 @@ class EnergyModel:
m = Model("Energy_Investment_Optimization")
P_ES = m.addVar(vtype=GRB.CONTINUOUS, name="P_ES")
P_CG = m.addVar(vtype=GRB.CONTINUOUS, name="P_CG")
IRR = m.addVar(vtype=GRB.CONTINUOUS, name="IRR")
IOR = m.addVar(vtype=GRB.CONTINUOUS, name="IOR")
E_CG = P_CG * self.cg_eff * self.work_hours_year
Revenue = self.ele_price * E_CG
revenue_year = self.ele_price * self.imp_load_year * self.work_hours_year
Investment_Cost = P_ES * self.es_cost + P_CG * self.cg_cost
m.setObjective(IRR, GRB.MINIMIZE)
m.addConstr(IRR * Revenue == Investment_Cost,
m.setObjective(IOR, GRB.MINIMIZE)
m.addConstr(IOR * revenue_year == Investment_Cost,
"Critical_Load_Constraint")
m.addConstr(P_CG * self.cg_eff >= self.imp_load_year,
"Critical_Load_Constraint")
......@@ -41,24 +49,29 @@ class EnergyModel:
"CG_Capacity_Constraint")
m.optimize()
cost_kWh = Investment_Cost.getValue() / E_CG.getValue()
if m.status == GRB.OPTIMAL:
irr = Investment_Cost.getValue() / Revenue.getValue()
if irr > self.max_invest_year:
return {"Error": f"当前区域的投资回报比(IRR = {irr:.2f})高于"
IOR = IOR.x
irr = calculate_irr(revenue_year, Investment_Cost.getValue(),
max_invest_year)
if IOR > self.max_invest_year:
return {"Error": f"当前区域的投资回报比(IOR = {IOR:.2f})高于"
f"设置的投资上限,建议不要投资。"}
else:
result = {
'pv': 0,
'es': P_ES.x,
'es_p': P_ES.x, 'es_cap': P_ES.x * 2,
'cg': P_CG.x,
'income_year': Revenue.getValue(),
'income_year': revenue_year,
'total_inv_cost': Investment_Cost.getValue(),
'irr': round(irr, 2)
'ior': round(IOR, 2),
'cost_kWh': round(cost_kWh, 2),
'irr': irr
}
return result
else:
return {"Error": "当前求解的限制条件不合理"}
return {"Error": "当前限制条件不合理"}
def all_calculate(self, d_params):
pv_cost = d_params["pv_cost"]
......@@ -68,57 +81,71 @@ class EnergyModel:
pv_eff = d_params["pv_eff"]
pv_area = d_params["pv_area"]
pv_limit = d_params["pv_limit"]
pv_area_ele = 0.15
m = Model("Energy_Investment_Optimization")
P_PV = m.addVar(vtype=GRB.CONTINUOUS, name="P_PV")
P_ES = m.addVar(vtype=GRB.CONTINUOUS, name="P_ES")
P_CG = m.addVar(vtype=GRB.CONTINUOUS, name="P_CG")
IRR = m.addVar(vtype=GRB.CONTINUOUS, name="IRR")
IOR = m.addVar(vtype=GRB.CONTINUOUS, name="IOR")
E_PV = P_PV * sun_hrs_year * pv_eff
E_CG = P_CG * self.work_hours_year * self.cg_eff
Revenue = self.ele_price * self.load_year * self.work_hours_year
revenue_year = (
P_PV * pv_eff * sun_hrs_year + P_CG * self.cg_eff * self.work_hours_year) * self.ele_price
Investment_Cost = P_PV * pv_cost + P_ES * self.es_cost + P_CG * self.cg_cost
m.setObjective(IRR, GRB.MINIMIZE)
m.addConstr(E_PV + E_CG >= self.load_year * self.work_hours_year,
"IRR_Constraint")
m.addConstr(IRR * Revenue == Investment_Cost, "IRR_Constraint")
m.addConstr(P_PV * pv_eff + E_CG * self.cg_eff >= max_load,
m.setObjective(IOR, GRB.MINIMIZE)
m.addConstr(E_PV + E_CG <= 1.1 * self.load_year * self.work_hours_year,
"IOR_Constraint")
m.addConstr(
E_PV + E_CG >= 0.95 * self.load_year * self.work_hours_year,
"IOR_Constraint")
m.addConstr(IOR * revenue_year == Investment_Cost, "IOR_Constraint")
m.addConstr(P_PV * pv_eff + P_CG * self.cg_eff >= self.load_year,
"PV_Constraint")
m.addConstr(P_PV <= min(pv_area_ele * pv_area, pv_limit),
"PV_Limit_Constraint")
m.addConstr(P_CG * self.cg_eff >= self.imp_load_year, "CG_Constraint")
m.addConstr(P_CG * self.cg_eff + P_ES * self.es_eff >= min_load,
m.addConstr(P_CG * self.cg_eff + P_ES * self.es_eff >= min(min_load,
self.imp_load_year),
"CG_Min_Load_Constraint")
m.addConstr(P_ES * self.es_eff >= self.imp_load_year,
"ES_Load_Constraint")
m.addConstr(P_ES * self.es_eff >= 0.2 * pv_eff * P_PV,
"ES_PV_Constraint")
m.optimize()
cost_kWh = Investment_Cost.getValue() / (
E_PV.getValue() + E_CG.getValue())
if m.status == GRB.OPTIMAL:
irr = IRR.x
if irr > self.max_invest_year:
return {"Error": f"当前区域的投资回报比(IRR = {irr:.2f})高于"
IOR = IOR.x
irr = calculate_irr(revenue_year.getValue(),
Investment_Cost.getValue(), max_invest_year)
if IOR > self.max_invest_year:
return {"Error": f"当前区域的投资回报比(IOR = {IOR:.2f})高于"
f"设置的投资上限,建议不要投资。"}
else:
result = {
'pv': P_PV.x,
'es': P_ES.x,
'es_p': P_ES.x, 'es_cap': P_ES.x * 2,
'cg': P_CG.x,
'income_year': Revenue,
'income_year': revenue_year.getValue(),
'total_inv_cost': Investment_Cost.getValue(),
'irr': round(irr, 2)
'ior': round(IOR, 2),
'cost_kWh': round(cost_kWh, 2),
'irr': irr
}
return result
else:
return {"Error": "当前求解的限制条件不合理"}
return {"Error": "当前限制条件不合理"}
def sale_calculate(self, d_params):
pv_cost = d_params["pv_cost"]
......@@ -128,63 +155,85 @@ class EnergyModel:
pv_eff = d_params["pv_eff"]
pv_area = d_params["pv_area"]
pv_limit = d_params["pv_limit"]
sale_price = d_params["sale_price"]
sale_limit = d_params["sale_limit"]
sale_cost = d_params["sale_cost"]
pv_area_ele = 0.15
try:
m = Model("Energy_Investment_Optimization")
P_PV = m.addVar(vtype=GRB.CONTINUOUS, name="P_PV")
P_ES = m.addVar(vtype=GRB.CONTINUOUS, name="P_ES")
P_CG = m.addVar(vtype=GRB.CONTINUOUS, name="P_CG")
IRR = m.addVar(vtype=GRB.CONTINUOUS, name="P_CG")
IOR = m.addVar(vtype=GRB.CONTINUOUS, name="P_CG")
E_PV = P_PV * sun_hrs_year * pv_eff
E_CG = P_CG * self.work_hours_year * self.cg_eff
Revenue = (E_PV + E_CG) * self.ele_price + (
sale_price - sale_cost - self.ele_price) * (
E_PV + E_CG - self.load_year * self.work_hours_year)
# 这个不对
revenue_year = ((
self.load_year * self.work_hours_year) * self.ele_price) + (
sale_price - sale_cost) * (
E_PV + E_CG - (
self.load_year * self.work_hours_year))
Investment_Cost = P_PV * pv_cost + P_ES * self.es_cost + P_CG * self.cg_cost
m.setObjective(IRR, GRB.MINIMIZE)
m.addConstr(IRR * Revenue == Investment_Cost)
m.setObjective(IOR, GRB.MINIMIZE)
m.addConstr(IOR * revenue_year == Investment_Cost)
m.addConstr(
E_PV + E_CG >= 1.2 * self.load_year * self.work_hours_year,
"IOR_Constraint")
m.addConstr(P_PV <= min(pv_area_ele * pv_area, pv_limit),
"PV_Limit_Constraint")
m.addConstr(P_CG * self.cg_eff >= self.imp_load_year, "CG_Constraint")
m.addConstr(P_CG * self.cg_eff >= self.imp_load_year,
"CG_Constraint")
m.addConstr(P_CG * self.cg_eff + P_PV * pv_eff >= max_load,
"CG_Min_Load_Constraint")
m.addConstr(P_ES * self.es_eff >= 0.2 * pv_eff * P_PV,
"ES_PV_Constraint")
m.addConstr(
P_PV * pv_eff + P_ES * pv_eff + P_CG * self.cg_eff <= self.load_year + (
sale_limit / 24),
# 售电限制
m.addConstr(P_PV + P_CG <= (max_load + sale_limit / 24),
"Total_Constraint")
m.optimize()
cost_kWh = Investment_Cost.getValue() / (
E_PV.getValue() + E_CG.getValue())
if m.status == GRB.OPTIMAL:
irr = IRR.x
if irr > self.max_invest_year:
return {"Error": f"当前区域的投资回报比(IRR = {irr:.2f})高于"
IOR = IOR.x
irr = calculate_irr(revenue_year.getValue(),
Investment_Cost.getValue(),
max_invest_year)
if IOR > self.max_invest_year:
return {
"Error": f"当前区域的投资回报比(IOR = {IOR:.2f})高于"
f"设置的投资上限,建议不要投资。"}
else:
result = {
'pv': P_PV.x,
'es': P_ES.x,
'es_p': P_ES.x, 'es_cap': P_ES.x * 2,
'cg': P_CG.x,
'income_year': Revenue.getValue(),
'income_year': revenue_year.getValue(),
'total_inv_cost': Investment_Cost.getValue(),
'irr': round(irr, 2)
'ior': round(IOR, 2),
'cost_kWh': round(cost_kWh, 2),
'irr': irr
}
return result
else:
return {"Error": "当前求解的限制条件不合理"}
except:
rlt_all = ems_model.all_calculate(dict(pv_cost=pv_cost,
sun_hrs_year=sun_hrs_year,
max_load=max_load,
min_load=min_load,
pv_eff=pv_eff,
pv_area=pv_area,
pv_limit=pv_limit))
return rlt_all
def com_strategy(self, d_params):
pv_cost = d_params["pv_cost"]
......@@ -204,21 +253,21 @@ class EnergyModel:
P_PV = m.addVar(vtype=GRB.CONTINUOUS, name="P_PV")
P_ES = m.addVar(vtype=GRB.CONTINUOUS, name="P_ES")
P_CG = m.addVar(vtype=GRB.CONTINUOUS, name="P_CG")
IRR = m.addVar(vtype=GRB.CONTINUOUS, name="P_CG")
coefficient_of_combined_objective_1 = 0.5
IOR = m.addVar(vtype=GRB.CONTINUOUS, name="P_CG")
coefficient_of_combined_objective_1 = 0.6
coefficient_of_combined_objective_2 = 0.4
coefficient_of_combined_objective_3 = 0.1
E_PV = P_PV * sun_hrs_year * pv_eff
E_CG = P_CG * self.work_hours_year * self.cg_eff
Revenue = (
revenue_year = (
self.ele_price * self.load_year * self.work_hours_year) + (
sale_price - sale_cost) * (
E_PV + E_CG - self.load_year * self.work_hours_year)
Investment_Cost = P_PV * pv_cost + P_ES * self.es_cost + P_CG * self.cg_cost
m.setObjective(IRR, GRB.MINIMIZE)
m.addConstr(IRR * Revenue == Investment_Cost)
m.setObjective(IOR, GRB.MINIMIZE)
m.addConstr(IOR * revenue_year == Investment_Cost)
m.addConstr(P_PV * pv_eff + E_CG * self.cg_eff >= max_load,
"PV_Constraint")
m.addConstr(P_PV <= min(pv_area_ele * pv_area, pv_limit),
......@@ -237,55 +286,68 @@ class EnergyModel:
"Total_Constraint")
m.optimize()
cost_kWh = Investment_Cost.getValue() / (
E_PV.getValue() + E_CG.getValue())
if m.status == GRB.OPTIMAL:
irr = Investment_Cost.getValue() / Revenue.getValue()
if irr > self.max_invest_year:
return {"提示": f"当前区域的投资回报比(IRR = {irr:.2f})高于"
IOR = Investment_Cost.getValue() / revenue_year.getValue()
irr = calculate_irr(revenue_year.getValue(),
Investment_Cost.getValue(), max_invest_year)
if IOR > self.max_invest_year:
return {"提示": f"当前区域的投资回报比(IOR = {IOR:.2f})高于"
f"设置的投资上限,建议不要投资。"}
else:
result = {
'pv': P_PV.x,
'es': P_ES.x,
'es_p': P_ES.x,
'es_cap': P_ES.x * 2,
'cg': P_CG.x,
'income_year': Revenue.getValue(),
'income_year': revenue_year.getValue(),
'total_inv_cost': Investment_Cost.getValue(),
'irr': round(irr, 2)
'ior': round(IOR, 2),
'cost_kWh': round(cost_kWh, 2),
'irr': irr
}
return result
else:
return {"Error": "当前求解的限制条件不合理"}
return {"Error": "当前限制条件不合理"}
if __name__ == '__main__':
load_year = 4500 # 年均负荷(kw)
imp_load_year = 2000 # 年均重要负荷(kw)
load_year = 2500 # 年均负荷(kw)
imp_load_year = 1500 # 年均重要负荷(kw)
es_cost = 1500 # 储能成本 元/kw
pv_cost = 800 # 光伏成本 元/kw
ele_price = 1.4 # 电价
cg_cost = 8000 # 煤制气成本加上燃料成本 元/kw
sale_price = 1000 # 售电价格
sale_cost = 0.5 # 售电成本
cg_cost = 6000 # 煤制气设备成本元/kw
cg_fuel_cost = 100 # 煤制气燃料成本元/kw
sale_price = 50 # 售电价格元
sale_cost = 0.5 # 售电价格元
work_hours_year = 2000 # 每年的工作时长为2000小时
sun_hrs_year = 1300 # 每年的光照时长为1300小时
max_load = 6000 # kw
min_load = 2400 # kw
pv_area = 50000 # 当前场地的光伏建设面积最大面积平方米
min_load = 1000 # kw
pv_area = 5000000 # 当前场地的光伏建设面积最大面积平方米
pv_eff = 0.8 # 光伏效率
max_invest_year = 5 # 当前投资收益最大限制
pv_limit = 7000 # 光伏最大限制
sale_limit = 100000 # 售电限制kw*h
sale_limit = 2400000 # 售电限制kw*h
pv_deg_rate = 0.6
es_deg_rate = 2.1
ems_model = EnergyModel(dict(load_year=load_year,
imp_load_year=imp_load_year,
es_cost=es_cost, ele_price=ele_price,
cg_cost=cg_cost,
cg_fuel_cost=cg_fuel_cost,
work_hours_year=work_hours_year,
max_invest_year=max_invest_year,
cg_eff=0.8, es_eff=0.8))
cg_eff=0.8, es_eff=0.8,
pv_deg_rate=pv_deg_rate,
es_deg_rate=es_deg_rate))
rlt_cri = ems_model.cri_calculate()
print("rlt_cri", rlt_cri)
# print("rlt_cri", rlt_cri)
rlt_all = ems_model.all_calculate(dict(pv_cost=pv_cost,
sun_hrs_year=sun_hrs_year,
max_load=max_load,
......
......@@ -35,8 +35,11 @@ class EmsInvEvalReq(Model):
@dataclass
class EmsInvEvalRsp(Model):
pv: float = Opt(Float("光伏配置").eg(4500))
es: float = Opt(Float("储能配置").eg(4500))
es_p: float = Opt(Float("储能功率配置").eg(4500))
es_cap: float = Opt(Float("储能容量配置").eg(4500))
cg: float = Opt(Float("煤制气").eg(4500))
income_year: float = Opt(Float("年收益").eg(4500))
total_inv_cost: float = Opt(Float("总投资成本").eg(4500))
irr: float = Opt(Float("投资回报率").eg(0.1))
irr: float = Opt(Float("内部收益率 ").eg(0.1))
ior: float = Opt(Float("投资回报率").eg(0.1))
cost_kWh: float = Opt(Float("度电成本").eg(0.1))
......@@ -44,9 +44,13 @@ async def post_inv_eval(req, body: EmsInvEvalReq) -> EmsInvEvalRsp:
sale_price=sale_price, sale_limit=sale_limit,
sale_cost=sale_cost, goal=goal)
cfg = await inv_eval(d_params)
return EmsInvEvalRsp(pv=cfg.get("pv", 0), es=cfg.get("es", 0),
return EmsInvEvalRsp(pv=cfg.get("pv", 0), es_p=cfg.get("es_p", 0),
es_cap=cfg.get("es_cap", 0),
cg=cfg.get("cg", 0),
income_year=cfg.get("income_year", 0),
irr=cfg.get("irr", 0))
total_inv_cost=cfg.get("total_inv_cost", 0),
irr=cfg.get("irr", 0), ior=cfg.get("ior", 0),
cost_kWh=cfg.get("cost_kWh", 0), )
except Exception as e:
return EmsInvEvalRsp(pv=0, es=0, cg=0, income_year=0, irr=0)
return EmsInvEvalRsp(pv=0, es_p=0, es_cap=0, cg=0, income_year=0,
total_inv_cost=0, irr=0, ior=0, cost_kWh=0)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment