| """ |
| tests/test_simulator.py |
| ======================= |
| Tests for the CIM physics engine and CIMSimulatorAdapter. |
| """ |
|
|
| import pytest |
| import numpy as np |
|
|
| from qdot.core.types import MeasurementModality |
| from qdot.simulator.cim import ConstantInteractionDevice, CIMSimulatorAdapter |
|
|
|
|
| class TestConstantInteractionDevice: |
| def setup_method(self): |
| self.dev = ConstantInteractionDevice(seed=42) |
|
|
| def test_current_returns_non_negative(self): |
| for vg1 in np.linspace(-1, 1, 10): |
| for vg2 in np.linspace(-1, 1, 10): |
| c = self.dev.current(vg1, vg2) |
| assert c >= 0, f"Negative current at ({vg1:.2f}, {vg2:.2f}): {c}" |
|
|
| def test_chemical_potential_depends_on_n(self): |
| mu_01 = self.dev.chemical_potential(0.0, 0.0, 0, 1) |
| mu_10 = self.dev.chemical_potential(0.0, 0.0, 1, 0) |
| |
| assert mu_01 != mu_10 |
|
|
| def test_tunnel_coupling_lowers_11_state(self): |
| """(1,1) state energy should be lowered by t_c vs no coupling.""" |
| dev_no_coupling = ConstantInteractionDevice(t_c=0.0, seed=42) |
| dev_coupled = ConstantInteractionDevice(t_c=0.4, seed=42) |
|
|
| e_no = dev_no_coupling.ground_state_energy(0.0, 0.0, 1, 1) |
| e_coupled = dev_coupled.ground_state_energy(0.0, 0.0, 1, 1) |
| assert e_coupled < e_no |
|
|
|
|
| class TestCIMSimulatorAdapter: |
| def setup_method(self): |
| self.adapter = CIMSimulatorAdapter(device_id="test_device", seed=42) |
|
|
| def test_sample_patch_shape(self): |
| m = self.adapter.sample_patch((-1, 1), (-1, 1), res=16) |
| assert m.array.shape == (16, 16) |
| assert m.modality == MeasurementModality.COARSE_2D |
| assert m.device_id == "test_device" |
|
|
| def test_sample_patch_normalised(self): |
| m = self.adapter.sample_patch((-1, 1), (-1, 1), res=16) |
| assert m.array.min() >= 0.0 - 1e-6 |
| assert m.array.max() <= 1.0 + 1e-6 |
|
|
| def test_line_scan_shape(self): |
| m = self.adapter.line_scan(axis="vg1", start=-1, stop=1, steps=64, fixed=0.0) |
| assert m.array.shape == (64,) |
| assert m.modality == MeasurementModality.LINE_SCAN |
| assert m.steps == 64 |
| assert m.axis == "vg1" |
|
|
| def test_line_scan_normalised(self): |
| m = self.adapter.line_scan(axis="vg2", start=-0.5, stop=0.5, steps=32) |
| assert m.array.min() >= 0.0 - 1e-6 |
| assert m.array.max() <= 1.0 + 1e-6 |
|
|
| def test_device_type_string(self): |
| assert "Simulator" in self.adapter.device_type |
|
|
| def test_set_voltages_does_not_raise(self): |
| self.adapter.set_voltages({"vg1": 0.3, "vg2": -0.2}) |
|
|
| def test_health_check(self): |
| assert self.adapter.health_check() is True |
|
|