你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-06 20:46:52 +08:00

This calculation only uses information from the grid so makes sense to be done by the grid class. The previous helper function was passed a copy of the grid as a parameter already.
122 行
3.4 KiB
Python
122 行
3.4 KiB
Python
from typing import Callable
|
|
|
|
import numpy as np
|
|
import pytest
|
|
from numpy.testing import assert_allclose, assert_array_equal
|
|
from pytest import param
|
|
|
|
from gprMax.grid.fdtd_grid import FDTDGrid
|
|
|
|
|
|
def get_current_in_3d_grid(
|
|
get_current_func: Callable[[int, int, int], float], shape: tuple[int, ...]
|
|
) -> np.ndarray:
|
|
"""Helper function to get current as a 3D grid
|
|
|
|
Args:
|
|
get_current_func: Function that returns the current value at a
|
|
point on a grid.
|
|
shape: shape of the grid
|
|
|
|
Returns:
|
|
result: 3D grid containing current values
|
|
"""
|
|
result = np.empty(shape)
|
|
for i in range(shape[0]):
|
|
for j in range(shape[1]):
|
|
for k in range(shape[2]):
|
|
result[i, j, k] = get_current_func(i, j, k)
|
|
return result
|
|
|
|
|
|
def tile(a: float, b: float, n: int = 1) -> np.ndarray:
|
|
"""Helper function to tile two numbers
|
|
|
|
Args:
|
|
a: first value
|
|
b: second value
|
|
n: number of repititions
|
|
|
|
Returns:
|
|
c: tiled numpy array
|
|
"""
|
|
return np.tile([[[a, b], [b, a]], [[b, a], [a, b]]], (n, n, n))
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"dy,dz,Hy,Hz,expected",
|
|
[
|
|
(0, 0, (1, 3), (0.5, 0.8), 0),
|
|
(0.1, 0.5, (0, 0), (0.5, 0.8), -0.15),
|
|
(0.1, 0.5, (1, 3), (0, 0), 0.2),
|
|
(0.1, 0, (1, 3), (0.5, 0.8), 0.2),
|
|
(0, 0.5, (1, 3), (0.5, 0.8), -0.15),
|
|
(0.1, 0.5, (1, 3), (0.5, 0.8), 0.05),
|
|
],
|
|
)
|
|
def test_calculate_Ix(dy, dz, Hy, Hz, expected, size=2):
|
|
grid = FDTDGrid()
|
|
grid.dy = dy
|
|
grid.dz = dz
|
|
grid.Hy = tile(Hy[0], Hy[1], size)
|
|
grid.Hz = tile(Hz[0], Hz[1], size)
|
|
|
|
actual_current = get_current_in_3d_grid(grid.calculate_Ix, grid.Hy.shape)
|
|
expected_current = tile(expected, -expected, size)
|
|
expected_current[:, 0, :] = 0
|
|
expected_current[:, :, 0] = 0
|
|
|
|
assert_allclose(actual_current, expected_current)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"dx,dz,Hx,Hz,expected",
|
|
[
|
|
(0, 0, (1, 3), (0.5, 0.8), 0),
|
|
(0.1, 0.5, (0, 0), (0.5, 0.8), -0.15),
|
|
(0.1, 0.5, (1, 3), (0, 0), 0.2),
|
|
(0.1, 0, (1, 3), (0.5, 0.8), 0.2),
|
|
(0, 0.5, (1, 3), (0.5, 0.8), -0.15),
|
|
(0.1, 0.5, (1, 3), (0.5, 0.8), 0.05),
|
|
],
|
|
)
|
|
def test_calculate_Iy(dx, dz, Hx, Hz, expected, size=2):
|
|
grid = FDTDGrid()
|
|
grid.dx = dx
|
|
grid.dz = dz
|
|
grid.Hx = tile(Hx[0], Hx[1], size)
|
|
grid.Hz = tile(Hz[0], Hz[1], size)
|
|
|
|
actual_current = get_current_in_3d_grid(grid.calculate_Iy, grid.Hx.shape)
|
|
expected_current = tile(-expected, expected, size)
|
|
expected_current[0, :, :] = 0
|
|
expected_current[:, :, 0] = 0
|
|
|
|
assert_allclose(actual_current, expected_current)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"dx,dy,Hx,Hy,expected",
|
|
[
|
|
(0, 0, (1, 3), (0.5, 0.8), 0),
|
|
(0.1, 0.5, (0, 0), (0.5, 0.8), -0.15),
|
|
(0.1, 0.5, (1, 3), (0, 0), 0.2),
|
|
(0.1, 0, (1, 3), (0.5, 0.8), 0.2),
|
|
(0, 0.5, (1, 3), (0.5, 0.8), -0.15),
|
|
(0.1, 0.5, (1, 3), (0.5, 0.8), 0.05),
|
|
],
|
|
)
|
|
def test_calculate_Iz(dx, dy, Hx, Hy, expected, size=2):
|
|
grid = FDTDGrid()
|
|
grid.dx = dx
|
|
grid.dy = dy
|
|
grid.Hx = tile(Hx[0], Hx[1], size)
|
|
grid.Hy = tile(Hy[0], Hy[1], size)
|
|
|
|
actual_current = get_current_in_3d_grid(grid.calculate_Iz, grid.Hx.shape)
|
|
expected_current = tile(expected, -expected, size)
|
|
expected_current[0, :, :] = 0
|
|
expected_current[:, 0, :] = 0
|
|
|
|
assert_allclose(actual_current, expected_current)
|