feat: adds fast calc that allows for variable temp
Some checks failed
gitea-physics/pdme/pipeline/head There was a failure building this commit
gitea-physics/pdme/pipeline/pr-master There was a failure building this commit

This commit is contained in:
Deepak Mallubhotla 2023-04-09 16:26:08 -05:00
parent c49b8eb034
commit 36454d5044
Signed by: deepak
GPG Key ID: BEBAEBF28083E022
2 changed files with 67 additions and 0 deletions

View File

@ -69,6 +69,47 @@ def fast_vs_for_dipoleses(
return numpy.einsum("...j->...", ases * bses)
def fast_vs_for_asymmetric_dipoleses(
dot_inputs: numpy.ndarray, dipoleses: numpy.ndarray, temp: numpy.ndarray
) -> numpy.ndarray:
"""
No error correction here baby.
Expects dot_inputs to be numpy array of [rx, ry, rz, f] entries, so a n by 4 where n is number of measurement points.
Dipoleses are expected to be array of arrays of arrays:
list of sets of dipoles which are part of a single arrangement to be added together.
Within each dipole, the expected format is [px, py, pz, sx, sy, sz, e1, e2, w]
The passed in w is expected to be half the actual. This is bad, but here for historical reasons to be changed later.
"""
raw_ps = dipoleses[:, :, 0:3]
ss = dipoleses[:, :, 3:6]
e1s = dipoleses[:, :, 6]
e2s = dipoleses[:, :, 7]
raw_ws = dipoleses[:, :, 8]
rs = dot_inputs[:, 0:3]
fs = dot_inputs[:, 3]
diffses = rs[:, None] - ss[:, None, :]
w1s = numpy.exp(-e1s / temp) * raw_ws
w2s = numpy.exp(-e2s / temp) * raw_ws
mag_prefactor = 4 * ((w1s * w2s) / ((w1s + w2s) ** 2))
ws = w1s + w2s
# some annoying broadcast thing here?
ps = (raw_ps.T * mag_prefactor.T).T
norms = numpy.linalg.norm(diffses, axis=3) ** 3
ases = (numpy.einsum("abcd,acd->abc", diffses, ps) / norms) ** 2
bses = (1 / numpy.pi) * (ws[:, None, :] / (fs[:, None] ** 2 + ws[:, None, :] ** 2))
return numpy.einsum("...j->...", ases * bses)
def between(a: numpy.ndarray, low: numpy.ndarray, high: numpy.ndarray) -> numpy.ndarray:
"""
Intended specifically for the case where a is a list of arrays, and each array must be between the single array low and high, but without error checking.

View File

@ -107,3 +107,29 @@ def test_between():
expected = numpy.array([False, False, True])
numpy.testing.assert_array_equal(actual, expected, err_msg="Between calc wrong")
def test_fast_v_calc_asymmetric_multidipoles_but_symmetric():
# expected format is [px, py, pz, sx, sy, sz, e1, e2, w]
d1 = [1, 2, 3, 4, 5, 6, 1, 1, 7 / 2]
d2 = [2, 5, 3, 4, -5, -6, 2, 2, 2 / 2]
dipoles = numpy.array([[d1, d2]])
dot_inputs = numpy.array([[-1, -1, -1, 11], [2, 3, 1, 5.5]])
# expected_ij is for dot i, dipole j
expected_11 = 0.00001421963287022476
expected_12 = 0.00001107180225755457
expected_21 = 0.000345021108583681380388722
expected_22 = 0.0000377061050587914705139781
expected = numpy.array([[expected_11 + expected_12, expected_21 + expected_22]])
numpy.testing.assert_allclose(
pdme.util.fast_v_calc.fast_vs_for_asymmetric_dipoleses(
dot_inputs, dipoles, 1e10
),
expected,
err_msg="Voltages at dot aren't as expected for multidipole calc.",
)