abstract-math 0.0.0.24__py3-none-any.whl → 0.0.0.26__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.
@@ -0,0 +1,4 @@
1
+ from abstract_flask.generator import *
2
+ directory = "/home/computron/Documents/pythonTools/modules/abstract_math/src/abstract_math/solar_math"
3
+ from_files = generate_from_files(directory=directory)
4
+ input(from_files)
@@ -1,7 +1,7 @@
1
1
  from abstract_flask import * # must provide Blueprint, request, jsonify, get_request_data, get_logFile, offer_help
2
2
  from ..solar_math import *
3
3
  # Auto-generated routes
4
- math_data_bp = Blueprint('math_data_bp', __name__, url_prefix='/utils')
4
+ math_data_bp = Blueprint('math_data_bp', __name__, url_prefix='/utils/')
5
5
  logger = get_logFile('math_data_bp')
6
6
 
7
7
  @math_data_bp.route("/normalized_velocity_conversioin", methods=["GET", "POST"], strict_slashes=False)
@@ -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 convert as dconvert, _factor as dfactor
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
- def normalized_velocity_conversioin(starting_velocity, input_time, input_units):
9
- sec_per_time = seconds_per(input_time) # sec / timeunit
10
- v_units_per_sec = div(starting_velocity, sec_per_time) # <input_units> / s
11
- v0_mps = dconvert(v_units_per_sec, input_units, "meters") # m / s
12
- return v0_mps
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 = 'meters', # how to interpret altitude numbers
21
- display_units: str = 'meters', # how to print areas/radii
22
- planet: str = 'earth',
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, 'meters')
57
+ r_m = planet_radius(planet, DEFAULT_UNITS)
31
58
  full_area_m2 = 4.0 * math.pi * (r_m ** 2)
32
- k_disp = dfactor('meters', display_units) # linear meter->display factor
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, 'meters')
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, 'meters')
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, 'meters', display_units)
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
- def simulate_radial_flight(
87
- planet: str,
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
- target_altitude_m: Optional[float] = None
140
+ target_alt_m: float = None
94
141
  ) -> dict:
95
- """
96
- Forward-Euler radial integrator (toy model).
97
- Returns a dict with SI (meters, seconds) internal results.
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 # outward positive, m/s
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
- has_target = target_altitude_m is not None and target_altitude_m > 0
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 has_target and r >= r_target:
160
+ if target_alt_m and r >= r_target:
128
161
  hit_target = True
129
162
  break
130
163
 
131
- a = - div(mu, mul(r, r)) # inward
132
- v = add(v, mul(a, dt_s))
133
- r = add(r, mul(v, dt_s))
134
- t = add(t, dt_s)
135
- steps += 1
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
- if (not has_target) and (v < 0) and (r < r0):
138
- turned_back_below_start = True
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
- "rFromCenter_m": r,
190
+ "r_m": r,
150
191
  "altitude_m": altitude_m,
151
192
  "vEnd_mps": v,
152
193
  "time_s": t,
153
- "gAtEnd_mps2": g_end,
154
- "gRatioSurface": div(g_end, g_surface),
194
+ "g_end_mps2": g_end,
195
+ "g_ratio_surface": div(g_end, g_surface),
155
196
  "steps": steps,
156
- "hitSurface": hit_surface,
157
- "hitTarget": hit_target,
158
- "turnedBackBelowStart": turned_back_below_start,
197
+ "hit_surface": hit_surface,
198
+ "hit_target": hit_target,
199
+ "turned_back": turned_back,
159
200
  "traveled_m": traveled_m,
160
- "vEsc_end_mps": math.sqrt(mul(2.0, div(mu, r))),
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
- start_distance: float,
166
- starting_velocity: float,
167
- input_units: str = "meters", # distance part of starting_velocity & start_distance
168
- input_time: str = "s", # time part of starting_velocity
169
- output_units: str = "meters",
170
- output_time: str = "s",
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: Optional[float] = None # in input_units above surface
223
+ target_distance: float = None
176
224
  ) -> dict:
177
- """
178
- Single-call wrapper:
179
-
180
- - start_distance: altitude above surface (input_units)
181
- - starting_velocity: <input_units>/<input_time>
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
- # Integrate in SI
192
- sim = simulate_radial_flight(
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
- target_altitude_m=target_alt_m
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
- # Distances for output
206
- alt_out = dconvert(sim["altitude_m"], "meters", output_units)
207
- r_out = dconvert(sim["rFromCenter_m"], "meters", output_units)
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
- "start_distance": start_distance,
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
- "altitude": alt_out, # in output_units
247
- "radius_from_center": r_out, # in output_units
248
- "distance_traveled": trav_out, # in output_units
249
- "velocity": v_out, # in output_units / output_time
250
- "velocity_escape_end": vesc_end_out, # same units/time as velocity
251
- "velocity_escape_destination": vesc_dest_out,
252
- "destination_radius": (
253
- dconvert(destination_radius_m, "meters", output_units) if destination_radius_m is not None else None
254
- ),
255
- "time": t_out, # in output_time units
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["hitSurface"],
261
- "hit_target": sim["hitTarget"],
262
- "turned_back_below_start": sim["turnedBackBelowStart"],
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, convert,
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 convert(value: float, unit_from: str, unit_to: str) -> float:
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.strip().lower()
50
+ n = name.lower()
50
51
  return _NAME_ALIASES.get(n, n)
51
52
 
52
53
  _BODY_BY_NAME: Dict[str, Dict[str, Any]] = {}
@@ -71,8 +72,8 @@ def get_planet_vars(name: str, units: str = "meters") -> Dict[str, Any]:
71
72
  d_m = body["diameter"]
72
73
 
73
74
  out = dict(body)
74
- out["radius"] = convert(r_m, "meters", units_norm)
75
- out["diameter"] = convert(d_m, "meters", units_norm)
75
+ out["radius"] = dconvert(r_m, "meters", units_norm)
76
+ out["diameter"] = dconvert(d_m, "meters", units_norm)
76
77
  out["radius_units"] = units_norm
77
78
  out["diameter_units"] = units_norm
78
79
  return out
@@ -108,7 +109,7 @@ def escape_velocity(name: str = "earth", altitude: float = 0.0, units: str = "me
108
109
  """
109
110
  mu = _BODY_BY_NAME[_normalize_name(name)]["mu"]
110
111
  r = _BODY_BY_NAME[_normalize_name(name)]["radius"] # meters
111
- h_m = convert(altitude, units, "meters")
112
+ h_m = dconvert(altitude, units, "meters")
112
113
  R = add(r, h_m)
113
114
  return math.sqrt(mul(2.0, div(mu, R)))
114
115
 
@@ -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
@@ -21,7 +21,7 @@ TIME_CONVERSIONS = {
21
21
  "days": DAYS,
22
22
  }
23
23
  ALL_TIME_UNITS = ("seconds", "minutes", "hours", "days")
24
-
24
+ DEFAULT_TIME="s"
25
25
  def normalize_time_unit(unit: str) -> str:
26
26
  u = unit.strip().lower()
27
27
  if u in TIME_CONVERSIONS:
@@ -1,30 +1,78 @@
1
1
  # src/utils/escape_velocity.py
2
2
  from ..imports import math, mul, div, add
3
- from ..constants.planet_constants import get_body
4
- from ..constants.distance_constants import convert as dconvert
5
- from ..constants.time_constants import get_time_unit_conversions, normalize_time_unit
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
- def _seconds_per(unit: str) -> float:
8
- """
9
- Map a time unit (alias-friendly) to seconds per that unit, using your time schema.
10
- """
11
- return get_time_unit_conversions(normalize_time_unit(unit))["conv"]["seconds"]
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 = "earth",
15
- distance: float = 0.0,
61
+ planet: str = DEFAULT_PLANET,
62
+ start_altitude: float = DEFAULT_START_ALTITUDE,
16
63
  *,
17
- input_units: str = "meters", # how to interpret `distance`
18
- output_units: str = "meters", # distance unit for the *speed*
19
- output_time: str = "s", # time unit for the *speed*
20
- as_radius: bool = False # False => `distance` is altitude above surface; True => radius from center
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
- distance: if as_radius=False => altitude above surface; if as_radius=True => radius from center
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(distance, (int, float)) and math.isfinite(distance) and distance >= 0):
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
- vesc_mps = math.sqrt(mul(2.0, div(mu, r_m)))
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
- vesc_units_per_sec = dconvert(vesc_mps, "meters", output_units)
65
- sec_per = _seconds_per(output_time) # seconds per 1 output_time
66
- vesc_out = mul(vesc_units_per_sec, sec_per) # <output_units>/<output_time>
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, "meters", output_units)
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: abstract_math
3
- Version: 0.0.0.24
3
+ Version: 0.0.0.26
4
4
  Author: putkoff
5
5
  Author-email: partners@abstractendeavors.com
6
6
  Classifier: Development Status :: 3 - Alpha
@@ -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=boJqK3XfflETwe8TKFBtPJ6vHNKGkC8JAsXI0Q04e7E,28510
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=EtcUmUWj27c7mcnm-hlfeCeYFuPytPevXx5vClVu6Q8,10000
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=HpRa4MWkJZu3Wcx6KchB8__RL4FfkVqRw78TAnjRRwo,691
12
- abstract_math/solar_math/src/constants/distance_constants.py,sha256=stM3nWxpANQEtoxFcbxpO0ly_UM4JJ2aH0VK42fHw6s,1985
13
- abstract_math/solar_math/src/constants/planet_constants.py,sha256=tt2nbFtRtYhUU9D918WK91D-S5Cv0HEJ-1j7f9Yb50w,6602
14
- abstract_math/solar_math/src/constants/time_constants.py,sha256=uVDMldwjJqKwXzHcAb-Z8QM20JrxSwLXlogjD_SXwRo,1874
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=oN7JPrDGoz-ZDK1ukNSnvWuq3a179gskfdXBLYz3xo0,6812
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=9oixNxWyY4pxa7e1INwbreD8GJEw2BZIgV_IqXiDd9Y,2971
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=_SyOscVvYsvbm1T1Rh4uqegXdf61mHll5s3UfQcdUnU,1162
19
- abstract_math-0.0.0.24.dist-info/METADATA,sha256=yDZwdi8whLWg21FqDF3ib1DkNc6wUOK51rJBVEvI12g,3081
20
- abstract_math-0.0.0.24.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
- abstract_math-0.0.0.24.dist-info/top_level.txt,sha256=b7jOgD9c0U-CGH-l7yxhMPukzD40kMEQkQRV_sGyVfE,14
22
- abstract_math-0.0.0.24.dist-info/RECORD,,
19
+ abstract_math/solar_math/src/utils/velocity_utils.py,sha256=eiXstQ3PF0KAUamSFOHFIL1chyWweygdTyvBjQB_DXo,1888
20
+ abstract_math-0.0.0.26.dist-info/METADATA,sha256=caQ-fCouVO-mjF4SWzBRrZj13NHMyMJ4jsp2BXbTfEk,3081
21
+ abstract_math-0.0.0.26.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
+ abstract_math-0.0.0.26.dist-info/top_level.txt,sha256=b7jOgD9c0U-CGH-l7yxhMPukzD40kMEQkQRV_sGyVfE,14
23
+ abstract_math-0.0.0.26.dist-info/RECORD,,