aboutsummaryrefslogtreecommitdiff
path: root/ivp/arenstorf.go
blob: 05b152777b8d8ed1bbf12a14dcdcfc0cf00a76e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Arenstorf orbit problem.
//
// Copyright (C) 2020 Juan Marín Noguera
//
// This file is part of Solvned.
//
// Solvned is free software: you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option) any 
// later version.
//
// Solvned is distributed in the hope that it will be useful, but WITHOUT ANY 
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Solvned. If not, see <https://www.gnu.org/licenses/>.

package ivp

import (
	"math"
	"github.com/JwanMan/mned"
)

var arenstorfOrbit = mned.IVP{
	Derivative: func(p mned.Point) ([]float64, bool) {
		const μ = 0.012277471
		const μ2 = 1 - μ
		 := p.Value[0] + μ
		xμ2 := p.Value[0] - μ2
		D1 := * + p.Value[1]*p.Value[1]
		D1 *= math.Sqrt(D1)
		D2 := xμ2*xμ2 + p.Value[1]*p.Value[1]
		D2 *= math.Sqrt(D2)
		return []float64{
			p.Value[2],
			p.Value[3],
			p.Value[0] + 2*p.Value[3] - μ2*/D1 - μ*xμ2/D2,
			p.Value[1]*(1-μ2/D1-μ/D2) - 2*p.Value[2],
		}, true
	},
	Start: mned.Point{
		Time:  0,
		Value: []float64{0.994, 0, 0, -2.001585106},
	},
}

// The Arenstorf orbit is a stable orbit of a satellite around the Earth taking
// into account the gravity of the Earth and the Moon and considering the
// satellite to have a negligible mass compared to both. The orbit was
// discovered by Richard Arenstorf and is given by the following formulae:
//
// ```
// μ = 0.012277471, μ' = 1 - μ;
// D1 = ((x+μ)^2 + y^2)^(3/2), D2 = ((x-μ')^2 + y^2)^(3/2);
// x" = x + 2y' - μ'(x+μ)/D1 - μ(x-μ')/D2;
// y" = y - 2x' - μ'y/D1 - μy/D2;
// x(0) = 0.994, y(0) = 0, x'(0) = 0, y'(0) = -2.001585106.
// ```
//
// The orbit has three big loops at one side and a small one at the other, and
// varying μ changes the number of loops. Because of the unstability, this
// problem is often used to test different ODE solving methods.
func ArenstorfOrbit() mned.IVP {
	return arenstorfOrbit.Clone()
}