Fix pneumatic node zero-flow reversal
This commit is contained in:
1 parent
16a7eb2d6c
commit
0fa166c8e5
3 files changed
+159
-3
No files matched your search
@@ -1,6 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from math import exp
|
||||
from math import exp, isfinite
|
||||
import unittest
|
||||
|
||||
from app.simulation.components.amesim.mechanical.translational import (
|
||||
@@ -130,7 +130,93 @@ def _single_mass_system(
|
||||
return GenericFluidSystem(network), mass
|
||||
|
||||
|
||||
def _high_stiffness_contact_impact_system() -> GenericFluidSystem:
|
||||
"""Return the reduced mechanical core of the four-branch stop impact.
|
||||
|
||||
The production model has four 50 kg piston groups coupled through LSTP00A
|
||||
contacts to one 170000 kg support group. When the support reaches its
|
||||
ideal upper stop, its velocity is reset while each contact still carries
|
||||
the finite, extremely fast LSTP damping transient. One branch is enough
|
||||
to retain that stiffness and state-transition interaction in a fast test.
|
||||
"""
|
||||
|
||||
medium = IdealGasMedium()
|
||||
zero_left = AmesimF000("zero_left")
|
||||
moving_mass = AmesimMecmas21(
|
||||
"moving_mass",
|
||||
medium,
|
||||
mass=50.0,
|
||||
useFriction=1.0,
|
||||
stoptype=4.0,
|
||||
x0=0.0090025,
|
||||
v0=1.0,
|
||||
)
|
||||
contact = AmesimLstp00a(
|
||||
"contact",
|
||||
medium,
|
||||
gap0=0.0,
|
||||
kcont=1.0e11,
|
||||
rcont=1.0e11,
|
||||
Pdis=1.0e-7,
|
||||
discContactOption=1.0,
|
||||
)
|
||||
support_mass = AmesimMecmas21(
|
||||
"support_mass",
|
||||
medium,
|
||||
mass=170000.0,
|
||||
useFriction=1.0,
|
||||
stoptype=1.0,
|
||||
xmin=0.0,
|
||||
xmax=0.01,
|
||||
x0=0.009,
|
||||
v0=1.0,
|
||||
)
|
||||
zero_right = AmesimF000("zero_right")
|
||||
|
||||
network = SimulationNetwork("high-stiffness-contact-impact")
|
||||
for component in (
|
||||
zero_left,
|
||||
moving_mass,
|
||||
contact,
|
||||
support_mass,
|
||||
zero_right,
|
||||
):
|
||||
network.add_component(component)
|
||||
network.connect("zero_left", "port_1", "moving_mass", "port_1")
|
||||
network.connect("moving_mass", "port_2", "contact", "port_1")
|
||||
network.connect("contact", "port_2", "support_mass", "port_1")
|
||||
network.connect("support_mass", "port_2", "zero_right", "port_1")
|
||||
return GenericFluidSystem(network)
|
||||
|
||||
|
||||
class MechanicalSolverCausalizationTests(unittest.TestCase):
|
||||
def test_high_stiffness_lstp_survives_ideal_stop_transition(self) -> None:
|
||||
system = _high_stiffness_contact_impact_system()
|
||||
|
||||
result = system.simulate(
|
||||
SolveIVPConfig(
|
||||
t_start=0.0,
|
||||
t_stop=0.002,
|
||||
max_step=0.002,
|
||||
method="BDF",
|
||||
rtol=1.0e-6,
|
||||
),
|
||||
sample_step=0.00025,
|
||||
)
|
||||
|
||||
self.assertTrue(result.success, result.message)
|
||||
totals = result.diagnostics["integration"]["totals"]
|
||||
self.assertEqual(totals["stateTransitionCount"], 1)
|
||||
self.assertEqual(totals["solverStartCount"], 2)
|
||||
self.assertEqual(totals["recoverableRetryCount"], 0)
|
||||
|
||||
self.assertAlmostEqual(result.series["support_mass.x"][-1], 0.01)
|
||||
self.assertAlmostEqual(result.series["support_mass.v"][-1], 0.0, delta=1.0e-9)
|
||||
self.assertAlmostEqual(result.series["moving_mass.v"][-1], 0.0, delta=1.0e-4)
|
||||
self.assertGreater(max(result.series["contact.force"]), 1.0e10)
|
||||
for values in result.series.values():
|
||||
self.assertTrue(all(isfinite(value) for value in values))
|
||||
|
||||
def test_lstp_contact_uses_exponential_damping_ramp_and_negative_force_option(
|
||||
self,
|
||||
) -> None:
|
||||
|
||||
Reference in new issue
Block a user