Пример #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)
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)
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
nx, ny = 32, 32
pres = 400
k = 1

# Directory for output
outdir_base = './../../results/MovingMesh/'

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

outfile = File(mesh.mpi_comm(), outdir_base+"psi_h.pvd")

V = VectorFunctionSpace(mesh, 'DG', 2)
Vcg = VectorFunctionSpace(mesh, 'CG', 1)

boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
boundaries.set_all(0)
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
Пример #5
0
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 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()
all_bounds.mark(boundaries, 98)
ds = Measure('ds', domain=mesh, subdomain_data=boundaries)

# Mark pressure boundary
pressure_transducer = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
pressure_transducer.set_all(0)
probe_1 = RightBoundary_Segment(xmax, probe1_y - probe_radius,
                                probe1_y + probe_radius)
probe_2 = RightBoundary_Segment(xmax, probe2_y - probe_radius,
                                probe2_y + probe_radius)
probe_3 = RightBoundary_Segment(xmax, probe3_y - probe_radius,
                                probe3_y + probe_radius)
probe_4 = RightBoundary_Segment(xmax, probe4_y - probe_radius,
Пример #6
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