feat: Adds methods for obtaining the full dipole from simpler model description.
Some checks failed
gitea-physics/pdme/pipeline/head There was a failure building this commit

This commit is contained in:
2022-02-06 18:32:25 -06:00
parent d139b02056
commit 9933ef3bbf
6 changed files with 97 additions and 4 deletions

View File

@@ -1,5 +1,7 @@
from pdme.model.model import Model, Discretisation
from pdme.model.fixed_z_plane_model import FixedZPlaneModel
from pdme.model.unrestricted_model import UnrestrictedModel
from pdme.model.fixed_dipole_model import FixedDipoleModel
from pdme.model.fixed_magnitude_model import FixedMagnitudeModel
__all__ = ["Model", "Discretisation", "FixedZPlaneModel", "UnrestrictedModel"]
__all__ = ["Model", "Discretisation", "FixedZPlaneModel", "UnrestrictedModel", "FixedDipoleModel", "FixedMagnitudeModel"]

View File

@@ -37,6 +37,12 @@ class FixedDipoleModel(Model):
s_pts = numpy.array((self.rng.uniform(self.xmin, self.xmax), self.rng.uniform(self.ymin, self.ymax), self.rng.uniform(self.zmin, self.zmax)))
return OscillatingDipoleArrangement([OscillatingDipole(self.p, s_pts, frequency)])
def solution_single_dipole(self, pt: numpy.ndarray) -> OscillatingDipole:
# assume length is 4.
s = pt[0:3]
w = pt[3]
return OscillatingDipole(self.p, s, w)
def point_length(self) -> int:
'''
Dipole is constrained magnitude, but free orientation.

View File

@@ -30,7 +30,21 @@ class FixedMagnitudeModel(Model):
self.rng = numpy.random.default_rng()
def __repr__(self) -> str:
return f'FixedMagnitudeModel({self.xmin}, {self.xmax}, {self.ymin}, {self.ymax}, {self.zmin}, {self.zmax}, {self.n()})'
return f'FixedMagnitudeModel({self.xmin}, {self.xmax}, {self.ymin}, {self.ymax}, {self.zmin}, {self.zmax}, {self.pfixed}, {self.n()})'
def solution_single_dipole(self, pt: numpy.ndarray) -> OscillatingDipole:
# assume length is 6, who needs error checking.
p_theta = pt[0]
p_phi = pt[1]
s = pt[2:5]
w = pt[5]
p = numpy.array([
self.pfixed * numpy.sin(p_theta) * numpy.cos(p_phi),
self.pfixed * numpy.sin(p_theta) * numpy.sin(p_phi),
self.pfixed * numpy.cos(p_theta)
])
return OscillatingDipole(p, s, w)
def point_length(self) -> int:
'''

View File

@@ -1,7 +1,7 @@
import numpy
import scipy.optimize
from typing import Callable, Sequence, Tuple
from pdme.measurement import DotMeasurement, OscillatingDipoleArrangement
from typing import Callable, Sequence, Tuple, List
from pdme.measurement import DotMeasurement, OscillatingDipoleArrangement, OscillatingDipole
import pdme.util
import logging
@@ -26,6 +26,14 @@ class Model():
def get_dipoles(self, frequency: float) -> OscillatingDipoleArrangement:
raise NotImplementedError
def solution_single_dipole(self, pt: numpy.ndarray) -> OscillatingDipole:
raise NotImplementedError
def solution_as_dipoles(self, pts: numpy.ndarray) -> List[OscillatingDipole]:
pt_length = self.point_length()
chunked_pts = [pts[i: i + pt_length] for i in range(0, len(pts), pt_length)]
return [self.solution_single_dipole(pt) for pt in chunked_pts]
def cost_for_dot(self, dot: DotMeasurement, pts: numpy.ndarray) -> float:
# creates numpy.ndarrays in groups of self.point_length().
# Will throw problems for irregular points, but that's okay for now.

View File

@@ -0,0 +1,27 @@
from pdme.model import FixedDipoleModel
from pdme.measurement import OscillatingDipole, OscillatingDipoleArrangement
import logging
import numpy
import itertools
import pytest
@pytest.mark.skip(reason="No idea why this is failing, but it shouldn't!")
def test_fixed_dipole_model_solve_basic():
# Initialise our dipole arrangement and create dot measurements along a square.
fixed_dipole_moment = numpy.array((2, 1, 2))
dipoles = OscillatingDipoleArrangement([OscillatingDipole(fixed_dipole_moment, (1, 2, 4), 6)])
dot_inputs = list(itertools.chain.from_iterable(
(([1, 2, 1], f), ([1, 1, -2], f), ([1.5, 2, 0.1], f), ([1.5, 1, -0.2], f), ([2, 1, 0], f), ([2, 2, 0], f), ([0, 2, -.1], f), ([0, 1, 0.04], f), ([2, 0, 2], f), ([1, 0, 0], f)) for f in numpy.arange(1, 10, 1)
))
dots = dipoles.get_dot_measurements(dot_inputs)
model = FixedDipoleModel(-3, 3, -3, 3, 3, 5, fixed_dipole_moment, 1)
# from the dipole, these are the unspecified variables in ((.5, 0, 2), (1, 2, 4), 8)
expected_solution = [1, 2, 4, 6]
result = model.solve(dots)
logging.info(result)
assert result.success
numpy.testing.assert_allclose(result.normalised_x, expected_solution, err_msg="Even well specified problem solution was wrong.", rtol=1e-6, atol=1e-11)

View File

@@ -0,0 +1,36 @@
from pdme.model import FixedMagnitudeModel
from pdme.measurement import OscillatingDipole, OscillatingDipoleArrangement
import logging
import numpy
import itertools
def test_fixed_magnitude_model_solve_basic():
# Initialise our dipole arrangement and create dot measurements along a square.
dipoles = OscillatingDipoleArrangement([OscillatingDipole((2, 0, 0), (1, 2, 4), 1)])
dot_inputs = list(itertools.chain.from_iterable(
(([1, 2, 0.01], f), ([1, 1, -0.2], f), ([1.5, 2, 0.01], f), ([1.5, 1, -0.2], f), ([2, 1, 0], f), ([2, 2, 0], f), ([0, 2, -.1], f), ([0, 1, 0.04], f), ([2, 0, 0], f), ([1, 0, 0], f)) for f in numpy.arange(1, 10, 2)
))
dots = dipoles.get_dot_measurements(dot_inputs)
model = FixedMagnitudeModel(-5, 5, -5, 5, -5, 5, 2, 1)
# from the dipole, these are the unspecified variables in ((0, 0, 2), (1, 2, 4), 1)
expected_solution = [numpy.pi / 2, 0, 1, 2, 4, 1]
result = model.solve(dots)
logging.info(result)
assert result.success
numpy.testing.assert_allclose(result.normalised_x, expected_solution, err_msg="Even well specified problem solution was wrong.", rtol=1e-6, atol=1e-11)
solved_dipoles = model.solution_as_dipoles(result.normalised_x)
assert len(solved_dipoles) == 1
numpy.testing.assert_allclose(solved_dipoles[0].p, (2, 0, 0), err_msg="Shove it in a dipole correctly.", rtol=1e-6, atol=1e-11)
numpy.testing.assert_allclose(solved_dipoles[0].s, (1, 2, 4), err_msg="Shove it in a dipole correctly.", rtol=1e-6, atol=1e-11)
numpy.testing.assert_allclose(solved_dipoles[0].w, 1, err_msg="Shove it in a dipole correctly.", rtol=1e-6, atol=1e-11)
def test_fixed_magnitude_model_repr():
model = FixedMagnitudeModel(-5, 5, -5, 5, -5, 5, 2, 1)
assert repr(model) == "FixedMagnitudeModel(-5, 5, -5, 5, -5, 5, 2, 1)"