Esempio n. 1
0
def test_magnetic_scalar_potential_coupling():

    mesh = load_example_mesh("unit_disc")

    points = mesh.vertices + np.array([0, 0, 20])

    U_1_chunk = mesh_magnetics.scalar_potential_coupling(mesh,
                                                         points,
                                                         Nchunks=1)
    U_2_chunk = mesh_magnetics.scalar_potential_coupling(mesh,
                                                         points,
                                                         Nchunks=2)

    assert_allclose(U_1_chunk, U_2_chunk, atol=1e-16)

    U_exact = mesh_magnetics.scalar_potential_coupling(mesh,
                                                       points,
                                                       approx_far=False)
    U_approx_far = mesh_magnetics.scalar_potential_coupling(mesh,
                                                            points,
                                                            approx_far=True,
                                                            margin=0.5)

    assert_allclose(U_exact,
                    U_approx_far,
                    atol=2e-3 * np.mean(np.abs(U_exact)))
def Dmatrix(mesh1, mesh2, Nchunks=100):
    """
    "Double-layer potential" coupling between two meshes
    using a Galerkin method with hat basis
    
    Discretize integral equations using hat functions
    on on both meshes. Potential from mesh1 hat functions
    is calculated analytically and integrated over the 
    hat functions of mesh2 numerically

    Parameters
    ----------
    mesh1 : Trimesh object
    mesh2 : Trimesh object
    Nchunks : int, optional
        Number of chunks in the potential calculation. The default is 100.

    Returns
    -------
    None.

    """
    face_points = mesh2.vertices[mesh2.faces]
    weights = np.array([[0.5, 0.25, 0.25], [0.25, 0.5, 0.25],
                        [0.25, 0.25, 0.5]])
    # Combine vertices for quadrature points
    Rquad = np.einsum("...ij,ik->...kj", face_points, weights)
    R = Rquad.reshape(-1, 3)
    U = scalar_potential_coupling(mesh1,
                                  R,
                                  Nchunks,
                                  multiply_coeff=False,
                                  approx_far=True)

    face_areas = mesh2.area_faces
    # Reshape and multiply by quadrature weights
    Dcomps = U.reshape(Rquad.shape[:2] +
                       (len(mesh2.vertices), )) * (face_areas[:, None, None] /
                                                   3)
    # Sum up the quadrature points
    D = mesh2.faces_sparse @ Dcomps[:, 0, :]
    D += mesh2.faces_sparse @ Dcomps[:, 1, :]
    D += mesh2.faces_sparse @ Dcomps[:, 2, :]

    if mesh1 is mesh2:
        # Recalculate diagonals
        d = np.diag(D)
        D -= np.diag(d)
        # Make rows sum to -2*pi*(vertex area), should be more accurate
        d2 = -2 * np.pi * mass_matrix(mesh2, lumped=False) - np.diag(
            D.sum(axis=1))
        D += d2
        # Make D solvable by adding rank-1 matrix
        D += np.ones_like(D) * np.max(np.linalg.svd(D, False,
                                                    False)) / D.shape[1]

    return D
# Load simple plane mesh that is centered on the origin
plane = load_example_mesh("10x10_plane_hires")
plane.apply_scale(scaling_factor)
# Rotate to x-plane
t = np.eye(4)
t[1:3, 1:3] = np.array([[0, 1], [-1, 0]])
plane.apply_transform(t)
# Subdivide face close to the mesh
from trimesh.proximity import signed_distance

dd = signed_distance(mesh, plane.triangles_center)
plane = plane.subdivide(np.flatnonzero(abs(dd) < 0.005))
dd = signed_distance(mesh, plane.triangles_center)
plane = plane.subdivide(np.flatnonzero(abs(dd) < 0.002))

UB = scalar_potential_coupling(mesh, plane.vertices, multiply_coeff=False)
mask = np.sum(UB, axis=1)
mask = mask > -0.5

Ua, Ub = basis_potentials(plane.vertices, 6)
bsuh = SuhBasis(mesh, 48)
# UB = scalar_potential_coupling(mesh, plane.vertices)
Usuh = UB @ bsuh.basis

sphere = trimesh.creation.icosphere(radius=0.02)
Ua_mesh, Ub_mesh = basis_potentials(sphere.vertices, 5)
UB_mesh = scalar_potential_coupling(mesh, mesh_field.vertices)
Usuh_mesh = UB_mesh @ bsuh.basis

#%%
comps = [0, 5, 13, 17]
Esempio n. 4
0
# Plot potential on the mesh
mlab.figure("Potential on the boundary", bgcolor=(1, 1, 1))
m = mlab.triangular_mesh(*mesh.vertices.T, mesh.faces, scalars=u, colormap="bwr")
m.actor.mapper.interpolate_scalars_before_mapping = True
m.module_manager.scalar_lut_manager.number_of_colors = 32
#%% Compute fields on a plane
# Load plane for the visualization of the potential
plane = load_example_mesh("10x10_plane_hires", process=True)
t = np.eye(4)
t[1:3, 1:3] = np.array([[0, 1], [-1, 0]])
plane.apply_transform(t)
plane.apply_scale(0.3)
plane = plane.subdivide()

Uplane = scalar_potential_coupling(
    mesh, plane.vertices, multiply_coeff=False, approx_far=True
)

uprim = phi0x(plane.vertices)
usec = (mu_r - 1) / (4 * np.pi) * Uplane @ u
uplane = uprim + usec

# Meshgrid on the same plane for the bfield
X, Y = np.meshgrid(
    np.linspace(-1.5, 1.5, 50), np.linspace(-1.5, 1.5, 50), indexing="ij"
)
pp = np.zeros((50 * 50, 3))
pp[:, 0] = X.flatten()
pp[:, 1] = Y.flatten()

Bplane = magnetic_field_coupling(mesh, pp, analytic=True)
Esempio n. 5
0
    s2.actor.property.line_width = 3.0


mlab.figure(bgcolor=(1, 1, 1))
plot_element()

#%%
#%% Scalar potential
points = np.array([[0.01, 1, 1], [0.01, 1, -1], [0.01, -1, -1], [0.01, -1, 1]
                   ]) * 2
tris = np.array([[0, 1, 2], [2, 3, 0]])
mesh2 = trimesh.Trimesh(points, tris)
for ii in range(7):
    mesh2 = mesh2.subdivide()

U = scalar_potential_coupling(mesh, mesh2.vertices,
                              multiply_coeff=True) @ scalars
mlab.figure(bgcolor=(1, 1, 1))
s3 = mlab.triangular_mesh(*mesh2.vertices.T,
                          mesh2.faces,
                          scalars=U,
                          colormap="bwr")
s3.enable_contours = True
s3.contour.minimum_contour = -5.2e-07
s3.contour.maximum_contour = 5.2e-07
s3.actor.property.render_lines_as_tubes = True
s3.actor.property.line_width = 3.0
s3.scene.x_plus_view()
plot_element()

#%%
#%% Vector potential