Vulcan
Aerospace Engineering Utilities Built on Janus
Loading...
Searching...
No Matches
Slosh.hpp
Go to the documentation of this file.
1// Vulcan Fuel Slosh Dynamics
2// Pure stateless functions for slosh modeling per NASA SP-8009
3#pragma once
4
6
7#include <janus/janus.hpp>
8
9namespace vulcan::dynamics {
10
11// =============================================================================
12// Pendulum Slosh Model (NASA SP-8009)
13// =============================================================================
14
34template <typename Scalar>
35Scalar pendulum_slosh_acceleration(const Scalar &theta, const Scalar &theta_dot,
36 const Scalar &length, const Scalar &zeta,
37 const Scalar &accel_transverse,
38 const Scalar &gravity) {
39 Scalar omega_n = janus::sqrt(gravity / length);
40 Scalar sin_theta = janus::sin(theta);
41 Scalar cos_theta = janus::cos(theta);
42
43 // θ̈ = -(g/L)*sin(θ) - 2ζω_n*θ̇ + (a_t/L)*cos(θ)
44 return -omega_n * omega_n * sin_theta -
45 Scalar(2) * zeta * omega_n * theta_dot +
46 (accel_transverse / length) * cos_theta;
47}
48
54template <typename Scalar>
55Scalar slosh_transverse_accel(const Vec3<Scalar> &accel_body,
56 const Scalar &theta) {
57 Scalar cos_theta = janus::cos(theta);
58 Scalar sin_theta = janus::sin(theta);
59 // a_t = a_x * cos(θ) - a_z * sin(θ) for pendulum in X-Z plane
60 return accel_body(0) * cos_theta - accel_body(2) * sin_theta;
61}
62
68template <typename Scalar>
69Vec3<Scalar> pendulum_slosh_position(const Scalar &theta,
70 const Scalar &length) {
71 return Vec3<Scalar>{length * janus::sin(theta), Scalar(0),
72 length * janus::cos(theta)};
73}
74
83template <typename Scalar>
84Vec3<Scalar> pendulum_slosh_force(const Scalar &theta, const Scalar &theta_dot,
85 const Scalar &theta_ddot,
86 const Scalar &length, const Scalar &m_slosh) {
87 Scalar sin_theta = janus::sin(theta);
88 Scalar cos_theta = janus::cos(theta);
89 Scalar theta_dot_sq = theta_dot * theta_dot;
90
91 // Slosh mass acceleration (relative to vehicle)
92 Vec3<Scalar> a_slosh{
93 length * (cos_theta * theta_ddot - sin_theta * theta_dot_sq), Scalar(0),
94 length * (-sin_theta * theta_ddot - cos_theta * theta_dot_sq)};
95
96 // Reaction force (Newton's 3rd law)
97 return -m_slosh * a_slosh;
98}
99
100// =============================================================================
101// Spring-Mass Slosh Model (3-DOF per tank)
102// =============================================================================
103
117template <typename Scalar>
118Scalar
119spring_slosh_acceleration(const Scalar &displacement, const Scalar &velocity,
120 const Scalar &stiffness, const Scalar &damping,
121 const Scalar &mass, const Scalar &vehicle_accel) {
122 return (-damping * velocity - stiffness * displacement -
123 mass * vehicle_accel) /
124 mass;
125}
126
136template <typename Scalar>
137Vec3<Scalar> spring_slosh_acceleration_3d(const Vec3<Scalar> &displacement,
138 const Vec3<Scalar> &velocity,
139 const Vec3<Scalar> &stiffness,
140 const Vec3<Scalar> &damping,
141 const Scalar &mass,
142 const Vec3<Scalar> &accel_body) {
143 Vec3<Scalar> accel;
144 for (int i = 0; i < 3; ++i) {
145 accel(i) = (-damping(i) * velocity(i) - stiffness(i) * displacement(i) -
146 mass * accel_body(i)) /
147 mass;
148 }
149 return accel;
150}
151
159template <typename Scalar>
160Vec3<Scalar> spring_slosh_force(const Vec3<Scalar> &displacement,
161 const Vec3<Scalar> &velocity,
162 const Vec3<Scalar> &stiffness,
163 const Vec3<Scalar> &damping) {
164 Vec3<Scalar> force;
165 for (int i = 0; i < 3; ++i) {
166 force(i) = stiffness(i) * displacement(i) + damping(i) * velocity(i);
167 }
168 return force;
169}
170
171// =============================================================================
172// NASA SP-8009 Parameter Estimation
173// =============================================================================
174
181template <typename Scalar>
182Scalar slosh_frequency_cylindrical(const Scalar &tank_radius,
183 const Scalar &fill_level,
184 const Scalar &gravity) {
185 // ω_s² ≈ 1.84 * g / R for deep fill (h/R > 1)
186 Scalar depth_ratio = fill_level * Scalar(2);
187 Scalar freq_factor =
188 janus::where(depth_ratio > Scalar(1), Scalar(1.84),
189 Scalar(1.84) * janus::tanh(Scalar(1.84) * depth_ratio));
190
191 return janus::sqrt(freq_factor * gravity / tank_radius);
192}
193
200template <typename Scalar>
201Scalar slosh_frequency_spherical(const Scalar &tank_radius,
202 const Scalar &fill_level,
203 const Scalar &gravity) {
204 // ω_s² ≈ 1.56 * g / R at 50% fill
205 Scalar fill_factor = Scalar(4) * fill_level * (Scalar(1) - fill_level);
206 Scalar omega_sq = Scalar(1.56) * gravity / tank_radius * fill_factor;
207 return janus::sqrt(omega_sq + Scalar(1e-6)); // Avoid zero at empty/full
208}
209
215template <typename Scalar>
216Scalar slosh_pendulum_length(const Scalar &omega_slosh, const Scalar &gravity) {
217 return gravity / (omega_slosh * omega_slosh);
218}
219
224template <typename Scalar>
225Scalar slosh_mass_fraction_cylindrical(const Scalar &fill_level) {
226 Scalar depth_ratio = fill_level * Scalar(2);
227 return janus::where(depth_ratio > Scalar(1), Scalar(0.70),
228 Scalar(0.35) + Scalar(0.35) * depth_ratio);
229}
230
236template <typename Scalar>
237Scalar slosh_mass_cylindrical(const Scalar &total_fuel_mass,
238 const Scalar &fill_level) {
239 return slosh_mass_fraction_cylindrical(fill_level) * total_fuel_mass;
240}
241
242} // namespace vulcan::dynamics
Definition Guided5Dof.hpp:13
Scalar velocity(const Scalar &r, const Scalar &a, double mu=constants::earth::mu)
Orbital velocity (vis-viva equation).
Definition OrbitalQuantities.hpp:35
Scalar gravity(const Scalar &altitude)
US Standard Atmosphere 1976 - Gravitational Acceleration (table-based).
Definition USSA1976.hpp:248