/
helper.go
107 lines (96 loc) · 3.13 KB
/
helper.go
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package main
import (
"fmt"
"os"
"time"
"github.com/ChristopherRabotin/smd"
"github.com/soniakeys/meeus/julian"
)
// Result stores a full valid result.
type Result struct {
launch time.Time
c3, rla, dla float64
flybys []GAResult
arrival time.Time
vInf float64
}
// CSV returns the CSV of this result
func (r Result) CSV() string {
rtn := fmt.Sprintf("%.3f (%s),%f,%f,%f,", julian.TimeToJD(r.launch), r.launch.Format(dateFormat), r.c3, r.rla, r.dla)
for _, flyby := range r.flybys {
rtn += flyby.CSV()
}
rtn += fmt.Sprintf("%.3f (%s),%f", julian.TimeToJD(r.arrival), r.arrival.Format(dateFormat), r.vInf)
return rtn
}
//Clone figure it out
func (r Result) Clone() Result {
newResult := Result{r.launch, r.c3, r.rla, r.dla, nil, r.arrival, r.vInf}
newResult.flybys = make([]GAResult, len(r.flybys))
for i, fb := range r.flybys {
newResult.flybys[i] = fb
}
return newResult
}
// NewResult initializes a result.
func NewResult(launch time.Time, c3, rla, dla float64, numGA int) Result {
return Result{launch, c3, rla, dla, make([]GAResult, numGA), time.Now(), -1}
}
// GAResult stores the result of a gravity assist.
type GAResult struct {
DT time.Time
deltaV float64
radius float64
bt, br float64
phi float64 // Only used in the case of a resonant orbit
}
// CSV returns the CSV of this result
func (g GAResult) CSV() string {
if g.DT != (time.Time{}) {
if g.phi != 0 {
return fmt.Sprintf("%.3f (%s),%f,%f,%f,%f,%f,", julian.TimeToJD(g.DT), g.DT.Format(dateFormat), g.deltaV, g.radius, g.bt, g.br, smd.Rad2deg(g.phi))
}
return fmt.Sprintf("%.3f (%s),%f,%f,%f,%f,", julian.TimeToJD(g.DT), g.DT.Format(dateFormat), g.deltaV, g.radius, g.bt, g.br)
}
return ""
}
// StreamResults is used to stream the results to the output file.
func StreamResults(prefix string, planets []smd.CelestialObject, rsltChan <-chan (Result)) {
f, err := os.Create(fmt.Sprintf("%s/%s-results.csv", outputdir, prefix))
if err != nil {
panic(err)
}
hdrs := "launch,c3,rla,dla,"
for pNo, planet := range planets[0:len(planets)] {
hdrs += planet.Name + "DT,"
hdrs += planet.Name + "DV,"
hdrs += planet.Name + "Rp,"
hdrs += planet.Name + "Bt,"
hdrs += planet.Name + "Br,"
if pNo > 0 && pNo < len(flybys) && flybys[pNo].isResonant {
// Repeat
hdrs += planet.Name + "-ResDT,"
hdrs += planet.Name + "-ResDV,"
hdrs += planet.Name + "-ResRp,"
hdrs += planet.Name + "-ResBt,"
hdrs += planet.Name + "-ResBr,"
hdrs += planet.Name + "-ResPhi,"
}
}
hdrs += "arrival,vInf,Bt,Br\n"
if _, err := f.WriteString(hdrs); err != nil {
panic(err)
}
for rslt := range rsltChan {
f.WriteString(rslt.CSV() + "\n")
wg.Done()
}
wg.Done() // Done writing everything.
}
type target struct {
BT1, BT2, BR1, BR2, Assocψ, Rp1, Rp2 float64
ega1Vin, ega1Vout, ega2Vin, ega2Vout float64
}
func (t target) String() string {
return fmt.Sprintf("ψ=%f ===\nGA1: Bt=%f\tBr=%f\trP=%f\nVin=%f\tVout=%f\tdelta=%f\n\nGA2: Bt=%f\tBr=%f\trP=%f\nVin=%f\tVout=%f\tdelta=%f\n", smd.Rad2deg(t.Assocψ), t.BT1, t.BR1, t.Rp1, t.ega1Vin, t.ega1Vout, t.ega1Vout-t.ega1Vin, t.BT2, t.BR2, t.Rp2, t.ega2Vin, t.ega2Vout, t.ega2Vout-t.ega2Vin)
}