Example #1
0
def test_l2_project(k):
    npart = 20
    mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, 5, 5)
    ncells = mesh.topology.index_map(2).size_local
    x, c = pyleopart.mesh_fill(mesh, ncells * npart)
    p = pyleopart.Particles(x, c)
    p.add_field("v", [2])
    vp = p.field("v")

    Q = dolfinx.function.VectorFunctionSpace(mesh, ("DG", k))
    pbasis = pyleopart.get_particle_contributions(p, Q._cpp_object)

    def sq_val(x):
        return [x[0]**k, x[1]**k]

    u = dolfinx.function.Function(Q)
    u.interpolate(sq_val)

    # Transfer from Function "u" to (particle) field "v"
    pyleopart.transfer_to_particles(p, vp, u._cpp_object, pbasis)

    #Init and conduct l2projection
    v = dolfinx.function.Function(Q)
    l2project = pyleopart.L2Project(p, v._cpp_object, "v")
    l2project.solve()

    l2_error = mesh.mpi_comm().allreduce(assemble_scalar(
        dot(u - v, u - v) * dx),
                                         op=MPI.SUM)
    assert l2_error < 1e-15
Example #2
0
def test_interpolate_project_dg_vector(k):
    npart = 20
    mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, 5, 5)
    ncells = mesh.topology.index_map(2).size_local
    x, c = pyleopart.mesh_fill(mesh, ncells * npart)
    p = pyleopart.Particles(x, c)

    Q = dolfinx.function.VectorFunctionSpace(mesh, ("DG", k))
    pbasis = pyleopart.get_particle_contributions(p, Q._cpp_object)

    def sq_val(x):
        return [x[0]**k, x[1]**k]

    u = dolfinx.function.Function(Q)
    u.interpolate(sq_val)

    p.add_field("v", [2])
    v = p.field("v")

    # Transfer from Function "u" to field "v"
    pyleopart.transfer_to_particles(p, v, u._cpp_object, pbasis)

    # Transfer from field "v" back to Function "u"
    pyleopart.transfer_to_function(u._cpp_object, p, v, pbasis)

    p.add_field("w", [2])
    w = p.field("w")
    # Transfer from Function "u" to field "w"
    pyleopart.transfer_to_particles(p, w, u._cpp_object, pbasis)

    # Compare fields "w" and "x"(squared)
    for pidx in range(len(x)):
        expected = p.field("x").data(pidx)**k
        assert np.isclose(p.field("w").data(pidx), expected).all()
Example #3
0
def test_simple_mesh_fill():
    np = 20
    mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, 5, 5)
    ncells = mesh.topology.index_map(2).size_local
    x, c = pyleopart.mesh_fill(mesh, ncells * np)
    x0 = x[0, :]
    p = pyleopart.Particles(x, c)
    assert ((p.field("x").data(0) == x0).all())
Example #4
0
def test_add_field():
    n = 20
    x = np.random.rand(n, 3)
    p = pyleopart.Particles(x, [0] * n)
    cp = p.cell_particles()
    assert (len(cp[0]) == n)
    p.add_field("w", [3])
    assert (p.field("w").value_shape == [3])
    p.add_field("u", [3, 2])
    u = p.field("u")
    assert (u.value_shape == [3, 2])
    assert (u.value_size == 6)
    with pytest.raises(IndexError):
        r = p.field("r")
Example #5
0
def test_add_delete_particles():
    n = 20
    x = np.random.rand(n, 3)
    p = pyleopart.Particles(x, list(range(n)))
    x = np.random.rand(3)

    # Add to cell 12
    p.add_particle(x, 12)
    cp = p.cell_particles()
    assert (len(cp[12]) == 2)

    # Delete from cell 1
    p.delete_particle(0, 0)
    cp = p.cell_particles()
    assert (len(cp[0]) == 0)

    # Add to cell 0
    p.add_particle(x, 1)
    cp = p.cell_particles()
    assert (cp[1][1] == 0)
Example #6
0
def test_simple_create():
    x = np.array([[1, 2, 3]], dtype=np.float64)
    p = pyleopart.Particles(x, [0])
    cp = p.cell_particles()
    assert (cp[0][0] == 0)
    assert ((p.field("x").data(0) == [1, 2, 3]).all())
Example #7
0
def test_l2_project_bounded(k, lb, ub):
    npart = 20
    mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, 20, 20)
    ncells = mesh.topology.index_map(2).size_local
    x, c = pyleopart.mesh_fill(mesh, ncells * npart)
    p = pyleopart.Particles(x, c)
    p.add_field("v", [1])
    vp = p.field("v")

    Q = dolfinx.function.FunctionSpace(mesh, ("DG", k))
    pbasis = pyleopart.get_particle_contributions(p, Q._cpp_object)

    class SlottedDisk:
        def __init__(self,
                     radius,
                     center,
                     width,
                     depth,
                     lb=0.0,
                     ub=1.0,
                     **kwargs):
            self.r = radius
            self.width = width
            self.depth = depth
            self.center = center
            self.lb = lb
            self.ub = ub

        def eval(self, x):
            values = np.empty((x.shape[1], ))
            xc = self.center[0]
            yc = self.center[1]

            # The mask is True within region of slotted disk and False elsewhere
            mask = (((x[0] - xc)**2 +
                     (x[1] - yc)**2 <= self.r**2)) & np.invert(
                         ((x[0] > (xc - self.width)) & (x[0] <=
                                                        (xc + self.width)) &
                          (x[1] >= yc + self.depth)))
            return mask * self.ub + np.invert(mask) * self.lb

    # Add disturbance to lower and upper bound, to make sure the bounded projection return the
    # original bounds
    slotted_disk = SlottedDisk(radius=0.15,
                               center=[0.5, 0.5],
                               width=0.05,
                               depth=0.0,
                               degree=3,
                               lb=lb - 0.1,
                               ub=ub + 0.1)
    u = dolfinx.function.Function(Q)
    u.interpolate(slotted_disk.eval)

    # Transfer from Function "u" to (particle) field "v"
    pyleopart.transfer_to_particles(p, vp, u._cpp_object, pbasis)

    #Init and conduct l2projection
    vh = dolfinx.function.Function(Q)
    l2project = pyleopart.L2Project(p, vh._cpp_object, "v")
    l2project.solve(lb, ub)

    # Assert if it stays within bounds
    assert np.min(vh.x.array()) < ub + 1e-12
    assert np.max(vh.x.array()) > lb - 1e-12