补充test_mql机械原语

This commit is contained in:
huojiarong committed 2026-07-15 10:02:53 +00:00
1 parent 8f14a3840f
commit 6f34ac16bf
4 files changed
+201 -21

No files matched your search

@@ -0,0 +1,94 @@
from __future__ import annotations
from dataclasses import dataclass
from math import pi
MM_TO_M = 1.0e-3
M_TO_MM = 1.0e3
M3_TO_CM3 = 1.0e6
M3_PER_S_TO_L_PER_MIN = 60_000.0
def circular_area(diameter_m: float) -> float:
if diameter_m < 0.0:
raise ValueError("diameter_m must be non-negative.")
return pi * diameter_m * diameter_m / 4.0
def mm_to_m(value: float) -> float:
return value * MM_TO_M
def m_to_mm(value: float) -> float:
return value * M_TO_MM
@dataclass(frozen=True)
class AmesimPistonGeometry:
"""Geometry relations used by AMESim PNRP17 pneumatic piston variables."""
piston_diameter_m: float
rod_diameter_m: float = 0.0
zero_length_m: float = 0.0
@property
def piston_area_m2(self) -> float:
return circular_area(self.piston_diameter_m)
@property
def rod_area_m2(self) -> float:
return circular_area(self.rod_diameter_m)
@property
def annulus_area_m2(self) -> float:
return self.piston_area_m2 - self.rod_area_m2
def chamber_length_m(self, port4_displacement_m: float, port5_displacement_m: float) -> float:
return self.zero_length_m + port5_displacement_m - port4_displacement_m
def chamber_length_mm(self, port4_displacement_m: float, port5_displacement_m: float) -> float:
return m_to_mm(self.chamber_length_m(port4_displacement_m, port5_displacement_m))
@property
def chamber_area_m2(self) -> float:
return self.annulus_area_m2
def chamber_volume_m3(self, port4_displacement_m: float, port5_displacement_m: float) -> float:
return self.chamber_area_m2 * self.chamber_length_m(
port4_displacement_m,
port5_displacement_m,
)
def chamber_volume_cm3(self, port4_displacement_m: float, port5_displacement_m: float) -> float:
return self.chamber_volume_m3(port4_displacement_m, port5_displacement_m) * M3_TO_CM3
def chamber_volume_rate_m3_s(self, port4_velocity_m_s: float, port5_velocity_m_s: float) -> float:
return self.chamber_area_m2 * (port5_velocity_m_s - port4_velocity_m_s)
def chamber_volume_rate_l_min(self, port4_velocity_m_s: float, port5_velocity_m_s: float) -> float:
return self.chamber_volume_rate_m3_s(
port4_velocity_m_s,
port5_velocity_m_s,
) * M3_PER_S_TO_L_PER_MIN
@dataclass(frozen=True)
class AmesimElasticEndstop:
"""Contact force part of AMESim LSTP00A elastic endstop."""
contact_stiffness_n_per_m: float
contact_damping_n_per_m_per_s: float = 0.0
gap0_m: float = 0.0
def penetration_m_from_gap_mm(self, gap_mm: float) -> float:
return max(-(mm_to_m(gap_mm) - self.gap0_m), 0.0)
def static_contact_force(self, gap_mm: float) -> float:
return self.contact_stiffness_n_per_m * self.penetration_m_from_gap_mm(gap_mm)
def contact_force(self, gap_mm: float, penetration_velocity_m_s: float = 0.0) -> float:
if self.penetration_m_from_gap_mm(gap_mm) <= 0.0:
return 0.0
damping_force = self.contact_damping_n_per_m_per_s * penetration_velocity_m_s
return max(self.static_contact_force(gap_mm) + damping_force, 0.0)