abstract-math 0.0.0.23__py3-none-any.whl → 0.0.0.25__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of abstract-math might be problematic. Click here for more details.
- abstract_math/createflask.py +4 -0
- abstract_math/flask_scripts/flask_utils.py +2 -1
- abstract_math/solar_math/main.py +149 -133
- abstract_math/solar_math/src/constants/__init__.py +3 -3
- abstract_math/solar_math/src/constants/distance_constants.py +25 -1
- abstract_math/solar_math/src/constants/planet_constants.py +9 -2
- abstract_math/solar_math/src/constants/time_constants.py +1 -1
- abstract_math/solar_math/src/utils/escape_velocity.py +71 -38
- abstract_math/solar_math/src/utils/velocity_utils.py +26 -0
- {abstract_math-0.0.0.23.dist-info → abstract_math-0.0.0.25.dist-info}/METADATA +1 -1
- {abstract_math-0.0.0.23.dist-info → abstract_math-0.0.0.25.dist-info}/RECORD +13 -12
- {abstract_math-0.0.0.23.dist-info → abstract_math-0.0.0.25.dist-info}/WHEEL +0 -0
- {abstract_math-0.0.0.23.dist-info → abstract_math-0.0.0.25.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from abstract_flask import * # must provide Blueprint, request, jsonify, get_request_data, get_logFile, offer_help
|
|
2
|
+
from ..solar_math import *
|
|
2
3
|
# Auto-generated routes
|
|
3
|
-
math_data_bp = Blueprint('math_data_bp', __name__, url_prefix='/utils')
|
|
4
|
+
math_data_bp = Blueprint('math_data_bp', __name__, url_prefix='/utils/')
|
|
4
5
|
logger = get_logFile('math_data_bp')
|
|
5
6
|
|
|
6
7
|
@math_data_bp.route("/normalized_velocity_conversioin", methods=["GET", "POST"], strict_slashes=False)
|
abstract_math/solar_math/main.py
CHANGED
|
@@ -1,25 +1,52 @@
|
|
|
1
1
|
# adapt_units_api.py (or wherever you glue this in)
|
|
2
2
|
from typing import *
|
|
3
|
-
from .src.constants.distance_constants import
|
|
3
|
+
from .src.constants.distance_constants import dconvert, _factor as dfactor
|
|
4
4
|
from .src.constants.time_constants import seconds_per
|
|
5
5
|
from .src.constants.planet_constants import planet_radius, get_body, g_at_radius
|
|
6
6
|
from .src.utils.geometry_utils import visible_area_flat, visible_surface_angle
|
|
7
|
+
from .src.utils import get_R_mu,get_normalized_distance,get_normalized_starting_velocity
|
|
7
8
|
from .src.imports import math, mul, div, add # your abstract_math ops
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
from .src.constants import (
|
|
10
|
+
DEFAULT_UNITS,
|
|
11
|
+
DEFAULT_TIME,
|
|
12
|
+
DEFAULT_PLANET,
|
|
13
|
+
DEFAULT_START_ALTITUDE,
|
|
14
|
+
DEFAULT_AS_RADIUS
|
|
15
|
+
)
|
|
16
|
+
def normalize_inputs(
|
|
17
|
+
planet: str,
|
|
18
|
+
start_altitude: float,
|
|
19
|
+
starting_velocity: float,
|
|
20
|
+
input_units: str,
|
|
21
|
+
input_time: str,
|
|
22
|
+
target_distance: float = None,
|
|
23
|
+
) -> dict:
|
|
24
|
+
"""Normalize input altitudes and velocities into SI (meters, seconds)."""
|
|
25
|
+
start_alt_m = get_normalized_distance(start_altitude, input_units)
|
|
26
|
+
target_alt_m = get_normalized_distance(target_distance, input_units)
|
|
27
|
+
|
|
28
|
+
v0_mps = get_normalized_starting_velocity(
|
|
29
|
+
start_altitude=start_alt_m,
|
|
30
|
+
starting_velocity=starting_velocity,
|
|
31
|
+
input_units=input_units,
|
|
32
|
+
input_time=input_time,
|
|
33
|
+
planet=planet,
|
|
34
|
+
)
|
|
13
35
|
|
|
36
|
+
return {
|
|
37
|
+
"start_alt_m": start_alt_m,
|
|
38
|
+
"target_alt_m": target_alt_m,
|
|
39
|
+
"v0_mps": v0_mps,
|
|
40
|
+
}
|
|
14
41
|
# --- Analyzer (prints a scan; no blocking input) ---
|
|
15
42
|
def analyze_visible_surface(
|
|
16
43
|
altitude_step: float = 200.0,
|
|
17
44
|
max_steps: int = 20,
|
|
18
45
|
fov_range: tuple[int, int] = (20, 160),
|
|
19
46
|
fov_interval: int = 10,
|
|
20
|
-
input_units: str =
|
|
21
|
-
display_units: str =
|
|
22
|
-
planet: str =
|
|
47
|
+
input_units: str = DEFAULT_UNITS, # how to interpret altitude numbers
|
|
48
|
+
display_units: str = DEFAULT_UNITS, # how to print areas/radii
|
|
49
|
+
planet: str = DEFAULT_PLANET,
|
|
23
50
|
printit: bool = False
|
|
24
51
|
):
|
|
25
52
|
"""
|
|
@@ -27,9 +54,9 @@ def analyze_visible_surface(
|
|
|
27
54
|
Results are printed in `display_units`.
|
|
28
55
|
"""
|
|
29
56
|
# Planet radius and full area (compute in meters, convert for display)
|
|
30
|
-
r_m = planet_radius(planet,
|
|
57
|
+
r_m = planet_radius(planet, DEFAULT_UNITS)
|
|
31
58
|
full_area_m2 = 4.0 * math.pi * (r_m ** 2)
|
|
32
|
-
k_disp = dfactor(
|
|
59
|
+
k_disp = dfactor(DEFAULT_UNITS, display_units) # linear meter->display factor
|
|
33
60
|
full_area_disp = full_area_m2 * (k_disp ** 2) # convert area to display units^2
|
|
34
61
|
|
|
35
62
|
all_stats = {"output": "", "input_units": input_units,
|
|
@@ -38,7 +65,7 @@ def analyze_visible_surface(
|
|
|
38
65
|
for i in range(1, max_steps + 1):
|
|
39
66
|
all_stats["vars"].append({})
|
|
40
67
|
altitude_in = altitude_step * i # input_units
|
|
41
|
-
altitude_m = dconvert(altitude_in, input_units,
|
|
68
|
+
altitude_m = dconvert(altitude_in, input_units, DEFAULT_UNITS)
|
|
42
69
|
|
|
43
70
|
all_stats["vars"][-1]['altitude_input'] = altitude_in
|
|
44
71
|
all_stats["vars"][-1]['input_units'] = input_units
|
|
@@ -51,9 +78,9 @@ def analyze_visible_surface(
|
|
|
51
78
|
|
|
52
79
|
for fov in range(fov_range[0], fov_range[1] + 1, fov_interval):
|
|
53
80
|
# Compute visible area/radius in meters, convert to display units
|
|
54
|
-
area_m2, vis_radius_m = visible_area_flat(fov, altitude_m,
|
|
81
|
+
area_m2, vis_radius_m = visible_area_flat(fov, altitude_m, DEFAULT_UNITS)
|
|
55
82
|
area_disp = area_m2 * (k_disp ** 2)
|
|
56
|
-
vis_radius_disp = dconvert(vis_radius_m,
|
|
83
|
+
vis_radius_disp = dconvert(vis_radius_m, DEFAULT_UNITS, display_units)
|
|
57
84
|
|
|
58
85
|
# Span uses geometry only; r_m is in meters
|
|
59
86
|
_, angle_deg = visible_surface_angle(vis_radius_m, r_m)
|
|
@@ -81,161 +108,146 @@ def analyze_visible_surface(
|
|
|
81
108
|
if printit:
|
|
82
109
|
print(all_stats.get('output'))
|
|
83
110
|
return all_stats
|
|
111
|
+
# --- core integrator step ---
|
|
112
|
+
def calculate_avrt(mu, v, r, t=0.0, dt_s=1.0, steps=0):
|
|
113
|
+
"""Single Euler step update for radial motion."""
|
|
114
|
+
a = - div(mu, mul(r, r)) # inward accel
|
|
115
|
+
v = add(v, mul(a, dt_s))
|
|
116
|
+
r = add(r, mul(v, dt_s))
|
|
117
|
+
t = add(t, dt_s)
|
|
118
|
+
steps += 1
|
|
119
|
+
return v, r, t, steps
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# --- tracker helper ---
|
|
123
|
+
def init_tracker(r0: float) -> dict:
|
|
124
|
+
"""Initialize stats tracker."""
|
|
125
|
+
return {
|
|
126
|
+
"furthest_r": r0,
|
|
127
|
+
"time_at_furthest": 0.0,
|
|
128
|
+
"furthest_step": 0,
|
|
129
|
+
"total_distance": 0.0,
|
|
130
|
+
}
|
|
84
131
|
|
|
85
132
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
start_altitude: float,
|
|
89
|
-
start_units: str,
|
|
133
|
+
# --- SI integrator with tracking ---
|
|
134
|
+
def simulate_radial_flight_si(
|
|
90
135
|
v0_mps: float,
|
|
136
|
+
start_alt_m: float,
|
|
137
|
+
planet: str,
|
|
91
138
|
dt_s: float = 1.0,
|
|
92
139
|
max_steps: int = 5_000_000,
|
|
93
|
-
|
|
140
|
+
target_alt_m: float = None
|
|
94
141
|
) -> dict:
|
|
95
|
-
"""
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
"""
|
|
99
|
-
if not (isinstance(start_altitude, (int, float)) and start_altitude >= 0):
|
|
100
|
-
return {"ok": False, "error": "Invalid start_altitude", "steps": 0}
|
|
101
|
-
if not (isinstance(v0_mps, (int, float)) and math.isfinite(v0_mps)):
|
|
102
|
-
return {"ok": False, "error": "Invalid starting_velocity (after unit conversion)", "steps": 0}
|
|
103
|
-
if not (dt_s > 0):
|
|
104
|
-
return {"ok": False, "error": "dt_s must be > 0", "steps": 0}
|
|
105
|
-
|
|
106
|
-
body = get_body(planet)
|
|
107
|
-
mu = body["mu"]
|
|
108
|
-
R = body["radius"]
|
|
109
|
-
|
|
110
|
-
r0 = add(R, dconvert(start_altitude, start_units, "meters"))
|
|
142
|
+
"""Forward-Euler radial integrator, SI only (meters/seconds)."""
|
|
143
|
+
R, mu = get_R_mu(planet=planet)
|
|
144
|
+
r0 = add(R, start_alt_m)
|
|
111
145
|
r = r0
|
|
112
|
-
v = v0_mps
|
|
146
|
+
v = v0_mps
|
|
113
147
|
t = 0.0
|
|
148
|
+
prev_r = r0
|
|
149
|
+
r_target = add(R, target_alt_m) if target_alt_m else float("inf")
|
|
150
|
+
traveled_m = 0.0
|
|
114
151
|
|
|
115
|
-
|
|
116
|
-
r_target = add(R, target_altitude_m if has_target else float("inf"))
|
|
117
|
-
|
|
118
|
-
hit_surface = False
|
|
119
|
-
hit_target = False
|
|
120
|
-
turned_back_below_start = False
|
|
121
|
-
|
|
152
|
+
hit_surface, hit_target, turned_back = False, False, False
|
|
122
153
|
steps = 0
|
|
154
|
+
tracker = init_tracker(r0)
|
|
155
|
+
|
|
123
156
|
for _ in range(max_steps):
|
|
124
157
|
if r <= R:
|
|
125
158
|
hit_surface = True
|
|
126
159
|
break
|
|
127
|
-
if
|
|
160
|
+
if target_alt_m and r >= r_target:
|
|
128
161
|
hit_target = True
|
|
129
162
|
break
|
|
130
163
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
164
|
+
v, r, t, steps = calculate_avrt(mu, v, r, t, dt_s, steps)
|
|
165
|
+
|
|
166
|
+
# update traveled distance
|
|
167
|
+
traveled_step = abs(r - prev_r)
|
|
168
|
+
traveled_m += traveled_step
|
|
169
|
+
tracker["total_distance"] += traveled_step
|
|
170
|
+
prev_r = r
|
|
136
171
|
|
|
137
|
-
|
|
138
|
-
|
|
172
|
+
# update furthest distance tracker
|
|
173
|
+
if r > tracker["furthest_r"]:
|
|
174
|
+
tracker["furthest_r"] = r
|
|
175
|
+
tracker["time_at_furthest"] = t
|
|
176
|
+
tracker["furthest_step"] = steps
|
|
177
|
+
|
|
178
|
+
# detect turnaround
|
|
179
|
+
if not target_alt_m and v < 0 and r < r0:
|
|
180
|
+
turned_back = True
|
|
139
181
|
break
|
|
140
182
|
|
|
141
183
|
altitude_m = max(0.0, r - R)
|
|
142
184
|
g_end = g_at_radius(mu, r)
|
|
143
185
|
g_surface = g_at_radius(mu, R)
|
|
144
|
-
traveled_m = max(0.0, altitude_m - (r0 - R))
|
|
145
186
|
|
|
146
187
|
return {
|
|
147
188
|
"ok": True,
|
|
148
189
|
"planet": planet,
|
|
149
|
-
"
|
|
190
|
+
"r_m": r,
|
|
150
191
|
"altitude_m": altitude_m,
|
|
151
192
|
"vEnd_mps": v,
|
|
152
193
|
"time_s": t,
|
|
153
|
-
"
|
|
154
|
-
"
|
|
194
|
+
"g_end_mps2": g_end,
|
|
195
|
+
"g_ratio_surface": div(g_end, g_surface),
|
|
155
196
|
"steps": steps,
|
|
156
|
-
"
|
|
157
|
-
"
|
|
158
|
-
"
|
|
197
|
+
"hit_surface": hit_surface,
|
|
198
|
+
"hit_target": hit_target,
|
|
199
|
+
"turned_back": turned_back,
|
|
159
200
|
"traveled_m": traveled_m,
|
|
160
|
-
"
|
|
201
|
+
"vesc_end_mps": math.sqrt(mul(2.0, div(mu, r))),
|
|
202
|
+
|
|
203
|
+
# extended stats
|
|
204
|
+
"furthest_r": tracker["furthest_r"],
|
|
205
|
+
"furthest_altitude_m": tracker["furthest_r"] - R,
|
|
206
|
+
"time_at_furthest": tracker["time_at_furthest"],
|
|
207
|
+
"total_distance_m": tracker["total_distance"],
|
|
161
208
|
}
|
|
162
209
|
|
|
163
210
|
|
|
211
|
+
# --- wrapper with unit conversions ---
|
|
164
212
|
def radial_travel(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
input_units: str =
|
|
168
|
-
input_time: str =
|
|
169
|
-
output_units: str =
|
|
170
|
-
output_time: str =
|
|
171
|
-
planet: str = "earth",
|
|
213
|
+
starting_velocity: float = None,
|
|
214
|
+
start_altitude: float = None,
|
|
215
|
+
input_units: str = DEFAULT_UNITS,
|
|
216
|
+
input_time: str = DEFAULT_TIME,
|
|
217
|
+
output_units: str = DEFAULT_UNITS,
|
|
218
|
+
output_time: str = DEFAULT_TIME,
|
|
172
219
|
*,
|
|
220
|
+
planet: str = DEFAULT_PLANET,
|
|
173
221
|
dt_s: float = 1.0,
|
|
174
222
|
max_steps: int = 5_000_000,
|
|
175
|
-
target_distance:
|
|
223
|
+
target_distance: float = None
|
|
176
224
|
) -> dict:
|
|
177
|
-
"""
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
"""
|
|
183
|
-
|
|
184
|
-
v0_mps = normalized_velocity_conversioin(starting_velocity, input_time, input_units)
|
|
185
|
-
|
|
186
|
-
# Optional target altitude (to meters)
|
|
187
|
-
target_alt_m = None
|
|
188
|
-
if target_distance is not None:
|
|
189
|
-
target_alt_m = dconvert(target_distance, input_units, "meters")
|
|
225
|
+
"""Wrapper: handles units, runs SI integrator, converts outputs."""
|
|
226
|
+
norm = normalize_inputs(
|
|
227
|
+
planet=planet, start_altitude=start_altitude, starting_velocity=starting_velocity,
|
|
228
|
+
input_units=input_units, input_time=input_time, target_distance=target_distance
|
|
229
|
+
)
|
|
190
230
|
|
|
191
|
-
|
|
192
|
-
|
|
231
|
+
sim = simulate_radial_flight_si(
|
|
232
|
+
v0_mps=norm["v0_mps"],
|
|
233
|
+
start_alt_m=norm["start_alt_m"],
|
|
193
234
|
planet=planet,
|
|
194
|
-
start_altitude=start_distance,
|
|
195
|
-
start_units=input_units,
|
|
196
|
-
v0_mps=v0_mps,
|
|
197
235
|
dt_s=dt_s,
|
|
198
236
|
max_steps=max_steps,
|
|
199
|
-
|
|
237
|
+
target_alt_m=norm["target_alt_m"],
|
|
200
238
|
)
|
|
201
|
-
|
|
202
|
-
if not sim.get("ok", False):
|
|
239
|
+
if not sim.get("ok"):
|
|
203
240
|
return sim
|
|
204
241
|
|
|
205
|
-
#
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
trav_out = dconvert(sim["traveled_m"], "meters", output_units)
|
|
209
|
-
|
|
210
|
-
# Velocity output: (output_units)/(output_time)
|
|
211
|
-
sec_per_out = seconds_per(output_time) # sec / out_timeunit
|
|
212
|
-
v_units_per_sec_out = dconvert(sim["vEnd_mps"], "meters", output_units)
|
|
213
|
-
v_out = mul(v_units_per_sec_out, sec_per_out)
|
|
214
|
-
|
|
215
|
-
# Escape velocity at end
|
|
216
|
-
vesc_units_per_sec_out = dconvert(sim["vEsc_end_mps"], "meters", output_units)
|
|
217
|
-
vesc_end_out = mul(vesc_units_per_sec_out, sec_per_out)
|
|
218
|
-
|
|
219
|
-
# Escape velocity at destination (if provided)
|
|
220
|
-
body = get_body(planet)
|
|
221
|
-
mu = body["mu"]; R = body["radius"]
|
|
222
|
-
destination_radius_m = None
|
|
223
|
-
vesc_dest_out = None
|
|
224
|
-
if target_alt_m is not None:
|
|
225
|
-
destination_radius_m = add(R, target_alt_m)
|
|
226
|
-
vesc_dest_mps = math.sqrt(mul(2.0, div(mu, destination_radius_m)))
|
|
227
|
-
vesc_dest_units_per_sec = dconvert(vesc_dest_mps, "meters", output_units)
|
|
228
|
-
vesc_dest_out = mul(vesc_dest_units_per_sec, sec_per_out)
|
|
229
|
-
|
|
230
|
-
# Time output in requested unit
|
|
231
|
-
t_out = div(sim["time_s"], sec_per_out)
|
|
232
|
-
t_label = output_time if output_time in ("s", "sec", "seconds", "m", "min", "minutes", "h", "hr", "hours") else "s"
|
|
242
|
+
# Output conversions
|
|
243
|
+
sec_per_out = seconds_per(output_time)
|
|
244
|
+
conv = lambda m: dconvert(m, DEFAULT_UNITS, output_units)
|
|
233
245
|
|
|
234
246
|
return {
|
|
235
247
|
"ok": True,
|
|
236
248
|
"planet": planet,
|
|
237
249
|
"inputs": {
|
|
238
|
-
"
|
|
250
|
+
"start_altitude": start_altitude,
|
|
239
251
|
"starting_velocity": starting_velocity,
|
|
240
252
|
"input_units": input_units,
|
|
241
253
|
"input_time": input_time,
|
|
@@ -243,21 +255,25 @@ def radial_travel(
|
|
|
243
255
|
"output_time": output_time,
|
|
244
256
|
"target_distance": target_distance,
|
|
245
257
|
},
|
|
246
|
-
|
|
247
|
-
"
|
|
248
|
-
"
|
|
249
|
-
"
|
|
250
|
-
"
|
|
251
|
-
"
|
|
252
|
-
"
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
"
|
|
256
|
-
"time_unit": t_label,
|
|
257
|
-
"g_end_mps2": sim["gAtEnd_mps2"], # keep SI precise for g
|
|
258
|
-
"g_ratio_surface": sim["gRatioSurface"],
|
|
258
|
+
# final state
|
|
259
|
+
"altitude": conv(sim["altitude_m"]),
|
|
260
|
+
"radius_from_center": conv(sim["r_m"]),
|
|
261
|
+
"distance_traveled": conv(sim["traveled_m"]),
|
|
262
|
+
"velocity": mul(dconvert(sim["vEnd_mps"], DEFAULT_UNITS, output_units), sec_per_out),
|
|
263
|
+
"velocity_escape_end": mul(dconvert(sim["vesc_end_mps"], DEFAULT_UNITS, output_units), sec_per_out),
|
|
264
|
+
"time": div(sim["time_s"], sec_per_out),
|
|
265
|
+
"time_unit": output_time,
|
|
266
|
+
"g_end_mps2": sim["g_end_mps2"],
|
|
267
|
+
"g_ratio_surface": sim["g_ratio_surface"],
|
|
259
268
|
"steps": sim["steps"],
|
|
260
|
-
"hit_surface": sim["
|
|
261
|
-
"hit_target": sim["
|
|
262
|
-
"
|
|
269
|
+
"hit_surface": sim["hit_surface"],
|
|
270
|
+
"hit_target": sim["hit_target"],
|
|
271
|
+
"turned_back": sim["turned_back"],
|
|
272
|
+
|
|
273
|
+
# extended stats (converted)
|
|
274
|
+
"furthest_distance": conv(sim["furthest_altitude_m"]),
|
|
275
|
+
"furthest_radius": conv(sim["furthest_r"]),
|
|
276
|
+
"time_at_furthest": div(sim["time_at_furthest"], sec_per_out),
|
|
277
|
+
"total_distance": conv(sim["total_distance_m"]),
|
|
263
278
|
}
|
|
279
|
+
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
from .distance_constants import (
|
|
3
3
|
DISTANCE_CONVERSIONS, ALL_DISTANCE_UNITS,
|
|
4
4
|
normalize_distance_unit, get_distance_unit_conversions,
|
|
5
|
-
_factor,
|
|
5
|
+
_factor, dconvert,DEFAULT_UNITS,DEFAULT_START_ALTITUDE
|
|
6
6
|
)
|
|
7
7
|
from .time_constants import (
|
|
8
8
|
TIME_CONVERSIONS, ALL_TIME_UNITS,
|
|
9
9
|
normalize_time_unit, get_time_unit_conversions,
|
|
10
|
-
time_factor, convert_time, seconds_per,
|
|
10
|
+
time_factor, convert_time, seconds_per,DEFAULT_TIME
|
|
11
11
|
)
|
|
12
12
|
from .planet_constants import (
|
|
13
13
|
PLANETS, G, g0, MU_MOON,
|
|
@@ -15,5 +15,5 @@ from .planet_constants import (
|
|
|
15
15
|
full_planet_surface_area, planet_volume, planet_circumference,
|
|
16
16
|
planet_mass, planet_surface_g, escape_velocity,
|
|
17
17
|
earth_radius, earth_diameter, full_earth_surface_area,
|
|
18
|
-
earth_volume, earth_circumference,
|
|
18
|
+
earth_volume, earth_circumference,DEFAULT_PLANET,DEFAULT_AS_RADIUS
|
|
19
19
|
)
|
|
@@ -19,6 +19,8 @@ DISTANCE_CONVERSIONS: Dict[str, Dict[str, Dict[str, float]]] = {
|
|
|
19
19
|
"feet": FEET
|
|
20
20
|
}
|
|
21
21
|
ALL_DISTANCE_UNITS = ("meters", "kilometers", "miles", "feet")
|
|
22
|
+
DEFAULT_UNITS="meters"
|
|
23
|
+
DEFAULT_START_ALTITUDE=0.0
|
|
22
24
|
# -------------------------
|
|
23
25
|
# Unit helpers
|
|
24
26
|
# -------------------------
|
|
@@ -41,5 +43,27 @@ def _factor(unit_from: str, unit_to: str) -> float:
|
|
|
41
43
|
ut = get_distance_unit_conversions(unit_to)["conv"]["meters"] # meters per 1 to-unit
|
|
42
44
|
return div(uf, ut)
|
|
43
45
|
|
|
44
|
-
def
|
|
46
|
+
def dconvert(value: float, unit_from: str, unit_to: str) -> float:
|
|
45
47
|
return mul(value, _factor(unit_from, unit_to))
|
|
48
|
+
def get_normalized_distance(
|
|
49
|
+
distance: Optional[float] = None,
|
|
50
|
+
input_units: str = DEFAULT_UNITS
|
|
51
|
+
):
|
|
52
|
+
distance = target_alt_m = distance or 0
|
|
53
|
+
if distance is not None:
|
|
54
|
+
target_alt_m = dconvert(value=distance,
|
|
55
|
+
unit_from=input_units,
|
|
56
|
+
unit_to=DEFAULT_UNITS
|
|
57
|
+
)
|
|
58
|
+
return target_alt_m
|
|
59
|
+
def get_target_distance(
|
|
60
|
+
distance: Optional[float] = None,
|
|
61
|
+
input_units: str = DEFAULT_UNITS,
|
|
62
|
+
output_units: str = DEFAULT_UNITS,
|
|
63
|
+
):
|
|
64
|
+
distance = target_distance = distance or 0
|
|
65
|
+
if distance is not None:
|
|
66
|
+
target_distance = dconvert(value=distance,
|
|
67
|
+
unit_from=input_units,
|
|
68
|
+
unit_to=output_units)
|
|
69
|
+
return target_distance
|
|
@@ -28,7 +28,8 @@ PLANETS = [
|
|
|
28
28
|
{ "name":'Neptune',"m0_deg":-55.12002969,"mu":6.83653e15,"a":4.4983964e12,"e":0.00859048,"radiusPx":10,"color":'#4363d8',"radius":24764000,"escapeVel":23500,"n":8,"peri_lon_deg":44.96476227 },
|
|
29
29
|
{ "name":'Moon',"m0_deg":0,"mu":MU_MOON,"a":3.844e8,"e":0.0549,"radiusPx":5,"color":'lightgray',"radius":1.737e6,"escapeVel":2380,"n":9}
|
|
30
30
|
]
|
|
31
|
-
|
|
31
|
+
DEFAULT_PLANET='earth'
|
|
32
|
+
DEFAULT_AS_RADIUS=False
|
|
32
33
|
# -------------------------
|
|
33
34
|
# Body enrichment + lookup
|
|
34
35
|
# -------------------------
|
|
@@ -46,7 +47,7 @@ def _enrich_body(b: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
46
47
|
|
|
47
48
|
_NAME_ALIASES = {"sol": "sun", "terra": "earth", "luna": "moon"}
|
|
48
49
|
def _normalize_name(name: str) -> str:
|
|
49
|
-
n = name.
|
|
50
|
+
n = name.lower()
|
|
50
51
|
return _NAME_ALIASES.get(n, n)
|
|
51
52
|
|
|
52
53
|
_BODY_BY_NAME: Dict[str, Dict[str, Any]] = {}
|
|
@@ -154,3 +155,9 @@ def get_body(planet: str) -> Dict[str, Any]:
|
|
|
154
155
|
|
|
155
156
|
def g_at_radius(mu: float, r_m: float) -> float:
|
|
156
157
|
return div(mu, mul(r_m, r_m))
|
|
158
|
+
|
|
159
|
+
def get_R_mu(planet: str = DEFAULT_PLANET):
|
|
160
|
+
body = get_body(planet)
|
|
161
|
+
mu = body.get("mu") # m^3/s^2
|
|
162
|
+
R = body.get("radius") # m
|
|
163
|
+
return R,mu
|
|
@@ -1,30 +1,78 @@
|
|
|
1
1
|
# src/utils/escape_velocity.py
|
|
2
2
|
from ..imports import math, mul, div, add
|
|
3
|
-
from ..constants
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
from ..constants import (
|
|
4
|
+
DEFAULT_UNITS,
|
|
5
|
+
DEFAULT_TIME,
|
|
6
|
+
DEFAULT_PLANET,
|
|
7
|
+
DEFAULT_START_ALTITUDE,
|
|
8
|
+
DEFAULT_AS_RADIUS
|
|
9
|
+
)
|
|
10
|
+
from ..constants.planet_constants import get_body,get_R_mu
|
|
11
|
+
from ..constants.distance_constants import dconvert,get_target_distance,get_normalized_distance
|
|
12
|
+
from ..constants.time_constants import get_time_unit_conversions, normalize_time_unit, seconds_per
|
|
13
|
+
from .velocity_utils import normalized_velocity_conversioin
|
|
14
|
+
def get_r_m(planet: str = DEFAULT_PLANET,start_altitude: float = DEFAULT_START_ALTITUDE,input_units: str = DEFAULT_UNITS,as_radius:bool = DEFAULT_AS_RADIUS):
|
|
15
|
+
R,mu = get_R_mu(planet=planet)
|
|
16
|
+
r_m = dconvert(start_altitude, input_units, DEFAULT_UNITS)
|
|
17
|
+
# Determine radius from center in meters
|
|
18
|
+
if not as_radius:
|
|
19
|
+
r_m = add(R, r_m)
|
|
20
|
+
if r_m <= 0:
|
|
21
|
+
return {"ok": False, "error": "computed radius is non-positive"}
|
|
22
|
+
return r_m
|
|
23
|
+
def get_vesc_mps(
|
|
24
|
+
planet: str = DEFAULT_PLANET,
|
|
25
|
+
start_altitude: float = DEFAULT_START_ALTITUDE,
|
|
26
|
+
input_units: str = DEFAULT_UNITS,
|
|
27
|
+
as_radius:bool = DEFAULT_AS_RADIUS
|
|
28
|
+
):
|
|
29
|
+
R,mu = get_R_mu(planet=planet)
|
|
30
|
+
r_m = get_r_m(planet=planet,start_altitude=start_altitude,input_units=input_units,as_radius=as_radius)
|
|
31
|
+
vesc_mps = math.sqrt(mul(2.0, div(mu, r_m)))
|
|
32
|
+
return vesc_mps
|
|
33
|
+
|
|
6
34
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
35
|
+
|
|
36
|
+
def get_normalized_starting_velocity(
|
|
37
|
+
start_altitude: float = None,
|
|
38
|
+
starting_velocity: float = None,
|
|
39
|
+
input_units: str = DEFAULT_UNITS, # distance part of starting_velocity & start_distance
|
|
40
|
+
input_time: str = DEFAULT_TIME, # time part of starting_velocity
|
|
41
|
+
output_units: str = DEFAULT_UNITS,
|
|
42
|
+
output_time: str = DEFAULT_TIME,
|
|
43
|
+
planet: str = DEFAULT_PLANET
|
|
44
|
+
):
|
|
45
|
+
start_altitude = start_altitude or 0
|
|
46
|
+
if starting_velocity == None:
|
|
47
|
+
starting_velocity = escape_velocity_at(planet=planet,
|
|
48
|
+
start_altitude=start_altitude,
|
|
49
|
+
input_time=input_time,
|
|
50
|
+
input_units=input_units,
|
|
51
|
+
output_time=input_time,
|
|
52
|
+
output_units=input_units
|
|
53
|
+
)
|
|
54
|
+
return normalized_velocity_conversioin(
|
|
55
|
+
velocity=starting_velocity,
|
|
56
|
+
input_time=input_time,
|
|
57
|
+
input_units=input_units
|
|
58
|
+
)
|
|
12
59
|
|
|
13
60
|
def escape_velocity_at(
|
|
14
|
-
planet: str =
|
|
15
|
-
|
|
61
|
+
planet: str = DEFAULT_PLANET,
|
|
62
|
+
start_altitude: float = DEFAULT_START_ALTITUDE,
|
|
16
63
|
*,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
64
|
+
input_time: str = DEFAULT_TIME, # how to interpret `distance`
|
|
65
|
+
input_units: str = DEFAULT_UNITS, # how to interpret `distance`
|
|
66
|
+
output_units: str = DEFAULT_UNITS, # distance unit for the *speed*
|
|
67
|
+
output_time: str = DEFAULT_TIME, # time unit for the *speed*
|
|
68
|
+
as_radius: bool = DEFAULT_AS_RADIUS # False => `distance` is altitude above surface; True => radius from center
|
|
21
69
|
) -> dict:
|
|
22
70
|
"""
|
|
23
71
|
Compute v_escape at a given location around `planet`.
|
|
24
72
|
|
|
25
73
|
Args:
|
|
26
74
|
planet: body name (must exist in PLANETS)
|
|
27
|
-
|
|
75
|
+
start_altitude: if as_radius=False => altitude above surface; if as_radius=True => radius from center
|
|
28
76
|
input_units: units of `distance`
|
|
29
77
|
output_units: distance unit of the returned speed
|
|
30
78
|
output_time: time unit of the returned speed ('s'|'min'|'h' etc.)
|
|
@@ -40,33 +88,18 @@ def escape_velocity_at(
|
|
|
40
88
|
"units": {"distance": output_units, "time": output_time}
|
|
41
89
|
}
|
|
42
90
|
"""
|
|
43
|
-
if not (isinstance(
|
|
91
|
+
if not (isinstance(start_altitude, (int, float)) and math.isfinite(start_altitude) and start_altitude >= 0):
|
|
44
92
|
return {"ok": False, "error": "distance must be a non-negative number"}
|
|
45
|
-
|
|
46
|
-
body = get_body(planet)
|
|
47
|
-
mu = body["mu"] # m^3/s^2
|
|
48
|
-
R = body["radius"] # m
|
|
49
|
-
|
|
50
|
-
# Determine radius from center in meters
|
|
51
|
-
if as_radius:
|
|
52
|
-
r_m = dconvert(distance, input_units, "meters")
|
|
53
|
-
else:
|
|
54
|
-
alt_m = dconvert(distance, input_units, "meters")
|
|
55
|
-
r_m = add(R, alt_m)
|
|
56
|
-
|
|
57
|
-
if r_m <= 0:
|
|
58
|
-
return {"ok": False, "error": "computed radius is non-positive"}
|
|
59
|
-
|
|
93
|
+
R,mu = get_R_mu(planet=planet)
|
|
60
94
|
# v_esc (m/s)
|
|
61
|
-
|
|
62
|
-
|
|
95
|
+
r_m = get_r_m(planet=planet,start_altitude=start_altitude,input_units=input_units,as_radius=as_radius)
|
|
96
|
+
vesc_mps = get_vesc_mps(planet=planet,start_altitude=start_altitude,input_units=input_units,as_radius=as_radius)
|
|
63
97
|
# Convert speed to <output_units>/<output_time>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
vesc_out = mul(
|
|
67
|
-
|
|
98
|
+
vesc_units_per_time = dconvert(vesc_mps, DEFAULT_UNITS, output_units)
|
|
99
|
+
time_per = seconds_per(output_time) # seconds per 1 output_time
|
|
100
|
+
vesc_out = mul(vesc_units_per_time, time_per) # <output_units>/<output_time>
|
|
68
101
|
# Also return the radius in output_units for convenience
|
|
69
|
-
r_out = dconvert(r_m,
|
|
102
|
+
r_out = dconvert(r_m, DEFAULT_UNITS, output_units)
|
|
70
103
|
|
|
71
104
|
return {
|
|
72
105
|
"ok": True,
|
|
@@ -24,3 +24,29 @@ def mps_to_distance_per_time(v_mps: float, dist_units: str, time_units: str) ->
|
|
|
24
24
|
v_units_per_sec = div(v_mps, meters_per_unit) # [dist_units / s]
|
|
25
25
|
sec_per_time = seconds_per(time_units)
|
|
26
26
|
return mul(v_units_per_sec, sec_per_time) # [dist_units / time_units]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def get_velocity_conversioin(
|
|
32
|
+
velocity,
|
|
33
|
+
input_time: str = DEFAULT_TIME,
|
|
34
|
+
input_units: str = DEFAULT_UNITS,
|
|
35
|
+
output_units: str = DEFAULT_UNITS,
|
|
36
|
+
output_time: str = DEFAULT_TIME,
|
|
37
|
+
):
|
|
38
|
+
v0_mps = distance_per_time_to_mps(v=velocity, dist_units=input_units, time_units=input_time)
|
|
39
|
+
v0_unit_p_time = mps_to_distance_per_time(v_mps=v0_mps, dist_units=output_units, time_units=output_time)
|
|
40
|
+
return v0_unit_p_time
|
|
41
|
+
|
|
42
|
+
def normalized_velocity_conversioin(
|
|
43
|
+
velocity,
|
|
44
|
+
input_time: str = DEFAULT_TIME,
|
|
45
|
+
input_units: str = DEFAULT_UNITS
|
|
46
|
+
):
|
|
47
|
+
v0_mps = get_velocity_conversioin(
|
|
48
|
+
velocity=velocity,
|
|
49
|
+
input_time=input_time,
|
|
50
|
+
input_units=input_units
|
|
51
|
+
)
|
|
52
|
+
return v0_mps
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
abstract_math/__init__.py,sha256=wr-kwaB8micSsR1nCHuDXRlsL59DWlqZQFN7M_rfZys,80
|
|
2
|
+
abstract_math/createflask.py,sha256=M66B9Da9m2aQmZRaEtKf9sH3UH1ARd6_OdJPzw17sNM,214
|
|
2
3
|
abstract_math/derive_tokens.py,sha256=mVzwkLv1Jo76R-SGR0hZbO5MPOr7vZpDC44eyxUvfzU,4585
|
|
3
4
|
abstract_math/safe_math.py,sha256=9T1-n6dcMYzJtem8xEIGEKOLR5X4DOIj_h9aotvyzdE,7347
|
|
4
5
|
abstract_math/flask_scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
abstract_math/flask_scripts/flask_utils.py,sha256=
|
|
6
|
+
abstract_math/flask_scripts/flask_utils.py,sha256=bXF4PS1qJ1SDA2w6ecNHK1A3FmN4P-F2U6l6wPwhZgE,28511
|
|
6
7
|
abstract_math/solar_math/__init__.py,sha256=FfPkmWi3cQ3BLvUUUf6k22rGBE8scDL1EoM5l24biVo,39
|
|
7
8
|
abstract_math/solar_math/flask_utils.py,sha256=c82LrZ0dKC3Y8LxqOs1zDR6gRy8oXSx9balBD18gNB0,459
|
|
8
|
-
abstract_math/solar_math/main.py,sha256=
|
|
9
|
+
abstract_math/solar_math/main.py,sha256=Dbwt0MKO8o5SwnkT9ejdIjf7e7PpzXTH7H9PrWAz3L0,9610
|
|
9
10
|
abstract_math/solar_math/src/__init__.py,sha256=qeal73F-NLu6sO_YSmD_komVpe17f0OFy2IfBR2QU_s,70
|
|
10
11
|
abstract_math/solar_math/src/imports.py,sha256=UZp2SkF8INamFVwLOIca6w9K-YKXsqhiqcf6bkWuLVo,181
|
|
11
|
-
abstract_math/solar_math/src/constants/__init__.py,sha256=
|
|
12
|
-
abstract_math/solar_math/src/constants/distance_constants.py,sha256=
|
|
13
|
-
abstract_math/solar_math/src/constants/planet_constants.py,sha256=
|
|
14
|
-
abstract_math/solar_math/src/constants/time_constants.py,sha256=
|
|
12
|
+
abstract_math/solar_math/src/constants/__init__.py,sha256=OmUwgtbnjcFC2NBLTIypQ6v-DwdOEmSu1u4h-WgifAQ,772
|
|
13
|
+
abstract_math/solar_math/src/constants/distance_constants.py,sha256=1TM_dzo0semwZkk5kveRljzPYN0ry5yNCmwORks4yUs,2793
|
|
14
|
+
abstract_math/solar_math/src/constants/planet_constants.py,sha256=GcJobNn5hYEJAGtdfrAgqy-3h0HOE-HzoivCQS7mJU8,6809
|
|
15
|
+
abstract_math/solar_math/src/constants/time_constants.py,sha256=i1gMbymsAkF23YwF4KGwEPpNuwNp1n5MCb4ALHdjxnU,1890
|
|
15
16
|
abstract_math/solar_math/src/utils/__init__.py,sha256=Vb2bfx1p9YSmhnbqXBjGVPt1OQZ9I7PG_fMQdFqj-3k,91
|
|
16
|
-
abstract_math/solar_math/src/utils/escape_velocity.py,sha256=
|
|
17
|
+
abstract_math/solar_math/src/utils/escape_velocity.py,sha256=nngwySzxqB7JOV1RLRHKj6O3v4O45yOIkV3lVchPdGg,4926
|
|
17
18
|
abstract_math/solar_math/src/utils/geometry_utils.py,sha256=Ij4mASNFp2-CWy425fxMTEuMPuAZHs-E0qvi3BjaNkk,4169
|
|
18
|
-
abstract_math/solar_math/src/utils/velocity_utils.py,sha256=
|
|
19
|
-
abstract_math-0.0.0.
|
|
20
|
-
abstract_math-0.0.0.
|
|
21
|
-
abstract_math-0.0.0.
|
|
22
|
-
abstract_math-0.0.0.
|
|
19
|
+
abstract_math/solar_math/src/utils/velocity_utils.py,sha256=eiXstQ3PF0KAUamSFOHFIL1chyWweygdTyvBjQB_DXo,1888
|
|
20
|
+
abstract_math-0.0.0.25.dist-info/METADATA,sha256=LraZOrilfTFHwpL7xHfCIp2qz4Aj0umUjTb3VKLXV1w,3081
|
|
21
|
+
abstract_math-0.0.0.25.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
22
|
+
abstract_math-0.0.0.25.dist-info/top_level.txt,sha256=b7jOgD9c0U-CGH-l7yxhMPukzD40kMEQkQRV_sGyVfE,14
|
|
23
|
+
abstract_math-0.0.0.25.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|