def test_shpere_pot_rotation_x(self, sensor_setup): """ V should be invariant to rotations """ tx = np.pi / 3 Mx = np.array(((1, 0, 0), (0, np.cos(tx), -np.sin(tx)), (0, np.sin(tx), np.cos(tx))), dtype=float) ty = np.pi / 2 My = np.array(((np.cos(ty), 0, np.sin(ty)), (0, 1, 0), (-np.sin(ty), 0, np.cos(ty))), dtype=float) tz = np.pi / 3 Mz = np.array(((np.cos(tz), -np.sin(tz), 0), (np.sin(tz), np.cos(tz), 0), (0, 0, 1)), dtype=float) R = Mx.dot(My.dot(Mz)) cathode = [1, 0, 0] anode = [-1, 0, 0] cond = [1.0, 0.5, 1] radii = [0.4, 0.5, 1] pot1 = sphere.potential_3layers_surface_electrodes( radii, cond, anode, cathode, sensor_setup) cathode = R.dot(cathode) anode = R.dot(anode) sensors = np.array([R.dot(p) for p in sensor_setup]) pot2 = sphere.potential_3layers_surface_electrodes( radii, cond, anode, cathode, sensors) np.testing.assert_allclose(pot1, pot2, rtol=1e-3, atol=1e-5)
def test_sphere_homogeneous_cond(self, sensor_setup): """ The potential should be the same, independent of the radii """ cathode = [1, 0, 0] anode = [-1, 0, 0] cond = [1, 1, 1] radii = [0.7, 0.85, 1] pot1 = sphere.potential_3layers_surface_electrodes( radii, cond, anode, cathode, sensor_setup) radii = [0.1, 0.2, 1] pot2 = sphere.potential_3layers_surface_electrodes( radii, cond, anode, cathode, sensor_setup) np.testing.assert_allclose(pot1, pot2)
def test_dirichlet_problem_sphere(self, sphere3_msh): m = sphere3_msh.crop_mesh(elm_type=4) cond = np.ones(len(m.elm.tetrahedra)) cond[m.elm.tag1 == 4] = .01 anode = m.nodes.node_number[m.nodes.node_coord[:, 2].argmax()] cathode = m.nodes.node_number[m.nodes.node_coord[:, 2].argmin()] bcs = [fem.DirichletBC([anode], [1]), fem.DirichletBC([cathode], [-1])] S = fem.FEMSystem(m, cond) A = S.A b = np.zeros(m.nodes.nr) dof_map = S.dof_map for bc in bcs: A, b, dof_map = bc.apply(A, b, dof_map) x = spalg.spsolve(A, b) for bc in bcs: x, dof_map = bc.apply_to_solution(x, dof_map) order = dof_map.inverse.argsort() x = x[order].squeeze() v_analytical = analytical_solutions.potential_3layers_surface_electrodes( [85, 90, 95], [1., .01, 1.], [0, 0, -95], [0, 0, 95], m.nodes.node_coord) v_analytical /= v_analytical[anode - 1] v_analytical -= v_analytical[0] x -= x[0] m.nodedata = [mesh_io.NodeData(v_analytical, 'Analytical'), mesh_io.NodeData(x, 'FEM')] #mesh_io.write_msh(m, '~/Tests/fem.msh') m = m.crop_mesh(3) assert rdm(m.nodedata[0].value, m.nodedata[1].value) < .1
def test_sphere_pot_symmetry_xz(self, sensor_setup): """ V should be symmetric to a reflection along the XY plane """ cathode = [1, 0, 0] anode = [1 / np.sqrt(2), 0, 1 / np.sqrt(2)] cond = [1.0, 0.5, 1] radii = [0.4, 0.5, 1] pot1 = sphere.potential_3layers_surface_electrodes( radii, cond, anode, cathode, sensor_setup) anode = [1 / np.sqrt(2), 0, -1 / np.sqrt(2)] p2 = sensor_setup p2[:, 2] *= -1 pot2 = sphere.potential_3layers_surface_electrodes( radii, cond, anode, cathode, p2) np.testing.assert_array_almost_equal(pot1, pot2)
def test_sphere_pot_continuity(self): """ V should be continuous across interfaces """ cathode = [1, 0, 0] anode = [-1, 0, 0] cond = [1.0, 0.5, 1] radii = [0.4, 0.5, 1] sensor = np.array(((0.5000001, 0, 0), (0.4999999, 0, 0)), dtype=float) pot = sphere.potential_3layers_surface_electrodes( radii, cond, anode, cathode, sensor) np.testing.assert_allclose(pot[0], pot[1], rtol=1e-3)
def test_tdcs_getdp_sphere(self, sphere_el_msh): surface_tags = [1100, 1101] currents = [-1, 1] cond = gmsh.ElementData(np.ones(sphere_el_msh.elm.nr), mesh=cube_msh) cond.value[sphere_el_msh.elm.tag1 == 4] = .01 v = fem.tdcs_getdp(sphere_el_msh, cond, currents, surface_tags) m = copy.deepcopy(sphere_el_msh) m.nodedata = [v] m = m.crop_mesh(3) v_fem = m.nodedata[0].value - m.nodedata[0].value[0] v_analytical = analytical_solutions.potential_3layers_surface_electrodes( [85, 90, 95], [1., .01, 1.], [0, 0, 95], [0, 0, -95], m.nodes.node_coord) v_analytical -= v_analytical[0] rdm = np.linalg.norm( v_fem/np.linalg.norm(v_fem) - v_analytical/np.linalg.norm(v_analytical)) #m.nodedata.append(gmsh.NodeData(v_analytical)) #gmsh.write_msh(m, '~/Tests/tdcs.msh') assert rdm < .2
def test_reciprocity(): cond = [1, 1, 1] radii = [0.7, 0.85, 1] electrodes = np.array(((1, 0, 0), (-1, 0, 0)), dtype=float) dipole_pos = np.array( ((0.5, 0, 0), (0.5 + 1e-10, 0., 0), (0.5, 1e-10, 0), (0.5, 0, 1e-10), (0.5 - 1e-10, 0., 0), (0.5, -1e-10, 0), (0.5, 0, -1e-10)), dtype=float) dipole_moment = np.array((1, 1, 1), dtype=float) pot = sphere.potential_3layers_surface_electrodes(radii, cond, electrodes[0, :], electrodes[1, :], dipole_pos) E_field = (pot[1:4] - pot[4:7]) / 2e-13 dipole_pot = sphere.potential_homogeneous_dipole(1., 1., dipole_pos[0], dipole_moment, electrodes) np.testing.assert_allclose(dipole_pot[0] - dipole_pot[1], -E_field.dot(dipole_moment), rtol=1e-4)