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
    ubar0_a,
    dt,
    theta_map=Constant(1.0),
    theta_L=theta_L,
    duh0=duh0,
    duh00=duh00)
pde_u = PDEStaticCondensation(mesh, p, forms_u['N_a'], forms_u['G_a'],
                              forms_u['L_a'], forms_u['H_a'], forms_u['B_a'],
                              forms_u['Q_a'], forms_u['R_a'], forms_u['S_a'],
                              2)

# Set-up Stokes Solve
forms_stokes = FormsStokes(mesh, mixedL, mixedG, alpha,
                           ds=ds).forms_multiphase(rho, ustar, dt, rho * nu, f)
ssc = StokesStaticCondensation(mesh, forms_stokes['A_S'], forms_stokes['G_S'],
                               forms_stokes['B_S'], forms_stokes['Q_S'],
                               forms_stokes['S_S'])

# Loop and output
step = 0
t = 0.

# Store tstep 0
assign(rho, rho0)
xdmf_rho.write_checkpoint(rho, "rho", t)
xdmf_u.write(Uh.sub(0), t)
xdmf_p.write(Uh.sub(1), t)
p.dump2file(mesh, fname_list, property_list, 'wb')
comm.barrier()

# Save some data in txt files
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)
예제 #4
0
       DirichletBC(mixedG.sub(0).sub(0), Constant(0),
                   CompiledSubDomain("near(x[0], 0.0) or near(x[0], lmbda)", lmbda=lmbdax)),
       DirichletBC(mixedG.sub(0).sub(2), Constant(0),
                   CompiledSubDomain("near(x[2], 0.0) or near(x[2], lmbda)", lmbda=lmbdaz))]

# Forms Stokes
alpha = Constant(6*k*k)
Rb = Constant(1.0)
eta_top = Constant(1.0)
eta_bottom = Constant(0.01)
eta = eta_bottom + phi * (eta_top - eta_bottom)
forms_stokes = FormsStokes(mesh, mixedL, mixedG, alpha) \
    .forms_steady(eta, Rb * phi * Constant((0, -1, 0)))

ssc = StokesStaticCondensation(mesh,
                               forms_stokes['A_S'], forms_stokes['G_S'],
                               forms_stokes['B_S'],
                               forms_stokes['Q_S'], forms_stokes['S_S'])

# Particle advector
C_CFL = 0.5
hmin = MPI.min(comm, mesh.hmin())
ap = advect_rk3(ptcls, u_vec.function_space(), u_vec, "closed")


# Write particles and their values to XDMF file
particles_directory = "./particles/"
points_list = list(Point(*pp) for pp in ptcls.positions())
particles_values = ptcls.get_property(property_idx)
XDMFFile(os.path.join(particles_directory, "step%.4d.xdmf" % 0)) \
    .write(points_list, particles_values)
예제 #5
0
    forms_u["L_a"],
    forms_u["H_a"],
    forms_u["B_a"],
    forms_u["Q_a"],
    forms_u["R_a"],
    forms_u["S_a"],
    2,
)

# Set-up Stokes Solve
forms_stokes = FormsStokes(mesh, mixedL, mixedG, alpha,
                           ds=ds).forms_multiphase(rho, ustar, dt, rho * nu, f)
ssc = StokesStaticCondensation(
    mesh,
    forms_stokes["A_S"],
    forms_stokes["G_S"],
    forms_stokes["B_S"],
    forms_stokes["Q_S"],
    forms_stokes["S_S"],
)

# Loop and output
step = 0
t = 0.0

# Store tstep 0
assign(rho, rho0)
xdmf_rho.write_checkpoint(rho, "rho", t)
xdmf_u.write(Uh.sub(0), t)
xdmf_p.write(Uh.sub(1), t)
p.dump2file(mesh, fname_list, property_list, "wb")
comm.barrier()
예제 #6
0
    ubar0_a,
    dt,
    theta_map=Constant(1.0),
    theta_L=theta_L,
    duh0=duh0,
    duh00=duh00)
pde_u = PDEStaticCondensation(mesh, p, forms_u['N_a'], forms_u['G_a'],
                              forms_u['L_a'], forms_u['H_a'], forms_u['B_a'],
                              forms_u['Q_a'], forms_u['R_a'], forms_u['S_a'],
                              2)

# Set-up Stokes Solve
forms_stokes = FormsStokes(mesh, mixedL, mixedG, alpha,
                           ds=ds).forms_multiphase(rho0, ustar, dt, mu, f)
ssc = StokesStaticCondensation(mesh, forms_stokes['A_S'], forms_stokes['G_S'],
                               forms_stokes['B_S'], forms_stokes['Q_S'],
                               forms_stokes['S_S'])

# Set pressure in upper left corner to zero
bc1 = DirichletBC(mixedG.sub(1), Constant(0), Corner(xmin, ymax), "pointwise")
bcs = [bc1]

lstsq_u = l2projection(p, W_2, 2)

# Loop and output
step = 0
t = 0.

# Store at step 0
xdmf_rho.write(rho0, t)
xdmf_u.write(Uh.sub(0), t)
예제 #7
0
    forms_u["L_a"],
    forms_u["H_a"],
    forms_u["B_a"],
    forms_u["Q_a"],
    forms_u["R_a"],
    forms_u["S_a"],
    2,
)

# Set-up Stokes Solve
forms_stokes = FormsStokes(mesh, mixedL, mixedG, alpha,
                           ds=ds).forms_multiphase(rho0, ustar, dt, mu, f)
ssc = StokesStaticCondensation(
    mesh,
    forms_stokes["A_S"],
    forms_stokes["G_S"],
    forms_stokes["B_S"],
    forms_stokes["Q_S"],
    forms_stokes["S_S"],
)

# Set pressure in upper left corner to zero
bc1 = DirichletBC(mixedG.sub(1), Constant(0), Corner(xmin, ymax), "pointwise")
bcs = [bc1]

lstsq_u = l2projection(p, W_2, 2)

# Loop and output
step = 0
t = 0.0

# Store at step 0
    forms_adv["S_a"],
    property_idx,
)

# Forms Stokes
# Set pressure in corner to zero
bc1 = DirichletBC(mixedG.sub(1), Constant(0), Corner(geometry), "pointwise")
bcs = [bc1]

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["B_S"],
    forms_stokes["Q_S"],
    forms_stokes["S_S"],
)

# Prepare time stepping loop
num_steps = np.rint(Tend / float(dt))
step = 0
t = 0.0

timer = Timer()
timer.start()

while step < num_steps:
    step += 1
    t += float(dt)