Related
I have a rather long question I hope I can get help with.
I have a code that runs a simulation by a "while true" loop and after that a "for" loop that saves data from the simulation and restart the sim after given time. This code works fine, but now Im trying to convert this into a multiprocess where I can get 4 simultaneous simulations and for loops. So I tried to put most of the code into a function and then called it but it does not seem to work. Sorry for the long code I appreciate any help!
The first working code without multiprocessing
for z in range(8):
for q in range(100):
time_re = time_re + 3000
tk.after(time_re,appender)
tk.after(time_re,restart)
ava(avaR1)
while True:
time_steps = range(0,iterations+1)
B = Beta.get()
G = Gamma.get()
D = Diff.get()
M = Mor.get()
steps_x_or_y = np.random.rand(n)
steps_x = steps_x_or_y < D/2
steps_y = (steps_x_or_y > D/2) & (steps_x_or_y < D)
nx = (x + np.sign(np.random.randn(n)) * steps_x) % l
ny = (y + np.sign(np.random.randn(n)) * steps_y) % l
for i in np.where( (S==1) & ( np.random.rand(n) < B ))[0]: # loop over infecting agents
S[(x==x[i]) & (y==y[i]) & (S==0)] = 1 # Susceptiples together with infecting agent becomes infected
S[ (S==1) & (np.random.rand(n) < G) ] = 2 # Recovery
S[ (S==1) & (np.random.rand(n) < M) ] = 3 # Death
nrInf1 = sum(S==1)
nrSus.append(sum(S==0))
nrInf.append(sum(S==1))
nrRec.append(sum(S==2))
nrRec1 = sum(S==2)
nrDea = sum(S == 3)
iterations += 1
tk.update()
tk.title('Infected:' + str(np.sum(S==1)))
x = nx # Update x
y = ny # Update y
The second code with me trying to change it to multiprocessing
def main1(i):
# Physical parameters of the system
x = np.floor(np.random.rand(n)*l) # x coordinates
y = np.floor(np.random.rand(n)*l) # y coordinates
S = np.zeros(n) # status array, 0: Susceptiple, 1: Infected, 2: recovered
I = np.argsort((x-l/2)**2 + (y-l/2)**2)
S[I[1:initial_infected]] = 1 # Infect agents that are close to center
nrRec1 = 0
nrDea = []
time_re = 0
particles = []
R = .5 # agent plot radius
nx = x # udpated x
ny = y # updated y
def restart():
global S
I = np.argsort((x-l/2)**2 + (y-l/2)**2)
S = np.zeros(n)
S[I[1:initial_infected]] = 1
rest = Button(tk, text='Restart',command= restart)
rest.place(relx=0.05, rely=.85, relheight= 0.12, relwidth= 0.15 )
def ava(k,o):
global b
k.append(sum(o)/3)
Beta.set(b) # Parameter slider for mortality rate
b += 0.03125
#bSaver.append(b)
def appender(o):
nrDea1.append(nrDea)
o.append(nrRec1)
for j in range(n): # Generate animated particles in Canvas
particles.append( canvas.create_oval( (x[j] )*res/l,
(y[j] )*res/l,
(x[j]+2*R )*res/l,
(y[j]+2*R )*res/l,
outline=ccolor[0], fill=ccolor[0]) )
if i == 1:
b=0
for z in range(3):
for q in range(3):
time_re = time_re + 1000
tk.after(time_re,appender(nrSRec1))
tk.after(time_re,restart)
tk.after(9000,ava(avaR1,nrSRec1))
elif i == 2:
b=0.25
for z in range(3):
for q in range(3):
time_re = time_re + 1000
tk.after(time_re,appender(nrSRec2))
tk.after(time_re,restart)
tk.after(9000,ava(avaR2,nrSRec2))
elif i == 3:
b=.50
for z in range(3):
for q in range(3):
time_re = time_re + 1000
tk.after(time_re,appender(nrSRec3))
tk.after(time_re,restart)
tk.after(9000,ava(avaR3,nrSRec3))
else:
b=.75
for z in range(3):
for q in range(3):
time_re = time_re + 1000
tk.after(time_re,appender(nrSRec4))
tk.after(time_re,restart)
tk.after(9000,ava(avaR4,nrSRec4))
while True:
B = Beta.get()
G = Gamma.get()
D = Diff.get()
steps_x_or_y = np.random.rand(n)
steps_x = steps_x_or_y < D/2
steps_y = (steps_x_or_y > D/2) & (steps_x_or_y < D)
nx = (x + np.sign(np.random.randn(n)) * steps_x) % l
ny = (y + np.sign(np.random.randn(n)) * steps_y) % l
for i in np.where( (S==1) & ( np.random.rand(n) < B ))[0]: # loop over infecting agents
S[(x==x[i]) & (y==y[i]) & (S==0)] = 1 # Susceptiples together with infecting agent becomes infected
S[ (S==1) & (np.random.rand(n) < G) ] = 2 # Recovery
nrDea= sum(S == 3)
nrRec1 = sum(S==2)
tk.update()
tk.title('Infected:' + str(np.sum(S==1)))
x = nx # Update x
y = ny # Update y
if __name__ == '__main__':
p1=mp.Process(target=main1, args=(1,))
p1.start()
p2=mp.Process(target=main1, args=(2,))
p2.start()
p3=mp.Process(target=main1, args=(3,))
p3.start()
p4=mp.Process(target=main1, args=(4,))
p4.start()
joinedList = avaR1+avaR2+avaR3+avaR4
print(joinedList)
Tk.mainloop(canvas)
When the frequency changes, clicks are sometimes heard.
I tried to eliminate the clicks in a couple of ways, e.g. changing the frequency only when the volume reaches 0 more than once. I tried to calculate when 1 period will end exactly but that didn't work either.
import sys
import sdl2
import sdl2.ext
import math
import struct
import ctypes
basefreq = 110
nframes = 0
tab = [1]
left=0
m= [0]
x=[0]
x2=[0]
x3=[11025]
x4=[0]
i2=[1]
x5=[0]
#ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.POINTER(sdl2.Uint8), ctypes.c_int)
def playNext(notused, stream, len):
global nframes
for i in range(0, len, 4):
t = (nframes + i) / 44100
i2[0] = i2[0] + 1
t4 = (nframes + i2[0]) / 44100
left2 = math.sin(2 * math.pi * t * (basefreq + int(tab[0])))
left = int(math.sin(2 * math.pi * t * (basefreq + int(tab[0]) )) * 32000)
right = int(math.sin(2 * math.pi * t * (basefreq + 1)) * 32000)
#print(t*100000)
x3[0]=x3[0]+1
t2 = 1 / (basefreq + tab[0])
d2 = i / (44100 * t2)
t3 = x3[0] / (basefreq + tab[0])
d3 = i / (44100 * t3)
width = 344/(basefreq + tab[0])
if (int(t * 100000) % 100000 == 0):
#print(t, " : ", i, " : ", x3[0], " : ", t3," : ", t2," : ",basefreq + tab[0])
x4[0]=0
x3[0] = 0
if (int(d2 * 10) % 2 == 0):
g = x2[0]
x2[0] = 0
dd = g / (44100 * t2)
# print(left, " : ", left)
x2[0] = x2[0] + 1
e = dd * 44100
x4[0]=x4[0]+1
#print(x4[0])
#if(int(left)*1000==0):
#if ((left * 100 <= 0 or left * 100 <= 0) and (left * 100 < 500 or left * 100 > -500)):
print(int(left2*100))
if (int(left2*100) ==0):
if (x5[0] == 10):
#if(int(t*10000)%int(t2*10000)==0):
#if (int(d2 * 10) % 2 == 0 and (i / 100) % int(e / 100) == 0 ):
#if(i*1000%int(t3*220*1000)==0):
tab[0] =math.sin(x[0] / 100)*100+100
x[0]=x[0]+1
i2[0] = i2[0] - 1
x5[0]=0
else:
x5[0]=x5[0]+1
if((nframes + i)%4==0):
stream[i] = left & 0xff
stream[i+1] = (left >> 8) & 0xff
stream[i+2] = right & 0xff
stream[i+3] = (right >> 8) & 0xff
nframes += len
def initAudio():
spec = sdl2.SDL_AudioSpec(0, 0, 0, 0)
spec.callback = playNext
spec.freq = 44100
spec.format = sdl2.AUDIO_S16SYS
spec.channels = 2
spec.samples = 1024
devid = sdl2.SDL_OpenAudioDevice(None, 0, spec, None, 0)
sdl2.SDL_PauseAudioDevice(devid, 0)
def run():
global basefreq
sdl2.SDL_Init(sdl2.SDL_INIT_AUDIO | sdl2.SDL_INIT_TIMER | sdl2.SDL_INIT_VIDEO)
window = sdl2.ext.Window("Tone Generator", size=(800, 600))
window.show()
running = True
initAudio()
while running:
events = sdl2.ext.get_events()
for event in events:
if event.type == sdl2.SDL_QUIT:
running = False
break
elif event.type == sdl2.SDL_KEYDOWN:
if event.key.keysym.sym == sdl2.SDLK_UP:
basefreq *= 2
elif event.key.keysym.sym == sdl2.SDLK_DOWN:
basefreq /= 2
break
sdl2.SDL_Delay(1)
return 0
if __name__ == "__main__":
sys.exit(run())
I think this problem is hard to solve.
Can someone help me with this problem?
Hi there smart people!
I am trying to implement a 1D, steady-state, real gas (compressibility factor) pipe flow model in Python using Pyomo + SCIP. It basically amounts to solving a DAE system. The formulation is an adopted version from chapter 10 in Koch, T.; Hiller, B.; Pfetsch, M.E.; Schewe, L. Evaluating Gas Network Capacities; Series on Optimization, MOS-SIAM, 2015.
However, I am encountering several problems:
The problem seems to be numerically sensitive to a combination of the discretization step length and input parameters (mass flow, pipe length).
Does not solve for any other model but ideal gas.
With a suitable discretization, and an ideal gas law, I get a result that seems reasonable (see example). In all other cases it turns out to be infeasible.
I may be overlooking something here, but I do not see it. Therefore, if anyone is inclined to try and help me out here, I would be thankful.
The example below should produce a valid output.
Edit: I realized I had one false constraint in there belonging to another model. The energy equation works now. However, the problems mentioned above remain.
from pyomo.dae import *
from pyomo.environ import *
import matplotlib.pyplot as plt
from math import pi
from dataclasses import dataclass
#dataclass
class ShomateParameters:
A: float
B: float
C: float
D: float
E: float
def specific_isobaric_heat_capacity(self, temperature):
# in J/(mol*K)
return self.A + self.B * (temperature/1000) + self.C * (temperature/1000)**2 + self.D * (temperature/1000)**3 + self.E/(temperature/1000)**2
def plot(self, temperature_start, temperature_end, points_to_mark=None):
assert temperature_start <= temperature_end, "temperature_start <= temperature_end must hold."
temperatures = [i for i in range(temperature_start, temperature_end+1)]
values = [self.specific_isobaric_heat_capacity(temp) for temp in temperatures]
fig, ax = plt.subplots()
ax.plot(temperatures, values)
if points_to_mark is not None:
ax.scatter(points_to_mark, [self.specific_isobaric_heat_capacity(temp) for temp in points_to_mark])
ax.set(xlabel='temperature [K]', ylabel='specific isobaric heat capacity [J/(mol*K)]',
title='Shomate equation:\n A + B*T + C*T^2 + D*T^3 + E/T^2')
ax.grid()
plt.show()
#dataclass
class Species:
MOLAR_MASS: float # kg/mol
CRITICAL_TEMPERATURE: float # Kelvin
CRITICAL_PRESSURE: float # Pa
DYNAMIC_VISCOSITY: float # Pa*s
SHOMATE_PARAMETERS: ShomateParameters
METHANE = Species(MOLAR_MASS=0.016043,
CRITICAL_TEMPERATURE=190.56,
CRITICAL_PRESSURE=4599000,
DYNAMIC_VISCOSITY=1.0245e-5,
SHOMATE_PARAMETERS=ShomateParameters(
A=-0.703029,
B=108.4773,
C=-42.52157,
D=5.862788,
E=0.678565))
# select gas species
gas = METHANE
# select equation of state ('ideal', 'AGA' or 'Papay')
formula = 'ideal'
PIPE_LENGTH = 24000 # meter
start = 0 # meter
end = start + PIPE_LENGTH
MASS_FLOW = 350 # kg/s
PIPE_SLOPE = 0.0
PIPE_DIAMETER = 1.0 # meter
PIPE_INNER_ROUGHNESS = 6e-5 # 15e-6 # meter 6e-6 # meter
# gravitational acceleration
G = 9.81 # meter**2/s**2
# gas temperature at entry
TEMPERATURE = 283.15
# temperature ambient soil
TEMPERATURE_SOIL = 283.15 # Kelvin
# gas pressure at entry
PRESSURE = 4.2e6 # Pa
GAS_CONSTANT = 8.314 # J/(mol*K)
print(gas.SHOMATE_PARAMETERS)
print(gas.SHOMATE_PARAMETERS.specific_isobaric_heat_capacity(TEMPERATURE))
gas.SHOMATE_PARAMETERS.plot(273, 400, points_to_mark=[TEMPERATURE])
##################################################################################
# Variable bounds
##################################################################################
pressure_bounds = (0, 1e7) # Pa
temperature_bounds = (0, 650) # Kelvin
density_bounds = (0, 100)
idealMolarIsobaricHeatCapacityBounds = (0, 200)
correctionIdealMolarIsobaricHeatCapacityBounds = (-250, 250)
velocity_bounds = (0, 300)
##################################################################################
# Create model
##################################################################################
m = ConcreteModel()
##################################################################################
# Parameters
##################################################################################
m.criticalPressure = Param(initialize=gas.CRITICAL_PRESSURE)
m.criticalTemperature = Param(initialize=gas.CRITICAL_TEMPERATURE)
m.molarMass = Param(initialize=gas.MOLAR_MASS)
m.dynamicViscosity = Param(initialize=gas.DYNAMIC_VISCOSITY)
m.gravitationalAcceleration = Param(initialize=G)
m.pipeSlope = Param(initialize=PIPE_SLOPE)
m.innerPipeRoughness = Param(initialize=PIPE_INNER_ROUGHNESS)
m.c_HT = Param(initialize=2)
m.pi = Param(initialize=pi)
m.temperatureSoil = Param(initialize=TEMPERATURE_SOIL)
m.gasConstantR = Param(initialize=GAS_CONSTANT)
m.massFlow = Param(initialize=MASS_FLOW)
m.pipeDiameter = Param(initialize=PIPE_DIAMETER)
m.crossSectionalArea = Param(initialize=m.pi * m.pipeDiameter**2 / 4)
m.alpha = Param(initialize=3.52)
m.beta = Param(initialize=-2.26)
m.gamma = Param(initialize=0.274)
m.delta = Param(initialize=-1.878)
m.e = Param(initialize=2.2)
m.d = Param(initialize=2.2)
##################################################################################
# Variables
##################################################################################
m.x = ContinuousSet(bounds=(start, end))
m.pressure = Var(m.x, bounds=pressure_bounds) #
m.dpressuredx = DerivativeVar(m.pressure, wrt=m.x, initialize=0, bounds=(-100, 100))
m.temperature = Var(m.x, bounds=temperature_bounds) #
m.dtemperaturedx = DerivativeVar(m.temperature, wrt=m.x, initialize=0, bounds=(-100, 100))
m.density = Var(m.x, bounds=density_bounds)
m.ddensitydx = DerivativeVar(m.density, wrt=m.x, initialize=0, bounds=(-100, 100))
m.z = Var(m.x, bounds=(-10, 10))
m.specificIsobaricHeatCapacity = Var(m.x)
m.idealMolarIsobaricHeatCapacity = Var(m.x, bounds=idealMolarIsobaricHeatCapacityBounds)
m.correctionIdealMolarIsobaricHeatCapacity = Var(m.x, bounds=correctionIdealMolarIsobaricHeatCapacityBounds)
m.mue_jt = Var(bounds=(-100, 100))
m.velocity = Var(m.x, bounds=velocity_bounds)
m.phiVar = Var()
##################################################################################
# Constraint rules
##################################################################################
# compressibility factor z and its derivatives; (pV/(nRT)=z
def z(p,
T,
p_c,
T_c,
formula=None):
p_r = p/p_c
T_r = T/T_c
if formula is None:
raise ValueError("formula must be equal to 'AGA' or 'Papay' or 'ideal'")
elif formula == 'AGA':
return 1 + 0.257 * p_r - 0.533 * p_r/T_r
elif formula == 'Papay':
return 1-3.52 * p_r * exp(-2.26 * T_r) + 0.247 * p_r**2 * exp(-1.878 * T_r)
elif formula == 'ideal':
return 1
else:
raise ValueError("formula must be equal to 'AGA' or 'Papay' or 'ideal'")
def dzdT(p,
T,
p_c,
T_c,
formula=None):
p_r = p/p_c
T_r = T/T_c
if formula is None:
raise ValueError("formula must be equal to 'AGA' or 'Papay'")
elif formula == 'AGA':
return 0.533 * p/p_c * T_c * 1/T**2
elif formula == 'Papay':
return 3.52 * p_r * (2.26/T_c) * exp(-2.26 * T_r) + 0.247 * p_r**2 * (-1.878/T_c) * exp(-1.878 * T_r)
elif formula == 'ideal':
return 0
else:
raise ValueError("formula must be equal to 'AGA' or 'Papay' or 'ideal'")
def dzdp(p,
T,
p_c,
T_c,
formula=None):
p_r = p/p_c
T_r = T/T_c
if formula is None:
raise ValueError("formula must be equal to 'AGA' or 'Papay' or 'ideal'")
elif formula == 'AGA':
return 0.257 * 1/p_c - 0.533 * (1/p_c)/T_r
elif formula == 'Papay':
return -3.52 * 1/p_c * exp(-2.26 * T_r) + 0.274 * 1/(p_c**2) * 2 * p * exp(-1.878 * T_r)
elif formula == 'ideal':
return 0
else:
raise ValueError("formula must be equal to 'AGA' or 'Papay' or 'ideal'")
def make_c_compr(formula):
assert formula == 'AGA' or formula == 'Papay' or formula == 'ideal'
def _c_compr(z_var,
p,
T,
p_c,
T_c):
return z_var - z(p, T, p_c, T_c, formula=formula)
return _c_compr
_c_compr = make_c_compr(formula)
def _c_compr_rule(m, x):
return 0 == _c_compr(m.z[x],
m.pressure[x],
m.temperature[x],
m.criticalPressure,
m.criticalTemperature)
m.c_compr = Constraint(m.x, rule=_c_compr_rule)
# specific isobaric heat capacity: ideal + correction term
def _c_mhc_real(molarMass,
specificIsobaricHeatCapacity,
idealMolarIsobaricHeatCapacity,
correctionIdealMolarIsobaricHeatCapacity):
return molarMass * specificIsobaricHeatCapacity - (idealMolarIsobaricHeatCapacity +
correctionIdealMolarIsobaricHeatCapacity)
def _c_mhc_real_rule(m, x):
return 0 == _c_mhc_real(m.molarMass,
m.specificIsobaricHeatCapacity[x],
m.idealMolarIsobaricHeatCapacity[x],
m.correctionIdealMolarIsobaricHeatCapacity[x])
m.c_mhc_real = Constraint(m.x, rule=_c_mhc_real_rule)
# _c_mhc_ideal_Shomate
def _c_mhc_ideal_Shomate(idealMolarIsobaricHeatCapacity, A, B, C, D, E, T):
return idealMolarIsobaricHeatCapacity - (A + B * (T/1000) + C * (T/1000)**2 + D * (T/1000)**3 + E/(T/1000)**2)
def _c_mhc_ideal_Shomate_rule(m, x):
return 0 == _c_mhc_ideal_Shomate(m.idealMolarIsobaricHeatCapacity[x],
gas.SHOMATE_PARAMETERS.A,
gas.SHOMATE_PARAMETERS.B,
gas.SHOMATE_PARAMETERS.C,
gas.SHOMATE_PARAMETERS.D,
gas.SHOMATE_PARAMETERS.E,
m.temperature[x])
m.c_mhc_ideal_Shomate = Constraint(m.x, rule=_c_mhc_ideal_Shomate_rule)
# _c_mhc_corr
def make_c_mhc_corr(formula):
assert formula == 'AGA' or formula == 'Papay' or formula == 'ideal'
if formula == 'AGA':
def _c_mhc_corr(correctionIdealMolarIsobaricHeatCapacity, alpha, beta, gamma, delta, p, T, p_c, T_c, R):
return correctionIdealMolarIsobaricHeatCapacity
elif formula == 'Papay':
def _c_mhc_corr(correctionIdealMolarIsobaricHeatCapacity, alpha, beta, gamma, delta, p, T, p_c, T_c, R):
# m.alpha = 3.52
# m.beta = -2.26
# m.gamma = 0.274
# m.delta = -1.878
p_r = p/p_c
T_r = T/T_c
return correctionIdealMolarIsobaricHeatCapacity + R * (
(gamma * delta + 0.5 * gamma * delta**2 * T_r) * p_r**2 * T_r * exp(delta * T_r) -
(2 * alpha * beta + alpha * beta**2 * T_r) * p_r * T_r * exp(beta * T_r))
elif formula == 'ideal':
def _c_mhc_corr(correctionIdealMolarIsobaricHeatCapacity, alpha, beta, gamma, delta, p, T, p_c, T_c, R):
return correctionIdealMolarIsobaricHeatCapacity
return _c_mhc_corr
_c_mhc_corr = make_c_mhc_corr(formula)
def _c_mhc_corr_rule(m, x):
return 0 == _c_mhc_corr(m.correctionIdealMolarIsobaricHeatCapacity[x],
m.alpha,
m.beta,
m.gamma,
m.delta,
m.pressure[x],
m.temperature[x],
m.criticalPressure,
m.criticalTemperature,
m.gasConstantR)
m.c_mhc_corr = Constraint(m.x, rule=_c_mhc_corr_rule)
# equation of state
def _c_eos(p, T, rho, molarMass, R, z):
return rho * z * R * T - p * molarMass
def _c_eos_rule(m, x):
return 0 == _c_eos(m.pressure[x],
m.temperature[x],
m.density[x],
m.molarMass,
m.gasConstantR,
m.z[x])
m.c_eos = Constraint(m.x, rule=_c_eos_rule)
# flow velocity equation
def _c_vel_flow(q, v, rho, A):
return A * rho * v - q
def _c_vel_flow_rule(m, x):
return 0 == _c_vel_flow(m.massFlow,
m.velocity[x],
m.density[x],
m.crossSectionalArea)
m.c_vel_flow = Constraint(m.x, rule=_c_vel_flow_rule)
# a smooth reformulation of the flow term with friction: lambda(q)|q|q (=phi)
def _c_friction(phi, q, k, D, e, d, A, eta):
beta = k/(3.71 * D)
lambda_slant = 1/(2*log10(beta))**2
alpha = 2.51 * A * eta / D
delta = 2 * alpha/(beta*log(10))
b = 2 * delta
c = (log(beta) + 1) * delta**2 - (e**2 / 2)
root1 = sqrt(q**2 + e**2)
root2 = sqrt(q**2 + d**2)
return phi - lambda_slant * (root1 + b + c/root2) * q
def _c_friction_rule(m):
return 0 == _c_friction(m.phiVar,
m.massFlow,
m.innerPipeRoughness,
m.pipeDiameter,
m.e,
m.d,
m.crossSectionalArea,
m.dynamicViscosity)
m.c_friction = Constraint(rule=_c_friction_rule)
# energy balance
def _diffeq_energy(q, specificIsobaricHeatCapacity, dTdx, T, rho, z, dzdT, dpdx, g, s, pi, D, c_HT, T_soil):
return q * specificIsobaricHeatCapacity * dTdx - (q * T / (rho * z) * dzdT * dpdx) + (q * g * s) + (pi * D * c_HT * (T - T_soil))
def _diffeq_energy_rule(m, x):
# if x == start:
# return Constraint.Skip
return 0 == _diffeq_energy(m.massFlow,
m.specificIsobaricHeatCapacity[x],
m.dtemperaturedx[x],
m.temperature[x],
m.density[x],
m.z[x],
dzdT(m.pressure[x],
m.temperature[x],
m.criticalPressure,
m.criticalTemperature,
formula=formula),
m.dpressuredx[x],
m.gravitationalAcceleration,
m.pipeSlope,
m.pi,
m.pipeDiameter,
m.c_HT,
m.temperatureSoil)
m.diffeq_energy = Constraint(m.x, rule=_diffeq_energy_rule)
# momentum balance
def _diffeq_momentum(rho, dpdx, q, A, drhodx, g, s, phi, D):
return rho * dpdx - q**2 / (A**2) * drhodx / rho + g * rho**2 * s + phi / (2 * A**2 * D)
def _diffeq_momentum_rule(m, x):
# if x == start:
# return Constraint.Skip
return 0 == _diffeq_momentum(m.density[x],
m.dpressuredx[x],
m.massFlow,
m.crossSectionalArea,
m.ddensitydx[x],
m.gravitationalAcceleration,
m.pipeSlope,
m.phiVar,
m.pipeDiameter)
m.diffeq_momentum = Constraint(m.x, rule=_diffeq_momentum_rule)
##################################################################################
# Discretization
##################################################################################
discretizer = TransformationFactory('dae.finite_difference')
discretizer.apply_to(m, nfe=60, wrt=m.x, scheme='BACKWARD')
##################################################################################
# Initial conditions
##################################################################################
m.pressure[start].fix(PRESSURE)
m.temperature[start].fix(TEMPERATURE)
##################################################################################
# Objective
##################################################################################
# constant
m.obj = Objective(expr=1)
m.pprint()
##################################################################################
# Solve
##################################################################################
solver = SolverFactory('scip')
# solver = SolverFactory('scip', executable="C:/Users/t.triesch/Desktop/scipampl-7.0.0.win.x86_64.intel.opt.spx2.exe")
results = solver.solve(m, tee=True, logfile="pipe.log")
##################################################################################
# Plot
##################################################################################
distance = [i/1000 for i in list(m.x)]
p = [value(m.pressure[x])/1e6 for x in m.x]
t = [value(m.temperature[x]) for x in m.x]
rho = [value(m.density[x]) for x in m.x]
v = [value(m.velocity[x]) for x in m.x]
fig = plt.figure()
gs = fig.add_gridspec(4, hspace=0.5)
axs = gs.subplots(sharex=True)
fig.suptitle('p[start] = {0} [MPa], p[end] = {1} [MPa],\n T[start]= {2} [K],\n massFlow[:]= {3} [kg/s],\n total length: {4} m'.format(
p[0], p[-1], t[0], m.massFlow.value, PIPE_LENGTH))
axs[0].plot(distance, p, '-')
axs[0].set(ylabel='p [MPa]')
axs[0].set_ylim([0, 10])
axs[0].grid()
axs[0].set_yticks([i for i in range(0, 11)])
axs[1].plot(distance, t, '-')
axs[1].set(ylabel='T [K]')
axs[1].set_ylim([250, 350])
axs[1].grid()
axs[2].plot(distance, rho, '-')
axs[2].set(ylabel='rho [kg/m^3]')
axs[2].grid()
axs[3].plot(distance, v, '-')
axs[3].set(ylabel='v [m/s]')
axs[3].grid()
for ax in axs.flat:
ax.set(xlabel='distance [km]')
plt.show()
So my problem seems quite trivial, but I'm new to python and am writing a simple program that calculates the reactions of a beam. My program does that successfully, but now I want to expand the capabilities to being able to plot the shear and bending moment diagrams along each beam. My thought process is to use a list and add the shear values (for now) to that list, in increments that divides the beam into 100 segments. Afterwards I want to be able to retrieve them and use these values to plot them.
class beam:
def __init__(self, emod, i, length):
self.emod = emod
self.i = i
self.length = length
def A(self, a, p): # Calculate reaction at A
return p * (self.length - a) / self.length
def B(self, a, p): # Calculate reaction at B
return p * a / self.length
def Mc(self, a, p): # Calculate moment at C
return p * a * (self.length - a) / self.length
def delc(self, a, p):
return p * a * a * (self.length - a) ** 2 / 3 / self.emod / self.i / self.length
def delx(self, x, a, p):
beta = (self.length - a) / self.length
delta = x / self.length
return p * self.length * self.length * (self.length - a) * delta * (
1 - beta * beta - delta * delta) / 6 / self.emod / self.i
def delx1(self, x, a, p):
alpha = a / self.length
delta = x / self.length
return p * self.length * self.length * a * delta * (
1 - alpha * alpha - delta * delta) / 6 / self.emod / self.i
def maxDisplacementCoords(self, a):
return a * (1.0 / 3 + 2 * (self.length - a) / 3 / a) ** 0.5
class shearValues: # This is the class that adds the shear values to a list
def __init__(self):
self.values = []
def add_values(self, beam, a_val, p):
j = float(0)
v = beam.A(a_val, p)
while j < beam.length:
if j < a_val:
continue
elif j > a_val:
continue
elif j == a_val:
v -= p
self.values.append(v)
j += beam.length / float(100)
v += beam.B(a_val, p)
self.values.append(v)
if __name__ == '__main__':
def inertia_x(h, w, t):
iy1 = w * h * h * h / 12
iy2 = (w - t) * (h - 2 * t) ** 3 / 12
return iy1 - 2 * iy2
beam_list = []
beam1 = beam(200000000000, inertia_x(0.203, 0.133, 0.025), 5)
beam2 = beam(200000000000, inertia_x(0.254, 0.146, 0.031), 5)
beam3 = beam(200000000000, inertia_x(0.305, 0.102, 0.025), 5)
beam_list.append(beam1)
beam_list.append(beam2)
beam_list.append(beam3)
while True:
my_beam = beam_list[1]
beam_choice = input("Which beam would you like to evaluate? 1, 2 or 3 ")
if beam_choice == '1':
my_beam = beam_list[0]
elif beam_choice == '2':
my_beam = beam_list[1]
elif beam_choice == '3':
my_beam = beam_list[2]
p = float(input("Enter the required load "))
a_val = float(input("Enter displacement of point load (origin at LHS) "))
print("Ay = {}".format(my_beam.A(a_val, p)))
print("By = {}".format(my_beam.B(a_val, p)))
print("Mc = {}".format(my_beam.Mc(a_val, p)))
print("Displacement at C = {}".format(my_beam.delc(a_val, p)))
displacement = input("Do you want to calculate a specific displacement? [Y]es or [N]o ").upper()
if displacement not in 'YN' or len(displacement) != 1:
print("Not a valid option")
continue
if displacement == 'Y':
x = float(input("Enter location on beam to calculate displacement (origin on LHS) "))
if x < a_val:
print("Displacement at {} = {}".format(x, my_beam.delx(x, a_val, p)))
elif x > a_val:
print("Displacement at {} = {}".format(x, my_beam.delx1(my_beam.length - x, a_val, p)))
elif x == displacement:
print("Displacement at {} = {}".format(x, my_beam.delc(a_val, p)))
elif displacement == 'N':
continue
print("Max displacement is at {} and is = {}".format(my_beam.maxDisplacementCoords(a_val),
my_beam.delx(my_beam.maxDisplacementCoords(a_val), a_val,
p)))
# The code doesn't execute the way it is intended from here
sv = shearValues()
sv.add_values(my_beam,a_val,p)
Currently it seems as if I have created an infinite loop.
As you can see, the code is not optimized at all but any help would be appreciated. And the calculations are correct.
I have a little problem with Python.
I'm try to write an application for DCM standard who some slice and draw the final model.
This is my code:
from lar import *
from scipy import *
import scipy
import numpy as np
from time import time
from pngstack2array3d import pngstack2array3d
colors = 2
theColors = []
DEBUG = False
MAX_CHAINS = colors
# It is VERY important that the below parameter values
# correspond exactly to each other !!
# ------------------------------------------------------------
MAX_CHUNKS = 75
imageHeight, imageWidth = 250,250 # Dx, Dy
# configuration parameters
# ------------------------------------------------------------
beginImageStack = 430
endImage = beginImageStack
nx = ny = 50
imageDx = imageDy = 50
count = 0
# ------------------------------------------------------------
# Utility toolbox
# ------------------------------------------------------------
def ind(x,y): return x + (nx+1) * (y + (ny+1) )
def invertIndex(nx,ny):
nx,ny = nx+1,ny+1
def invertIndex0(offset):
a0, b0 = offset / nx, offset % nx
a1, b1 = a0 / ny, a0 % ny
return b0,b1
return invertIndex0
def invertPiece(nx,ny):
def invertIndex0(offset):
a0, b0 = offset / nx, offset % nx
a1, b1 = a0 / ny, a0 % ny
return b0,b1
return invertIndex0
# ------------------------------------------------------------
# computation of d-chain generators (d-cells)
# ------------------------------------------------------------
# cubic cell complex
# ------------------------------------------------------------
def the3Dcell(coords):
x,y= coords
return [ind(x,y),ind(x+1,y),ind(x,y+1),ind(x+1,y+1)]
# construction of vertex coordinates (nx * ny )
# ------------------------------------------------------------
V = [[x,y] for y in range(ny+1) for x in range(nx+1) ]
if __name__=="__main__" and DEBUG == True:
print "\nV =", V
# construction of CV relation (nx * ny)
# ------------------------------------------------------------
CV = [the3Dcell([x,y]) for y in range(ny) for x in range(nx)]
if __name__=="__main__" and DEBUG == True:
print "\nCV =", CV
#hpc = EXPLODE(1.2,1.2,1.2)(MKPOLS((V,CV[:500]+CV[-500:])))
#box = SKELETON(1)(BOX([1,2,3])(hpc))
#VIEW(STRUCT([box,hpc]))
# construction of FV relation (nx * ny )
# ------------------------------------------------------------
FV = []
v2coords = invertIndex(nx,ny)
for h in range(len(V)):
x,y= v2coords(h)
if (x < nx) and (y < ny): FV.append([h,ind(x+1,y),ind(x,y+1),ind(x+1,y+1)])
if __name__=="__main__" and DEBUG == True:
print "\nFV =",FV
#hpc = EXPLODE(1.2,1.2,1.2)(MKPOLS((V,FV[:500]+FV[-500:])))
#box = SKELETON(1)(BOX([1,2,3])(hpc))
#VIEW(STRUCT([box,hpc]))
# construction of EV relation (nx * ny )
# ------------------------------------------------------------
EV = []
v2coords = invertIndex(nx,ny)
for h in range(len(V)):
x,y = v2coords(h)
if x < nx: EV.append([h,ind(x+1,y)])
if y < ny: EV.append([h,ind(x,y+1)])
if __name__=="__main__" and DEBUG == True:
print "\nEV =",EV
#hpc = EXPLODE(1.2,1.2,1.2)(MKPOLS((V,EV[:500]+EV[-500:])))
#box = SKELETON(1)(BOX([1,2,3])(hpc))
#VIEW(STRUCT([box,hpc]))
# ------------------------------------------------------------
# computation of boundary operators (∂3 and ∂2s)
# ------------------------------------------------------------
"""
# computation of the 2D boundary complex of the image space
# ------------------------------------------------------------
Fx0V, Ex0V = [],[] # x == 0
Fx1V, Ex1V = [],[] # x == nx-1
Fy0V, Ey0V = [],[] # y == 0
Fy1V, Ey1V = [],[] # y == ny-1
v2coords = invertIndex(nx,ny)
for h in range(len(V)):
x,y = v2coords(h)
if (y == 0):
if x < nx: Ey0V.append([h,ind(x+1,y)])
if (x < nx):
Fy0V.append([h,ind(x+1,y),ind(x,y)])
elif (y == ny):
if x < nx: Ey1V.append([h,ind(x+1,y)])
if (x < nx):
Fy1V.append([h,ind(x+1,y),ind(x,y)])
if (x == 0):
if y < ny: Ex0V.append([h,ind(x,y+1)])
if (y < ny):
Fx0V.append([h,ind(x,y+1),ind(x,y)])
elif (x == nx):
if y < ny: Ex1V.append([h,ind(x,y+1)])
if (y < ny):
Fx1V.append([h,ind(x,y+1),ind(x,y)])
FbV = Fy0V+Fy1V+Fx0V+Fx1V
EbV = Ey0V+Ey1V+Ex0V+Ex1V
"""
"""
if __name__=="__main__" and DEBUG == True:
hpc = EXPLODE(1.2,1.2,1.2)(MKPOLS((V,FbV)))
VIEW(hpc)
hpc = EXPLODE(1.2,1.2,1.2)(MKPOLS((V,EbV)))
VIEW(hpc)
"""
# computation of the ∂2 operator on the boundary space
# ------------------------------------------------------------
print "start partial_2_b computation"
#partial_2_b = larBoundary(EbV,FbV)
print "end partial_2_b computation"
# computation of ∂3 operator on the image space
# ------------------------------------------------------------
print "start partial_3 computation"
partial_3 = larBoundary(FV,CV)
print "end partial_3 computation"
# ------------------------------------------------------------
# input from volume image (test: 250 x 250 x 250)
# ------------------------------------------------------------
out = []
Nx,Ny = imageHeight/imageDx, imageWidth/imageDx
segFaces = set(["Fy0V","Fy1V","Fx0V","Fx1V"])
for inputIteration in range(imageWidth/imageDx):
startImage = endImage
endImage = startImage + imageDy
xEnd, yEnd = 0,0
theImage,colors,theColors = pngstack2array3d('SLICES2/', startImage, endImage, colors)
print "\ntheColors =",theColors
theColors = theColors.reshape(1,2)
background = max(theColors[0])
foreground = min(theColors[0])
print "\n(background,foreground) =",(background,foreground)
if __name__=="__main__" and DEBUG == True:
print "\nstartImage, endImage =", (startImage, endImage)
for i in range(imageHeight/imageDx):
for j in range(imageWidth/imageDy):
xStart, yStart = i * imageDx, j * imageDy
xEnd, yEnd = xStart+imageDx, yStart+imageDy
image = theImage[:, xStart:xEnd, yStart:yEnd]
nx,ny = image.shape
if __name__=="__main__" and DEBUG == True:
print "\n\tsubimage count =",count
print "\txStart, yStart =", (xStart, yStart)
print "\txEnd, yEnd =", (xEnd, yEnd)
print "\timage.shape",image.shape
# ------------------------------------------------------------
# image elaboration (chunck: 50 x 50)
# ------------------------------------------------------------
"""
# Computation of (local) boundary to be removed by pieces
# ------------------------------------------------------------
if pieceCoords[0] == 0: boundaryPlanes += ["Fx0V"]
elif pieceCoords[0] == Nx-1: boundaryPlanes += ["Fx1V"]
if pieceCoords[1] == 0: boundaryPlanes += ["Fy0V"]
elif pieceCoords[1] == Ny-1: boundaryPlanes += ["Fy1V"]
"""
#if __name__=="__main__" and DEBUG == True:
#planesToRemove = list(segFaces.difference(boundaryPlanes))
#FVtoRemove = CAT(map(eval,planesToRemove))
count += 1
# compute a quotient complex of chains with constant field
# ------------------------------------------------------------
chains2D = [[] for k in range(colors)]
def addr(x,y): return x + (nx) * (y + (ny))
for x in range(nx):
for y in range(ny):
if (image[x,y] == background):
chains2D[1].append(addr(x,y))
else:
chains2D[0].append(addr(x,y))
#if __name__=="__main__" and DEBUG == True:
#print "\nchains3D =\n", chains3D
# compute the boundary complex of the quotient cell
# ------------------------------------------------------------
objectBoundaryChain = larBoundaryChain(partial_3,chains2D[1])
b2cells = csrChainToCellList(objectBoundaryChain)
sup_cell_boundary = MKPOLS((V,[FV[f] for f in b2cells]))
# remove the (local) boundary (shared with the piece boundary) from the quotient cell
# ------------------------------------------------------------
"""
cellIntersection = matrixProduct(csrCreate([FV[f] for f in b2cells]),csrCreate(FVtoRemove).T)
#print "\ncellIntersection =", cellIntersection
cooCellInt = cellIntersection.tocoo()
b2cells = [cooCellInt.row[k] for k,val in enumerate(cooCellInt.data) if val >= 4]
"""
# ------------------------------------------------------------
# visualize the generated model
# ------------------------------------------------------------
print "xStart, yStart =", xStart, yStart
if __name__=="__main__":
sup_cell_boundary = MKPOLS((V,[FV[f] for f in b2cells]))
if sup_cell_boundary != []:
out += [T([1,2])([xStart,yStart]) (STRUCT(sup_cell_boundary))]
if count == MAX_CHUNKS:
VIEW(STRUCT(out))
# ------------------------------------------------------------
# interrupt the cycle of image elaboration
# ------------------------------------------------------------
if count == MAX_CHUNKS: break
if count == MAX_CHUNKS: break
if count == MAX_CHUNKS: break
And this is the error take from the terminal :
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-4-2e498c6090a0> in <module>()
213
214 image = theImage[:, xStart:xEnd, yStart:yEnd]
--> 215 nx,ny = image.shape
216
217 if __name__=="__main__" and DEBUG == True:
ValueError: too many values to unpack
Someone can help me to solve this issue????
Based on the line:
image = theImage[:, xStart:xEnd, yStart:yEnd]
image is a 3d array, not a 2d array (it appears to be multiple slices of an image), with the 2nd and 3rd dimensions representing x and y respectively. Thus, if you want to get its dimensions you'll need to unpack it into three dimensions, something like:
nslice, nx, ny = image.shape