I am trying to solve a PDE using odeint and the method of lines. My code is definitely wrong - and I'm trying to figure out where it is going wrong.
I am calling the ode solver using odeint(odefunc,y0,tspan) where tspan = np.linspace(0.0, 0.5, 5) & y0 = 1.0*np.ones(3).
I tried printing t within odefunc and am confused by the output. Despite the fact that I am solving up to t=0.5, the last t-value to print is 0.015081203121127767. The number of outputs matches tspan, but I cannot see how it could possibly be solving up to t = 0.5 when the last time in the de function is 0.015. What am I missing?
My DE is time dependent - so this is making it very hard to figure out where things are going wrong because I don't seem to be seeing the times where everything fails.
ETA - this is failing, but running this without some of the irrelevant stuff I am getting the warning ODEintWarning: Excess work done on this call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative information., which I'm assuming is part of the issue - but it doesn't appear to be halting the code.
MWE
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import math
import sys
plt.interactive(False)
sigma = 2320
rho = 1000
gravity = 9.81 # [m/s^2]
g = gravity*3600*3600 # [m/hour^2]
S = 0.01
settlingVelocity = 0.02 # [m/s]
ws = settlingVelocity*3600 # [m/hour]
n = 0.04 # [SI]
J = 400 # [Ws/m]
k = 0.02
Cstar = 0.2 * sigma # [kg/m^3]
W = 2 # [m]
D0 = 1.2
Lw = 20
L = 100
tend = 0.5 # in hours
tspan = np.linspace(0.0, tend, 5)
def d(t): # metres
if t < 50: # hours
return 0.5
else:
return 0.05
def Q(t):
return 3600 * (math.sqrt(S)/n)*((W*d(t))**(5/3))/((2*d(t) + W)**(2/3))
def h(t):
return d(t)/2
def beta(t):
return (sigma - rho) * g * h(t)/sigma
def Omega(t):
return rho * g * S * Q(t) # [W/m]
def PsiTime(t):
return rho * g * Q(t) * (D0 - d(t))/(Lw)
N = 10
X = np.linspace(0, L, N)
delX = L/ (N-1)
def odefunc(y, t):
def zetaEh(t):
return k * (PsiTime(t) + Omega(t)) / (J + beta(t))
def zetaEW(t):
return (2*d(t)/(W + 2*d(t))) * k * Omega(t)/(J + beta(t))
def zetaR(t):
return (W/(W + 2*d(t))) * k*Omega(t)/(beta(t))
def zetaEF(t,i):
return (W/(W + 2*d(t))) * k * Omega(t) / (J + beta(t))
C = y[:N]
M = y[N:]
print("time: ", t)
dCdt = np.zeros(X.shape)
dMdt = np.zeros(X.shape)
dCdt[0] = ( # forward difference for dCdx
-Q(t) / (W*d(t)) * (C[1] - C[0]) / delX
+ (zetaEh(t) / (W * d(t))) * ((Cstar - C[0]) / Cstar)
- (ws * C[0] * (beta(t))) / (d(t) * (J + beta(t)))
)
dMdt[0] = 0
# gully channel
for i in range (1, N-1): # central difference
if M[i] + W *C[i] * ws - zetaR(t) * (Cstar - C[i]) / Cstar < 0:
reMass = M[i] + W * C[i] * ws
dCdt[i] = (
-Q(t) / (W*d(t)) * (C[i+1] - C[i - 1]) / (2*delX)
+ 1 / (W * d(t)) * ((zetaEW(t) + zetaEF(t,i)) * (Cstar - C[i]) / Cstar
+ reMass * (1 - (beta(t))/ (J + beta(t))))
- C[i] * ws/d(t)
)
dMdt[i] = -M[i]
else:
dCdt[i] = (
-Q(t) / (W*d(t)) * (C[i+1] - C[i - 1]) / (2*delX)
+ 1 / (W * d(t)) * (zetaEW(t) + zetaR(t)) * (Cstar - C[i]) / Cstar
- C[i] * ws / d(t)
)
dMdt[i] = W * C[i] * ws - zetaR(t) * (Cstar - C[i]) / Cstar
# Final node - backward difference
if M[N-1] + W * C[N-1] * ws - zetaR(t) * (Cstar - C[N-1]) / Cstar < 0:
reMass = M[N-1] + W * C[N-1] * ws
dCdt[N-1] = (
-Q(t) / (W * d(t)) * (C[N-1] - C[N-2]) / delX
+ 1 / (W * d(t)) * ((zetaEW(t) + zetaEF(t, i)) * (Cstar - C[N-1]) / Cstar
+ reMass * (1 - (beta(t)) / (J + beta(t))))
- C[i] * ws / d(t)
)
dMdt[N-1] = -M[N-1]
else:
dCdt[N-1] = (
-Q(t) / (W * d(t)) * (C[N-2] - C[N - 1]) / delX
+ 1 / (W * d(t)) * (zetaEW(t) + zetaR(t)) * (Cstar - C[N-1]) / Cstar
- C[N-1] * ws / d(t)
)
dMdt[N-1] = W * C[N-1] * ws - zetaR(t) * (Cstar - C[N-1]) / Cstar
dydt = np.ravel([dCdt, dMdt])
return dydt
init_C = 0.0 * np.ones(X.shape)
init_M = 0.0 * np.ones(X.shape)
init= np.ravel([init_C, init_M])
sol = odeint(odefunc, init, tspan)
conc = sol[:, :N]
Related
I am trying to make several plots for a project of mine using the following code:
import pprint
import scipy
import scipy.linalg # SciPy Linear Algebra Library
import numpy as np
from scipy.linalg import lu , lu_factor, lu_solve
from scipy.integrate import quad
import matplotlib.pyplot as plt
#Solving the equations for the Prandtl case
K = 100
alpha = 0.1
visc = 5
diff = 5
N = 0.01
L = 5000
height = 250
subdivisions = 100
tick = 10
points = np.arange(0,L/2+tick,tick)
def H(y):
return ( height * (1 + np.cos(2 * np.pi * y/L)) )
def Bsfc(y):
return 0.1
final_system = []
b=[]
for q in range(-K,K+1):
equation1 = []
equation2 = []
equation3 = []
Aki = []
Cki = []
Dki = []
for k in range(-K,K+1):
R = 2 * N**2 * np.cos(alpha)**2 / (visc * diff) * (k * np.pi / L)**2
Q = N**2 * np.sin(alpha)**2 / (3 * visc * diff)
S1 = abs(R + np.sqrt(Q**3 + R**2) )**(1/3)
S2 = - abs( np.sqrt(Q**3 + R**2) -R )**(1/3)
phi = np.sqrt(S1**2 + S2**2 - S1*S2)
Lk = np.arccos(- (S1 + S2)/ (2 * phi) )
m1 = - np.sqrt(S1 + S2)
m2 = - np.sqrt(phi) * np.exp(1j * Lk/2)
m3 = m2.conjugate()
def f1r(y):
return (np.exp(m1 * H(y)) * np.cos(2 * (q - k) * np.pi * y / L) ).real
def f1i(y):
return (np.exp(m1 * H(y)) * np.cos(2 * (q - k) * np.pi * y / L) ).imag
gamma1 = 2/L * (quad(f1r,0,L/2,limit=subdivisions)[0] + quad(f1i,0,L/2,limit=subdivisions)[0]*1j)
def f2r(y):
return (np.exp(m2 * H(y)) * np.cos(2 * (q - k) * np.pi * y / L) ).real
def f2i(y):
return (np.exp(m2 * H(y)) * np.cos(2 * (q - k) * np.pi * y / L) ).imag
gamma2 = 2/L * (quad(f2r,0,L/2,limit=subdivisions)[0] + quad(f2i,0,L/2,limit=subdivisions)[0]*1j)
if k == 0:
equation1.append(2 * gamma2.real)
Cki.append(k)
equation1.append(-2 * gamma2.imag)
Dki.append(k)
else:
equation1.append(gamma1)
Aki.append(k)
equation1.append(2 * gamma2.real)
Cki.append(k)
equation1.append(-2 * gamma2.imag)
Dki.append(k)
if q != 0:
if k == 0:
equation2.append(0)
equation2.append(0)
else:
equation2.append(k * gamma1 / (m1**3) )
equation2.append(2 * k * (gamma2 / (m2**3) ).real)
equation2.append(-2 * k * (gamma2 / (m2**3) ).imag)
if k == 0:
equation3.append(2 * (m2**2 * gamma2).real)
equation3.append(-2 * (m2**2 * gamma2).imag)
else:
equation3.append(m1**2 * gamma1)
equation3.append(2 * (m2**2 * gamma2).real)
equation3.append(-2 * (m2**2 * gamma2).imag)
final_system.append(equation1)
def f4r(y):
return (Bsfc(y) * np.cos(2 * q * np.pi * y / L) ).real
def f4i(y):
return (Bsfc(y) * np.cos(2 * q * np.pi * y / L) ).imag
b.append(2/L * (quad(f4r,0,L/2,limit=subdivisions)[0] + quad(f4i,0,L/2,limit=subdivisions)[0]*1j))
if q != 0:
final_system.append(equation2)
b.append(0)
final_system.append(equation3)
b.append(0)
final_system = np.array(final_system)
b=np.array(b)
#LU solver
P, Ls, U = scipy.linalg.lu(final_system)
Bl = np.linalg.inv(P) # b
Z = np.linalg.solve(Ls,Bl)
X = np.linalg.solve(U,Z)
print (np.allclose(final_system # X, b))
#Getting the values for Ak, Ck and Dk
strings = []
for k in range(-K,K+1):
if k != 0:
strings.append('A')
strings.append('R')
strings.append('I')
Ak = []
Rk = []
Ik = []
for k in range(0,len(X)):
if 'A' in strings[k]:
Ak.append(X[k])
if 'R' in strings[k]:
Rk.append(X[k])
if 'I' in strings[k]:
Ik.append(X[k])
Ck=[]
for k in range(0,len(Rk)):
Ck.append(Rk[k] + Ik[k] * 1j)
Ck = np.array(Ck)
Dk = Ck.conjugate()
Ak = np.array(Ak)
#Getting the Buoyancy value
z = np.arange(0,2010,10)
y = np.arange(-L,L+10,10)
Y,Z = np.meshgrid(y,z)
B = np.ones_like(Y)*[0]
for k in range(-K,K+1):
R = 2 * N**2 * np.cos(alpha)**2 / (visc * diff) * (k * np.pi / L)**2
Q = N**2 * np.sin(alpha)**2 / (3 * visc * diff)
S1 = abs(R + np.sqrt(Q**3 + R**2) )**(1/3)
S2 = - abs( np.sqrt(Q**3 + R**2) -R )**(1/3)
phi = np.sqrt(S1**2 + S2**2 - S1*S2)
Lk = np.arccos(- (S1 + S2)/ (2 * phi) )
m1 = - np.sqrt(S1 + S2)
m2 = -np.sqrt(phi) * np.exp(1j * Lk/2)
m3 = m2.conjugate()
if k != 0:
B = B + ( Ak[Aki.index(k)] * np.exp(m1 * Z) * np.exp(2j * (k) * np.pi * Y / L) )
B = B + ( ( Ck[Cki.index(k)] * np.exp(m2 * Z) + Dk[Dki.index(k)] * np.exp(m3 * Z) ) * np.exp(2j * (k) * np.pi * Y / L) )
for k in range(0,B.shape[0]):
for t in range(0,B.shape[1]):
if Z[k][t] < H(Y[k][t]):
B[k][t] = np.nan
if Z[k][t] == H(Y[k][t]):
print (B[k][t], "B value at the ground")
if abs(Z[k][t] - H(Y[k][t])) < 0.1:
if B[k][t] > 0.101:
print (B[k][t],'error -------------------------------------------------')
# print (B[k][t], Z[k][t], H(Y[k][t]), Y[k][t], '-----------------------------------------------------------------------------' )
Bp = Bsfc(Y) * np.exp(-Z * np.sqrt(N * np.sin(alpha) ) / (4*visc*diff)**(1/4) ) * np.cos(np.sqrt(N*np.sin(alpha)) /((4*visc*diff)**(1/4))*Z )
##Plotting the buoyancy
fig = plt.figure(figsize=(10,10)) # create a figure
plt.rcParams.update({'font.size':16})
plt.title('Buoyancy')
plt.contourf(Y,Z,B,np.arange(-0.2,0.201,0.001),cmap='seismic')
#plt.contourf(Y,Z,B,cmap='seismic')
plt.colorbar(label='1/s')
plt.xlabel("Y axis")
plt.ylabel("Height")
plt.xlim([-L,L])
plt.ylim([0,1500])
plt.show()
The following plot shows a run that yielded a good result:
Buoyancy
However, when I increase the "height" parameter, I start getting unstable results, which I suspect occurs because of numerical instabilities:
Buoyancy unstable
Is there a way to increase numerical precision in python? I have experimented a bit with numpy.double, but with unsuccessful results so far.
Thanks
I guess you'll find your answer here on Stackoverflow
In the standard library, the decimal module may be what you're looking
for. Also, I have found mpmath to be quite helpful...
I had read documentation and trying to understand how to work with scipy.optimize.minimize(), but my code just doesn't work, it keeps showing that"ValueError: The user-provided objective function must return a scalar value."
Here is my code:
PH = np.linspace(0, 14, 71)
ni_total = 0.1
citrate_total = 0.9
ammonia_total = 0.3
def concs(citrate_total,ni_total, ammonia_total, PH):
h = 10 ** (-PH)
def equations(p):
cit3, nio2, nh4 = p
Hcit = h*cit3*k4
H2cit = h*Hcit*k3
H3cit = h*H2cit*k2
ni2pfree = (nio2*k1*(h**2))/(1+((nio2*k1*(h**2))/ni_total))
NiH2cit = k7*ni2pfree*H2cit
NiHcit = k6*ni2pfree*Hcit
Nicit = k5*ni2pfree*cit3
nh3 = k8*nh4/h
nin4p2 = k9*(nh4**4)/(h**2)
nin6p2 = k10*(nh4**6) /(h**4)
return (citrate_total - Hcit - H2cit - H3cit - Nicit - NiHcit - NiH2cit - cit3,
ni_total - Nicit - NiHcit - NiH2cit - ni2pfree - nin4p2- nin6p2- nio2,
ammonia_total-nh3-4*nin4p2-6*nin6p2-nh4)
initial_guess=[0.1,0.1,0.1]
res = minimize(equations,initial_guess)
cit3 = res.x[0]
nio2 = res.x[1]
nh4 = res.x[2]
ni2pfree = (nio2 * k1 * (h ** 2)) / (1 + ((nio2 * k1 * (h ** 2)) / ni_total))
Hcit = h * cit3 *k4
H2cit = h * Hcit * k3
H3cit = h * H2cit * k2
NiH2cit = k7 * ni2pfree * H2cit
NiHcit = k6 * ni2pfree * Hcit
Nicit = k5 * ni2pfree * cit3
nh3 = k8 * nh4 / h
nin4p2 = k9 * (nh4 ** 4) / (h ** 2)
nin6p2 = k10 * (nh4 ** 6) / (h ** 4)
return [cit3, nio2, nh4, ni2pfree, Hcit, H2cit, H3cit, NiH2cit, NiHcit, Nicit,nh3,nin4p2,nin6p2]
The function scipy.optimize.minimize() takes in (among others) as arguments the objective fun and initial value x0. fun must return a single real number (also referred to as a scalar); not a list or a tuple.
In contrast, your function returns
def equations(p):
# code
return (..., ..., ...)
Change it to
def equations(p):
# code
return x
with the function value x of equations() that you actually want to minimize.
I am trying to create a specific output pattern for a textfile I wanted to later load into C++.
I wrote a file in Python that creates random coordinates and movement values in a circle.
The output is supposed to have the output:
Place_1 Place_2 Place_3 Movement_1 Movement_2 Movement_3\n
Place_1 Place_2 Place_3 Movement_1 Movement_2 Movement_3\n
Place_1 Place_2 Place_3 Movement_1 Movement_2 Movement_3
The Code is use is
import numpy as np
file = open('log.txt', 'a')
def f(n, center, radius, ecc):
pos = np.zeros((n,6))
r = ecc * radius
for i in range(n):
while 1:
x_1 = -1 + 2 * np.random.rand(1)
x_2 = -1 + 2 * np.random.rand(1)
if (x_1*x_1 + x_2*x_2)<1 :
pos[i,0] = center[0] + r * 2 * x_1 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
pos[i,1] = center[1] + r * 2 * x_2 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
pos[i,2] = center[2] + r * (1 - 2 * (x_1*x_1 + x_2*x_2))
pos[i,3] = (-1 + 2 * np.random.rand(1))
pos[i,4] = (-1 + 2 * np.random.rand(1))
pos[i,5] = (-1 + 2 * np.random.rand(1))
break
string = str(pos[i,:]).strip('[]').rstrip('\n')
file.write(string)
return
f(10000, np.array((127,127,127)), 92, 0.9)
file.close()
The log I create is however very badly formated. How can I get the required format?
You're going to a lot of trouble here that you don't need. This seems to solve the problem, simply.
import numpy as np
file = open('log.txt', 'a')
def f(n, center, radius, ecc):
r = ecc * radius
for i in range(n):
while 1:
pos = [0]*6
x_1 = -1 + 2 * np.random.rand(1)[0]
x_2 = -1 + 2 * np.random.rand(1)[0]
if (x_1*x_1 + x_2*x_2) < 1:
pos[0] = center[0] + r * 2 * x_1 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
pos[1] = center[1] + r * 2 * x_2 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
pos[2] = center[2] + r * (1 - 2 * (x_1*x_1 + x_2*x_2))
pos[3] = (-1 + 2 * np.random.rand(1)[0])
pos[4] = (-1 + 2 * np.random.rand(1)[0])
pos[5] = (-1 + 2 * np.random.rand(1)[0])
break
print(*pos, file=file)
f(10000, np.array((127,127,127)), 92, 0.9)
file.close()
A solution without numpy:
import math
import random
file = open('log.txt', 'a')
def f(n, center, radius, ecc):
r = ecc * radius
for _ in range(n):
pos = [0]*6
while 1:
x_1 = 2 * random.random() - 1
x_2 = 2 * random.random() - 1
vector = x_1*x_1 + x_2*x_2
if vector < 1:
break
pos[0] = center[0] + r * 2 * x_1 * math.sqrt(1 - vector)
pos[1] = center[1] + r * 2 * x_2 * math.sqrt(1 - vector)
pos[2] = center[2] + r * (1 - 2 * vector)
pos[3] = 2 * random.random() -1
pos[4] = 2 * random.random() -1
pos[5] = 2 * random.random() -1
print(*pos, file=file)
f(10000, (127,127,127), 92, 0.9)
file.close()
Use np.savetxt:
import numpy as np
def f(n, center, radius, ecc):
pos = np.zeros((n,6))
r = ecc * radius
for i in range(n):
while 1:
x_1 = -1 + 2 * np.random.rand(1)
x_2 = -1 + 2 * np.random.rand(1)
if (x_1*x_1 + x_2*x_2)<1 :
pos[i,0] = center[0] + r * 2 * x_1 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
pos[i,1] = center[1] + r * 2 * x_2 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
pos[i,2] = center[2] + r * (1 - 2 * (x_1*x_1 + x_2*x_2))
pos[i,3] = (-1 + 2 * np.random.rand(1))
pos[i,4] = (-1 + 2 * np.random.rand(1))
pos[i,5] = (-1 + 2 * np.random.rand(1))
break
np.savetxt('file.txt',pos,delimiter=';')
return
f(100, np.array((127,127,127)), 92, 0.9)
For the formatting issue you can make the coordinates into characters (What I mean is that turn coordinates into a character that would be printed like _ or / something like that) Also you can put empty space in a print like print(" Hello.") also to go to a different line in the console do print("\n Hello."). This probably was not what you were looking for but I hope this somewhat helps.
I am happily integrating a simple ODE with scipy.odeint. This is my integration fuction:
def f(self, x, t_0):
h = x[0:3]
f = x[3:6]
der = []
der.append((self.q_0 - f[0] * self.u[0] * self.k[0] * numpy.sign(h[0] - h[1]) * numpy.sqrt(abs(h[0] - h[1]))) / self.A[0])
der.append((f[0] * self.u[0] * self.k[0] * numpy.sign(h[0] - h[1]) * numpy.sqrt(abs(h[0] - h[1])) -
f[1] * self.u[1] * self.k[1] * numpy.sign(h[1]) * numpy.sqrt(abs(h[1]))) / self.A[1])
der.append((f[1] * self.u[1] * self.k[1] * numpy.sign(h[1] - h[2]) * numpy.sqrt(abs(h[1] - h[2])) -
f[2] * self.u[2] * self.k[2] * numpy.sign(h[2]) * numpy.sqrt(abs(h[2]))) / self.A[2])
der.append(0)
der.append(0)
der.append(0)
return numpy.array(der)
Everything works fine if I call scipy.integrate.odeint except I decided to provide the Jacobian so I can do the integration faster. This is the Jacobian which I figured out by hand:
def F(self, x, t_0):
h = x[0:3]
f = x[3:6]
u = self.u
k = self.k
A = self.A
result = numpy.zeros((6, 6))
sqrt_diff_h0_h1 = numpy.sign(h[0] - h[1]) * numpy.sqrt(abs(h[0] - h[1]))
sqrt_diff_h1_h2 = numpy.sign(h[1] - h[2]) * numpy.sqrt(abs(h[1] - h[2]))
sqrt_diff_h1 = numpy.sign(h[1]) * numpy.sqrt(abs(h[1]))
sqrt_diff_h2 = numpy.sign(h[2]) * numpy.sqrt(abs(h[2]))
result[0][0] = -(u[0] * f[0] * k[0]) / (2 * A[0] * sqrt_diff_h0_h1)
result[0][1] = (u[0] * f[0] * k[0]) / (2 * A[0] * sqrt_diff_h0_h1)
result[0][3] = -(u[0] * k[0] * sqrt_diff_h0_h1) / A[0]
result[1][0] = (u[0] * f[0] * k[0]) / (2 * A[1] * sqrt_diff_h0_h1)
result[1][1] = -((u[0] * f[0] * k[0] * A[1]) / (2 * sqrt_diff_h0_h1)) - \
((u[1] * f[1] * k[1] * A[1]) / (2 * sqrt_diff_h1))
result[1][3] = (u[0] * k[0] * sqrt_diff_h0_h1) / A[1]
result[1][4] = -(u[1] * k[1] * sqrt_diff_h1) / A[1]
result[2][1] = (u[1] * f[1] * k[1]) / (2 * A[2] * sqrt_diff_h1_h2)
result[2][2] = -((u[1] * f[1] * k[1] * A[2]) / (2 * sqrt_diff_h1_h2)) - \
((u[2] * f[2] * k[2] * A[2]) / (2 * sqrt_diff_h2))
result[2][4] = (u[1] * k[1] * sqrt_diff_h1_h2) / A[2]
result[2][5] = -(u[2] * k[2] * sqrt_diff_h2) / A[2]
return result
If I supply F to scipy.odeint.integrate, it actually takes more time. This, of course, doesn't mean much but I am wondering how to determine if the Jacobian is correct? I need it for other purposes of linearization.
I've been working with this equations of Potential Flow
pSI: 0 = 10 * y + 23.8732414638 * (pi + atan(abs((x - 12) / x))) + 23.8732414638 * (pi - atan(abs((y + 12) / x)))-234.882642242
V: 0 = ((10 + 23.8732414638 * x / (x*2 + (y - 12)*2) + 23.8732414638 * x / (x*2 + (y + 12)*2))**2 + (23.8732414638 * (y - 12) / (x*2 + (y - 12)*2) + 23.8732414638 * (y + 12) / (x*2 + (y + 12)*2))*2)*0.5-8
using the next code to solve them:
# Prototype of N-R for a system of two non-linear equations
# evaluating functions of two variables
from math import *
eq1 = raw_input('Enter the equation 1: ')
eq2 = raw_input('Enter the equation 2: ')
x0 = float(input('Enter x: '))
y0 = float(input('Enter y: '))
def f(x,y):
return eval(eq1)
def g(x,y):
return eval(eq2)
x = x0
y = y0
for n in range(1, 8):
a = (f(x + 1e-06, y) - f(x,y)) / 1e-06
b = (f(x, y + 1e-06) - f(x,y)) / 1e-06
c = - f(x,y)
d = (g(x + 1e-06, y) - g(x,y)) / 1e-06
eE = (g(x, y + 1e-06) - g(x,y)) / 1e-06
fF = - g(x,y)
print "f(x, y)= ", eq1
print "g(x, y)= ", eq2
print """x y """
print x, y
print """a b c d e f """
print a, b, c, d, e, fF
print """
a * x + b * y = c
d * x + e * y = f
"""
print a," * x + ",b," * y = ",c
print d," * x + ",eE," * y = ",fF
_Sy = (c - a * fF / d) / (b - a * eE / d)
_Sx = (fF / d) - (eE / d) * _Sy
Ea_X = (_Sx ** 2 + _Sy ** 2)**0.5
x = x + _Sx
y = y + _Sy
print "Sx = ", _Sx
print "Sy = ", _Sy
print "x = ", x
print "y = ", y
print "|X_1 - X_0| = ", Ea_X
And gives me the Zero division Error
Traceback (most recent call last):
File "C:\Documents and Settings\Principal\Mis documentos\Finished_Non_lin_N_R.py", line 38, in <module>
d = (g(x + 1e-06, y) - g(x,y)) / 1e-06
File "C:\Documents and Settings\Principal\Mis documentos\Finished_Non_lin_N_R.py", line 27, in g
return eval(eq2)
File "<string>", line 1, in <module>
ZeroDivisionError: float division by zero
Then I tried with this one that I've found in one solved question:
from scipy.optimize import fsolve
from math import *
def equations(p):
x, y = p
return ( ((10 + 23.8732414638 * x / (x**2 + (y - 12)**2) + 23.8732414638 * x / (x**2 + (y + 12)**2))**2 + (23.8732414638 * (y -12) / (x**2 + (y - 12)**2) + 23.8732414638 * (y + 12) / (x**2 + (y + 12)**2))**2)**0.5-8, 10 * y + 23.8732414638 * (pi + atan(abs((x - 12) / x))) + 23.8732414638 * (pi - atan(abs((y + 12) / x)))-234.882642242)
x, y = fsolve(equations, (0, 18))
print equations((x, y))
And with the next problem:
<module2>:19: RuntimeWarning: divide by zero encountered in long_scalars
<module2>:19: RuntimeWarning: divide by zero encountered in double_scalars
(-1.3374190643844486e-11, -2.8308022592682391e-11)
And the last part of this story is that I have some code that actually works
but is too clumsy and a little bit inaccurate, and I would like some suggestions in order to make it simple:
from math import *
U = 10
b = 15
h = 12
cF = 0.5 * U * b / pi
pSI0 = 234.882642242
VP = 12.0
X0 = 0
Y0 = 40
sX = 0.01
sY = 0.01
print cF
def FirstFor(A,B,C,D):
for n in range(1,808):
for m in range(1,4002):
X = A - B*n
Y = C - D*m
pSI = U * Y + cF * (pi + atan(abs((Y - h) / X))) + cF * (pi - atan(abs((Y + h) / X)))
Vaprox = ((10 + 23.8732414638 * X / (X**2 + (Y - 12)**2) + 23.8732414638 * X / (X**2 + (Y + 12)**2))**2 +(23.8732414638 * (Y - 12) / (X**2 + (Y - 12)**2) + 23.8732414638 * (Y + 12) / (X**2 + (Y + 12)**2))**2)**0.5
EA1 = abs(pSI0 - pSI)
EA2 = abs(VP - Vaprox)
if EA1 < 0.05 and EA2 < 0.05:
X1f = X
Y1f = Y
H3 = [X1f,Y1f]
print n,m,X,Y,"GG son",EA1,EA2
print H3
for n in range(1,808):
for m in range(1,4002):
X = H3[0] - B*n*0.001
Y = H3[1] - D*m*0.001
pSI = U * Y + cF * (pi + atan(abs((Y - h) / X))) + cF * (pi - atan(abs((Y + h) / X)))
Vaprox = ((10 + 23.8732414638 * X / (X**2 + (Y - 12)**2) + 23.8732414638 * X / (X**2 + (Y + 12)**2))**2 +(23.8732414638 * (Y - 12) / (X**2 + (Y - 12)**2) + 23.8732414638 * (Y + 12) / (X**2 + (Y + 12)**2))**2)**0.5
EA1 = abs(pSI0 - pSI)
EA2 = abs(VP - Vaprox)
if EA1 < 0.0001 and EA2 < 0.0001:
X2f = X
Y2f = Y
I3 = [X2f,Y2f]
print n,m,X,Y,"GG son",EA1,EA2
print I3
for n in range(1,808):
for m in range(1,4002):
X = H3[0] + B*n*0.001
Y = H3[1] + D*m*0.001
pSI = U * Y + cF * (pi + atan(abs((Y - h) / X))) + cF * (pi - atan(abs((Y + h) / X)))
Vaprox = ((10 + 23.8732414638 * X / (X**2 + (Y - 12)**2) + 23.8732414638 * X / (X**2 + (Y + 12)**2))**2 +(23.8732414638 * (Y - 12) / (X**2 + (Y - 12)**2) + 23.8732414638 * (Y + 12) / (X**2 + (Y + 12)**2))**2)**0.5
EA1 = abs(pSI0 - pSI)
EA2 = abs(VP - Vaprox)
if EA1 < 0.0001 and EA2 < 0.0001:
X2f = X
Y2f = Y
I3 = [X2f,Y2f]
print n,m,X,Y,"GG son",EA1,EA2
print I3
# starting with the FirstFor
FirstFor(X0,sX,Y0,sY)
print "\n This should be good"
raw_input()