# Path: sucemfem/Sources/PostProcess.py
# class VoltageAlongLine(object):
#     """Measure voltage along a straight line between two points"""
#     def __init__(self, field_function):
#         self.field_function = field_function
# 
#     def calculate_voltage(self, start_pt, end_pt):
#         fn = self.field_function
#         delta = end_pt - start_pt
#         l_hat = unit_vector(delta)
#         # Evaluate E . l_hat where E is the electric field vector and
#         # l_hat is a unit vector along the integration path.
#         eval_fn = lambda l: np.dot(l_hat, fn(*(start_pt + delta*l)))
#         # Integrate over unit length
#         intg = romberg(eval_fn, 0, 1)
#         # Multiply by inteval length to de-normalise
#         interval_len = vector_length(delta)
#         intg = intg*interval_len
#         return intg
# 
# Path: sucemfem/Sources/PostProcess.py
# class ComplexVoltageAlongLine(object):
#     """Measure complex voltage along a straight line between two points"""
#     def __init__(self, function_space):
#         self.function_space = function_space
# 
#     def set_dofs(self, dofs):
#         self.dofs = dofs
#         self.x_r = as_dolfin_vector(self.dofs.real)
#         self.x_i = as_dolfin_vector(self.dofs.imag)
#         self.E_r = dolfin.Function(self.function_space, self.x_r)
#         self.E_i = dolfin.Function(self.function_space, self.x_i)
#         self.real_voltage = VoltageAlongLine(self.E_r)
#         self.imag_voltage = VoltageAlongLine(self.E_i)
# 
#     def calculate_voltage(self, start_pt, end_pt):
#         return (self.real_voltage.calculate_voltage(start_pt, end_pt) +
#                 1j*self.imag_voltage.calculate_voltage(start_pt, end_pt))


import unittest
import numpy as np
import dolfin
from sucemfem.Sources.PostProcess import VoltageAlongLine
from sucemfem.Sources.PostProcess import ComplexVoltageAlongLine
        self.mesh = dolfin.UnitCube(3,3,3)
        self.V = dolfin.FunctionSpace(self.mesh, "Nedelec 1st kind H(curl)", 2)
        self.u = dolfin.interpolate(
            dolfin.Expression(('0','0', '2*x[2]')), self.V)
        self.DUT = VoltageAlongLine(self.u)

    def test_calculate_voltage(self):
        # Should result in 1v
        p1v_pts = (np.array([[0.5,0.35,0], [0.5,0.5,1]]),
                   np.array([[0,0,0], [1,1,1]]))
        # Should result in -1v
        m1v_pts = (np.array([[0.25,0.5,1-3e-16], [0.5,0.75,3e-16]]),
                   np.array([[1,1,1], [0,0,0]]))
        # Should result in 0v
        p0v_pts = np.array([[0,0,1], [1,1,1]])
        self.assertAlmostEqual(self.DUT.calculate_voltage(*p1v_pts[0]), 1.)
        self.assertAlmostEqual(self.DUT.calculate_voltage(*p1v_pts[1]), 1.)
        self.assertAlmostEqual(self.DUT.calculate_voltage(*m1v_pts[0]), -1.)
        self.assertAlmostEqual(self.DUT.calculate_voltage(*m1v_pts[1]), -1.)
        self.assertAlmostEqual(self.DUT.calculate_voltage(*p0v_pts), 0.)


class test_ComplexVoltageAlongLine(unittest.TestCase):
    def setUp(self):
        self.mesh = dolfin.UnitCube(3,3,3)
        self.V = dolfin.FunctionSpace(self.mesh, "Nedelec 1st kind H(curl)", 3)
        self.u_r = dolfin.interpolate(
            dolfin.Expression(('0','0', '2*x[2]')), self.V)
        self.u_i = dolfin.interpolate(
            dolfin.Expression(('0','0', '-x[2]*x[2]')), self.V)

# Path: sucemfem/Sources/PostProcess.py
# class VoltageAlongLine(object):
#     """Measure voltage along a straight line between two points"""
#     def __init__(self, field_function):
#         self.field_function = field_function
# 
#     def calculate_voltage(self, start_pt, end_pt):
#         fn = self.field_function
#         delta = end_pt - start_pt
#         l_hat = unit_vector(delta)
#         # Evaluate E . l_hat where E is the electric field vector and
#         # l_hat is a unit vector along the integration path.
#         eval_fn = lambda l: np.dot(l_hat, fn(*(start_pt + delta*l)))
#         # Integrate over unit length
#         intg = romberg(eval_fn, 0, 1)
#         # Multiply by inteval length to de-normalise
#         interval_len = vector_length(delta)
#         intg = intg*interval_len
#         return intg
# 
# Path: sucemfem/Sources/PostProcess.py
# class ComplexVoltageAlongLine(object):
#     """Measure complex voltage along a straight line between two points"""
#     def __init__(self, function_space):
#         self.function_space = function_space
# 
#     def set_dofs(self, dofs):
#         self.dofs = dofs
#         self.x_r = as_dolfin_vector(self.dofs.real)
#         self.x_i = as_dolfin_vector(self.dofs.imag)
#         self.E_r = dolfin.Function(self.function_space, self.x_r)
#         self.E_i = dolfin.Function(self.function_space, self.x_i)
#         self.real_voltage = VoltageAlongLine(self.E_r)
#         self.imag_voltage = VoltageAlongLine(self.E_i)
# 
#     def calculate_voltage(self, start_pt, end_pt):
#         return (self.real_voltage.calculate_voltage(start_pt, end_pt) +
#                 1j*self.imag_voltage.calculate_voltage(start_pt, end_pt))


# Path: sucemfem/Sources/tests/test_postprocessing.py
import unittest
import numpy as np
import dolfin
from sucemfem.Sources.PostProcess import VoltageAlongLine
from sucemfem.Sources.PostProcess import ComplexVoltageAlongLine

        self.mesh = dolfin.UnitCube(3,3,3)
        self.V = dolfin.FunctionSpace(self.mesh, "Nedelec 1st kind H(curl)", 2)
        self.u = dolfin.interpolate(
            dolfin.Expression(('0','0', '2*x[2]')), self.V)
        self.DUT = VoltageAlongLine(self.u)

    def test_calculate_voltage(self):
        # Should result in 1v
        p1v_pts = (np.array([[0.5,0.35,0], [0.5,0.5,1]]),
                   np.array([[0,0,0], [1,1,1]]))
        # Should result in -1v
        m1v_pts = (np.array([[0.25,0.5,1-3e-16], [0.5,0.75,3e-16]]),
                   np.array([[1,1,1], [0,0,0]]))
        # Should result in 0v
        p0v_pts = np.array([[0,0,1], [1,1,1]])
        self.assertAlmostEqual(self.DUT.calculate_voltage(*p1v_pts[0]), 1.)
        self.assertAlmostEqual(self.DUT.calculate_voltage(*p1v_pts[1]), 1.)
        self.assertAlmostEqual(self.DUT.calculate_voltage(*m1v_pts[0]), -1.)
        self.assertAlmostEqual(self.DUT.calculate_voltage(*m1v_pts[1]), -1.)
        self.assertAlmostEqual(self.DUT.calculate_voltage(*p0v_pts), 0.)


class test_ComplexVoltageAlongLine(unittest.TestCase):
    def setUp(self):
        self.mesh = dolfin.UnitCube(3,3,3)
        self.V = dolfin.FunctionSpace(self.mesh, "Nedelec 1st kind H(curl)", 3)
        self.u_r = dolfin.interpolate(
            dolfin.Expression(('0','0', '2*x[2]')), self.V)
        self.u_i = dolfin.interpolate(
            dolfin.Expression(('0','0', '-x[2]*x[2]')), self.V)

        self.x = self.u_r.vector().array() + 1j*self.u_i.vector().array()