コード例 #1
0
def test_closed_boundary(advection_scheme):
    # FIXME: rk3 scheme does not bounces off the wall properly
    xmin, xmax = 0., 1.
    ymin, ymax = 0., 1.

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10)

    # Particle
    x = np.array([[0.975, 0.475]])

    # Given velocity field:
    vexpr = Constant((1., 0.))
    # Given time do_step:
    dt = 0.05
    # Then bounced position is
    x_bounced = np.array([[0.975, 0.475]])

    p = particles(x, [x, x], mesh)

    V = VectorFunctionSpace(mesh, "CG", 1)
    v = Function(V)
    v.assign(vexpr)

    # Different boundary parts
    bound_left = UnitSquareLeft()
    bound_right = UnitSquareRight()
    bound_top = UnitSquareTop()
    bound_bottom = UnitSquareBottom()

    # Mark all facets
    facet_marker = MeshFunction('size_t', mesh, mesh.topology().dim() - 1)
    facet_marker.set_all(0)

    # Mark as closed
    bound_right.mark(facet_marker, 1)

    # Mark other boundaries as open
    bound_left.mark(facet_marker, 2)
    bound_top.mark(facet_marker, 2)
    bound_bottom.mark(facet_marker, 2)

    if advection_scheme == 'euler':
        ap = advect_particles(p, V, v, facet_marker)
    elif advection_scheme == 'rk2':
        ap = advect_rk2(p, V, v, facet_marker)
    elif advection_scheme == 'rk3':
        ap = advect_rk3(p, V, v, facet_marker)
    else:
        assert False

    # Do one timestep, particle must bounce from wall of
    ap.do_step(dt)
    xpE = p.positions()

    # Check if particle correctly bounced off from closed wall
    xpE_root = comm.gather(xpE, root=0)
    if comm.rank == 0:
        xpE_root = np.float64(np.vstack(xpE_root))
        error = np.linalg.norm(x_bounced - xpE_root)
        assert(error < 1e-10)
コード例 #2
0
def test_l2projection_bounded_3D(polynomial_order, lb, ub):
    xmin, ymin, zmin = 0., 0., 0.
    xmax, ymax, zmax = 1., 1., 1.
    nx = 10

    interpolate_expression = Ball(0.15, [0.5, 0.5, 0.5],
                                  degree=3,
                                  lb=lb,
                                  ub=ub)

    property_idx = 1
    mesh = BoxMesh(Point(xmin, ymin, zmin), Point(xmax, ymax, zmax), nx, nx,
                   nx)

    V = FunctionSpace(mesh, "DG", polynomial_order)

    x = RegularBox(Point(0., 0., 0.), Point(1., 1.,
                                            1.)).generate([100, 100, 100])
    s = assign_particle_values(x, interpolate_expression)

    # Just make a complicated particle, possibly with scalars and vectors mixed
    p = particles(x, [s], mesh)

    vh = Function(V)
    lstsq_rho = l2projection(p, V, property_idx)
    lstsq_rho.project(vh.cpp_object(), lb, ub)

    # Assert if it stays within bounds
    assert np.any(vh.vector().get_local() < ub + 1e-12)
    assert np.any(vh.vector().get_local() > lb - 1e-12)
コード例 #3
0
def test_l2projection_bounded(polynomial_order, lb, ub):
    # Test l2 projection if it stays within bounds given by lb and ub
    interpolate_expression = SlottedDisk(radius=0.15,
                                         center=[0.5, 0.5],
                                         width=0.05,
                                         depth=0.,
                                         degree=3,
                                         lb=lb,
                                         ub=ub)

    xmin, xmax = 0., 1.
    ymin, ymax = 0., 1.

    property_idx = 5

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40)

    V = FunctionSpace(mesh, "DG", polynomial_order)

    x = RandomRectangle(Point(xmin, ymin), Point(xmax,
                                                 ymax)).generate([500, 500])
    s = assign_particle_values(x, interpolate_expression)

    # Just make a complicated particle, possibly with scalars and vectors mixed
    p = particles(x, [x, s, x, x, s], mesh)

    vh = Function(V)
    lstsq_rho = l2projection(p, V, property_idx)
    lstsq_rho.project(vh, lb, ub)

    # Assert if it stays within bounds
    assert np.all(vh.vector().get_local() < ub + 1e-12)
    assert np.all(vh.vector().get_local() > lb - 1e-12)
コード例 #4
0
def test_l2projection(polynomial_order, in_expression):
    # Test l2 projection for scalar and vector valued expression
    interpolate_expression = Expression(in_expression, degree=3)

    xmin, xmax = 0., 1.
    ymin, ymax = 0., 1.

    property_idx = 5

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40)

    if len(interpolate_expression.ufl_shape) == 0:
        V = FunctionSpace(mesh, "DG", polynomial_order)
    elif len(interpolate_expression.ufl_shape) == 1:
        V = VectorFunctionSpace(mesh, "DG", polynomial_order)

    v_exact = Function(V)
    v_exact.interpolate(interpolate_expression)

    x = RandomRectangle(Point(xmin, ymin), Point(xmax,
                                                 ymax)).generate([500, 500])
    s = assign_particle_values(x, interpolate_expression)

    # Just make a complicated particle, possibly with scalars and vectors mixed
    p = particles(x, [x, s, x, x, s], mesh)

    vh = Function(V)
    lstsq_rho = l2projection(p, V, property_idx)
    lstsq_rho.project(vh)

    error_sq = abs(assemble(dot(v_exact - vh, v_exact - vh) * dx))
    assert error_sq < 1e-15
コード例 #5
0
def test_pde_constrained(polynomial_order, in_expression):
    interpolate_expression = Expression(in_expression, degree=3)
    xmin, xmax = 0., 1.
    ymin, ymax = 0., 1.

    property_idx = 1
    dt = 1.
    k = polynomial_order

    # Make mesh
    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40)

    # Make function spaces and functions
    W_e = FiniteElement("DG", mesh.ufl_cell(), k)
    T_e = FiniteElement("DG", mesh.ufl_cell(), 0)
    Wbar_e = FiniteElement("DGT", mesh.ufl_cell(), k)

    W = FunctionSpace(mesh, W_e)
    T = FunctionSpace(mesh, T_e)
    Wbar = FunctionSpace(mesh, Wbar_e)

    psi_h, psi0_h = Function(W), Function(W)
    lambda_h = Function(T)
    psibar_h = Function(Wbar)

    uadvect = Constant((0, 0))

    # Define particles
    x = RandomRectangle(Point(xmin, ymin), Point(xmax,
                                                 ymax)).generate([500, 500])
    s = assign_particle_values(x, interpolate_expression)
    psi0_h.assign(interpolate_expression)

    # Just make a complicated particle, possibly with scalars and vectors mixed
    p = particles(x, [s], mesh)
    p.interpolate(psi0_h, 1)

    # Initialize forms
    FuncSpace_adv = {
        'FuncSpace_local': W,
        'FuncSpace_lambda': T,
        'FuncSpace_bar': Wbar
    }
    forms_pde = FormsPDEMap(mesh, FuncSpace_adv).forms_theta_linear(
        psi0_h, uadvect, dt, Constant(1.0))
    pde_projection = PDEStaticCondensation(mesh, p, forms_pde['N_a'],
                                           forms_pde['G_a'], forms_pde['L_a'],
                                           forms_pde['H_a'], forms_pde['B_a'],
                                           forms_pde['Q_a'], forms_pde['R_a'],
                                           forms_pde['S_a'], [], property_idx)

    # Assemble and solve
    pde_projection.assemble(True, True)
    pde_projection.solve_problem(psibar_h, psi_h, lambda_h, 'none', 'default')

    error_psih = abs(assemble((psi_h - psi0_h) * (psi_h - psi0_h) * dx))
    error_lamb = abs(assemble(lambda_h * lambda_h * dx))

    assert error_psih < 1e-15
    assert error_lamb < 1e-15
コード例 #6
0
def test_failsafe_sweep():
    interpolate_expression = Expression('x[0]', degree=1)
    mesh = UnitSquareMesh(5, 5)
    V = FunctionSpace(mesh, "DG", 1)

    v = Function(V)
    v.assign(interpolate_expression)

    np_min, np_max = 1, 2
    np_failsafe = 4

    # Initialize particles
    x = RandomRectangle(Point(0.0, 0.0), Point(1., 1.)).generate([100, 100])
    s = assign_particle_values(x, interpolate_expression)
    # Broadcast to other procs
    x = comm.bcast(x, root=0)
    s = comm.bcast(s, root=0)

    property_idx = 1
    p = particles(x, [s], mesh)
    AD = AddDelete(p, np_min, np_max, [v])
    AD.do_sweep_failsafe(np_failsafe)

    # Must recover linear
    lstsq_rho = l2projection(p, V, property_idx)
    lstsq_rho.project(v.cpp_object())

    error = sqrt(
        assemble(
            (v - interpolate_expression) * (v - interpolate_expression) * dx))

    assert len(p.positions() == mesh.num_cells() * np_failsafe)
    assert error < 1e-12
コード例 #7
0
def test_advect_periodic(advection_scheme):
    # FIXME: this unit test is sensitive to the ordering of the particle
    # array, i.e. xp0_root and xpE_root may contain exactly the same entries
    # but only in a different order. This will return an error right now

    xmin, xmax = 0., 1.
    ymin, ymax = 0., 1.
    pres = 3

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10)

    lims = np.array([[xmin, xmin, ymin, ymax], [xmax, xmax, ymin, ymax],
                     [xmin, xmax, ymin, ymin], [xmin, xmax, ymax, ymax]])

    vexpr = Constant((1., 1.))
    V = VectorFunctionSpace(mesh, "CG", 1)

    x = RandomRectangle(Point(0.05, 0.05), Point(0.15, 0.15)).generate([pres, pres])
    x = comm.bcast(x, root=0)
    dt = 0.05

    v = Function(V)
    v.assign(vexpr)

    p = particles(x, [x*0, x**2], mesh)

    if advection_scheme == 'euler':
        ap = advect_particles(p, V, v, 'periodic', lims.flatten())
    elif advection_scheme == 'rk2':
        ap = advect_rk2(p, V, v, 'periodic', lims.flatten())
    elif advection_scheme == 'rk3':
        ap = advect_rk3(p, V, v, 'periodic', lims.flatten())
    else:
        assert False

    xp0 = p.positions()
    t = 0.
    while t < 1.-1e-12:
        ap.do_step(dt)
        t += dt
    xpE = p.positions()

    # Check if position correct
    xp0_root = comm.gather(xp0, root=0)
    xpE_root = comm.gather(xpE, root=0)

    num_particles = p.number_of_particles()

    if comm.Get_rank() == 0:
        xp0_root = np.float32(np.vstack(xp0_root))
        xpE_root = np.float32(np.vstack(xpE_root))

        # Sort on x positions
        xp0_root = xp0_root[xp0_root[:, 0].argsort(), :]
        xpE_root = xpE_root[xpE_root[:, 0].argsort(), :]

        error = np.linalg.norm(xp0_root - xpE_root)
        assert error < 1e-10
        assert num_particles - pres**2 == 0
コード例 #8
0
def test_advect_periodic(advection_scheme):
    xmin, ymin, zmin = 0., 0., 0.
    xmax, ymax, zmax = 1., 1., 1.
    pres = 10

    mesh = UnitCubeMesh(10, 10, 10)

    lims = np.array([[xmin, xmin, ymin, ymax, zmin, zmax],
                     [xmax, xmax, ymin, ymax, zmin, zmax],
                     [xmin, xmax, ymin, ymin, zmin, zmax],
                     [xmin, xmax, ymax, ymax, zmin, zmax],
                     [xmin, xmax, ymin, ymax, zmin, zmin],
                     [xmin, xmax, ymin, ymax, zmax, zmax]])

    vexpr = Constant((1., 1., 1.))
    V = VectorFunctionSpace(mesh, "CG", 1)
    v = Function(V)
    v.assign(vexpr)

    x = RandomBox(Point(0., 0., 0.), Point(1., 1.,
                                           1.)).generate([pres, pres, pres])
    x = comm.bcast(x, root=0)
    dt = 0.05

    p = particles(x, [x * 0, x**2], mesh)

    if advection_scheme == 'euler':
        ap = advect_particles(p, V, v, 'periodic', lims.flatten())
    elif advection_scheme == 'rk2':
        ap = advect_rk2(p, V, v, 'periodic', lims.flatten())
    elif advection_scheme == 'rk3':
        ap = advect_rk3(p, V, v, 'periodic', lims.flatten())
    else:
        assert False

    xp0 = p.positions()
    t = 0.
    while t < 1. - 1e-12:
        ap.do_step(dt)
        t += dt
    xpE = p.positions()

    xp0_root = comm.gather(xp0, root=0)
    xpE_root = comm.gather(xpE, root=0)

    assert len(xp0) == len(xpE)
    num_particles = p.number_of_particles()

    if comm.Get_rank() == 0:
        xp0_root = np.float32(np.vstack(xp0_root))
        xpE_root = np.float32(np.vstack(xpE_root))

        # Sort on x positions
        xp0_root = xp0_root[xp0_root[:, 0].argsort(), :]
        xpE_root = xpE_root[xpE_root[:, 0].argsort(), :]

        error = np.linalg.norm(xp0_root - xpE_root)
        assert error < 1e-10
        assert num_particles - pres**3 == 0
コード例 #9
0
def test_open_boundary(advection_scheme):
    xmin, xmax = 0.0, 1.0
    ymin, ymax = 0.0, 1.0
    pres = 3

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10)

    # Particle
    x = RandomRectangle(Point(0.955, 0.45), Point(1.0,
                                                  0.55)).generate([pres, pres])
    x = comm.bcast(x, root=0)

    # Given velocity field:
    vexpr = Constant((1.0, 1.0))
    # Given time do_step:
    dt = 0.05

    p = particles(x, [x, x], mesh)

    V = VectorFunctionSpace(mesh, "CG", 1)
    v = Function(V)
    v.assign(vexpr)

    # Different boundary parts
    bound_left = UnitSquareLeft()
    bound_right = UnitSquareRight()
    bound_top = UnitSquareTop()
    bound_bottom = UnitSquareBottom()

    # Mark all facets
    facet_marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
    facet_marker.set_all(0)

    # Mark as open
    bound_right.mark(facet_marker, 2)

    # Mark other boundaries as closed
    bound_left.mark(facet_marker, 1)
    bound_top.mark(facet_marker, 1)
    bound_bottom.mark(facet_marker, 1)

    if advection_scheme == "euler":
        ap = advect_particles(p, V, v, facet_marker)
    elif advection_scheme == "rk2":
        ap = advect_rk2(p, V, v, facet_marker)
    elif advection_scheme == "rk3":
        ap = advect_rk3(p, V, v, facet_marker)
    else:
        assert False

    # Do one timestep, particle must bounce from wall of
    ap.do_step(dt)
    num_particles = p.number_of_particles()

    # Check if all particles left domain
    if comm.rank == 0:
        assert (num_particles == 0)
コード例 #10
0
def test_advect_periodic_facet_marker(advection_scheme):
    xmin, xmax = 0.0, 1.0
    ymin, ymax = 0.0, 1.0

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10)
    facet_marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
    facet_marker.set_all(0)
    boundaries = Boundaries()
    boundaries.mark(facet_marker, 3)

    lims = np.array([
        [xmin, xmin, ymin, ymax],
        [xmax, xmax, ymin, ymax],
        [xmin, xmax, ymin, ymin],
        [xmin, xmax, ymax, ymax],
    ])

    vexpr = Constant((1.0, 1.0))
    V = VectorFunctionSpace(mesh, "CG", 1)

    x = RandomRectangle(Point(0.05, 0.05), Point(0.15, 0.15)).generate([3, 3])
    x = comm.bcast(x, root=0)
    dt = 0.05

    v = Function(V)
    v.assign(vexpr)

    p = particles(x, [x * 0, x**2], mesh)

    if advection_scheme == "euler":
        ap = advect_particles(p, V, v, facet_marker, lims.flatten())
    elif advection_scheme == "rk2":
        ap = advect_rk2(p, V, v, facet_marker, lims.flatten())
    elif advection_scheme == "rk3":
        ap = advect_rk3(p, V, v, facet_marker, lims.flatten())
    else:
        assert False

    xp0 = p.positions()
    t = 0.0
    while t < 1.0 - 1e-12:
        ap.do_step(dt)
        t += dt
    xpE = p.positions()

    # Check if position correct
    xp0_root = comm.gather(xp0, root=0)
    xpE_root = comm.gather(xpE, root=0)

    if comm.Get_rank() == 0:
        xp0_root = np.float32(np.vstack(xp0_root))
        xpE_root = np.float32(np.vstack(xpE_root))
        error = np.linalg.norm(xp0_root - xpE_root)
        assert error < 1e-10
コード例 #11
0
def test_bounded_domain_boundary(xlims, ylims, advection_scheme):
    xmin, xmax = xlims
    ymin, ymax = ylims
    pres = 1

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10)

    ymin += 0.0025
    lims = np.array([xmin, xmax, ymin, ymax])

    v_arr = np.array([-1.0, -1.0])
    vexpr = Constant(v_arr)
    V = VectorFunctionSpace(mesh, "CG", 1)

    x = RandomRectangle(Point(0.05, 0.05), Point(0.15,
                                                 0.15)).generate([pres, pres])
    dt = 0.005

    v = Function(V)
    v.assign(vexpr)

    p = particles(x, [x], mesh)

    if advection_scheme == 'euler':
        ap = advect_particles(p, V, v, 'bounded', lims.flatten())
    elif advection_scheme == 'rk2':
        ap = advect_rk2(p, V, v, 'bounded', lims.flatten())
    elif advection_scheme == 'rk3':
        ap = advect_rk3(p, V, v, 'bounded', lims.flatten())
    else:
        assert False

    original_num_particles = p.number_of_particles()
    t = 0.
    while t < 3.0 - 1e-12:
        ap.do_step(dt)
        t += dt

        assert p.number_of_particles() == original_num_particles

        xpn = np.array(p.get_property(0)).reshape((-1, 2))
        x0 = np.array(p.get_property(1)).reshape((-1, 2))

        analytical_position = x0 + t * v_arr

        analytical_position[:, 0] = np.maximum(
            np.minimum(xmax, analytical_position[:, 0]), xmin)
        analytical_position[:, 1] = np.maximum(
            np.minimum(ymax, analytical_position[:, 1]), ymin)

        error = np.abs(xpn - analytical_position)

        assert np.all(np.abs(error) < 1e-12)
コード例 #12
0
def test_advect_open(advection_scheme):
    pres = 3

    mesh = UnitCubeMesh(10, 10, 10)

    # Particle
    x = RandomBox(Point(0.955, 0.45, 0.5),
                  Point(0.99, 0.55, 0.6)).generate([pres, pres, pres])
    x = comm.bcast(x, root=0)

    # Given velocity field:
    vexpr = Constant((1.0, 1.0, 1.0))
    # Given time do_step:
    dt = 0.05

    p = particles(x, [x, x], mesh)

    V = VectorFunctionSpace(mesh, "CG", 1)
    v = Function(V)
    v.assign(vexpr)

    # Different boundary parts
    bounds = Boundaries()
    bound_right = UnitCubeRight()

    # Mark all facets
    facet_marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
    facet_marker.set_all(0)
    bounds.mark(facet_marker, 1)
    bound_right.mark(facet_marker, 2)

    # Mark as open
    bound_right.mark(facet_marker, 2)

    if advection_scheme == "euler":
        ap = advect_particles(p, V, v, facet_marker)
    elif advection_scheme == "rk2":
        ap = advect_rk2(p, V, v, facet_marker)
    elif advection_scheme == "rk3":
        ap = advect_rk3(p, V, v, facet_marker)
    else:
        assert False

    # Do one timestep, particle must bounce from wall of
    ap.do_step(dt)
    num_particles = p.number_of_particles()

    # Check if all particles left domain
    if comm.rank == 0:
        assert num_particles == 0
コード例 #13
0
def test_advect_particle(advection_scheme):
    if comm.rank == 0:
        print('Run advect_particle')

    # Rotate one particle, and compute the error
    mesh = UnitSquareMesh(10, 10)

    # Particle
    x = np.array([[0.25, 0.25]])
    dt_list = [0.08, 0.04, 0.02, 0.01, 0.005]

    # Velocity field
    vexpr = Expression(('-pi*(x[1] - 0.5)', 'pi*(x[0]-0.5)'), degree=3)
    V = VectorFunctionSpace(mesh, "CG", 1)
    v = Function(V)
    v.assign(vexpr)

    error_list = []

    for dt in dt_list:
        p = particles(x, [x, x], mesh)
        if advection_scheme == 'euler':
            ap = advect_particles(p, V, v, 'closed')
        elif advection_scheme == 'rk2':
            ap = advect_rk2(p, V, v, 'closed')
        elif advection_scheme == 'rk3':
            ap = advect_rk3(p, V, v, 'closed')
        else:
            assert False

        xp_0 = p.positions()
        t = 0.
        while t < 2.-1e-12:
            ap.do_step(dt)
            t += dt

        xp_end = p.positions()
        error_list.append(np.linalg.norm(xp_0 - xp_end))

    if not all(eps == 0 for eps in error_list):
        rate = compute_convergence(dt_list, error_list)
        if advection_scheme == 'euler':
            # First order for euler
            assert any(i > 0.9 for i in rate)
        elif advection_scheme == 'rk2':
            # Second order for rk2
            assert any(i > 1.95 for i in rate)
        elif advection_scheme == 'rk3':
            # Third order for rk3
            assert any(i > 2.9 for i in rate)
コード例 #14
0
def test_mesh_generator_2d():
    """Basic functionality test."""
    mesh = RectangleMesh(Point(0.0, 0.0), Point(1.0, 1.0), 5, 5)
    for x in mesh.coordinates():
        x[0] += 0.5 * x[1]

    w = RandomCell(mesh)
    pts = w.generate(3)
    assert len(pts) == mesh.num_cells() * 3

    interpolate_expression = Expression("x[0] + x[1]", degree=1)
    s = assign_particle_values(pts, interpolate_expression, on_root=False)
    p = particles(pts, [s], mesh)

    assert np.linalg.norm(np.sum(pts, axis=1) - s) <= 1e-15
    assert np.linalg.norm(pts - p.positions()) <= 1e-15
コード例 #15
0
def test_l2_projection_3D(polynomial_order, in_expression):
    xmin, ymin, zmin = 0.0, 0.0, 0.0
    xmax, ymax, zmax = 1.0, 1.0, 1.0
    nx = 25

    property_idx = 1
    mesh = BoxMesh(Point(xmin, ymin, zmin), Point(xmax, ymax, zmax), nx, nx,
                   nx)

    interpolate_expression = Expression(in_expression, degree=3)

    if len(interpolate_expression.ufl_shape) == 0:
        V = FunctionSpace(mesh, "DG", polynomial_order)
    elif len(interpolate_expression.ufl_shape) == 1:
        V = VectorFunctionSpace(mesh, "DG", polynomial_order)

    v_exact = Function(V)
    v_exact.assign(interpolate_expression)

    x = RandomBox(Point(0.0, 0.0, 0.0), Point(1.0, 1.0,
                                              1.0)).generate([4, 4, 4])
    s = assign_particle_values(x, interpolate_expression)

    # Just make a complicated particle, possibly with scalars and vectors mixed
    p = particles(x, [s], mesh)

    # Do AddDelete sweep
    AD = AddDelete(p, 13, 15, [v_exact])
    AD.do_sweep()

    vh = Function(V)
    lstsq_vh = l2projection(p, V, property_idx)
    lstsq_vh.project(vh.cpp_object())

    error_sq = abs(assemble(dot(v_exact - vh, v_exact - vh) * dx))
    if comm.Get_rank() == 0:
        assert error_sq < 1e-13
コード例 #16
0
def test_mesh_generator_3d():
    """Basic functionality test."""
    mesh = BoxMesh(Point(0.0, 0.0, 0.0), Point(1.0, 1.0, 1.0), 5, 5, 5)
    for x in mesh.coordinates():
        x[0] += 0.5 * x[1] + 0.2 * x[2]

    w = RandomCell(mesh)
    pts = w.generate(3)
    assert len(pts) == mesh.num_cells() * 3

    interpolate_expression = Expression("x[0] + x[1] + x[2]", degree=1)
    s = assign_particle_values(pts, interpolate_expression, on_root=False)

    assert np.linalg.norm(np.sum(pts, axis=1) - s) <= 1e-15

    p = particles(pts, [s], mesh)
    assert pts.shape == p.positions().shape

    for i in range(10000):
        s, t, u, v = w._random_bary(4)
        assert s >= 0 and s <= 1
        assert t >= 0 and t <= 1
        assert u >= 0 and u <= 1
        assert v >= 0 and v <= 1
コード例 #17
0
ファイル: get_terminus.py プロジェクト: jbassis/MICI-2021
def read_calving_front_sim(fname_base):
    fname_ext = '.npz'
    fname = fname_base + fname_ext
    print(fname)

    # Load particle data
    if path.exists(fname):
        tracer_data = np.load(fname)
    else:
        print('Cannot read file')

    t = tracer_data['t'].item()

    # Load mesh
    mesh_file = fname_base + '.xml'
    mesh = Mesh(mesh_file)

    # Make particle class
    n = len(tracer_data['xm'])
    xp = np.vstack(
        (tracer_data['xm'], tracer_data['zm'])).transpose().reshape(n, 2)
    pstrain = tracer_data['strain']
    pepsII = tracer_data['epsII']
    ptemp = tracer_data['temp']
    p = particles(xp, [pstrain, ptemp, pepsII], mesh)

    # Interpolate particles to mesh
    Vdg = FunctionSpace(mesh, 'DG', 1)
    strain = Function(Vdg)
    lstsq_strain = l2projection(p, Vdg, 1)  # First variable???
    lstsq_strain.project_mpm(strain)  # Projection is stored in phih0

    # Boundary mesh with portion above sea level marked
    bmesh = BoundaryMesh(mesh, 'exterior', order=True)
    x = bmesh.coordinates()
    #ymax = np.max(x[x[:,0]==0,1])
    filter = (x[:, 0] > 1e-4) & (x[:, 1] > 0)
    xm = np.min(x[filter, 0])
    id = np.argwhere(x[:, 0] == xm).item()
    # Check if nodes increasing or decreasing
    if (x[id - 1, 0] > x[id, 0]):
        # Decrease nodes
        inc = -1
        stop = 0
    else:
        # Increase nodes
        inc = 1
        stop = len(x)

    iold = id
    for i in range(id, stop, inc):
        if x[i, 1] > 0.0:
            slope = (x[i, 1] - x[iold, 1]) / (x[i, 0] - x[iold, 0])
            #print(x[i,0],strain(x[i]),strain(x[i])>0.99,slope,slope<-pi/3)
            #print(-slope*180/pi)
            if strain(x[i]) > 0.1:
                L = x[iold, 0]
                break
            elif np.abs(slope) > pi / 6:
                L = x[iold, 0]
                break

            iold = i
    print('Terminus position', L)
    # Extract profile centered on terminus
    filter = (x[:, 1] > 0.0) & (x[:, 0] > 10) & (x[:, 0] < L + 5 * 800)
    xp = x[filter, 0] - L
    zp = x[filter, 1]
    idx = np.argsort(xp)
    xp = xp[idx]
    zp = zp[idx]
    zp = gaussian_filter(zp, 1.5)

    #fname = fname_base + 'term_pos.npz'
    #print(fname)

    return xp, zp
コード例 #18
0
def read_files(fname_base):
    L = []
    t = []
    for step in range(0, 1000000, 10):

        fname_ext = str(step).zfill(3) + '.npz'
        fname = fname_base + fname_ext
        print(fname)

        # Load particle data
        if path.exists(fname):
            tracer_data = np.load(fname)
        else:
            print('Cannot read file')
            break

        t.append(tracer_data['t'].item())

        # Load mesh
        mesh_file = fname_base + str(step).zfill(3) + '.xml'
        mesh = Mesh(mesh_file)

        # Make particle class
        n = len(tracer_data['xm'])
        xp = np.vstack(
            (tracer_data['xm'], tracer_data['zm'])).transpose().reshape(n, 2)
        pstrain = tracer_data['strain']
        pepsII = tracer_data['epsII']
        ptemp = tracer_data['temp']
        p = particles(xp, [pstrain, ptemp, pepsII], mesh)

        # Interpolate particles to mesh
        Vdg = FunctionSpace(mesh, 'DG', 1)
        strain = Function(Vdg)
        lstsq_strain = l2projection(p, Vdg, 1)  # First variable???
        lstsq_strain.project_mpm(strain)  # Projection is stored in phih0

        # Boundary mesh with portion above sea level marked
        bmesh = BoundaryMesh(mesh, 'exterior', order=True)
        x = bmesh.coordinates()
        #ymax = np.max(x[x[:,0]==0,1])
        filter = (x[:, 0] > 1e-4) & (x[:, 1] > 0)
        xm = np.min(x[filter, 0])
        id = np.argwhere(x[:, 0] == xm).item()
        # Check if nodes increasing or decreasing
        if (x[id - 1, 0] > x[id, 0]):
            # Decrease nodes
            inc = -1
            stop = 0
        else:
            # Increase nodes
            inc = 1
            stop = len(x)

        iold = id
        for i in range(id, stop, inc):
            if x[i, 1] > 0.0:
                slope = (x[i, 1] - x[iold, 1]) / (x[i, 0] - x[iold, 0])
                #print(x[i,0],strain(x[i]),strain(x[i])>0.99,slope,slope<-pi/3)
                #print(-slope*180/pi)
                if strain(x[i]) > 0.99:
                    L.append(x[iold, 0])
                    break
                elif np.abs(slope) > pi / 6:
                    L.append(x[iold, 0])
                    break

                iold = i
        print('Terminus position', L[-1])
        if i == stop - inc:
            print('No terminus identified')
            L.append(np.Nan)

    fname = fname_base + 'term_pos.npz'
    print(fname)
    # Least squares fit to data
    #if len(t)>len(L):
    #    print('Not equal')
    #    t =t[0:-1]

    print(len(t), len(L))
    t = np.array(t)
    L = np.array(L)
    filter = (t > 2 / 12)  #
    t, L = np.array(t), np.array(L)
    dLdt, b, rvalue, pvalue1, err = linregress(t[filter], L[filter])
    print('Rate of terminus advance', dLdt, 'Errror', err)
    np.savez(fname,
             t=t,
             L=L,
             dLdt=dLdt,
             err=err,
             pvalue=pvalue1,
             rvalue=rvalue)
    return None
コード例 #19
0
        uh = Function(V)
        uh.assign(Expression(("-Uh*x[1]", "Uh*x[0]"), Uh=Uh, degree=3))

        psi0_expression = GaussianPulse(center=(xc, yc),
                                        sigma=float(sigma),
                                        U=[Uh, Uh],
                                        time=0.0,
                                        height=1.0,
                                        degree=3)

        # Generate particles
        x = RandomCircle(Point(x0, y0), r).generate([pres, pres])
        s = np.zeros((len(x), 1), dtype=np.float_)

        # Initialize particles with position x and scalar property s at the mesh
        p = particles(x, [s], mesh)
        property_idx = 1  # Scalar quantity is stored at slot 1

        # Initialize advection class, use RK3 scheme
        ap = advect_rk3(p, V, uh, "open")

        # Define the variational (projection problem)
        W_e = FiniteElement("DG", mesh.ufl_cell(), k)
        T_e = FiniteElement("DG", mesh.ufl_cell(), 0)
        Wbar_e = FiniteElement("DGT", mesh.ufl_cell(), k)

        W = FunctionSpace(mesh, W_e)
        T = FunctionSpace(mesh, T_e)
        Wbar = FunctionSpace(mesh, Wbar_e)

        psi_h, psi0_h = Function(W), Function(W)
コード例 #20
0
temp_fun = temp_init(Ts, Tb, surf_fun, bed_fun, degree=1)

# Create functions defined on mesh with initial values
strain_mesh.assign(strain_init)
temp_mesh.assign(interpolate(temp_fun, Vdg))
epsII_mesh.assign(strain_init)

# Particle values at nodes
pstrain = assign_particle_values(xp, strain_fun)
pepsII = assign_particle_values(xp, strain_fun)
ptemp = assign_particle_values(xp, temp_fun)
print('Done initializing function spaces')

# Now we initialize the particle class
print('Creating particles')
p = particles(xp, [pstrain, ptemp, pepsII], mesh.mesh)
print('Done particles')

# Make sure we have enough particles per cell
#AD = AddDelete(p, p_min, p_max, [strain_mesh, temp_mesh,epsII_mesh]) # Sweep over mesh to delete/insert particles
#AD.do_sweep()

(xp, pstrain, ptemp,
 pepsII) = (p.return_property(mesh, 0), p.return_property(mesh, 1),
            p.return_property(mesh, 2), p.return_property(mesh, 3))
#_____________________________________________
# Initialize temperature model
print('Initializing temperature')
Tmodel = tempModel(mesh.mesh, Tb=Tb, Ts=Ts)
x = SpatialCoordinate(mesh.mesh)
zb = bot_fun(x[0])
コード例 #21
0
def test_moving_mesh():
    t = 0.
    dt = 0.025
    num_steps = 20
    xmin, ymin = 0., 0.
    xmax, ymax = 2., 2.
    xc, yc = 1., 1.
    nx, ny = 20, 20
    pres = 150
    k = 1

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), nx, ny)
    n = FacetNormal(mesh)

    # Class for mesh motion
    dU = PeriodicVelocity(xmin, xmax, dt, t, degree=1)

    Qcg = VectorFunctionSpace(mesh, 'CG', 1)

    boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
    boundaries.set_all(0)
    leftbound = Left(xmin)

    leftbound.mark(boundaries, 99)
    ds = Measure('ds', domain=mesh, subdomain_data=boundaries)

    # Create function spaces
    Q_E_Rho = FiniteElement("DG", mesh.ufl_cell(), k)
    T_1 = FunctionSpace(mesh, 'DG', 0)
    Qbar_E = FiniteElement("DGT", mesh.ufl_cell(), k)

    Q_Rho = FunctionSpace(mesh, Q_E_Rho)
    Qbar = FunctionSpace(mesh, Qbar_E)

    phih, phih0 = Function(Q_Rho), Function(Q_Rho)
    phibar = Function(Qbar)

    # Advective velocity
    uh = Function(Qcg)
    uh.assign(Constant((0., 0.)))
    # Mesh velocity
    umesh = Function(Qcg)
    # Total velocity
    uadvect = uh-umesh

    # Now throw in the particles
    x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([pres, pres])
    s = assign_particle_values(x, GaussianPulse(center=(xc, yc), sigma=float(0.25),
                                                U=[0, 0], time=0., height=1., degree=3))
    x = comm.bcast(x, root=0)
    s = comm.bcast(s, root=0)
    p = particles(x, [s], mesh)

    # Define projections problem
    FuncSpace_adv = {'FuncSpace_local': Q_Rho, 'FuncSpace_lambda': T_1, 'FuncSpace_bar': Qbar}
    FormsPDE = FormsPDEMap(mesh, FuncSpace_adv, ds=ds)
    forms_pde = FormsPDE.forms_theta_linear(phih0, uadvect, dt, Constant(1.0), zeta=Constant(0.))
    pde_projection = PDEStaticCondensation(mesh, p,
                                           forms_pde['N_a'], forms_pde['G_a'], forms_pde['L_a'],
                                           forms_pde['H_a'],
                                           forms_pde['B_a'],
                                           forms_pde['Q_a'], forms_pde['R_a'], forms_pde['S_a'],
                                           [], 1)

    # Initialize the initial condition at mesh by an l2 projection
    lstsq_rho = l2projection(p, Q_Rho, 1)
    lstsq_rho.project(phih0.cpp_object())

    for step in range(num_steps):
        # Compute old area at old configuration
        old_area = assemble(phih0*dx)

        # Pre-assemble rhs
        pde_projection.assemble_state_rhs()

        # Move mesh
        dU.compute_ubc()
        umesh.assign(project(dU, Qcg))

        ALE.move(mesh, project(dU * dt, Qcg))
        dU.update()

        # Relocate particles as a result of mesh motion
        # NOTE: if particles were advected themselve,
        # we had to run update_facets_info() here as well
        p.relocate()

        # Assemble left-hand side on new config, but not the right-hand side
        pde_projection.assemble(True, False)
        pde_projection.solve_problem(phibar.cpp_object(), phih.cpp_object(),
                                     'mumps', 'none')

        # Needed to compute conservation, note that there
        # is an outgoing flux at left boundary
        new_area = assemble(phih*dx)
        gamma = conditional(ge(dot(uadvect, n), 0), 0, 1)
        bflux = assemble((1-gamma) * dot(uadvect, n) * phih * ds)

        # Update solution
        assign(phih0, phih)

        # Put assertion on (global) mass balance, local mass balance is
        # too time consuming but should pass also
        assert new_area - old_area + bflux * dt < 1e-12

        # Assert that max value of phih stays close to 2 and
        # min value close to 0. This typically will fail if
        # we do not do a correct relocate of particles
        assert np.amin(phih.vector().get_local()) > -0.015
        assert np.amax(phih.vector().get_local()) < 1.04
コード例 #22
0
Uhbar0 = Function(mixedG)

# Set initial density field
initial_density = BinaryBlock(geometry, float(rho1), float(rho2), degree=1)
zero_expression = Expression(("0.", "0."), degree=1)

# Initialize particles
x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate(
    [pres, int(pres * (ymax - ymin) / (xmax - xmin))])
up = assign_particle_values(x, zero_expression)
rhop = assign_particle_values(x, initial_density)

# Increment requires dup to be stored, init zero
dup = up

p = particles(x, [rhop, up, dup], mesh)

# Init rho0 field
lstsq_rho = l2projection(p, Q_Rho, 1)
lstsq_rho.project(rho0, float(rho2), float(rho1))

# Initialize l2 projection for specific momentum
lstsq_u = l2projection(p, W_2, 2)

# Initialize advection class
ap = advect_rk3(p, W_2, Udiv, 'closed')

# Set-up boundary conditions (free slip)
boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
boundaries.set_all(0)
all_bounds = Boundaries()
コード例 #23
0
ALE.move(mesh, displacement)

# Entrainment functional measures
de = 1
cf = MeshFunction("size_t", mesh, mesh.topology().dim(), 0)
CompiledSubDomain("x[1] > db - DOLFIN_EPS", db=db).mark(cf, de)
dx = Measure("dx", subdomain_data=cf)

# Setup particles
pres = 25
x = RandomBox(Point(xmin, ymin, zmin), Point(xmax, ymax, zmax)).generate([pres, pres, pres])
s = np.zeros((len(x), 1), dtype=np.float_)

# Interpolate initial function onto particles, index slot 1
property_idx = 1
ptcls = particles(x, [s], mesh)

# Define the variational (projection problem)
k = 1
W_e = FiniteElement("DG", mesh.ufl_cell(), k)
T_e = FiniteElement("DG", mesh.ufl_cell(), 0)
Wbar_e = FiniteElement("DGT", mesh.ufl_cell(), k)

# Composition field space
Wh = FunctionSpace(mesh, W_e)
Th = FunctionSpace(mesh, T_e)
Wbarh = FunctionSpace(mesh, Wbar_e)

phi = interpolate(StepFunction(), Wh)
gamma0 = interpolate(StepFunction(), Wh)