def test_unsteady_stokes():
    nx, ny = 15, 15
    k = 1
    nu = Constant(1.0e-0)
    dt = Constant(2.5e-2)
    num_steps = 20
    theta0 = 1.0  # Initial theta value
    theta1 = 0.5  # Theta after 1 step
    theta = Constant(theta0)

    mesh = UnitSquareMesh(nx, ny)

    # The 'unsteady version' of the benchmark in the 2012 paper by Labeur&Wells
    u_exact = Expression(
        (
            "sin(t) * x[0]*x[0]*(1.0 - x[0])*(1.0 - x[0])*(2.0*x[1] \
                           -6.0*x[1]*x[1] + 4.0*x[1]*x[1]*x[1])",
            "-sin(t)* x[1]*x[1]*(1.0 - x[1])*(1.0 - x[1])*(2.0*x[0] \
                           - 6.0*x[0]*x[0] + 4.0*x[0]*x[0]*x[0])",
        ),
        t=0,
        degree=7,
        domain=mesh,
    )
    p_exact = Expression("sin(t) * x[0]*(1.0 - x[0])",
                         t=0,
                         degree=7,
                         domain=mesh)
    du_exact = Expression(
        (
            "cos(t) * x[0]*x[0]*(1.0 - x[0])*(1.0 - x[0])*(2.0*x[1] \
                            - 6.0*x[1]*x[1] + 4.0*x[1]*x[1]*x[1])",
            "-cos(t)* x[1]*x[1]*(1.0 - x[1])*(1.0 - x[1])*(2.0*x[0] \
                            -6.0*x[0]*x[0] + 4.0*x[0]*x[0]*x[0])",
        ),
        t=0,
        degree=7,
        domain=mesh,
    )

    ux_exact = Expression(
        (
            "x[0]*x[0]*(1.0 - x[0])*(1.0 - x[0])*(2.0*x[1] \
                            - 6.0*x[1]*x[1] + 4.0*x[1]*x[1]*x[1])",
            "-x[1]*x[1]*(1.0 - x[1])*(1.0 - x[1])*(2.0*x[0] \
                            - 6.0*x[0]*x[0] + 4.0*x[0]*x[0]*x[0])",
        ),
        degree=7,
        domain=mesh,
    )

    px_exact = Expression("x[0]*(1.0 - x[0])", degree=7, domain=mesh)

    sin_ext = Expression("sin(t)", t=0, degree=7, domain=mesh)

    f = du_exact + sin_ext * div(px_exact * Identity(2) -
                                 2 * sym(grad(ux_exact)))

    Vhigh = VectorFunctionSpace(mesh, "DG", 7)
    Phigh = FunctionSpace(mesh, "DG", 7)

    # New syntax:
    V = VectorElement("DG", mesh.ufl_cell(), k)
    Q = FiniteElement("DG", mesh.ufl_cell(), k - 1)
    Vbar = VectorElement("DGT", mesh.ufl_cell(), k)
    Qbar = FiniteElement("DGT", mesh.ufl_cell(), k)

    mixedL = FunctionSpace(mesh, MixedElement([V, Q]))
    mixedG = FunctionSpace(mesh, MixedElement([Vbar, Qbar]))
    V2 = FunctionSpace(mesh, V)

    Uh = Function(mixedL)
    Uhbar = Function(mixedG)
    U0 = Function(mixedL)
    Uhbar0 = Function(mixedG)
    u0, p0 = split(U0)
    ubar0, pbar0 = split(Uhbar0)
    ustar = Function(V2)

    # Then the boundary conditions
    bc0 = DirichletBC(mixedG.sub(0), Constant((0, 0)), Gamma)
    bc1 = DirichletBC(mixedG.sub(1), Constant(0), Corner, "pointwise")
    bcs = [bc0, bc1]

    alpha = Constant(6 * k * k)
    forms_stokes = FormsStokes(mesh, mixedL, mixedG,
                               alpha).forms_unsteady(ustar, dt, nu, f)
    ssc = StokesStaticCondensation(
        mesh,
        forms_stokes["A_S"],
        forms_stokes["G_S"],
        forms_stokes["G_ST"],
        forms_stokes["B_S"],
        forms_stokes["Q_S"],
        forms_stokes["S_S"],
    )

    t = 0.0
    step = 0
    for step in range(num_steps):
        step += 1
        t += float(dt)
        if comm.Get_rank() == 0:
            print("Step " + str(step) + " Time " + str(t))

        # Set time level in exact solution
        u_exact.t = t
        p_exact.t = t

        du_exact.t = t - (1 - float(theta)) * float(dt)
        sin_ext.t = t - (1 - float(theta)) * float(dt)

        ssc.assemble_global_lhs()
        ssc.assemble_global_rhs()
        for bc in bcs:
            ssc.apply_boundary(bc)

        ssc.solve_problem(Uhbar, Uh, "none", "default")
        assign(U0, Uh)
        assign(ustar, U0.sub(0))
        assign(Uhbar0, Uhbar)
        if step == 1:
            theta.assign(theta1)

        udiv_e = sqrt(assemble(div(Uh.sub(0)) * div(Uh.sub(0)) * dx))

    u_ex_h = interpolate(u_exact, Vhigh)
    p_ex_h = interpolate(p_exact, Phigh)

    u_error = sqrt(assemble(dot(Uh.sub(0) - u_ex_h, Uh.sub(0) - u_ex_h) * dx))
    p_error = sqrt(assemble(dot(Uh.sub(1) - p_ex_h, Uh.sub(1) - p_ex_h) * dx))

    assert udiv_e < 1e-12
    assert u_error < 1.5e-4
    assert p_error < 1e-2
def test_steady_stokes(k):
    # Polynomial order and mesh resolution
    nx_list = [4, 8, 16]

    nu = Constant(1)

    if comm.Get_rank() == 0:
        print('{:=^72}'.format('Computing for polynomial order ' + str(k)))

    # Error listst
    error_u, error_p, error_div = [], [], []

    for nx in nx_list:
        if comm.Get_rank() == 0:
            print('# Resolution ' + str(nx))

        mesh = UnitSquareMesh(nx, nx)

        # Get forcing from exact solutions
        u_exact, p_exact = exact_solution(mesh)
        f = div(p_exact * Identity(2) - 2 * nu * sym(grad(u_exact)))

        # Define FunctionSpaces and functions
        V = VectorElement("DG", mesh.ufl_cell(), k)
        Q = FiniteElement("DG", mesh.ufl_cell(), k - 1)
        Vbar = VectorElement("DGT", mesh.ufl_cell(), k)
        Qbar = FiniteElement("DGT", mesh.ufl_cell(), k)

        mixedL = FunctionSpace(mesh, MixedElement([V, Q]))
        mixedG = FunctionSpace(mesh, MixedElement([Vbar, Qbar]))

        Uh = Function(mixedL)
        Uhbar = Function(mixedG)

        # Set forms
        alpha = Constant(6 * k * k)
        forms_stokes = FormsStokes(mesh, mixedL, mixedG,
                                   alpha).forms_steady(nu, f)

        # No-slip boundary conditions, set pressure in one of the corners
        bc0 = DirichletBC(mixedG.sub(0), Constant((0, 0)), Gamma)
        bc1 = DirichletBC(mixedG.sub(1), Constant(0), Corner, "pointwise")
        bcs = [bc0, bc1]

        # Initialize static condensation class
        ssc = StokesStaticCondensation(mesh, forms_stokes['A_S'],
                                       forms_stokes['G_S'],
                                       forms_stokes['B_S'],
                                       forms_stokes['Q_S'],
                                       forms_stokes['S_S'], bcs)

        # Assemble global system and incorporates bcs
        ssc.assemble_global_system(True)
        # Solve using mumps
        ssc.solve_problem(Uhbar, Uh, "mumps", "default")

        # Compute velocity/pressure/local div error
        uh, ph = Uh.split()
        e_u = np.sqrt(np.abs(assemble(dot(uh - u_exact, uh - u_exact) * dx)))
        e_p = np.sqrt(np.abs(assemble((ph - p_exact) * (ph - p_exact) * dx)))
        e_d = np.sqrt(np.abs(assemble(div(uh) * div(uh) * dx)))

        if comm.rank == 0:
            error_u.append(e_u)
            error_p.append(e_p)
            error_div.append(e_d)
            print('Error in velocity ' + str(error_u[-1]))
            print('Error in pressure ' + str(error_p[-1]))
            print('Local mass error ' + str(error_div[-1]))

    if comm.rank == 0:
        iterator_list = [1. / float(nx) for nx in nx_list]
        conv_u = compute_convergence(iterator_list, error_u)
        conv_p = compute_convergence(iterator_list, error_p)

        assert any(conv > k + 0.75 for conv in conv_u)
        assert any(conv > (k - 1) + 0.75 for conv in conv_p)
        with open(conservation_data, "a") as write_file:
            data = [
                t, total_mass, mass_change_flux, mass_change_noflux, mt_change,
                mt_change_noflux, rho_min, rho_max
            ]
            writer = csv.writer(write_file)
            writer.writerow(['{:10.7g}'.format(val) for val in data])
    del (t1)

    # Solve Stokes
    t1 = Timer("[P] Stokes assemble ")
    ssc.assemble_global()
    del (t1)

    t1 = Timer("[P] Stokes solve ")
    ssc.solve_problem(Uhbar, Uh, solver, "default")
    del (t1)

    t1 = Timer("[P] Update mesh fields")
    # Needed for particle advection
    assign(Udiv, Uh.sub(0))
    assign(rho0, rho)

    # Needed for constrained map
    if projection_type == 'PDE':
        assign(ubar0_a, Uhbar.sub(0))
        assign(u0, ustar)
        assign(duh00, duh0)
        assign(duh0, project(Uh.sub(0) - ustar, W_2))
    del (t1)
Exemple #4
0
def output_data_step(append=False):
    urms = (1.0 / (lmbdax*lmbdaz) * assemble(dot(u_vec, u_vec) * dx)) ** 0.5
    conservation = abs(assemble(phi * dx) - conservation0)
    entrainment = assemble(1.0 / (lmbdax * lmbdaz * Constant(db)) * phi * dx(de))
    output_functionals(data_filename, [float(t), float(dt), urms, conservation, entrainment],
                       append=append)


# Initial Stokes solve
time = Timer("ZZZ Stokes assemble")
ssc.assemble_global_system(True)
del time
time = Timer("ZZZ Stokes solve")
for bc in bcs:
    ssc.apply_boundary(bc)
ssc.solve_problem(Uhbar.cpp_object(), Uh.cpp_object(), "mumps", "default")
del time

# Transfer the computed velocity function and compute functionals
velocity_assigner.assign(u_vec, Uh.sub(0))
output_data_step(append=False)

time_snap_shot_interval = 5.0
next_snap_shot_time = time_snap_shot_interval

for j in range(50000):
    max_u_vec = u_vec.vector().norm("linf")
    dt.assign(C_CFL * hmin / max_u_vec)

    t.assign(float(t) + float(dt))
    if float(t) > 2000.0:
Exemple #5
0
    try:
        pde_u.solve_problem(ustar_bar, ustar, "mumps", "default")
    except Exception:
        # FIXME: work-around
        lstsq_u.project(ustar)
    del (t1)

    # Solve Stokes
    t1 = Timer("[P] Stokes assemble ")
    ssc.assemble_global()
    for bc in bcs:
        ssc.apply_boundary(bc)
    del (t1)

    t1 = Timer("[P] Stokes solve ")
    ssc.solve_problem(Uhbar, Uh, "mumps", "default")
    del (t1)

    t1 = Timer("[P] Update mesh fields")
    # Needed for particle advection
    assign(Udiv, Uh.sub(0))

    # Needed for constrained map
    assign(rho0, rho)
    assign(ubar0_a, Uhbar.sub(0))
    assign(u0, ustar)
    assign(duh00, duh0)
    assign(duh0, project(Uh.sub(0) - ustar, W_2))
    del (t1)

    t1 = Timer("[P] Update particle field")
    t1 = Timer("[P] assemble projection")
    pde_projection.assemble(True, True)
    del t1
    t1 = Timer("[P] solve projection")
    pde_projection.solve_problem(ubar_a.cpp_object(), ustar.cpp_object(),
                                 lamb.cpp_object(), "mumps", "default")
    del t1

    # Solve Stokes
    t1 = Timer("[P] Stokes assemble ")
    ssc.assemble_global_system(True)
    for bc in bcs:
        ssc.apply_boundary(bc)
    del t1
    t1 = Timer("[P] Stokes solve")
    ssc.solve_problem(Uhbar.cpp_object(), Uh.cpp_object(), "mumps", "none")
    del t1

    # Needed for particle advection
    assign(Udiv, Uh.sub(0))

    # Needed for constrained map
    assign(ubar0_a, Uhbar.sub(0))
    assign(u0_a, ustar)
    assign(duh00, duh0)
    assign(duh0, project(Uh.sub(0) - ustar, W_2))

    p.increment(Udiv.cpp_object(), ustar.cpp_object(),
                np.array([1, 2], dtype=np.uintp), theta_p, step)

    if step == 2: