1import copy
3import numpy as np
4import pytest
6from cymsim.config import Hit, MalletExciter, StickExciter
7from cymsim.exciter import build_patch
8from cymsim.simulate import Simulator
12def result(coarse_config):
13 return Simulator(coarse_config).run()
16def test_single_hit_run(result, coarse_config):
17 n_out = int(coarse_config.numerics.fs * coarse_config.numerics.duration)
18 assert result.pressure_rayleigh.shape == (n_out,)
19 assert np.isfinite(result.pressure_unbaffled).all()
20 assert np.abs(result.pressure_unbaffled).max() > 0.1 # a 9.6 J stroke is loud
21 (h,) = result.hits
22 assert h.peak_force > 100 and 0.5e-3 < h.contact_time < 20e-3
23 assert 0 < h.rebound_velocity < coarse_config.hits[0].velocity
24 assert h.energy_out < h.energy_in
25 for e in result.energy_log:
26 assert e.total <= h.energy_in * 1.01 # energy only leaves through damping
27 assert result.energy_log[-1].max_w_over_h > 1 # this stroke is clearly nonlinear
30def test_linear_reference_run_is_less_energetic_at_high_frequency(coarse_config):
31 cfg = copy.deepcopy(coarse_config)
32 cfg.numerics.nonlinear = False
33 lin = Simulator(cfg).run()
34 assert np.isfinite(lin.pressure_unbaffled).all()
37def test_two_hits(coarse_config):
38 cfg = copy.deepcopy(coarse_config)
39 cfg.numerics.duration = 0.03
40 cfg.hits = [Hit(time=0.0, r=0.137, phi=0.3, velocity=8.0, exciter=MalletExciter()),
41 Hit(time=0.015, r=0.19, phi=2.0, velocity=7.0, exciter=StickExciter(patch_points=5))]
42 sim = Simulator(cfg)
43 assert sim.schedule.n_hits == 2 and sim.schedule.n_points == 7 # padded to the mallet's 7
44 res = sim.run()
45 assert len(res.hits) == 2
46 assert res.hits[1].kind == "stick" and res.hits[1].peak_force > 0
47 assert 0 < res.hits[1].contact_time < 5e-3
48 assert res.hits[0].rebound_velocity > 0 and res.hits[1].rebound_velocity > 0
51def test_contact_patch_geometry(coarse_config):
52 sim = Simulator(coarse_config)
53 stick = build_patch(Hit(r=0.19, phi=0.5, velocity=7.0, exciter=StickExciter()), sim.mesh, sim.profile)
54 assert stick.n_points == 7 and np.isclose(np.hypot(stick.x[3], stick.y[3]), 0.19)
55 assert np.allclose(stick.weights.sum(1), 1.0)
56 assert np.isclose(stick.free_contact_time(), 2.94 * stick.max_compression() / 7.0, rtol=1e-2)
57 mallet = build_patch(Hit(r=0.137, phi=0.3, velocity=8.0, exciter=MalletExciter()), sim.mesh, sim.profile)
58 assert np.isclose(mallet.max_compression(), MalletExciter.compression)
59 assert abs(mallet.offsets.max()) < 5e-3