Example #1
0
def test_surface():
    """test whether the surface is calculated correctly"""
    for dim in [1, 2, 3]:
        radius = 1 + random.random()
        eps = 1e-10
        vol1 = spherical.volume_from_radius(radius + eps, dim=dim)
        vol0 = spherical.volume_from_radius(radius, dim=dim)
        surface_approx = (vol1 - vol0) / eps
        surface = spherical.surface_from_radius(radius, dim=dim)
        assert surface == pytest.approx(surface_approx, rel=1e-3)

        r2s = spherical.make_surface_from_radius_compiled(dim)
        assert surface == pytest.approx(r2s(radius))

        if dim == 1:
            with pytest.raises(RuntimeError):
                spherical.radius_from_surface(surface, dim=dim)
        else:
            assert spherical.radius_from_surface(
                surface, dim=dim) == pytest.approx(radius)
Example #2
0
    def get_triangulation(self, resolution: float = 1) -> Dict[str, Any]:
        """obtain a triangulated shape of the droplet surface

        Args:
            resolution (float):
                The length of a typical triangulation element. This affects the
                resolution of the triangulation.

        Returns:
            dict: A dictionary containing information about the triangulation. The exact
            details depend on the dimension of the problem.
        """
        if self.dim == 2:
            num = max(3, int(np.ceil(self.surface_area / resolution)))
            angles = np.linspace(0, 2 * np.pi, num + 1, endpoint=True)
            vertices = self.interface_position(angles)
            lines = np.c_[np.arange(num), np.arange(1, num + 1) % num]
            return {"vertices": vertices, "lines": lines}

        elif self.dim == 3:
            # estimate the number of triangles covering the surface
            try:
                surface_area = self.surface_area
            except (NotImplementedError, AttributeError):
                # estimate surface area from 3d spherical droplet
                surface_area = spherical.surface_from_radius(self.radius,
                                                             dim=3)
            num_est = (4 * surface_area) / (np.sqrt(3) * resolution**2)
            tri = triangulated_spheres.get_triangulation(num_est)

            φ, θ = tri["angles"][:, 0], tri["angles"][:, 1]
            return {
                "vertices": self.interface_position(θ, φ),
                "triangles": tri["cells"],
            }

        else:
            raise NotImplementedError(
                f"Triangulation not implemented for {self.dim}d")
Example #3
0
 def surface_area(self) -> float:
     """float: surface area of the droplet"""
     return spherical.surface_from_radius(self.radius, self.dim)