From 7578cefdadd619b505f2b9ad35e5a5067a51d9e6 Mon Sep 17 00:00:00 2001 From: Dieter Werthmuller Date: Thu, 2 Jan 2025 17:16:29 +0100 Subject: [PATCH] Bugfix, closes #348 --- CHANGELOG.rst | 11 +++++++---- emg3d/fields.py | 6 ++++-- tests/test_fields.py | 24 +++++++++++++++++------- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index afdab7fe..b104b1a9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,12 +6,15 @@ Changelog """""""""" -latest ------- +v1.8.5 : Bugfix and pyproject +----------------------------- -- Maintenance: +- Bugfix and maintenance: - - Changed from ``setup.py`` to ``pyproject.toml``. + - Fix bug in Dipole/Wire sources when coordinates are mixed increasing and + decreasing over several cells + [#348](https://github.com/emsig/emg3d/issues/348). + - Changed build backend from ``setup.py`` to ``pyproject.toml``. v1.8.4 : NumPy v2 diff --git a/emg3d/fields.py b/emg3d/fields.py index ceb15491..3572955c 100644 --- a/emg3d/fields.py +++ b/emg3d/fields.py @@ -898,7 +898,7 @@ def min_max_ind(vector, i): ez = 1 - rz # Add to field (only if segment inside cell). - if min(rx, ry, rz) >= 0 and np.max(np.abs(ar-al)) > 0: + if min(rx, ex, ry, ey, rz, ez) >= 0 and np.max(abs(ar-al)) > 0: vfield.fx[ix, iy, iz] += ey*ez*x_len vfield.fx[ix, iy+1, iz] += ry*ez*x_len @@ -918,7 +918,9 @@ def min_max_ind(vector, i): # Ensure unity (should not be necessary). for field in [vfield.fx, vfield.fy, vfield.fz]: sum_s = abs(field.sum()) - if abs(sum_s-1) > 1e-6: # Normalize and warn. + # Normalize and warn; SHOULD NEVER HAPPEN + # (if it happens add it to the tests and remove the pragma-flag! + if abs(sum_s-1) > 1e-6: # pragma: no cover msg = f"emg3d: Normalizing Source: {sum_s:.10f}." warnings.warn(msg, UserWarning) field /= sum_s diff --git a/tests/test_fields.py b/tests/test_fields.py index b273ec7e..2b68e3d1 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -652,6 +652,7 @@ def test_basics_diag_large(self): grid = emg3d.TensorMesh([h, h, h], (-3, -3, -3)) # Large diagonal source in the middle + # x, y, z increasing source = np.array([[-2.5, -2.5, -2.5], [2.5, 2.5, 2.5]]) vfield = fields._dipole_vector(grid, source) @@ -672,6 +673,22 @@ def test_basics_diag_large(self): assert_allclose(vfield.fx[1, 1:3, 1:3].ravel(), vfield.fx[2, 2:4, 2:4].ravel()[::-1]) + # Large diagonal source in the middle + # x, z increasing, y decreasing + source = np.array([[-2.5, 2.5, -2.5], [2.5, -2.5, 2.5]]) + vfield2 = fields._dipole_vector(grid, source) + assert_allclose(vfield.fx, np.fliplr(vfield2.fx)) + assert_allclose(vfield.fy, -np.fliplr(vfield2.fy)) + assert_allclose(vfield.fz, np.fliplr(vfield2.fz)) + + # Large diagonal source in the middle + # x, z decreasing, y increasing + source = np.array([[2.5, -2.5, 2.5], [-2.5, 2.5, -2.5]]) + vfield3 = fields._dipole_vector(grid, source) + assert_allclose(vfield.fx, -np.fliplr(vfield3.fx)) + assert_allclose(vfield.fy, np.fliplr(vfield3.fy)) + assert_allclose(vfield.fz, -np.fliplr(vfield3.fz)) + def test_decimals(self): h1 = [2, 1, 1, 2] h2 = [2, 1.04, 1.04, 2] @@ -698,13 +715,6 @@ def test_warnings(self): with pytest.raises(ValueError, match='Provided finite dipole'): fields._dipole_vector(grid, source) - # This is a warning that should never be raised... - hx, x0 = np.ones(4), -2 - grid = emg3d.TensorMesh([hx, hx, hx], (x0, x0, x0)) - source = np.array([[-2, 2, 0], [0, -2, 0]]) - with pytest.warns(UserWarning, match="Normalizing Source: 1.25000000"): - fields._dipole_vector(grid, source, 30) - @pytest.mark.parametrize("njit", [True, False]) def test_edge_curl_factor(njit):