예제 #1
0
def make_source_and_target_points(side,
                                  inner_radius,
                                  outer_radius,
                                  ambient_dim,
                                  nsources=10,
                                  ntargets=20):
    if side == -1:
        test_src_geo_radius = outer_radius
        test_tgt_geo_radius = inner_radius
    elif side == +1:
        test_src_geo_radius = inner_radius
        test_tgt_geo_radius = outer_radius
    elif side == "scat":
        test_src_geo_radius = outer_radius
        test_tgt_geo_radius = outer_radius
    else:
        raise ValueError(f"unknown side: {side}")

    from pytential.source import PointPotentialSource
    point_sources = make_circular_point_group(ambient_dim,
                                              nsources,
                                              test_src_geo_radius,
                                              func=lambda x: x**1.5)
    point_source = PointPotentialSource(point_sources)

    from pytential.target import PointsTarget
    test_targets = make_circular_point_group(ambient_dim, ntargets,
                                             test_tgt_geo_radius)
    point_target = PointsTarget(test_targets)

    return point_source, point_target
예제 #2
0
    def get_source(self, actx):
        if self.is_interior:
            source_ctr = np.array([[0.35, 0.1, 0.15]]).T
        else:
            source_ctr = np.array([[5, 0.1, 0.15]]).T

        source_rad = 0.3

        sources = source_ctr + source_rad * 2 * (np.random.rand(3, 10) - 0.5)
        from pytential.source import PointPotentialSource
        return PointPotentialSource(actx.from_numpy(sources))
예제 #3
0
    def get_source(self, queue):
        if self.is_interior:
            source_ctr = np.array([[0.35, 0.1, 0.15]]).T
        else:
            source_ctr = np.array([[5, 0.1, 0.15]]).T

        source_rad = 0.3

        sources = source_ctr + source_rad * 2 * (np.random.rand(3, 10) - 0.5)
        from pytential.source import PointPotentialSource
        return PointPotentialSource(queue.context,
                                    cl.array.to_device(queue, sources))
예제 #4
0
    np.random.seed(22)
    source_charges = np.random.randn(point_sources.shape[1])
    source_charges[-1] = -np.sum(source_charges[:-1])
    source_charges = source_charges.astype(dtype)
    assert np.sum(source_charges) < 1e-15

    source_charges_dev = cl.array.to_device(queue, source_charges)

    # }}}

    # {{{ establish BCs

    from pytential.source import PointPotentialSource
    from pytential.target import PointsTarget

    point_source = PointPotentialSource(cl_ctx, point_sources)

    pot_src = sym.IntG(
        # FIXME: qbx_forced_limit--really?
        knl,
        sym.var("charges"),
        qbx_forced_limit=None,
        **knl_kwargs)

    test_direct = bind((point_source, PointsTarget(test_targets)),
                       pot_src)(queue,
                                charges=source_charges_dev,
                                **concrete_knl_kwargs)

    if case.bc_type == "dirichlet":
        bc = bind((point_source, density_discr),
예제 #5
0
def get_bvp_error(lpot_source, fmm_order, qbx_order, k=0):
    # This returns a tuple (err_l2, err_linf, nit).
    queue = cl.CommandQueue(lpot_source.cl_context)

    lpot_source = lpot_source.copy(
        qbx_order=qbx_order,
        fmm_level_to_order=(False if fmm_order is False else
                            lambda *args: fmm_order))

    d = lpot_source.ambient_dim

    assert k == 0  # Helmholtz would require a different representation

    from sumpy.kernel import LaplaceKernel, HelmholtzKernel
    lap_k_sym = LaplaceKernel(d)
    if k == 0:
        k_sym = lap_k_sym
        knl_kwargs = {}
    else:
        k_sym = HelmholtzKernel(d)
        knl_kwargs = {"k": sym.var("k")}

    density_discr = lpot_source.density_discr

    # {{{ find source and target points

    source_angles = (np.pi / 2 +
                     np.linspace(0,
                                 2 * np.pi * BVP_EXPERIMENT_N_ARMS,
                                 BVP_EXPERIMENT_N_ARMS,
                                 endpoint=False)) / BVP_EXPERIMENT_N_ARMS
    source_points = 0.75 * np.array([
        np.cos(source_angles),
        np.sin(source_angles),
    ])
    target_angles = (np.pi + np.pi / 2 +
                     np.linspace(0,
                                 2 * np.pi * BVP_EXPERIMENT_N_ARMS,
                                 BVP_EXPERIMENT_N_ARMS,
                                 endpoint=False)) / BVP_EXPERIMENT_N_ARMS
    target_points = 1.5 * np.array([
        np.cos(target_angles),
        np.sin(target_angles),
    ])

    np.random.seed(17)
    source_charges = np.random.randn(BVP_EXPERIMENT_N_ARMS)

    source_points_dev = cl.array.to_device(queue, source_points)
    target_points_dev = cl.array.to_device(queue, target_points)
    source_charges_dev = cl.array.to_device(queue, source_charges)

    from pytential.source import PointPotentialSource
    from pytential.target import PointsTarget

    point_source = PointPotentialSource(lpot_source.cl_context,
                                        source_points_dev)

    pot_src = sym.IntG(
        # FIXME: qbx_forced_limit--really?
        k_sym,
        sym.var("charges"),
        qbx_forced_limit=None,
        **knl_kwargs)

    ref_direct = bind((point_source, PointsTarget(target_points_dev)),
                      pot_src)(queue, charges=source_charges_dev,
                               **knl_kwargs).get()

    sym_sqrt_j = sym.sqrt_jac_q_weight(density_discr.ambient_dim)

    bc = bind((point_source, density_discr),
              sym.normal_derivative(density_discr.ambient_dim,
                                    pot_src,
                                    where=sym.DEFAULT_TARGET))(
                                        queue,
                                        charges=source_charges_dev,
                                        **knl_kwargs)

    rhs = bind(density_discr, sym.var("bc") * sym_sqrt_j)(queue, bc=bc)

    # }}}

    # {{{ solve

    bound_op = bind(
        lpot_source,
        -0.5 * sym.var("u") + sym_sqrt_j * sym.Sp(k_sym,
                                                  sym.var("u") / sym_sqrt_j,
                                                  qbx_forced_limit="avg",
                                                  **knl_kwargs))

    from pytential.solve import gmres
    gmres_result = gmres(bound_op.scipy_op(queue, "u", np.float64,
                                           **knl_kwargs),
                         rhs,
                         tol=1e-10,
                         stall_iterations=100,
                         progress=True,
                         hard_failure=True)

    u = gmres_result.solution

    # }}}

    points_target = PointsTarget(target_points_dev)
    bound_tgt_op = bind((lpot_source, points_target),
                        sym.S(k_sym,
                              sym.var("u") / sym_sqrt_j,
                              qbx_forced_limit=None))

    test_via_bdry = bound_tgt_op(queue, u=u).get()

    err = ref_direct - test_via_bdry

    err_l2 = la.norm(err, 2) / la.norm(ref_direct, 2)
    err_linf = la.norm(err, np.inf) / la.norm(ref_direct, np.inf)
    return err_l2, err_linf, gmres_result.iteration_count