I im trying to define at what flow "pressure_hill" are equal to "pressure_returnline" in function def calculateflow(Q):
im trying to use sympy solve but get error message below.
pressure_returnlie and pressure_hill are calculating a pressure drop that depends on flowvalue from water. I know that both will have the same pressure drop and I want to calculate what flow I have in each pipe.
When running the code I get TypeError: cannot determine truth value of Relational
Is there a better way than using sympy solver?
Thanks // Sebastian
import numpy as np
import fluids
from scipy import stats
# #input h and D0
# h = 100 # mm
D0 = 149# mm
# flow = 5/60 #m3/min
# density = 999 #kg/m3
pi = 3.1416
# mu = 1E-3 # viscosity
# length = 10 # meter
# #calculation
def valve_pos(pos,control_sig,time):## Change / Secound
cntrl_max = 254
cntrl_min = 1
cntrl_mid = 127
time_forw = 1
time_back = 1.5
time_forw_min = 6
time_back_min = 5
min_pos = 5
max_pos = 149
cntrl_time = 0
cntrl_time_min = 0
way = 1
if control_sig == cntrl_mid:
return 0
if control_sig > cntrl_mid:
cntrl_time = time_forw
cntrl_time_min = time_forw_min
way = 1
else:
cntrl_time = time_back
cntrl_time_min = time_back_min
way = -1
coeff = stats.linregress([cntrl_min,cntrl_mid,cntrl_max],[-1,0,1])
rate = ((max_pos - min_pos) / cntrl_time) * (control_sig*coeff[0] + coeff[1]) * time
rate_min = ((max_pos - min_pos) / cntrl_time_min) * way * time
if abs(rate) < abs(rate_min):
rate = rate_min
if ((pos + rate) > max_pos) & (way > 0):
rate = 0
if ((pos - rate) < min_pos) & (way < 0):
rate = 0
return rate
def velocity(D0, flow):
d = D0/1000
area = (d**2*pi)/4
w0 = flow/area # flow velocity m/s
return w0
def knife_valve_pressure_loss (h,D0, density, flow):
w0 = velocity(D0,flow)
if h/D0 < 0.9 and h/D0 >= 0.2:
a = np.array([7.661175,-72.63827,345.7625,-897.8331,1275.939,-938.8331,278.8193])
i = np.array([0,1,2,3,4,5,6])
dzeta = np.exp(2.3*sum(a*(h/D0)**i))
elif h/D0 >= 0.9:
dzeta = 0.6 - 0.6 * (h/D0)
elif h/D0 < 0.2 and h/D0 >= 0.0:
dzeta = 13114 * (h/D0)**2 - 5216.1 * h/D0 + 553.17
else:
print ('formula cannot be used for this h/D0')
return 0
pressure_loss = dzeta * density * 0.5 * w0**2
if pressure_loss < 0:
pressure_loss = 0
return pressure_loss/100000
def pipe_losses(D0,flow,density,length,mu= 1E-3):
w0 = velocity(D0,flow)
Re = fluids.Reynolds(V=w0, D=D0/1000, rho=1000, mu=mu)
fd = fluids.friction_factor(Re, eD=1E-5/0.05)
K = fluids.K_from_f(fd=fd, L=length, D=D0/1000)
K += fluids.exit_normal()
K += 4*fluids.bend_rounded(Di=D0/1000, angle=90, fd=fd)
K += 3.6
pressure_loss_pipe_fittings = fluids.dP_from_K(K, rho=density, V=w0)/100000
liftheight_loss = 2/10.2
return pressure_loss_pipe_fittings + liftheight_loss
def pressure_hill(flow, h = 149, length = 17, D0 = 139, density = 999):
p_valve = knife_valve_pressure_loss (h,D0, density, flow)
p_system = pipe_losses(D0,flow,density,length)
return p_valve + p_system
def pressure_returnline(flow, h = 149, length = 1, D0 = 139, density = 999):
p_valve = knife_valve_pressure_loss (h,D0, density, flow)
p_system = pipe_losses((76/1000),flow,density,0.5)
return p_valve + p_system
def calculateflow(Q):
from sympy import symbols, solve, Eq, Symbol
x,y = symbols('x,y')
sol = solve(pressure_hill(x) - pressure_returnline(y) ,(x,y))
sol
calculateflow(0.1)
Traceback (most recent call last):
File "<ipython-input-59-42d41eef9605>", line 1, in <module>
calculateflow(0.1)
File "system_losses.py", line 122, in calculateflow
sol = solve(pressure_hill(x) - pressure_returnline(y) ,(x,y))
File "system_losses.py", line 109, in pressure_hill
p_valve = knife_valve_pressure_loss (h,D0, density, flow)
File "system_losses.py", line 90, in knife_valve_pressure_loss
if pressure_loss < 0:
File "relational.py", line 398, in __bool__
raise TypeError("cannot determine truth value of Relational")
TypeError: cannot determine truth value of Relational
I am trying to find the global minima of a function using scipy.optimizer methods and keep running into NoneType issues. I have tried multiple algorithms including differential_evolution, shgo, and brute but keep running into errors.
Here is the setup:
def sizing_trade_study(ranges, payload):
with open("config.yml", "r") as yml:
cfg = yaml.load(yml)
first_int = True
km = []
for range in ranges:
km.append( range * 1000)
print(km)
params = (km, payload)
if first_int:
x0 = [float(cfg['design_variables']['initial_guess']['prop_radius']),
float(cfg['design_variables']['initial_guess']['speed']),
float(cfg['design_variables']['initial_guess']['battery_mass']),
float(cfg['design_variables']['initial_guess']['motor_mass']),
float(cfg['design_variables']['initial_guess']['mtow'])]
lb = [float(cfg['design_variables']['lower_bound']['prop_radius']),
float(cfg['design_variables']['lower_bound']['speed']),
float(cfg['design_variables']['lower_bound']['battery_mass']),
float(cfg['design_variables']['lower_bound']['motor_mass']),
float(cfg['design_variables']['lower_bound']['mtow'])] # Min cruise at 1.3 * VStall
ub = [float(cfg['design_variables']['upper_bound']['prop_radius']),
float(cfg['design_variables']['upper_bound']['speed']),
float(cfg['design_variables']['upper_bound']['battery_mass']),
float(cfg['design_variables']['upper_bound']['motor_mass']),
float(cfg['design_variables']['upper_bound']['mtow'])]
# bounds = (slice(lb[0], ub[0]), slice(lb[1], ub[1]), slice(lb[2], ub[2]), slice(lb[3], ub[3]), slice(lb[4], ub[4]))
# bounds = [(lb[0], ub[0]), (lb[1], ub[1]), (lb[2], ub[2]), (lb[3], ub[3]), (lb[4], ub[4])]
bounds = optimize.Bounds(lb,ub)
result = optimize.differential_evolution(objective_function, bounds, args=(params,))
print(result)
def objective_function(x, *params):
global trials
trials = trials+1
print(trials)
performance.compute_performance(x, params[0][0], params[0][1])
Here is the function I am trying to optimize:
import yaml
import simple_mission
import reserve_mission
import config_weight
def compute_performance(x, range, payload):
rprop = x[0]
speed = x[1]
battery = x[2]
motors = x[3]
mtow = x[4]
w = mtow * 9.8
with open("config.yml", "r") as yml:
cfg = yaml.load(yml)
bat_energy_density = int(cfg['performance']['bat_energy_density'])
motor_power_density = int(cfg['performance']['motor_power_density'])
discharge_depth = float(cfg['performance']['discharge_depth'])
e_nominal, flight_time, hover_output, cruise_output = simple_mission.run_simple_mission(rprop, speed, w, range)
reserve_e = reserve_mission.reserve_mission(rprop,speed, w, range)
mass = config_weight.config_weight(battery,motors, rprop, w, mtow, hover_output, cruise_output, payload)
batt = reserve_e - battery * bat_energy_density * discharge_depth / 1000
motor = hover_output.pow_hover / 1000 - motors * motor_power_density
weight = mass - w
return batt+ motor+ weight
The failure doesn't happen immediately but after a couple of runs of the optimizer function. For example, with differential_evolution, it always happens after the 75th trial.
Here is the stacktrace:
69
70
71
72
73
74
75
76
Traceback (most recent call last):
File "sizing_trade_study.py", line 62, in <module>
sizing_trade_study(args.ranges, args.payload)
File "sizing_trade_study.py", line 42, in sizing_trade_study
result = optimize.differential_evolution(objective_function, bounds, args=(params,))
File "/usr/local/anaconda3/envs/simple_mission/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py", line 308, in differential_evolution
ret = solver.solve()
File "/usr/local/anaconda3/envs/simple_mission/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py", line 759, in solve
next(self)
File "/usr/local/anaconda3/envs/simple_mission/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py", line 1082, in __next__
self.constraint_violation[candidate]):
File "/usr/local/anaconda3/envs/simple_mission/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py", line 1008, in _accept_trial
return energy_trial <= energy_orig
TypeError: '>=' not supported between instances of 'float' and 'NoneType'
Any help is greatly appreciated!
The issue is with one of the retrieved values from your bounds or objective_function, which in turn is being passed in as a NoneType to energy_orig within differential_evolution()
Source: https://github.com/scipy/scipy/blob/master/scipy/optimize/_differentialevolution.py
if feasible_orig and feasible_trial:
return energy_trial <= energy_orig
You should make sure that each key value is not empty from your config.yml or other function parameters. It's hard to tell which could be the problem. However, you could wrap it around a try/catch to get this to not stop on the 75th try for the meantime.
try:
result = optimize.differential_evolution(
objective_function,
bounds,
args=(params,),
)
except TypeError:
import pdb; pdb.set_trace()
I've set pdb, which will allow to to debug the values of each parameter, feel free to swap it out with a pass if you need to continue swiftly
With reference to the images in the attached files, i want to model using pyomo.
What I have done so far.
from pyomo.environ import *
from pyomo.opt import SolverFactory
import pyomo.environ
n=13
distanceMatrix=[[0,8,4,10,12,9,15,8,11,5,9,4,10],
[8,0,7,6,8,6,7,10,12,9,8,7,5],
[4,7,0,7,9,5,8,5,4,8,6 ,10,8],
[10,6 ,7,0,6,11,5 ,9,8,12,11,6,9],
[12,8 ,9,6, 0,7,9,6,9,8,4,11,10],
[9,6,5,11,7,0,10,4,3,10,6,5,7],
[15,7 ,8,5,9,10,0,10,9,8,5,9,10],
[8,10 ,5,9,6,4,10,0,11,5,9,6,7],
[11,12,4,8, 9,3,9,11,0, 9,11,11,6],
[5,9,8,12,8,10,8,5,9,0,6,7,5],
[9,8,6,11,4,6,5,9,11,6,0,10,7],
[4,7,10,6,11,5,9,6,11,7,10,0,9],
[10,5,8,9,10,7,10,7,6,5,7,9,0]]
travel_time=[[0,8,4,10,12,9,15,8,11,5,9,4,10],
[8,0,7,6,8,6,7,10,12,9,8,7,5],
[4,7,0,7,9,5,8,5,4,8,6 ,10,8],
[10,6 ,7,0,6,11,5 ,9,8,12,11,6,9],
[12,8 ,9,6, 0,7,9,6,9,8,4,11,10],
[9,6,5,11,7,0,10,4,3,10,6,5,7],
[15,7 ,8,5,9,10,0,10,9,8,5,9,10],
[8,10 ,5,9,6,4,10,0,11,5,9,6,7],
[11,12,4,8, 9,3,9,11,0, 9,11,11,6],
[5,9,8,12,8,10,8,5,9,0,6,7,5],
[9,8,6,11,4,6,5,9,11,6,0,10,7],
[4,7,10,6,11,5,9,6,11,7,10,0,9],
[10,5,8,9,10,7,10,7,6,5,7,9,0]]
Time_windows = [(1400,1500), (0000,2400), (0000,2400),(0700,2400),(0000,2400),(0000,0700),(0700,2400),(0700,2400),(0000,0700),(0000,2400),\
(0000,2400),(0000,2400),(0700,2400)]
Service_time = [0000, 1600,1600,180,30,120,120,60,30,30,90,120,330]
demand = [9999.00, 9999.00,9999.00,12.00, 4.00, 6.00, 8.00,16.00,6.00,16.00,12.00,24.00,8.00]
K = 4 # no. of vehicles
C = 280; # capacity
speed = 40; # default speed
M = 200;
startCity = 0
model = ConcreteModel()
# sets
#model.M = Set(initialize=range(1, n+1))
model.N = Set(initialize=range(1, n+1))
model.K = Set(initialize=range(1, K+1))
model.Nc = Set(initialize=range(3, n+1)) # set of customers
# Param
model.cost = Param(model.N, model.N, initialize=lambda model, i, j: distanceMatrix[i-1][j-1])
model.travel_time = Param(model.N, model.N,initialize=lambda model, i,j: travel_time[i-1][j-1])
model.Time_windows = Param(model.N, initialize=lambda model, i: travel_time[i-1]) # time_windows
model.Service_time = Param(model.N, initialize=lambda model, i: Service_time[i-1]) # Service time
model.demand = Param(model.N, initialize=lambda model, i: demand[i-1])
model.M = Param(initialize=M)
model.C = Param(initialize=C)
# variables
model.x_ijl = Var(model.N, model.N, model.K, within=Binary) # decision variable = 1 iff vehicle l in K uses arc (i,j) in A
model.d_il = Var(model.N, model.K, bounds=(0,None)) # the accumulative demand at node i in V for vehicle l in K
model.w_il = Var(model.N, model.K, bounds=(0,None)) # start time of service at node i in V for vehicle l in K
"""
Constriants
"""
# All l vehicles must leave the depot
def leave_depot(model,l):
return sum(model.x_ijl[0,j,l] for j in model.N) == 1
model.leave_depot = Constraint(model.K, rule=leave_depot)
# All l vehicles must return to the depot
def return_depot(model,l):
return sum(model.x_ijl[i,0,l] for i in model.N) == 1
model.return_depot = Constraint(model.K, rule=return_depot)
# ensures that all customers are serviced exactly once.
def customer_service(model, j):
return sum(sum(model.x_ijl[i,j,l] for l in model.K) for i in model.N) ==1
model.customer_service1 = Constraint(model.Nc, rule=customer_service)
# Inflow and outflow must be equal except for the depot nodes
def flow(model,j,l):
return sum(model.x_ijl[i,j,l] for i in model.N if i < j) == sum(model.x_ijl[j,i,l] for i in model.N if j < i)
model.flow1 = Constraint(model.N,model.K, rule=flow)
# Time windows
def time_windows1(model,i,l):
return model.Time_windows[i][0] <=model.w_il[i,l] <= model.Time_windows[i][1]
model.time_windows = Constraint(model.N,model.K, rule=time_windows1)
# service time
def service_time(model,i,j,l):
return model.w_il[i,l] + model.Service_time[i] + model.travel_time[i,j] <= model.w_il[j,l] + (1 - model.x_ijl[i,j,l])*200
model.service_time = Constraint(model.N, model.N, model.K, rule=service_time)
# vehicle must be empty at start and end of routes
def empty(model, l):
return model.d_il[0,l] + model.d_il[-1,l] == 0
model.empty = Constraint(model.K, rule=empty)
# accumulative demand for all nodes except disposal sites
def demands_forall_nodes(model,i,j,l):
return model.d_il[i,l] + model.demand[i] <= model.d_il[j,l]+(1 - model.x_ijl[i,j,l]*200)
model.demands_forall_nodes = Constraint(model.Nc, model.N,model.K,rule=demands_forall_nodes)
# Capacity contraints
def vehicle_capacity(model, i,l):
return model.d_il[i,l] <= model.C
model.vehicle_capacity = Constraint(model.N, model.K, rule=vehicle_capacity)
# Objective Function
def objective(model):
return sum(model.cost[i,j]*model.x_ijl[i,j,l] for i in model.N for j in model.N for l in model.K)
model.obj = Objective(rule=objective)
opt = SolverFactory("glpk")
results = opt.solve(model, tee=True)
results.write()
However, I got an error with constriant 2 (from image 2) which I know similar will apply to constraint 3 and constriant 9. The error is:
ERROR: Rule failed when generating expression for constraint leave_depot with
index 1: KeyError: "Index '(0, 1, 1)' is not valid for indexed component
'x_ijl'"
ERROR: Constructing component 'leave_depot' from data=None failed: KeyError:
"Index '(0, 1, 1)' is not valid for indexed component 'x_ijl'"
Traceback (most recent call last):
File "vrptwModel.py", line 81, in <module>
model.leave_depot = Constraint(model.K, rule=leave_depot)
File "/usr/local/lib/python2.7/dist-packages/pyomo/core/base/block.py", line 540, in __setattr__
self.add_component(name, val)
File "/usr/local/lib/python2.7/dist-packages/pyomo/core/base/block.py", line 980, in add_component
val.construct(data)
File "/usr/local/lib/python2.7/dist-packages/pyomo/core/base/constraint.py", line 793, in construct
ndx)
File "/usr/local/lib/python2.7/dist-packages/pyomo/core/base/misc.py", line 61, in apply_indexed_rule
return rule(model, index)
File "vrptwModel.py", line 80, in leave_depot
return sum(model.x_ijl[0,j,l] for j in model.N) == 1
File "vrptwModel.py", line 80, in <genexpr>
return sum(model.x_ijl[0,j,l] for j in model.N) == 1
File "/usr/local/lib/python2.7/dist-packages/pyomo/core/base/indexed_component.py", line 543, in __getitem__
index = self._validate_index(index)
File "/usr/local/lib/python2.7/dist-packages/pyomo/core/base/indexed_component.py", line 695, in _validate_index
% ( idx, self.name, ))
KeyError: "Index '(0, 1, 1)' is not valid for indexed component 'x_ijl'"
My problem is modeling constraint 2 and 3.
Please could someone help me to write these constraints correctly
The problem is that you started your indexing sets at 1 not 0. Change m.x_ijl[0,j,l] to m.x_ijl[1,j,l].