馬蹄軌道とCへの統合


8

制限された3体問題の特定のケースを研究しています。いくつかのオブジェクトが馬蹄形の軌道パターンに従っていることをわかっています、と私は記事の中にいくつかのアドバイス、次のよC. Iにおける統合コードを通して何かを整理しようとしている制限三体の周期的な馬蹄形の軌道の家族、これにより、理想的な初期条件と重心系の方程式が得られます。(mは地球の質量であり、結果として質量の中心参照系での太陽の位置(x、y)は、3番目の物体の座標であり、(制限された問題が必要とする)質量がないと仮定されます。

O=(x2+y2)/2+(1m)r1+mr2+(1m)m2
r12=(xm)2+y2

r22=(xm+1)2+y2
a(x)=dOdx+2v(y)
a(y)=dOdy2v(x)

「太陽」と「地球」の位置は、同じ参照系では(m、0)と(m-1,0)に固定されています。(地球が円軌道を持っていると仮定して、回転基準系。)

これらすべてから、システムを説明する方程式を計算しました。

a(x)=x+(m1)(xm)((xm)2+y2)1.52m(xm+1)((xm+1)2+y2)1.5+2v(y)
a(y)=yy(1m)((xm)2+y2)1.52ym((xm+1)2+y2)1.52v(x)

Runge-Kutta 4のアルゴリズムを使用して、これらの方程式を統合しました。(私はコードが非常にねじれていることを知っていますが、私はポインターを使用できず、どこでも構造体を使用しています)。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

#define dt 0.0001
#define N 100

typedef struct{
    long double x,y;
}vec;

typedef struct{
    vec k1,k2,k3,k4;
}runge;

typedef struct{
    runge r,v;
}big;

double dS,dE,m;

double accx(double,double,double);
double accy(double,double,double);
void rad(vec);
big rungekutta(vec,vec);
vec moto(vec,runge);
double jacobi(vec);

int main(){
  vec r,v;
    big f;
    double J,t;
    int i,Num;
    FILE* s1;
    s1=fopen("HorseShoe.dat","w");

    Num=(int)N/dt;
    scanf("%Lf",&r.x);
    scanf("%Lf",&r.y);
    scanf("%Lf",&v.x);
    scanf("%Lf",&v.y);
    scanf("%lf",&m);

    for(i=0;i<Num;i++){
        t=(i+1)*dt;
        rad(r);
        f=rungekutta(r,v);
        r=moto(r,f.r);
        v=moto(v,f.v);
        J=jacobi(r);
        fprintf(s1,"%lf\t%Lf\t%Lf\t%Lf\t%Lf\t%lf\n",t,r.x,r.y,v.x,v.y,J);
    }
return 0;
}

void rad(vec r){
    dS=pow(r.x-m,2)+pow(r.y,2);
    dE=pow(r.x-m+1,2)+pow(r.y,2);
}

double jacobi(vec r){
    return pow(r.x,2)+pow(r.y,2)+2*(1-m)/dS+2*m/dE+m*(1-m);
}

double accx(double x,double y,double v){
    return x-(x-m)*(1-m)/pow(pow(x-m,2)+pow(y,2),1.5)-m*(x-m+1)/pow(pow(x-m+1,2)+pow(y,2),1.5)+2*v;
}

double accy(double x,double y,double v){
    return y-(1-m)*y/pow(pow(y,2)+pow(x-m,2),1.5)-m*y/pow(pow(y,2)+pow(x-m+1,2),1.5)-2*v;
}

big rungekutta(vec r,vec v){
    big f;
    f.r.k1.x=v.x;
    f.r.k1.y=v.y;
    f.v.k1.x=accx(r.x,r.y,v.y);
    f.v.k1.y=accy(r.x,r.y,v.x);
    f.r.k2.x=v.x+f.v.k1.x*dt/2;
    f.r.k2.y=v.y+f.v.k1.y*dt/2;
    f.v.k2.x=accx(r.x+f.r.k1.x*dt/2,r.y+f.r.k1.y*dt/2,v.y+f.v.k1.y*dt/2);
    f.v.k2.y=accy(r.x+f.r.k1.x*dt/2,r.y+f.r.k1.y*dt/2,v.x+f.v.k1.x*dt/2);
    f.r.k3.x=v.x+f.v.k2.x*dt/2;
    f.r.k3.y=v.y+f.v.k2.y*dt/2;
    f.v.k3.x=accx(r.x+f.r.k2.x*dt/2,r.y+f.r.k2.y*dt/2,v.y+f.v.k2.y*dt/2);
    f.v.k3.y=accy(r.x+f.r.k2.x*dt/2,r.y+f.r.k2.y*dt/2,v.x+f.v.k2.x*dt/2);
    f.r.k4.x=v.x+f.v.k3.x*dt;
    f.r.k4.y=v.y+f.v.k3.y*dt;
    f.v.k4.x=accx(r.x+f.r.k3.x*dt,r.y+f.r.k3.y*dt,v.y+f.v.k3.y*dt);
    f.v.k4.y=accy(r.x+f.r.k3.x*dt,r.y+f.r.k3.y*dt,v.x+f.v.k3.x*dt);
    return f;
}

vec moto(vec r,runge rk){
    r.x+=(rk.k1.x+2*rk.k2.x+2*rk.k3.x+rk.k4.x)*dt/6;
    r.y+=(rk.k1.y+2*rk.k2.y+2*rk.k3.y+rk.k4.y)*dt/6;
    return r;
}

結果をプロットするとスパイラルが得られますが、与えられた入力を使用すると馬蹄軌道が得られます。私は多くの異なる入力を試しました(m = 0.0001とm = 0.000003、後者は地球と太陽の質量の実際の値と同じです(太陽の質量は1-m))。

何が悪いのかわからない(おそらくすべて:D)。


(方程式の)変数が何であるかを説明すれば、人々はより良​​い助けになるかもしれません:O、x、y、m、r1 / 2など。また、あなたの質問では、問題が何であるかが明確になっていません出会い。「何が悪いのかわかりません」-何を取得することになっていて、代わりに何を取得するのですか
Alex

先に進む前に、2つのことを確認したいと思います。数学で間違いを犯したかどうかを確認するために使用した参考資料へのリンクと、入力です。入力がオフになっている可能性があります。これは非標準の単位系であり、地球の質量は約であり、太陽の質量はこの小さい数から1を引いたものであり、位置ベクトルは約1です。時間もスケーリングされているように見えます。ここはSIユニットの場所ではありません。メートル×106バツy
David Hammen

質問を編集して、質問の詳細を追加しました(少し厄介な場合は、ここで最初の質問です)。私はG = 1を使用しましたが、もちろんSI単位は使用できませんでした;)
Elisa

5
何が問題で、どのように修正したかを詳しく説明した質問に回答を投稿してください。これは、この質問に来る将来の他の人に役立つかもしれません!
ゼファー2016

2
ほんの少しでも重要な発言:4 re次のルンゲクッタはシンプレクティックではありません。つまり、時間の経過とともに総軌道エネルギーが変化します。最初は遅くなりますが、その深刻度は指数関数的に増加します。希望する積分間隔に応じて、RK4を捨てて、天体力学により適したものを選んでください。背景と推奨事項については、たとえばこのペーパーを参照してください。
Rody Oldenhuis 2016

回答:


1

方程式やコードについては詳しく説明しませんが、使用した正確な開始位置については触れていないため、最初に安定した馬蹄軌道状態ベクトルを解決していないと思います。

太陽と地球の位置は、同期(回転)フレームで固定されます。しかし、アストロイドはどこから始めましたか?特定の開始位置では、小惑星に正しい開始速度(速度と方向)を与える必要があります。そうしないと、安定しない場合があり、あなたが言及したように、さまようかスパイラルを回るだけです。

この答えを見て、正しい方程式を示し、プロットする前に安定した馬蹄軌道を解いてください。

私は、x軸上で地球の反対側の位置から始めます。地球よりも太陽から少し離れている、または近い場所から始めます。次に、(回転フレーム内で)低速で正確にy軸の方向に打ち上げます。私はそれが地球に向かってドリフトし、その後ブーメランが開始領域の領域に戻るのを見ます。再びx軸と交差したときに、速度がyにどれだけ近いかを確認します。最適化ゼロソルバーを使用してbrentq、戻り速度が正反対の方向になるまで初期速度を調整します。

それが本当なら、軌道は周期的で繰り返され、CR3BPの制約の下で古い軌道と呼ぶことができます。


この回答から(参考文献を含め、そこにはもっとたくさんの情報があります!):

バツ¨=バツ+2y˙1μバツ+μr1μバツ1+μr2
y¨=y2バツ˙1μyr1μyr2
z¨=1μzr1μzr2

ここに画像の説明を入力してください

上:不安定な馬蹄軌道の半サイクル

ここに画像の説明を入力してください

上:半サイクル時間の計算に使用される、同じぐらついた馬蹄軌道の最初のx軸交差までの時間。

ここに画像の説明を入力してください

上:この計算によるサイクルタイム(黒い点)と、周期的な周期推定方法によるサイクル時間(赤い点)。良い質的な合意。また、xの各開始点での開始y速度。

以下:これらのプロット用のPythonスクリプト。

def x_acc(x, ydot):
    r1    = np.abs(x-x1)
    r2    = np.abs(x-x2)
    xddot = x + 2*ydot  -  ((1-mu)/r1**3)*(x+mu) - (mu/r2**3)*(x-(1-mu))
    return xddot

def C_calc(x, y, z, xdot, ydot, zdot):
    r1 = np.sqrt((x-x1)**2 + y**2 + z**2)
    r2 = np.sqrt((x-x2)**2 + y**2 + z**2)
    C = (x**2 + y**2 + 2.*(1-mu)/r1 + 2.*mu/r2 - (xdot**2 + ydot**2 + zdot**2))
    return C

def deriv(X, t): 
    x, y, z, xdot, ydot, zdot = X
    r1 = np.sqrt((x-x1)**2 + y**2 + z**2)
    r2 = np.sqrt((x-x2)**2 + y**2 + z**2)
    xddot = x + 2*ydot  -  ((1-mu)/r1**3)*(x+mu) - (mu/r2**3)*(x-(1-mu))
    yddot = y - 2*xdot  -  ((1-mu)/r1**3)*y      - (mu/r2**3)*y
    zddot =             -  ((1-mu)/r1**3)*z      - (mu/r2**3)*z
    return np.hstack((xdot, ydot, zdot, xddot, yddot, zddot))

# http://cosweb1.fau.edu/~jmirelesjames/hw4Notes.pdf

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint as ODEint
from scipy.optimize import brentq

halfpi, pi, twopi = [f*np.pi for f in (0.5, 1, 2)]

mu = 0.001

x1 = -mu
x2 = 1. - mu

x = np.linspace(-1.4, 1.4, 1201)
y = np.linspace(-1.4, 1.4, 1201)

Y, X = np.meshgrid(y, x, indexing='ij')
Z    = np.zeros_like(X)

xdot, ydot, zdot = [np.zeros_like(X) for i in range(3)]

C = C_calc(X, Y, Z, xdot, ydot, zdot)
C[C>8] = np.nan

if True:
    plt.figure()
    plt.imshow(C)
    plt.colorbar()
    levels = np.arange(2.9, 3.2, 0.04) 
    CS = plt.contour(C, levels,
                 origin='lower',
                 linewidths=2) 
    plt.show()

ydot0s   = np.linspace(-0.08, 0.08, 20)
x0ydot0s = []
for ydot0 in ydot0s:
    x0, infob =  brentq(x_acc, -1.5, -0.5, args=(ydot0), xtol=1E-11, rtol=1E-11,
                           maxiter=100, full_output=True, disp=True)
    x0ydot0s.append((x0, ydot0))

states = [np.array([x0, 0, 0, 0, ydot0, 0]) for (x0, ydot0) in x0ydot0s]

times  = np.arange(0, 150, 0.01)

results = []
for X0 in states:
    answer, info = ODEint(deriv, X0, times, atol = 1E-11, full_output=True)
    results.append(answer.T.copy())

resultz = []
for x0ydot0, thing in zip(x0ydot0s, results):
    y     = thing[1]
    check = y[2:]*y[1:-1] < 0
    zc    = np.argmax(y[2:]*y[1:-1] < 0) + 1
    if zc > 10:
        resultz.append((thing, zc, x0ydot0))

if True:
    plt.figure()
    hw = 1.6
    for j, (thing, zc, x0ydot0) in enumerate(resultz):
        x, y = thing[:2,:zc]
        plt.plot(x, y)
    plt.xlim(-hw, hw)
    plt.ylim(-hw, hw)
    plt.plot([x1], [0], 'ok')
    plt.plot([x2], [0], 'ok')
    plt.show()

if True:
    plt.figure()
    for j, (thing, zc, x0ydot0) in enumerate(resultz):
        x, y = thing[:2]
        plt.plot(times[:zc], y[:zc])
    plt.show()

if True:
    plt.figure()
    for j, (thing, zc, x0ydot0) in enumerate(resultz):
        x0, ydot0 = x0ydot0
        cycle_time = 2. * times[zc] / twopi
        ratio = abs(x0/x2)
        T_simple_model = twopi * abs(x0/x2)**1.5
        T_synodic_simple_model = 1. / (1. - twopi/T_simple_model) # https://astronomy.stackexchange.com/a/25002/7982
        plt.subplot(2, 1, 1)
        plt.plot(x0, cycle_time, 'ok')
        plt.plot(x0, abs(T_synodic_simple_model), 'or')
        plt.subplot(2, 1, 2)
        plt.plot(x0, ydot0, 'ok')
    plt.subplot(2, 1, 1)
    plt.xlabel('x0', fontsize=16)
    plt.ylabel('cycle times (periods)', fontsize=16)
    plt.subplot(2, 1, 2)
    plt.xlabel('x0', fontsize=16)
    plt.ylabel('ydot0', fontsize=16)
    plt.show()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.