Adding and printing items, using lists using python - python

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.

Related

how to speed up master.scene._render_pygame_def_update() time

im trying to make a 3d renderer but i can only get at most 20fps on idle.
i tried using #functools.lru_cache(maxsize=None) on project_and_rotate() and got it up to 40fps on idle.
is there any way i could make this any faster
im using a long math formula i found a few month ago but it seems to be to slow for the map in projected_des
from math import *
import pygame
import numpy
from functools import lru_cache
#lru_cache(maxsize=None)
def project_and_rotate(x, y, z,rotx,roty,rotz,posx,posy,posz,cx,cy,cz,scale,render_distance):
x,y,z=x-posx,y-posy,z-posz
if abs(x)>render_distance or abs(z)>render_distance:return None
px = (((x * cos(rotz) - sin(rotz) * y) * cos(roty) - z * sin(roty)) * (315 / ((((z * cos(roty) + (x * cos(rotz) - sin(rotz) * y) * sin(roty)) * cos(rotx) + (y * cos(rotz) + x * sin(rotz)) * sin(rotx)) + 5) + cz))) * scale + cx
py = (((y * cos(rotz) + x * sin(rotz)) * cos(rotx) - (z * cos(roty) + (x * cos(rotz) - sin(rotz) * y) * sin(roty)) * sin(rotx)) * (315 / ((((z * cos(roty) + (x * cos(rotz) - sin(rotz) * y) * sin(roty)) * cos(rotx) + (y * cos(rotz) + x * sin(rotz)) * sin(rotx)) + 5) + cz))) * scale + cy
return [round(px),round(py)]
class coordinate:
def __init__(self,x,y,z):
self.x=x
self.y=y
self.z=z
class verticies_structure:
def __init__(self):
self._verts=[]
def add_vert(self,x,y,z):
self._verts.append(coordinate(x,y,z))
def get_coords(self,indexes):
return self._verts[indexes[0]:indexes[1]]
class camera:
def __init__(self,w,h,render_distance,fov=45):
self.fov=360-fov
self.w=w
self.h=h
self.x=0
self.rx=0
self.cx=0
self.y=0
self.ry=0
self.cy=0
self.z=0
self.rz=0
self.cz=0
self.render_distance=render_distance
def false(f,value):
if value==f:
value=f+0.01
return value
def inf360(value):
if value>359:value=0
if value<0:value=359
return value
class mesh(object):
def __init__(self,file_obj,cam):
self.cam=cam
self.verts=verticies_structure()
self.source=file_obj
self.read_object_file()
self.verts=verticies_structure()
size=100
for x in range(size):
for z in range(size):
self.verts.add_vert(x-size//2,0,z-size//2)
self.w2s_vect=numpy.vectorize(self.w2s)
self.array_verts=numpy.array(self.verts._verts)
def w2s(self,coord):
cam=self.cam
return project_and_rotate(coord.x,coord.y,coord.z,cam.ry,cam.rx,cam.rz,cam.x,cam.y,cam.z,cam.cx,cam.cy,cam.cz,10,cam.render_distance)
def projected_des(self,cam):
#return self.w2s_vect(self.array_verts).tolist()
return map( lambda coord:project_and_rotate(coord.x,coord.y,coord.z,cam.ry,cam.rx,cam.rz,cam.x,cam.y,cam.z,cam.cx,cam.cy,cam.cz,10,cam.render_distance),self.verts.get_coords([0,-1]))
def read_object_file(self):
self.verts=verticies_structure()
import re
reComp = re.compile("(?<=^)(v |vn |vt |f )(.*)(?=$)", re.MULTILINE)
with open(self.source) as f:
data = [txt.group() for txt in reComp.finditer(f.read())]
v_arr, vn_arr, vt_arr, f_arr = [], [], [], []
for line in data:
tokens = line.split(' ')
if tokens[0] == 'v':
v_arr.append([float(c) for c in tokens[1:]])
elif tokens[0] == 'vn':
vn_arr.append([float(c) for c in tokens[1:]])
elif tokens[0] == 'vt':
vn_arr.append([float(c) for c in tokens[1:]])
elif tokens[0] == 'f':
f_arr.append([[int(i) if len(i) else 0 for i in c.split('/')] for c in tokens[1:]])
vertices, normals = [], []
for face in f_arr:
for tp in face:
self.verts.add_vert(*v_arr[tp[0]-1])
self.array_verts=numpy.array(self.verts._verts)
class draw:
class frame:
class pygame_uitl:
def grid(rowx,rowy,px,color=(255,255,255)):
display=pygame.display.get_surface()
for r in range(rowx):
r+=1
pygame.draw.line(display,color,(0,(display.get_height()/(rowx+1))*r),(display.get_width(),(display.get_height()/(rowx+1))*r),px)
for r in range(rowy):
r+=1
pygame.draw.line(display,color,((display.get_width()/(rowy+1))*r,0),((display.get_width()/(rowy+1))*r,display.get_height()),px)
class system:
class pygame_util:
def get_orientation():
inf=pygame.display.Info()
w,h=inf.current_w,inf.current_h
if w>h:
return 1
else:
return 0
class Drivers:
class Pygame:
DEFAULT="PG-default"
SDL2="PG-sdl2"
class master:
class scene:
def __init__(self,wh:list,display_driver:str,render_distance:int,fps:int):
self._model={
"class 1":[],
"class 2":[],
"class 3":[],
"class 4":[]}
self._fps=fps
self._window_wh=wh
self._driver=display_driver
self._camera=camera(*wh,render_distance)
self._mode="mesh"
self._super_ls=0
if display_driver==Drivers.Pygame.DEFAULT:
self._render_pygame_def_setup()
def add_model(self,file):
model=mesh(file,self._camera)
vertexes=len(model.verts._verts)
if vertexes>100:
self._model["class 4"].append(model)
elif vertexes>50:
self._model["class 3"].append(model)
elif vertexes>25:
self._model["class 2"].append(model)
else:
self._model["class 1"].append(model)
def regulate_camera(self):
self._camera.rx,self._camera.ry,self._camera.rz=false(0,self._camera.rx),false(0,self._camera.ry),false(0,self._camera.rz)
self._camera.cx,self._camera.cy,self._camera.cz=false(0,self._camera.cx),false(0,self._camera.cy),false(0,self._camera.cz)
def correct_camera(self,orient=1):
self._orient=orient
if orient:
self._camera.cx=self._window_wh[1]//2
self._camera.cy=self._window_wh[0]
self._camera.ry=0.4
else:
self._camera.cx=self._window_wh[0]//2
self._camera.cy=self._window_wh[1]
self._camera.ry=0.2
def auto_render_distance(self):
if self._driver==Drivers.Pygame.DEFAULT:
if self._pygame_clock.get_fps()+5>self._fps:
self._camera.render_distance+=1
else:
self._camera.render_distance-=1
def landscape_super(self):
self._super_ls=1
self._lss_hdri_file_jpg_surf=pygame.Surface([self._window_wh[0],self._window_wh[1]//2.01])
self._lss_hdri_file_jpg_surf.fill((200,220,255))
def _render_pygame_def_setup(self):
self._pygame_clock=pygame.time.Clock()
self._pygame_screen=pygame.display.set_mode((self._camera.w,self._camera.h),pygame.DOUBLEBUF|pygame.HWACCEL|pygame.HWSURFACE)
def _render_pygame_def_update(self):
self._pygame_screen.fill((0,70,0))
self.regulate_camera()
for idx,vclass in self._model.items():
for model in vclass:
for point in model.projected_des(self._camera):
if point!=None:
try:self._pygame_screen.set_at(point,(255,255,255))
except:pass
if self._super_ls:
self._pygame_screen.blit(self._lss_hdri_file_jpg_surf,(0,0))
def _render_pygame_def_finish(self):
pygame.display.flip()
self._pygame_clock.tick(self._fps)
scene=master.scene([2176,1080],Drivers.Pygame.DEFAULT,render_distance=25,fps=60)
scene.add_model("cube.obj")
scene.correct_camera(0)
scene.landscape_super()
#make the sky mapped to edge of render
pygame.font.init()
while 1:
rx,ry=pygame.mouse.get_rel()
scene._camera.rx+=rx/200
scene._render_pygame_def_update()
#scene.auto_render_distance()
scene._pygame_screen.blit(pygame.font.SysFont(None,60).render(str(scene._pygame_clock.get_fps()),None,(255,0,0)),(0,0))
scene._render_pygame_def_finish()
Something like this would reduce the number of math expressions in project_and_rotate
#lru_cache(maxsize=None)
def project_and_rotate(x, y, z,rotx,roty,rotz,posx,posy,posz,cx,cy,cz,scale,render_distance):
x,y,z=x-posx,y-posy,z-posz
if abs(x)>render_distance or abs(z)>render_distance:
return None
cos_rotz = cos(rotz)
sin_rotz = sin(rotz)
cos_roty = cos(roty)
sin_roty = sin(roty)
cos_rotx = cos(rotx)
sin_rotx = sin(rotx)
intermediate_1 = (x * cos_rotz - sin_rotz * y)
intermediate_2 = (z * cos_roty + intermediate_1 * sin_roty)
intermediate_3 = (y * cos_rotz + x * sin_rotz) * sin_rotx)
intermediate_4 = (315 / (((intermediate_2 * cos_rotx + intermediate_3 + 5) + cz))) * scale
px = ((intermediate_1 * cos_roty - z * sin_roty) * intermediate_4 + cx
py = (((y * cos_rotz + x * sin_rotz) * cos_rotx - intermediate_2 * sin_rotx) * intermediate_4 + cy
return [round(px), round(py)]
However, to fully improve your script -- it would be wise to profile the code to see where the script is taking the most time.
For a better discussion you should see https://codereview.stackexchange.com/

real gas, 1D pipe flow in Pyomo + SCIP failing through energy equation?

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()

Why doesn't update repaint a scene?

I am making a marching cubes project in python using PyQt5 and PyOpenGL. I am trying to hide the wireframe cube which marches across the screen, referenced as mainWindow.marchingCube to disappear after cycling through. I managed to get the disappearing cycle to occur, but the cube does not actually disappear. I called the QOpenGLWidget's update function, but the cube still did not disappear.
import sys
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QSlider,
QOpenGLWidget, QLabel, QPushButton
)
from PyQt5.QtCore import Qt
from OpenGL.GL import (
glLoadIdentity, glTranslatef, glRotatef,
glClear, glBegin, glEnd,
glColor3fv, glVertex3fv,
GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT,
GL_QUADS, GL_LINES
)
from OpenGL.GLU import gluPerspective
from numerics import sin, cos, tan, avg, rnd #Numerics is my custom math library.
import random, time
class mainWindow(QMainWindow): #Main class.
shapes = [] #this will hold instances of the following classes: cube
dataPoints = []
zoomLevel = -10
rotateDegreeV = -90
rotateDegreeH = 0
marchActive = False
limit = -1
meshPoints = []
class cube():
render = True
solid = False
color = (1, 1, 1)
def config(self, x, y, z, size = 0.1, solid = False, color = (1, 1, 1)):
self.solid = solid
self.color = color
self.size = size / 2
s = self.size
self.vertices = [
(-s + x, s + y, -s + z),
(s + x, s + y, -s + z),
(s + x, -s + y, -s + z),
(-s + x, -s + y, -s + z),
(-s + x, s + y, s + z),
(s + x, s + y, s + z),
(s + x, -s + y, s + z),
(-s + x, -s + y, s + z)
]
self.edges = [
(0,1), (0,3), (0,4), (2,1),
(2,3), (2,6), (7,3), (7,4),
(7,6), (5,1), (5,4), (5,6)
]
self.facets = [
(0, 1, 2, 3), (0, 1, 6, 5),
(0, 3, 7, 4), (6, 5, 1, 2),
(6, 7, 4, 5), (6, 7, 3, 2)
]
def show(self):
self.render = True
def hide(self):
self.render = False
class dataPoint():
location = (0, 0, 0)
value = 0
shape = None
def place(self, x, y, z):
self.location = (x, y, z)
def set(self, val):
self.value = val
def setShape(self, shape):
self.shape = shape
class meshPoint():
location = (0, 0, 0)
shape = None
def place(self, x, y, z):
self.location = (x, y, z)
def setShape(self, shape):
self.shape = shape
def keyPressEvent(self, event): #This is the keypress detector. I use this to determine input to edit grids.
try:
key = event.key()
#print(key)
if key == 87:
self.rotateV(5)
elif key == 65:
self.rotateH(5)
elif key == 83:
self.rotateV(-5)
elif key == 68:
self.rotateH(-5)
elif key == 67:
self.zoom(1)
elif key == 88:
self.zoom(-1)
elif key == 77:
self.marchStep()
except:
pass
def __init__(self):
super(mainWindow, self).__init__()
self.currentStep = 0
self.width = 700 #Variables used for the setting of the size of everything
self.height = 600
self.setGeometry(0, 0, self.width + 50, self.height) #Set the window size
self.initData(3, 3, 3)
def setupUI(self):
self.openGLWidget = QOpenGLWidget(self) #Create the GLWidget
self.openGLWidget.setGeometry(0, 0, self.width, self.height)
self.openGLWidget.initializeGL()
self.openGLWidget.resizeGL(self.width, self.height) #Resize GL's knowledge of the window to match the physical size?
self.openGLWidget.paintGL = self.paintGL #override the default function with my own?
self.filterSlider = QSlider(Qt.Vertical, self)
self.filterSlider.setGeometry(self.width + 10, int(self.height / 2) - 100, 30, 200)
self.filterSlider.valueChanged[int].connect(self.filter)
self.limitDisplay = QLabel(self)
self.limitDisplay.setGeometry(self.width, int(self.height / 2) - 130, 50, 30)
self.limitDisplay.setAlignment(Qt.AlignCenter)
self.limitDisplay.setText('-1')
self.marchButton = QPushButton(self)
self.marchButton.setGeometry(self.width, int(self.height / 2) - 160, 50, 30)
self.marchButton.setText('March!')
self.marchButton.clicked.connect(self.marchStep)
def marchStep(self):
if not self.marchActive:
marchAddr = len(self.shapes)
self.shapes.append(self.cube())
self.marchingCube = self.shapes[marchAddr]
self.marchActive = True
self.currentStep = 0
if self.currentStep == len(self.marchPoints):
self.currentStep = 0
#print('meshPoints: {}'.format(self.meshPoints))
for mp in self.meshPoints:
#print(mp.shape)
self.shapes.remove(mp.shape)
self.meshPoints.clear()
self.marchingCube.hide()
return
if self.currentStep == 0:
self.marchingCube.show()
p = self.marchPoints[self.currentStep]
x, y, z = p
self.marchingCube.config(x, y, z, size = 1)
points = []
for i in range(8):
point = self.getDataPointByLocation(self.marchingCube.vertices[i])
points.append(point)
self.openGLWidget.update()
#print('step: {} x: {} y: {} z: {}'.format(self.currentStep, x, y, z))
#for point in points:
# print(point.location, end = ' ')
#print()
for pair in self.marchingCube.edges:
pointA = points[pair[0]]
pointB = points[pair[1]]
#print('pointA.value: {} pointB.value: {} limit: {}'.formatpointA.value, pointB.value, self.limit)
if (pointA.value < self.limit and pointB.value > self.limit) or (pointA.value > self.limit and pointB.value < self.limit):
xA, yA, zA = pointA.location
xB, yB, zB = pointB.location
valA = (pointA.value + 1) / 2
valB = (pointB.value + 1) / 2
xC = float(avg([xA, xB]))
yC = float(avg([yA, yB]))
zC = float(avg([zA, zB]))
mp = self.meshPoint()
mp.place(xC, yC, zC)
mp.setShape(self.cube())
mp.shape.config(xC, yC, zC, size = 0.05, solid = True, color = (1, 0, 0))
self.shapes.append(mp.shape)
self.meshPoints.append(mp)
self.currentStep += 1
self.openGLWidget.update()
def zoom(self, value):
self.zoomLevel += value
self.openGLWidget.update()
def rotateV(self, value):
self.rotateDegreeV += value
self.openGLWidget.update()
def rotateH(self, value):
self.rotateDegreeH += value
self.openGLWidget.update()
def filter(self, value):
self.limit = rnd((value / 49.5) -1, -2)
for d in self.dataPoints:
if d.value < self.limit:
d.shape.hide()
else:
d.shape.show()
self.limitDisplay.setText(str(self.limit))
self.openGLWidget.update()
def getDataPointByLocation(self, coord):
x, y, z = coord
for dp in self.dataPoints:
if dp.location == (x, y, z):
return dp
return False
def paintGL(self):
glLoadIdentity()
gluPerspective(45, self.width / self.height, 0.1, 110.0) #set perspective?
glTranslatef(0, 0, self.zoomLevel) #I used -10 instead of -2 in the PyGame version.
glRotatef(self.rotateDegreeV, 1, 0, 0) #I used 2 instead of 1 in the PyGame version.
glRotatef(self.rotateDegreeH, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
if len(self.shapes) != 0:
glBegin(GL_LINES)
for s in self.shapes:
glColor3fv(s.color)
if s.render and not s.solid:
for e in s.edges:
for v in e:
glVertex3fv(s.vertices[v])
glEnd()
glBegin(GL_QUADS)
for s in self.shapes:
glColor3fv(s.color)
if s.render and s.solid:
for f in s.facets:
for v in f:
glVertex3fv(s.vertices[v])
glEnd()
def initData(self, sizeX, sizeY, sizeZ):
marchSizeX = sizeX - 1
marchSizeY = sizeY - 1
marchSizeZ = sizeZ - 1
xOff = -(sizeX / 2) + 0.5
yOff = -(sizeY / 2) + 0.5
zOff = -(sizeZ / 2) + 0.5
xMarchOff = -(marchSizeX / 2) + 0.5
yMarchOff = -(marchSizeY / 2) + 0.5
zMarchOff = -(marchSizeZ / 2) + 0.5
vals = []
self.marchPoints = []
for z in range(marchSizeZ):
for y in range(marchSizeY):
for x in range(marchSizeX):
self.marchPoints.append((x + xMarchOff, y + yMarchOff ,z + zMarchOff))
for z in range(sizeZ):
for y in range(sizeY):
for x in range(sizeX):
loc = len(self.dataPoints)
val = self.generate(x + xOff, y + yOff, z + zOff)
self.dataPoints.append(self.dataPoint())
self.dataPoints[loc].place(x + xOff, y + yOff, z + zOff)
self.dataPoints[loc].set(val)
loc2 = len(self.shapes)
self.shapes.append(self.cube())
self.shapes[loc2].config(x + xOff, y + yOff, z + zOff, solid = True, color = (0, (val + 1) / 2, (val + 1) / -2 + 1))
self.dataPoints[loc].setShape(self.shapes[loc2])
vals.append(val)
print(avg(vals))
def generate(self, xIn, yIn, zIn): #Function which produces semi-random values based on the supplied coordinates.
i = -(xIn * yIn * (10 + zIn))
j = xIn * yIn * (10 + zIn)
if i < j:
mixer = random.randint(i, j)
else:
mixer = random.randint(j, i + 1)
a = avg([sin(cos(xIn)), tan(tan(yIn)), cos(tan(zIn))])
out = mixer * a
while out > 10:
out -= 5
while out < -10:
out += 5
return float(out / 10)
app = QApplication([])
window = mainWindow()
window.setupUI()
window.show()
sys.exit(app.exec_())
Why doesn't the cube disappear? I have caught wind during my web searches on the subject that update does not always work as expected. Directly calling self.openGLWidget.paintGL() does not work either. What must I do to make the cube disappear?
EDIT:
If I make a call to rotate, rotate, or zoom, the screen refreshes and the meshpoints as well as the marching cube all disappear. I think I may end up making a workaround by calling one of those with a zero value.
To test, save the following code in a file named numerics.py in the same directory as the rest of the code.
from decimal import Decimal as dec
degrad = 'deg'
pi = 3.14159265358979323846
terms = dec(9) #number of terms used for the trig calculations
def version():
print('numerics.py version 1.0.0')
print('Packaged with the cubes project')
def mode(modeinput = ''): #switch between degrees and radians or check the current mode
global degrad
if modeinput == 'deg':
degrad = 'deg'
return 'deg'
if modeinput == 'rad':
degrad = 'rad'
return 'rad'
if modeinput == '':
return degrad
else:
return False
def accuracy(accinput = ''):
global terms
global pi
if accinput == '':
return terms
terms = dec(accinput)
PI = calculatePi(accinput)
print('Pi is: {}'.format(PI))
return terms
def calculatePi(placeIn = terms):
if placeIn > 15:
if input("Warning: You have chosen to calculate more than 20 digits of pi. This may take a LONG TIME and may be inacurate. Enter 'yes' if you wish to proceed. If you enter anything else, this function will revert to 10 digits.") == 'yes':
place = placeIn
else:
place = 10
else:
place = placeIn
print('Calculating Pi...\nPlease wait, as this may take a while.')
PI = dec(3)
addSub = True
for i in range(2, 2 * (int(place) ** 6) + 1, 2):
if addSub:
PI += dec(4) / (dec(i) * dec(i + 1) * dec(i + 2))
elif not addSub:
PI -= dec(4) / (dec(i) * dec(i + 1) * dec(i + 2))
addSub = not addSub
return rnd(PI, -(place), mode = 'cutoff')
def radToDeg(radin):
return (dec(radin) * dec(180 / pi))
def degToRad(degin):
return (dec(degin) * dec(pi / 180))
def avg(numsIn): #return the average of two numbers, specified as an integer or float
num1 = dec(0)
for i in numsIn:
num1 += dec(i)
return rnd(dec(num1 / dec(len(numsIn))))
def sin(anglein, dr = degrad): #return sine of the supplied angle using the predetermined mode or the supplied mode
if dr == 'deg':
while anglein > 180:
anglein -= 360
while anglein < -180:
anglein += 360
angle = degToRad(anglein)
if dr == 'rad':
while anglein > pi:
anglein -= (2 * pi)
while anglein < -pi:
anglein += (2 * pi)
angle = anglein
return rnd(rawsin(dec(angle)), -terms)
def arcsin(ratioin, dr = degrad): #return arcsine of the supplied ratio using the predetermined mode or the supplied mode
if ratioin > 1 or ratioin < -1: #if the input is illegal
return False
attempt = dec(0) #start at 0
target = rnd(dec(ratioin), -terms) #identify the target value
#print('target is: {}'.format(target))
for i in range(-1, int(terms) + 1): #for each place from 10s to terms decimal place (use -i, not i)
#print('Editing place {0}'.format(10 ** -i)) #debugging
for j in range(10): #for 10 steps
#print('current attempt: {}'.format(attempt), end = ' ')
if rnd(sin(attempt, dr), -terms) == target:
if attempt < 0:
final = (attempt * dec(-1))
else:
final = attempt
#print('attempt: {0} final: {1}'.format(attempt, final))
return final
if rnd(sin(attempt, dr), -terms) < target:
#add some
attempt += (dec(10) ** -i)
#print('attempt: {}'.format(attempt), end = ' ')
if rnd(sin(attempt, dr), -terms) > target:
#subtract some
attempt -= (dec(10) ** -i)
#print('attempt: {}'.format(attempt), end = ' ')
#print('')
if attempt < 0:
final = (attempt * dec(-1))
else:
final = attempt
#print('attempt: {0} final: {1}'.format(attempt, final))
return (final)
def cos(anglein, dr = degrad): #return cosine of the supplied angle
if dr == 'deg':
return rawsin(degToRad(90 - anglein))
else:
angle = anglein
return rnd(rawsin(90 - angle), -terms)
def arccos(ratioin, dr = degrad): #return arccosine of the supplied ratio
if ratioin > 1 or ratioin < -1:
return False
attempt = dec(0) #start at 0
target = rnd(dec(ratioin), -terms) #identify the target value
#print('target is: {}'.format(target))
for i in range(-1, int(terms) + 1): #for each place from 10s to terms decimal place (use -i, not i)
#print('Editing place {0}'.format(10 ** -i)) #debugging
for j in range(10): #for 10 steps
#print('current attempt: {}'.format(attempt), end = ' ')
if rnd(cos(attempt, dr), -terms) == target:
if attempt < 0:
final = (attempt * dec(-1))
else:
final = attempt
#print('attempt: {0} final: {1}'.format(attempt, final))
return final
if rnd(cos(attempt, dr), -terms) < target:
#add some
attempt += (dec(10) ** -i)
#print('attempt: {}'.format(attempt), end = ' ')
if rnd(cos(attempt, dr), -terms) > target:
#subtract some
attempt -= (dec(10) ** -i)
#print('attempt: {}'.format(attempt), end = ' ')
#print('')
if attempt < 0:
final = (attempt * dec(-1))
else:
final = attempt
#print('attempt: {0} final: {1}'.format(attempt, final))
return (final)
def tan(anglein, dr = degrad): #return tangent of the supplied angle
a = sin(anglein, dr)
b = cos(anglein, dr)
if (not a == 0) and (not b == 0):
return rnd((a / b), -terms)
else:
return False
def arctan(ratioin, dr = degrad): #return arctangent of the supplied ratio
if ratioin > 1 or ratioin < -1:
return False
attempt = dec(0) #start at 0
target = rnd(dec(ratioin), -terms) #identify the target value
#print('target is: {}'.format(target))
for i in range(-1, int(terms) + 1): #for each place from 10s to terms decimal place (use -i, not i)
#print('Editing place {0}'.format(10 ** -i)) #debugging
for j in range(10): #for 10 steps
#print('current attempt: {}'.format(attempt), end = ' ')
if rnd(tan(attempt, dr), -terms) == target:
if attempt < 0:
final = (attempt * dec(-1))
else:
final = attempt
#print('attempt: {0} final: {1}'.format(attempt, final))
return final
if rnd(tan(attempt, dr), -terms) < target:
#add some
attempt += (dec(10) ** -i)
#print('attempt: {}'.format(attempt), end = ' ')
if rnd(tan(attempt, dr), -terms) > target:
#subtract some
attempt -= (dec(10) ** -i)
#print('attempt: {}'.format(attempt), end = ' ')
#print('')
if attempt < 0:
final = (attempt * dec(-1))
else:
final = attempt
#print('attempt: {0} final: {1}'.format(attempt, final))
return (final)
def rawsin(anglein): #return the result of sine of the supplied angle, using radians
#This is the taylor series used.
#final = x - (x^3 / 3!) + (x^5 / 5!) - (x^7 / 7!) + (x^9 / 9!) - (x^11 / 11!)...
angle = dec(anglein)
final = angle
add = False
for i in range(3, int(terms) * 3, 2):
if add:
final += dec(angle ** i) / fact(i)
elif not add:
final -= dec(angle ** i) / fact(i)
add = not add
return final
def fact(intin): #return the factorial of the given integer, return False if not given an int
if intin == int(intin):
intout = 1
for i in range(1, intin + 1):
intout *= i
return intout
else:
return False
def rnd(numIn, decPlcIn = -terms, mode = 'fiveHigher'): #return the given number, rounded to the given decimal place.
#use 1 to indicate 10s, 0 to indicate 1s, -2 to indicate 100ths, etc.
num1 = dec(numIn)
decPlc = dec(decPlcIn)
if mode == 'fiveHigher':
return dec(str(dec(round(num1 * (dec(10) ** -decPlc))) * (dec(10) ** decPlc)).rstrip('0'))
elif mode == 'cutoff':
return dec(str(dec(int(num1 * (dec(10) ** -decPlc))) * (dec(10) ** decPlc)).rstrip('0'))
def root(numIn, rootVal):
num = dec(numIn)
rt = dec(dec(1) / rootVal)
num1 = num ** rt
return rnd(num1, -terms)
def quad(aIn, bIn, cIn): #Plugin for the quadratic formula. Provide a, b, and c.
a = dec(aIn)
b = dec(bIn)
c = dec(cIn)
try:
posResult = (-b + root((b ** dec(2)) - (dec(4) * a * c), 2)) / (dec(2) * a)
except:
posResult = False
try:
negResult = (-b - root((b ** dec(2)) - (dec(4) * a * c), 2)) / (dec(2) * a)
except:
negResult = False
return (posResult, negResult)
You are missing 1 call to self.openGLWidget.update(). There is a return statement in the instruction block of the if. The function is terminated at this point and the self.openGLWidget.update() instruction at the end of the code is never executed.
Add self.openGLWidget.update() right before return, to solve the issue:
class mainWindow(QMainWindow):
# [...]
def marchStep(self):
if not self.marchActive:
# [...]
self.currentStep = 0
if self.currentStep == len(self.marchPoints):
# [...]
self.meshPoints.clear()
self.marchingCube.hide()
self.openGLWidget.update() # <--------- ADD
return
if self.currentStep == 0:
self.marchingCube.show()
# [...]

Python : Ramer-Douglas-Peucker (RDP) algorithm with number of points instead of epsilon

I would like to modify this following python script for RDP algorithm with the purpose of not using epsilon but to choose the number of points I want to keep at the final :
class DPAlgorithm():
def distance(self, a, b):
return sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)
def point_line_distance(self, point, start, end):
if (start == end):
return self.distance(point, start)
else:
n = abs(
(end[0] - start[0]) * (start[1] - point[1]) - (start[0] - point[0]) * (end[1] - start[1])
)
d = sqrt(
(end[0] - start[0]) ** 2 + (end[1] - start[1]) ** 2
)
return n / d
def rdp(self, points, epsilon):
"""
Reduces a series of points to a simplified version that loses detail, but
maintains the general shape of the series.
"""
dmax = 0.0
index = 0
i=1
for i in range(1, len(points) - 1):
d = self.point_line_distance(points[i], points[0], points[-1])
if d > dmax :
index = i
dmax = d
if dmax >= epsilon :
results = self.rdp(points[:index+1], epsilon)[:-1] + self.rdp(points[index:], epsilon)
else:
results = [points[0], points[-1]]
return results
I found a Java script in that spirit : https://gist.github.com/msbarry/9152218
Does anyone know a version for Python 3.X ?
Thanks
Momow
Ported JS code from the link above to Python [2.7]:
# -*- coding: utf-8 -*-
import math
import time
def timenow():
return int(time.time() * 1000)
def sqr(x):
return x*x
def distSquared(p1, p2):
return sqr(p1[0] - p2[0]) + sqr(p1[1] - p2[1])
class Line(object):
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
self.lengthSquared = distSquared(self.p1, self.p2)
def getRatio(self, point):
segmentLength = self.lengthSquared
if segmentLength == 0:
return distSquared(point, p1);
return ((point[0] - self.p1[0]) * (self.p2[0] - self.p1[0]) + \
(point[1] - self.p1[1]) * (self.p2[1] - self.p1[1])) / segmentLength
def distanceToSquared(self, point):
t = self.getRatio(point)
if t < 0:
return distSquared(point, self.p1)
if t > 1:
return distSquared(point, self.p2)
return distSquared(point, [
self.p1[0] + t * (self.p2[0] - self.p1[0]),
self.p1[1] + t * (self.p2[1] - self.p1[1])
])
def distanceTo(self, point):
return math.sqrt(self.distanceToSquared(point))
def simplifyDouglasPeucker(points, pointsToKeep):
weights = []
length = len(points)
def douglasPeucker(start, end):
if (end > start + 1):
line = Line(points[start], points[end])
maxDist = -1
maxDistIndex = 0
for i in range(start + 1, end):
dist = line.distanceToSquared(points[i])
if dist > maxDist:
maxDist = dist
maxDistIndex = i
weights.insert(maxDistIndex, maxDist)
douglasPeucker(start, maxDistIndex)
douglasPeucker(maxDistIndex, end)
douglasPeucker(0, length - 1)
weights.insert(0, float("inf"))
weights.append(float("inf"))
weightsDescending = weights
weightsDescending = sorted(weightsDescending, reverse=True)
maxTolerance = weightsDescending[pointsToKeep - 1]
result = [
point for i, point in enumerate(points) if weights[i] >= maxTolerance
]
return result

NoneType error with Python class and function

Despite my function returning an array, I get an TypeError: 'NoneType' object is not callable error. I first define classes, and then insert the function.
I'm relatively new to Python, and would appreciate any help/comments.
The Classes are:
from scipy import array, dot, zeros, empty
from scipy.optimize import brentq
from numpy import *
from numpy.random import uniform
from time import time
# from mpi4py import MPI
class UtilTheory:
"""
"""
def utility(self, other):
raise NotImplementedError("You need to implement method 'utility' "
"in the child class.")
def demand(self, p):
raise NotImplementedError("You need to implement method 'demand' "
"in the child class.")
def excessDemand(self, p):
p = array(p)
return self.demand(p) - self.endowment
def indUtility(self, p):
x = self.demand(p)
return self.utility(x)
def __add__(self, other):
economy = Economy([self, other])
return economy
def __radd__(self, other):
economy = Economy([self] + other)
def __rmul__(self, other):
economy = Economy(other * [self])
return economy
class Consumer(UtilTheory, object):
"""
Defines general features of a consumer
"""
def __init__(self, endowment=array([1,1]), alpha=0.5, rho=0.0):
self.endowment = array(endowment)
self.alpha = float(alpha)
self.rho = rho
self.sigma = 1.0 / (1.0 - rho)
def __str__(self):
return ('e=' + str(self.endowment) +
', alpha=' + str(self.alpha) +
', rho=' + str(self.rho))
def demand(self, p):
endowment = self.endowment
alpha = self.alpha
sigma = self.sigma
p = array(p)
m = dot(endowment, p)
x1 = ((alpha / p[0]) ** sigma * m /
(alpha ** sigma * p[0] ** (1 - sigma) +
(1 - alpha) ** sigma * p[1] ** (1 - sigma)))
x2 = (((1.0 - alpha) / p[1]) ** sigma * m /
(alpha ** sigma * p[0] ** (1 - sigma) +
(1 - alpha) ** sigma * p[1] ** (1 - sigma)))
return array([x1, x2])
def utility(self, x):
if self.rho != 0:
return ((self.alpha * x[0] ** self.rho +
(1.0 - self.alpha) * x[1] ** self.rho) **
(1.0 / self.rho))
return x[0] ** self.alpha * x[1] ** (1.0 - self.alpha)
class Economy:
"""
Consists of consumers
"""
def __init__(self, consumers):
"""
Consumers should be a list of consumers
"""
self.consumers = consumers
def excessDemand(self, p):
result = zeros(2)
for consumer in self.consumers:
result = result + consumer.excessDemand(p)
return result
def demand(self, p):
result = zeros(2)
for consumer in self.consumers:
result = result + consumer.demand(p)
return result
def excessDemandGood0(self, p0):
p = array([p0, 1.0 - p0])
result = 0
for consumer in self.consumers:
result = result + consumer.excessDemand(p)[0]
return result
def __add__(self,other):
try:
return Economy(self.consumers + other.consumers)
except:
return Economy(self.consumers + [other])
def numEquilibria(self, n=100):
# p = array([p0, 1 - p0])
q = linspace(0, 1, n)
result = empty(len(q))
#print result
for i, p0 in enumerate(q):
a = self.excessDemandGood0(p0)
#print a
result[i] = a
index = zeros(len(q))
for i in range(1, 2):
if result[i] <= 0:
index[i - 1] = 1
else:
index[i - 1] = 0
for i in range(2, n - 1):
test=result[i - 1] * result[i]
#print test
if test <= 0:
index[i - 1] = 1
else:
index[i - 1] = 0
for i in range(n - 2, n - 1):
if result[i] > 0:
index[i - 1] = 1
else:
index[i - 1] = 0
count = sum(index)
# print "The number of equilibria is"
return count
# print "Excess Demand funciton on the grid:"
# print result
# print "Index when excess demand goes from possitive to negative"
# print index
def __rmul__(self, other):
economy = Economy(other * self.consumers)
return economy
def equilibrium(self, startbracket=None):
def g(x):
return self.excessDemandGood0(x)
if startbracket == None:
startbracket = [1e-10, 1-1e-10]
eqPrice1 = brentq(g, startbracket[0], startbracket[1])
return array([eqPrice1, 1 - eqPrice1])
def __len__(self):
return len(self.consumers)
def __str__(self):
resultString = 'Economy with ' + str(len(self)) + ' consumers.\n'
for consumer in self.consumers:
resultString = resultString + str(consumer) + '\n'
return resultString
I get the error when implementing the following stats() function which calls on randomEconEq():
def randomEcon(e1=[1, 0], e2=[0, 1], iterate_max=100):
rho1 = random.uniform(-8, -1)
rho2 = random.uniform(-8, -1)
alpha1 = random.uniform(0, 1)
alpha2 = random.uniform(0, 1)
x = Consumer(endowment=e1, alpha=alpha1, rho=rho1)
y = Consumer(endowment=e2, alpha=alpha2, rho=rho2)
econ = Economy([x, y])
return econ
def randomEconEq(iterate_max=100):
iterate = 0
eq_vec = []
start = time()
while iterate < iterate_max:
iterate += 1
econ = randomEcon()
equilibria = econ.numEquilibria()
eq_vec.append(equilibria)
# print eq_vec
if (econ.numEquilibria() > 1):
print "Number of multiple equilibria is " + \
str(econ.numEquilibria())
print str(econ)
print str(eq_vec)
end = time()
totaltime = end - start
#print('Total Time is ' + str(totaltime))
return eq_vec
def stats(eq_vec, iterate_max):
one_eq = zeros(len(eq_vec))
three_eq = zeros(len(eq_vec))
five_eq = zeros(len(eq_vec))
more_eq = zeros(len(eq_vec))
# print (eq_vec)
for i in range(len(eq_vec)):
if eq_vec[i] == 1:
one_eq[i] = 1
if eq_vec[i] == 3:
three_eq[i] = 1
if eq_vec[i] == 5:
five_eq[i] = 1
if eq_vec[i] > 5:
more_eq[i] = 1
Eq1 = sum(one_eq)
Eq3 = sum(three_eq)
Eq5 = sum(five_eq)
EqMore = sum(more_eq)
prob1 = float((Eq1 / iterate_max) * 100)
prob3 = float((Eq3 / iterate_max) * 100)
prob5 = float((Eq5 / iterate_max) * 100)
probMore = float((EqMore/iterate_max) * 100)
print ('The Vector of the number of equililbria is:' + str(eq_vec))
print ('Probability of 1 equilibrium is (percent) ' + str(prob1))
print ('Probability of 3 equilibria is (percent) ' + str(prob3))
print ('Probability of 5 equilibria is (percent) ' + str(prob5))
print ('Probability of 1 equilibria is (percent) ' + str(probMore))
eq_vec = randomEconEq(100)
stats(eq_vec, 100)
The error appears in the last two lines of code when implementing the function stats().
An example which creates the error is:
stats(randomEconEq(100), 100)
and the complete traceback is:
>>> stats(randomEconEq(100), 100)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable

Categories