Esempio n. 1
0
def test_mean_curvature(ctx_factory,
                        discr_name,
                        resolutions,
                        discr_and_ref_mean_curvature_getter,
                        visualize=False):
    ctx = ctx_factory()
    queue = cl.CommandQueue(ctx)
    actx = PyOpenCLArrayContext(queue)

    from pytools.convergence import EOCRecorder
    eoc = EOCRecorder()

    for r in resolutions:
        discr, ref_mean_curvature = \
                discr_and_ref_mean_curvature_getter(actx, r)
        mean_curvature = bind(discr,
                              sym.mean_curvature(discr.ambient_dim))(actx)

        h = 1.0 / r
        from meshmode.dof_array import flat_norm
        h_error = flat_norm(mean_curvature - ref_mean_curvature, np.inf)
        eoc.add_data_point(h, h_error)
    print(eoc)

    order = min([g.order for g in discr.groups])
    assert eoc.order_estimate() > order - 1.1
Esempio n. 2
0
 def operator(self, sigma):
     """
     Returns the two second kind integral equations.
     """
     rep = self.representation(sigma, qbx_forced_limit="avg")
     rep_diff = sym.normal_derivative(2, rep)
     int_eq1 = sigma[0] / 2 + rep
     int_eq2 = -sym.mean_curvature(2) * sigma[0] + sigma[1] / 2 + rep_diff
     return np.array([int_eq1, int_eq2])
Esempio n. 3
0
    def operator(self,
                 sigma: sym.var,
                 mean_curvature: Optional[sym.var] = None,
                 **kwargs) -> sym.var:
        """
        :arg mean_curvature: an expression for the mean curvature that can be
            used in the construction of the operator.
        :returns: a Fredholm integral equation of the second kind for the
            Beltrami PDE with the unknown density *sigma*.
        """
        from sumpy.kernel import LaplaceKernel
        if isinstance(self.kernel, LaplaceKernel):
            raise TypeError(
                f"{type(self).__name__} does not support the Laplace "
                "kernel, use LaplaceBeltramiOperator instead")

        if mean_curvature is None:
            mean_curvature = sym.mean_curvature(self.ambient_dim, dim=self.dim)

        kappa = self.dim * mean_curvature
        context = self.kernel_arguments.copy()
        context.update(kwargs)

        knl = self.kernel
        lknl = LaplaceKernel(knl.dim)

        # {{{ layer potentials

        # laplace
        S0 = partial(sym.S, lknl, qbx_forced_limit=+1, **kwargs)  # noqa: N806
        D0 = partial(sym.D, lknl, qbx_forced_limit="avg",
                     **kwargs)  # noqa: N806
        Sp0 = partial(sym.Sp, lknl, qbx_forced_limit="avg",
                      **kwargs)  # noqa: N806
        Dp0 = partial(sym.Dp, lknl, qbx_forced_limit="avg",
                      **kwargs)  # noqa: N806

        # base
        S = partial(sym.S, knl, qbx_forced_limit=+1, **context)  # noqa: N806
        Sp = partial(sym.Sp, knl, qbx_forced_limit="avg",
                     **context)  # noqa: N806
        Spp = partial(sym.Spp, knl, qbx_forced_limit="avg",
                      **context)  # noqa: N806

        # }}}

        if self.precond == "left":
            # similar to 6.2 in [ONeil2017]
            op = (sigma / 4 - D0(D0(sigma)) + S(kappa * Sp(sigma)) +
                  S(Spp(sigma) + Dp0(sigma)) - S(Dp0(sigma)) + S0(Dp0(sigma)))
        else:
            # similar to 6.2 in [ONeil2017]
            op = (sigma / 4 - Sp0(Sp0(sigma)) +
                  (Spp(S(sigma)) + Dp0(S(sigma))) - Dp0(S(sigma) - S0(sigma)) +
                  kappa * Sp(S(sigma)))

        return op
Esempio n. 4
0
def plot_solution(actx, vis, filename, discr, t, x):
    names_and_fields = []

    try:
        from pytential import bind, sym
        kappa = bind(discr, sym.mean_curvature(discr.ambient_dim))(actx)
        names_and_fields.append(("kappa", kappa))
    except ImportError:
        pass

    vis.write_vtk_file(filename, names_and_fields, overwrite=True)
Esempio n. 5
0
    def operator(self,
                 sigma: sym.var,
                 mean_curvature: Optional[sym.var] = None,
                 **kwargs) -> sym.var:
        """
        :arg mean_curvature: an expression for the mean curvature that can be
            used in the construction of the operator.
        :returns: a Fredholm integral equation of the second kind for the
            Laplace-Beltrami PDE with the unknown density *sigma*.
        """
        if mean_curvature is None:
            mean_curvature = sym.mean_curvature(self.ambient_dim, dim=self.dim)

        kappa = self.dim * mean_curvature
        context = self.kernel_arguments.copy()
        context.update(kwargs)

        knl = self.kernel

        # {{{ layer potentials

        S = partial(sym.S, knl, qbx_forced_limit=+1, **context)  # noqa: N806
        Sp = partial(sym.Sp, knl, qbx_forced_limit="avg",
                     **context)  # noqa: N806
        Spp = partial(sym.Spp, knl, qbx_forced_limit="avg",
                      **context)  # noqa: N806
        D = partial(sym.D, knl, qbx_forced_limit="avg",
                    **context)  # noqa: N806
        Dp = partial(sym.Dp, knl, qbx_forced_limit="avg",
                     **context)  # noqa: N806

        def Wl(operand: sym.Expression) -> sym.Expression:  # noqa: N802
            return sym.Ones() * sym.integral(self.ambient_dim, self.dim,
                                             operand)

        def Wr(operand: sym.Expression) -> sym.Expression:  # noqa: N802
            return sym.Ones() * sym.integral(self.ambient_dim, self.dim,
                                             operand)

        # }}}

        if self.precond == "left":
            # NOTE: based on Lemma 3.1 in [ONeil2017] for :math:`-\Delta_\Gamma`
            op = (sigma / 4 - D(D(sigma)) + S(Spp(sigma) + Dp(sigma)) +
                  S(kappa * Sp(sigma)) - S(Wl(S(sigma))))
        else:
            # NOTE: based on Lemma 3.2 in [ONeil2017] for :math:`-\Delta_\Gamma`
            op = (sigma / 4 - Sp(Sp(sigma)) + (Spp(S(sigma)) + Dp(S(sigma))) +
                  kappa * Sp(S(sigma)) + Wr(S(S(sigma))))

        return op
Esempio n. 6
0
    def operator(self, sigma, **kwargs):
        """
        :param u: symbolic variable for the density.
        :param kwargs: additional keyword arguments passed on to the layer
            potential constructor.

        :returns: the second kind integral operator for the clamped plate
            problem from [Farkas1990]_.
        """
        rep = self.representation(sigma, qbx_forced_limit="avg", **kwargs)
        drep_dn = sym.normal_derivative(self.dim, rep)

        int_eq1 = sigma[0] / 2 + rep
        int_eq2 = -sym.mean_curvature(self.dim) * sigma[0] + sigma[1] / 2 + drep_dn

        return np.array([int_eq1, int_eq2])
Esempio n. 7
0
            fig.savefig(f"{filename}_y")
            plt.close(fig)
        else:
            from meshmode.discretization.visualization import make_visualizer
            vis = make_visualizer(actx, density_discr,
                    vis_order=case.target_order,
                    force_equidistant=True)

            ref_error = actx.np.abs(result - ref_result) + 1.0e-16

            from pytential.symbolic.primitives import _scaled_max_curvature
            scaled_kappa = bind(places,
                    _scaled_max_curvature(places.ambient_dim),
                    auto_where=case.name)(actx)
            kappa = bind(places,
                    sym.mean_curvature(places.ambient_dim),
                    auto_where=case.name)(actx)

            vis.write_vtk_file(f"{filename}.vtu", [
                ("result", result),
                ("ref", ref_result),
                ("error", ref_error),
                ("log_error", actx.np.log10(ref_error)),
                ("kappa", kappa - 1.0),
                ("scaled_kappa", scaled_kappa),
                ], use_high_order=True, overwrite=True)

    return h_max, error


class StokesletIdentity: