Как избежать расходящихся решений с помощью odeint? способ съемки

Я пытаюсь решить уравнение в Python. В основном, что я хочу сделать, это решить уравнение:

(1/x^2)*d(Gam*dL/dx)/dx)+(a^2*x^2/Gam-(m^2))*L=0

Это уравнение Клейна-Гордона для массивного скалярного поля в пространстве-времени Шварцшильда. Предположим, что мы знаем m и Gam=x^2-2*x. Начальное/граничное условие, которое я знаю, это L(2+epsilon)=1 и L(infty)=0. Обратите внимание, что асимптотическое поведение уравнения

L(x-->infty)-->Exp[(m^2-a^2)*x]/x and Exp[-(m^2-a^2)*x]/x 

Тогда, если a^2>m^2, у нас будут колебательные решения, а если a^2 < m^2, у нас будут расходящиеся и распадающиеся решения.

Что меня интересует, так это решение распада, однако, когда я пытаюсь решить приведенное выше уравнение, преобразуя его в систему дифференциальных уравнений первого порядка и используя метод стрельбы, чтобы найти «а», которое может дать мне поведение, которое Мне интересно, у меня всегда есть расходящееся решение. Я предполагаю, что это происходит потому, что odeint всегда находит расходящееся асимптотическое решение. Есть ли способ избежать или сказать odeint, что меня интересует решение распада? Если нет, то знаете ли вы, как я могу решить эту проблему? Может быть, используя другой метод решения моей системы дифференциальных уравнений? Если да, то каким методом?

По сути, я добавляю новую систему уравнений для «а».

(d^2a/dx^2=0, da/dx(2+epsilon)=0,a(2+epsilon)=a_0)

чтобы иметь «а» в качестве константы. Затем я рассматриваю разные значения для «a_0» и спрашиваю, выполнены ли мои граничные условия.

Спасибо за ваше время. С уважением,

Луис П.


person Luis Enrique Padilla Albores    schedule 16.06.2018    source источник
comment
Это больше вопрос о физике или научных вычислениях. Какой код вы используете для съемки? Как вы включаете значение в бесконечности?   -  person Lutz Lehmann    schedule 16.06.2018


Ответы (1)


Я включаю значение на бесконечности с учетом асимптотического поведения, это означает, что у меня будет связь между полем и его производной. Я опубликую код для вас, если он будет полезен:

from IPython import get_ipython
get_ipython().magic('reset -sf')
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from math import *
from scipy.integrate import ode

Это исходные условия для Шварцшильда. Поле инвариантно при масштабировании, тогда я могу использовать $L(2+\epsilon)=1$

def init_sch(u_sch):
    om = u_sch[0]
    return np.array([1,0,om,0]) #conditions near the horizon, [L_c,dL/dx,a,da/dx]

Это наша система уравнений

def F_sch(IC,r,rho_c,m,lam,l,j=0,mu=0):
    L = IC[0]
    ph = IC[1]
    om = IC[2]
    b = IC[3]

    Gam_sch=r**2.-2.*r

    dR_dr = ph
    dph_dr = (1./Gam_sch)*(2.*(1.-r)*ph+L*(l*(l+1.))-om**2.*r**4.*L/Gam_sch+(m**2.+lam*L**2.)*r**2.*L)
    dom_dr = b
    db_dr = 0.
    return [dR_dr,dph_dr,dom_dr,db_dr]

Затем я пробую разные значения «ом» и спрашиваю, выполнены ли мои граничные условия. p_sch — параметры моей модели. В общем, то, что я хочу сделать, немного сложнее, и в целом мне потребуется больше параметров, чем в просто массивном корпусе. Однако мне нужно начать с самого простого, о чем я и спрашиваю здесь.

p_sch = (1,1,0,0) #[rho_c,m,lam,l], lam and l are for a more complicated case 
ep = 0.2
ep_r = 0.01
r_end = 500
n_r = 500000
n_omega = 1000
omega = np.linspace(p_sch[1]-ep,p_sch[1],n_omega)
r = np.linspace(2+ep_r,r_end,n_r)
tol = 0.01
a = 0

for j in range(len(omega)): 
    print('trying with $omega =$',omega[j])
    omeg = [omega[j]]
    ini = init_sch(omeg)
    Y = odeint(F_sch,ini,r,p_sch,mxstep=50000000)
    print Y[-1,0]
#Here I ask if my asymptotic behavior is fulfilled or not. This should be basically my value at infinity
    if abs(Y[-1,0]*((p_sch[1]**2.-Y[-1,2]**2.)**(1/2.)+1./(r[-1]))+Y[-1,1]) < tol:
        print(j,'times iterations in omega')
        print("R'(inf)) = ", Y[-1,0])        
        print("\omega",omega[j])
        omega_1 = [omega[j]] 
        a = 10
        break           
    if a > 1:
        break

По сути, я хочу здесь решить систему уравнений, дающую разные начальные условия, и найти значение для «a=» (или «om» в коде), которое должно быть близко к моим граничным условиям. Мне это нужно, потому что после этого я могу дать такому начальному гостю метод секущей и попытаться найти лучшее значение для «а». Однако всегда, когда я запускаю этот код, у меня есть разные решения, которые, конечно, не интересуют меня. Я пытаюсь сделать то же самое, но с учетом scipy.integrate.solve_vbp, но когда я запускаю следующий код:

from IPython import get_ipython
get_ipython().magic('reset -sf')
import numpy as np
import matplotlib.pyplot as plt
from math import *
from scipy.integrate import solve_bvp

def bc(ya,yb,p_sch):
    m = p_sch[1]
    om = p_sch[4]
    tol_s = p_sch[5]
    r_end = p_sch[6]

    return np.array([ya[0]-1,yb[0]-tol_s,ya[1],yb[1]+((m**2-yb[2]**2)**(1/2)+1/r_end)*yb[0],ya[2]-om,yb[2]-om,ya[3],yb[3]])

def fun(r,y,p_sch):
    rho_c = p_sch[0]
    m = p_sch[1]
    lam = p_sch[2]
    l = p_sch[3]

    L = y[0]
    ph = y[1]
    om = y[2]
    b = y[3]

    Gam_sch=r**2.-2.*r

    dR_dr = ph
    dph_dr = (1./Gam_sch)*(2.*(1.-r)*ph+L*(l*(l+1.))-om**2.*r**4.*L/Gam_sch+(m**2.+lam*L**2.)*r**2.*L)
    dom_dr = b
    db_dr = 0.*y[3]
    return np.vstack((dR_dr,dph_dr,dom_dr,db_dr))

eps_r=0.01
r_end = 500
n_r = 50000
r = np.linspace(2+eps_r,r_end,n_r)
y = np.zeros((4,r.size))
y[0]=1
tol_s = 0.0001
p_sch= (1,1,0,0,0.8,tol_s,r_end)


sol = solve_bvp(fun,bc, r, y, p_sch)

Я получаю эту ошибку: ValueError: ожидается, что bc return будет иметь форму (11,), но на самом деле имеет (8,). ValueError: ожидается, что bc return будет иметь форму (11,), но на самом деле имеет (8,).

person Luis Enrique Padilla Albores    schedule 17.06.2018