2nd order differential equation coupled to integro-differential equation in python - python

I'm trying to solve the following equations numerically in python
where f(r)=S*exp(-r^2/b^2) and µ and m_π are constants.
I have tried rewriting the 2nd order differential equation into two first order equations and solving the system of equations with root finding.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from scipy.integrate import trapz
from scipy.optimize import root
b=1
S=20
m=135
mn = 939.5
mu = m*mn/(mn+m)
g = (2*mu)
def f(r):
return S*np.exp(-r**2/b**2)
def diff(phi,r,E):
return (phi[1],g*(-E+m)*phi[0]-2/r*phi[1]+g*f(r))
phi0 = [b/m,b/m] #Initial
def phi_fun(E):
rs = np.linspace(1e-5,50,1000)
ys = odeint(lambda phi,r: diff(phi,r,E), phi0, rs)
integral = 12*np.pi*trapz(ys[:,0]*f(rs)*rs**4,rs)
return integral - E
E_true = root(phi_fun, -2).x
rs = np.linspace(1e-5,50,1000)
ys = odeint(lambda phi,r: diff(phi,r,E_true), phi0, rs)
phi_true = ys[:,0]
plt.plot(rs, phi_true,linewidth=2,label=r'$\phi(r)$')
print("Minimum found at E =",E_true)
This does not produce a result I would expect and maybe I have done something wrong. I was thinking about using IDEsolver but I'm not sure how to implement this. Any suggestions?
Thanks in advance!

Related

Solving second order differential equation in python

I want to solve second ODE's with the help of python.
The objective is:
d^2V/dx^2 = hsin(ex)
dV/dx = 0
Some info: L is the thickness of a plate, and it is equal to 5 mm. x is the position in the plate and goes from 0 to L. V is the electrical potential.
I dont understand how to put this in the code.
So far i have done this in python:
import numpy as np
from scipy.integrate import odeint
import math
rho_0 =3.3*10**16 #C/m^3
epsilon = 2.1*10**10 #Nm^2/C^2
L = 5*10**-3
h = rho_0/epsilon
e = (4*math.pi)/L
def dV_dx(x,V):
return [h*np.sin(e*x)]
t = np.linspace(0,1,100)
sol = odeint(model,y,t) #need to put in the 'model',and 'y' value above in the code
thanks in advance!

Singular Jacobian in Boundary Value Problem

I am solving a set of coupled ODEs using solve_bvp in python. I have solved the equations for the boundary conditions that U = 0 and B = 0 on the boundaries, however I am trying to solve them such that U' = 0 and B = 0 on the boundary. My problem is that I keep encountering a singular jacobian in the return message - my guess is that the initial guess is diverging, however I have tried a range of initial guesses and still no solution. Is there a more systematic way of figuring this out? My code is below:
import numpy as np
from scipy import integrate
from scipy.integrate import solve_bvp
import matplotlib.pyplot as plt
%matplotlib inline
x = np.linspace(-0.5, 0.5, 1000)
y = np.ones((4, x.size))
y[0] = U_0*np.tanh(Q*x)
U_0 = 0.1
Q = 30
## Then we calculate the total energy
def FullSolver(x,y,Ha, Rm):
def fun(x, y):
U, dU, B, dB = y;
d2U = -2*U_0*Q**2*(1/np.cosh(Q*x))**2*np.tanh(Q*x)-((Ha**2)/(Rm))*dB;
d2B = -Rm*dU;
return dU, d2U, dB, d2B
def bc(ya, yb):
return ya[1], yb[1], ya[2]-0, yb[2]+0
# sol will give us the solutions which are accessible if we need them
sol = solve_bvp(fun, bc, x, y, tol=1e-12)
return(sol.x, sol.yp[0], sol.y[2], sol.message)
FullSolver(x, y, 0.000005, 0.00009)

Trouble Solving and Plotting Solution to Simple Differential Equation

I'm trying to solve the differential equation R^{2} = 1/R with initial condition that R(0) = 0 in python. I should get the solution that R'(t) = (3/2 * t)^(2/3) as I get this from mathematica. Plot of solution to R'[t]^2 = 1/R with initial condition R(0) = 0
I used the following code in python:
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
sqrt = np.sqrt
# function that returns dy/dt
def model(y,t):
#k = 1
dydt = sqrt(1/y)
return dydt
# initial condition
y0 = [0.0]
# time points
t = np.linspace(0,5)
# solve ODE
y = odeint(model,y0,t)
# plot results
plt.plot(t,y)
plt.ylabel('$R/R_0$')
plt.xticks([])
plt.yticks([])
plt.show()
however I get only 0 as I'm apparently dividing by zero at some point python plot of differential equation R'[t]^2 = 1/R, which is not correct. Could someone point out what I could do to get the solution and plot I am expecting.
Thank you
Your model needs to be changed.I get your equation for the solution would be something like this https://www.wolframalpha.com/input/?i=R%27%28t%29%5E2+%3D+1%2FR
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
# function that returns dy/dt
def model(y,t):
#k = 1
dydt = 1*y**-1/2
return dydt
# initial condition
y0 = 0.1
# time points
t = np.linspace(0,20)
# solve ODE
y = odeint(model,y0,t)
# plot results
plt.plot(t,y)
plt.ylabel('$R$')
plt.xlabel('$t$')
plt.xticks([])
plt.yticks([])
plt.show()
Your starting value is 0, which results in the derivative being zero (y * -1, or simpler -y), which means 0 will get added to your current y-value, thus remaining at zero for the whole integration. Your code is correct, but not your formulation.
I see a 1/R in your link, so use that, e.g. dydt = 1/y; which will fail, because it results in division by zero, so don't start at zero, because your derivative is not defined there. There also appears to be a square root somewhere, that you imported, but never use.

Simultaneous numerical fit of two equations using Numpy least square method

I am trying to fit below mentioned two equations using python leastsq method but am not sure whether this is the right approach. First equation has incomplete gamma function in it while the second one is slightly complex, and along with an exponential function contains a term which is obtained by using a separate fitting formula.
J_mg = T_incomplete(hw/T_mag)
J_nmg = e^(-hw/T)*g(w,T)
Here g is a function of w and T and is calucated using a given fitting formula.
I am following the steps outlined in this question.
Here is what I have done
import numpy as np
from scipy.optimize import leastsq
from scipy.special import gammaincc
from scipy.special import gamma
from matplotlib.pyplot import plot
# generating data
NPTS = 10
hw = np.linspace(0.5, 10, NPTS)
j1 = np.linspace(0.001,10,NPTS)
j2 = np.linspace(0.003,10,NPTS)
T_mag = np.linspace(0.3,0.5,NPTS)
#defining functions
def calc_gaunt_factor(hw,T):
fitting_coeff= np.loadtxt('fitting_coeff.txt', skiprows=1)
#T is in KeV
#K_b = 8.6173303(50)e−5 ev/K
g = 0
gamma = 0.0136/T
theta= hw/T
A= (np.log10(gamma**2) +0.5)*0.4
B= (np.log10(theta)+1.5)*0.4
for i in range(11):
for j in range(11):
g_ij = fitting_coeff[i][j]*(A**i)*(B**j)
g = g_ij+g
return g
def j_w_mag(hw,T_mag):
order= 0.001
return np.sqrt(1/T_mag)*gamma(order)*gammaincc(order,hw/T_mag)
def j_w_nonmag(hw,T):
gamma = 0.0136/T
theta= hw/T
return np.sqrt(1/T)*np.exp((-hw)/T)*calc_gaunt_factor(hw,T)
def residual_func(T,T_mag,hw,j1,j2):
err_unmag = np.nan_to_num(j1 - j_w_nonmag(hw,T))
err_mag = np.nan_to_num(j2 - j_w_mag(hw,T_mag))
err= np.concatenate((err_unmag, err_mag))
return err
par_init = np.array([.35])
best, cov, info, message, ler = leastsq(residual_func,par_init,args=(T_mag,hw,j1,j2),full_output=True)
print("Best-Fit Parameters:")
print("T=%s" %(best[0]))
I am getting weird value for my fitting parameter, T. Is this the right approach? Thanks.

Pendulum-like odeint integration

I'm trying to solve a pendulum-like differential equation that goes like d2(phi)/dt = -(g/R) *sin(phi) (it's the skateboard problem in Taylor's Classical Mechanics). I'm new to scipy and odeint and the like, so I'm doing this to prepare for more sophisticated numerical solutions in the future.
I've used code from here to try and navigate the coding, but all I'm coming up with is a flat line for phi(t). I think it stems from the fact that I'm trying to split a second order differential equation into two first orders, where one doesn't depend on the other (because d(phi)/dt to make an appearance); but I'm not sure how to go about fixing it.
Anyone know what's wrong with it?
# integrate skateboard problem, plot result
from numpy import *
from scipy.integrate import odeint
import matplotlib.pyplot as plt
def skate(y, t, params):
phi, omega = y
g, R = params
derivs = [omega, -(g/R)*np.sin(phi)]
return derivs
# Parameters
g = 9.81
R = 5
params = [g, R]
#Initial values
phi0 = 20
omega0 = 0
y0 = [phi0, omega0]
t = linspace(0, 20, 5000)
solution = odeint(skate, y0, t, args=(params,))
plt.plot(t, solution[:,0])
plt.xlabel('time [s]')
plt.ylabel('angle [rad]')
plt.show()
I suspect a bug here: -(g/R)*np.sin(phi). Perhaps you forget to define the alias for numpy lib import (for example: import numpy as np). Instead you just did (from numpy import *). Try this:
def skate(y, t, params):
phi, omega = y
g, R = params
derivs = [omega, -(g/R)*sin(phi)]
return derivs

Categories

Resources