diff --git a/pytential/symbolic/primitives.py b/pytential/symbolic/primitives.py index ea59b67652ef5cc1ecdce44fb95ce3c63bd70a49..7667fc0151ea4a62372ca874f374d94652bf01f4 100644 --- a/pytential/symbolic/primitives.py +++ b/pytential/symbolic/primitives.py @@ -1669,6 +1669,16 @@ def normal_derivative(ambient_dim, operand, dim=None, dofdesc=None): * d(operand)) +def normal_second_derivative(ambient_dim, operand, dim=None, dofdesc=None): + d = Derivative() + n = normal(ambient_dim, dim, dofdesc) + nabla = d.dnabla(ambient_dim) + + return d.resolve(n.scalar_product( + n.scalar_product(nabla) * d(d.resolve(nabla * d(operand))) + )) + + def Sp(kernel, *args, **kwargs): dofdesc = kwargs.get("target") if "qbx_forced_limit" not in kwargs: @@ -1702,9 +1712,9 @@ def Spp(kernel, *args, **kwargs): dim = kwargs.pop("dim", None) dofdesc = kwargs.get("target") - return normal_derivative( + return normal_second_derivative( ambient_dim, - Sp(kernel, *args, **kwargs), + S(kernel, *args, **kwargs), dim=dim, dofdesc=dofdesc) diff --git a/test/test_symbolic.py b/test/test_symbolic.py index 508ff2961b7b46a3a9b2eaa71530c1c8f4d58076..12145d692b12616037f54c20839fa579510071f5 100644 --- a/test/test_symbolic.py +++ b/test/test_symbolic.py @@ -201,6 +201,23 @@ def test_expr_pickling(): # }}} +# {{{ test basic layer potentials + +@pytest.mark.parametrize("lpot_class", [ + sym.S, sym.Sp, sym.Spp, sym.D, sym.Dp + ]) +def test_layer_potential_construction(lpot_class, ambient_dim=2): + from sumpy.kernel import LaplaceKernel + + kernel_sym = LaplaceKernel(ambient_dim) + density_sym = sym.var("sigma") + lpot_sym = lpot_class(kernel_sym, density_sym, qbx_forced_limit=None) + + assert lpot_sym is not None + +# }}} + + @pytest.mark.parametrize(("name", "source_discr_stage", "target_granularity"), [ ("default", None, None), ("default-explicit", sym.QBX_SOURCE_STAGE1, sym.GRANULARITY_NODE),