Salve a tutti,
è la prima volta che mi approccio a Python e avrei bisogno di un aiuto.
Sto effettuando la modellizzazione di una rete di teleriscaldamento e non riesce a calcolarmi la portata massica incognita con il vincolo di conservazione (segnato in rosso) ---> in pratica in ogni nodo quello che entra deve essere uguale a quello che esce. Ed è proprio questo vincolo che dovrebbe essere la soluzione per calcolarmi le portate massiche rimanenti.
Questo è l'errore che mi dà in output
Objectives:
obj : Size=1, Index=None, Active=True
ERROR: evaluating object as numeric value: y[5,12]
(object: <class 'pyomo.core.base.var._GeneralVarData'>)
No value for uninitialized NumericValue object y[5,12]
ERROR: evaluating object as numeric value: obj
(object: <class 'pyomo.core.base.objective.ScalarObjective'>)
No value for uninitialized NumericValue object y[5,12]
None : None : None
Questo è lo script:
from pyomo.opt import SolverFactory
from pyomo.core import AbstractModel
from pyomo.dataportal.DataPortal import DataPortal
from pyomo.environ import Set,Var,Param,Constraint,Binary,NonNegativeReals, Objective, maximize
model = AbstractModel()
data= DataPortal()
######## definition of all the sets ########
#definition of all the nodes
model.N=Set()
data.load(filename='N.csv', set=model.N)
#definition of the plant node
model.NI=Set(within=model.N)
data.load(filename='NI.csv', set=model.NI)
#definition of all the arcs
model.A=Set(dimen=2, within=model.N*model.N)
data.load(filename='A.csv', set=model.A)
#definition of plant arcs
model.AI=Set(dimen=2, within=model.N*model.N)
data.load(filename='AI.csv', set=model.AI)
#definition of existing feedline pipes
model.AFE=Set(dimen=2, within=model.N*model.N)
data.load(filename='AFE.csv', set=model.AFE)
#definition of existing user feedline pipes
model.AFUE=Set(dimen=2, within=model.N*model.N)
data.load(filename='AFUE.csv', set=model.AFUE)
#definition of potential feedline pipes
model.AFP=Set(dimen=2, within=model.N*model.N)
data.load(filename='AFP.csv', set=model.AFP)
def NodesOut_init(model, node):
retval = []
for (i,j) in model.A:
if i == node:
retval.append(j)
return retval
model.NodesOut = Set(model.N, initialize=NodesOut_init)
def NodesIn_init(model, node):
retval = []
for (i,j) in model.A:
if j == node:
retval.append(i)
return retval
model.NodesIn = Set(model.N, initialize=NodesIn_init)
####### define all the parameters ######
#each existing and potential user is associated with a thermal demand P
model.Pe = Param(model.AFUE)
data.load(filename = 'powere.csv', param=model.Pe, index=model.AFUE)
model.Pp = Param(model.AFP)
data.load(filename = 'powerp.csv' , param=model.Pp, index=model.AFP)
#definition of the limit of existing mass flow rate feedline depending on diameter
model.m_max = Param(model.AFE)
data.load(filename= 'm_max.csv' , param=model.m_max, index=model.AFE)
#definition of the limit of user existing mass flow rate feedline depending on diameter
model.m_max_AFUE = Param(model.AFUE)
data.load(filename= 'm_max_AFUE.csv' , param=model.m_max_AFUE, index=model.AFUE)
#connection of all edges
model.dist=Param(model.A)
data.load(filename='distances.csv', param=model.dist, index=model.A)
#connection of all potential edges
model.distP=Param(model.AFP)
data.load(filename='distances_pot.csv' , param=model.distP, index=model.AFP)
#cost of thermal power
price_thermal_energy=0.02194 #€/kWh
#cost of heat exchanger
cost_HX=200 #€/kW
#DT heat exchanger
DT_HX= 30 #°
#cost of the pipeline
price_pipeline= 29 #€/m
#min pressure at each node
Pmin=2 #bar
#max pressure at plant node
Pmax=9 #bar
#DP min for each arc
DPmin=0.5 #bar
#DP max for each at plant node
DPmax=2 #bar
#mean velocity in the pipeline
v=2 #m/s
#max mass flow rate with a diameter of 50 mm ---> the one of all the potentials
m_max_pot=3.92 #kg/s
#######define variables########
#binary variable y[i,j]: 1 if the connection i,j is present, 0 otherwise
model.y = Var(model.AFP,within=Binary)
#mass flow rate along pipes
model.m = Var(model.A,within=NonNegativeReals)
#DP along the pipeline
model.DP = Var(model.A, within=NonNegativeReals)
#P at the nodes
model.P = Var(model.N, within=NonNegativeReals)
######## definition of the constraints #########
def definition_mass_flow_rate_feedline_existing_user(model,a,b):
return model.m[a,b]==(model.Pe[a,b])/(4.186*DT_HX)
model.mass_flow_rate_feedline_existing_user=Constraint(model.AFUE,rule=definition_mass_flow_rate_feedline_existing_user)
def definition_mass_flow_rate_feedline_potential_user(model,c,d):
return model.m[c,d]==(model.Pp[c,d])/(4.186*DT_HX)*model.y[c,d]
model.mass_flow_rate_feedline_potential_user=Constraint(model.AFP,rule=definition_mass_flow_rate_feedline_potential_user)
def definition_mass_flow_rate_existing_feedline_limit(model,e,f):
return model.m[e,f]<=model.m_max[e,f]
model.mass_flow_rate_existing_feedline_limit=Constraint(model.AFE,rule=definition_mass_flow_rate_existing_feedline_limit)
def definition_mass_flow_rate_existing_user_feedline_limit(model,g,h):
return model.m[g,h]<=model.m_max_AFUE[g,h]
model.mass_flow_rate_existing_user_feedline_limit=Constraint(model.AFUE,rule=definition_mass_flow_rate_existing_user_feedline_limit)
def definition_mass_flow_rate_feedline_potential_user_limit(model,i,l):
return model.m[i,l]<=m_max_pot*model.y[i,l]
model.mass_flow_rate_feedline_potential_user_limit=Constraint(model.AFP,rule=definition_mass_flow_rate_feedline_potential_user_limit)
[color=#800000]def mass_flow_conservation_rule(model,node):
return (sum(model.m[j,node] for j in model.NodesIn if (j,node) in model.A)-sum(model.m[node,y] for y in model.NodesOut if (node,y) in model.A))==0
model.mass_flow_conservation = Constraint(model.N, rule=mass_flow_conservation_rule)
[/color]
def pressure_node_plant_max_rule(model,m):
return model.P[m]<=Pmax
model.pressure_node_plant_max = Constraint(model.NI, rule=pressure_node_plant_max_rule)
def pressure_nodes_min_rule(model,n):
return model.P[n]>=Pmin
model.pressure_nodes_min = Constraint(model.N, rule=pressure_nodes_min_rule)
def DP_max_plant_rule(model,o,p):
return model.DP[o,p]<=DPmax
model.DP_max_plant = Constraint(model.AI, rule=DP_max_plant_rule)
def DP_min_ex_arcs_rule(model,q,r):
return model.DP[q,r]>=DPmin
model.DP_min_ex_arcs = Constraint(model.AFUE, rule=DP_min_ex_arcs_rule)
def DP_min_pot_arcs_rule(model,s,t):
return model.DP[s,t]>=DPmin*model.y[s,t]
model.DP_min_pot_arcs = Constraint(model.AFP, rule=DP_min_pot_arcs_rule)
def DP_feedline_rule_1(model,v,z):
return model.DP[v,z]>=0.001074*model.m[v,z]-0.0184
model.DP_feedline_1 = Constraint(model.A, rule=DP_feedline_rule_1)
def DP_feedline_rule_2(model,aa,bb):
return model.DP[aa,bb]>=0.003118*model.m[aa,bb]-0.2282
model.DP_feedline_2 = Constraint(model.A, rule=DP_feedline_rule_2)
def DP_feedline_rule_3(model,cc,dd):
return model.DP[cc,dd]>=0.005495*model.m[cc,dd]-0.71735
model.DP_feedline_3 = Constraint(model.A, rule=DP_feedline_rule_3)
def DP_feedline_rule_4(model,ee,ff):
return model.DP[ee,ff]>=0.007909*model.m[ee,ff]-1.51368
model.DP_feedline_4 = Constraint(model.A, rule=DP_feedline_rule_4)
def DP_feedline_rule_5(model,gg,hh):
return model.DP[gg,hh]>=0.01026*model.m[gg,hh]-2.54843
model.DP_feedline_5 = Constraint(model.A, rule=DP_feedline_rule_5)
####### definition of the objective function #######
def ob(model):
return sum((model.Pp[i]*(price_thermal_energy*365*24*20-cost_HX)-price_pipeline*model.distP[i])*model.y[i] for i in model.AFP)
model.obj=Objective(rule=ob, sense=maximize)
instance=model.create_instance(data)
opt=SolverFactory('cplex',executable=r"path")
opt.solve(instance)
instance.display()