示例#1
0
def test_save_and_read_function_timeseries(tempdir):
    filename = os.path.join(tempdir, "function.h5")

    mesh = UnitSquareMesh(MPI.comm_world, 10, 10)
    Q = FunctionSpace(mesh, ("CG", 3))
    F0 = Function(Q)
    F1 = Function(Q)
    E = Expression("t*x[0]", t=0.0, degree=1)
    F0.interpolate(E)

    # Save to HDF5 File
    hdf5_file = HDF5File(mesh.mpi_comm(), filename, "w")
    for t in range(10):
        E.t = t
        F0.interpolate(E)
        hdf5_file.write(F0, "/function", t)
    hdf5_file.close()

    # Read back from file
    hdf5_file = HDF5File(mesh.mpi_comm(), filename, "r")
    for t in range(10):
        E.t = t
        F1.interpolate(E)
        vec_name = "/function/vector_%d" % t
        F0 = hdf5_file.read_function(Q, vec_name)
        # timestamp = hdf5_file.attributes(vec_name)["timestamp"]
        # assert timestamp == t
        F0.vector().axpy(-1.0, F1.vector())
        assert F0.vector().norm(cpp.la.Norm.l2) < 1.0e-12
    hdf5_file.close()
def _check_space_order(problem, method):
    mesh_generator, solution, weak_F = problem()

    # Translate data into FEniCS expressions.
    fenics_sol = Expression(smp.prining.ccode(solution['value']),
                            degree=solution['degree'],
                            t=0.0
                            )

    # Create initial solution.
    theta0 = Expression(fenics_sol.cppcode,
                        degree=solution['degree'],
                        t=0.0,
                        cell=triangle
                        )

    # Estimate the error component in space.
    # Leave out too rough discretizations to avoid showing spurious errors.
    N = [2 ** k for k in range(2, 8)]
    dt = 1.0e-8
    Err = []
    H = []
    for n in N:
        mesh = mesh_generator(n)
        H.append(MPI.max(mesh.hmax()))
        V = FunctionSpace(mesh, 'CG', 3)
        # Create boundary conditions.
        fenics_sol.t = dt
        #bcs = DirichletBC(V, fenics_sol, 'on_boundary')
        # Create initial state.
        theta_approx = method(V,
                              weak_F,
                              theta0,
                              0.0, dt,
                              bcs=[solution],
                              tol=1.0e-12,
                              verbose=True
                              )
        # Compute the error.
        fenics_sol.t = dt
        Err.append(errornorm(fenics_sol, theta_approx)
                   / norm(fenics_sol, mesh=mesh)
                   )
        print('n: %d    error: %e' % (n, Err[-1]))

    from matplotlib import pyplot as pp
    # Compare with order 1, 2, 3 curves.
    for o in [2, 3, 4]:
        pp.loglog([H[0], H[-1]],
                  [Err[0], Err[0] * (H[-1] / H[0]) ** o],
                  color='0.5'
                  )
    # Finally, the actual data.
    pp.loglog(H, Err, '-o')
    pp.xlabel('h_max')
    pp.ylabel('||u-u_h|| / ||u||')
    pp.show()
    return
示例#3
0
def _check_spatial_order(problem, method):
    mesh_generator, solution, weak_F = problem()

    # Translate data into FEniCS expressions.
    fenics_sol = Expression(sympy.printing.ccode(solution['value']),
                            degree=solution['degree'],
                            t=0.0)

    # Create initial solution.
    theta0 = Expression(fenics_sol.cppcode,
                        degree=solution['degree'],
                        t=0.0,
                        cell=triangle)

    # Estimate the error component in space.
    # Leave out too rough discretizations to avoid showing spurious errors.
    N = [2**k for k in range(2, 8)]
    dt = 1.0e-8
    Err = []
    H = []
    for n in N:
        mesh = mesh_generator(n)
        H.append(MPI.max(mesh.hmax()))
        V = FunctionSpace(mesh, 'CG', 5)
        # Create boundary conditions.
        fenics_sol.t = dt
        # bcs = DirichletBC(V, fenics_sol, 'on_boundary')
        # Create initial state.
        theta_approx = method(V,
                              weak_F,
                              theta0,
                              0.0,
                              dt,
                              bcs=[solution],
                              tol=1.0e-12,
                              verbose=True)
        # Compute the error.
        fenics_sol.t = dt
        Err.append(
            errornorm(fenics_sol, theta_approx) / norm(fenics_sol, mesh=mesh))
        print('n: %d    error: %e' % (n, Err[-1]))

    # Plot order curves for comparison.
    for order in [2, 3, 4]:
        plt.loglog([H[0], H[-1]], [Err[0], Err[0] * (H[-1] / H[0])**order],
                   color='0.5')
    # Finally, the actual data.
    plt.loglog(H, Err, '-o')
    plt.xlabel('h_max')
    plt.ylabel('||u-u_h|| / ||u||')
    plt.show()
    return
示例#4
0
def test_interpolation_rank0(V):
    @function.expression.numba_eval
    def expr_eval(values, x, t):
        values[:, 0] = 1.0 * t

    f = Expression(expr_eval, shape=())
    f.t = 1.0
    w = interpolate(f, V)
    with w.vector().localForm() as x:
        assert (x[:] == 1.0).all()
    f.t = 2.0
    w = interpolate(f, V)
    with w.vector().localForm() as x:
        assert (x[:] == 2.0).all()
def _compute_time_errors(problem, method, mesh_sizes, Dt, plot_error=False):
    mesh_generator, solution, ProblemClass, cell_type = problem()
    # Translate data into FEniCS expressions.
    fenics_sol = Expression(smp.printing.ccode(solution['value']),
                            degree=solution['degree'],
                            t=0.0,
                            cell=cell_type
                            )
    # Compute the problem
    errors = {'theta': numpy.empty((len(mesh_sizes), len(Dt)))}
    # Create initial state.
    # Deepcopy the expression into theta0. Specify the cell to allow for
    # more involved operations with it (e.g., grad()).
    theta0 = Expression(fenics_sol.cppcode,
                        degree=solution['degree'],
                        t=0.0,
                        cell=cell_type
                        )
    for k, mesh_size in enumerate(mesh_sizes):
        mesh = mesh_generator(mesh_size)
        V = FunctionSpace(mesh, 'CG', 1)
        theta_approx = Function(V)
        theta0p = project(theta0, V)
        stepper = method(ProblemClass(V))
        if plot_error:
            error = Function(V)
        for j, dt in enumerate(Dt):
            # TODO We are facing a little bit of a problem here, being the
            # fact that the time stepper only accept elements from V as u0.
            # In principle, though, this isn't necessary or required. We
            # could allow for arbitrary expressions here, but then the API
            # would need changing for problem.lhs(t, u).
            # Think about this.
            stepper.step(theta_approx, theta0p,
                         0.0, dt,
                         tol=1.0e-12,
                         verbose=False
                         )
            fenics_sol.t = dt
            #
            # NOTE
            # When using errornorm(), it is quite likely to see a good part
            # of the error being due to the spatial discretization.  Some
            # analyses "get rid" of this effect by (sometimes implicitly)
            # projecting the exact solution onto the discrete function
            # space.
            errors['theta'][k][j] = errornorm(fenics_sol, theta_approx)
            if plot_error:
                error.assign(project(fenics_sol - theta_approx, V))
                plot(error, title='error (dt=%e)' % dt)
                interactive()
    return errors, stepper.name, stepper.order
示例#6
0
def _compute_time_errors(problem, method, mesh_sizes, Dt, plot_error=False):
    mesh_generator, solution, ProblemClass, _ = problem()
    # Translate data into FEniCS expressions.
    fenics_sol = Expression(sympy.printing.ccode(solution),
                            degree=MAX_DEGREE,
                            t=0.0)
    # Compute the problem
    errors = numpy.empty((len(mesh_sizes), len(Dt)))
    # Create initial state.
    # Deepcopy the expression into theta0. Specify the cell to allow for
    # more involved operations with it (e.g., grad()).
    theta0 = Expression(fenics_sol.cppcode, degree=MAX_DEGREE, t=0.0)
    for k, mesh_size in enumerate(mesh_sizes):
        mesh = mesh_generator(mesh_size)

        # Choose the function space such that the exact solution can be
        # represented as well as possible.
        V = FunctionSpace(mesh, 'CG', 4)

        theta_approx = Function(V)
        theta0p = project(theta0, V)

        stepper = method(ProblemClass(V))
        if plot_error:
            error = Function(V)
        for j, dt in enumerate(Dt):
            # TODO We are facing a little bit of a problem here, being the fact
            # that the time stepper only accept elements from V as u0.  In
            # principle, though, this isn't necessary or required. We could
            # allow for arbitrary expressions here, but then the API would need
            # changing for problem.lhs(t, u).  Think about this.
            theta_approx.assign(stepper.step(theta0p, 0.0, dt))
            fenics_sol.t = dt

            # NOTE
            # When using errornorm(), it is quite likely to see a good part of
            # the error being due to the spatial discretization.  Some analyses
            # "get rid" of this effect by (sometimes implicitly) projecting the
            # exact solution onto the discrete function space.

            errors[k][j] = errornorm(fenics_sol, theta_approx)
            if plot_error:
                error.assign(project(fenics_sol - theta_approx, V))
                plot(error, title='error (dt={:e})'.format(dt))
                plt.show()
    return errors
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
示例#8
0
v = TestFunction(V)
f = Constant(beta - 2 - 2 * alpha)

F = u * v * dx + dt * dot(grad(u), grad(v)) * dx - (u_n + dt * f) * v * dx
a, L = lhs(F), rhs(F)

# Time-stepping
u = Function(V)
t = 0
vtkfile = File('heat/solution_3D.pvd')

for n in range(num_steps):

    # Update current time
    t += dt
    u_D.t = t

    # Compute solution
    solve(a == L, u, bc)

    # Plot solution
    # plot(u)
    # axi.triplot(u)
    vtkfile << u

    # Compute error at vertices
    # u_e = interpolate(u_D, V)
    # error = np.abs(u_e.vector().array() - u.vector().array()).max()
    # print('t = %.2f: error = %.3g' % (t, error))

    # Update previous solution
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)

ap = advect_rk3(p, V, uh, 'open')

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

for step in range(num_steps):
    u_expr.t = step * float(dt)
    u_expre_neg.t = step * float(dt)

    uh.assign(u_expr)

    # Compute area at old configuration
    old_area = assemble(phih0*dx)

    # Pre-assemble rhs
    pde_projection.assemble_state_rhs()

    # Advect the particles
    ap.do_step(float(dt))

    # Move mesh
    umesh.assign(u_expre_neg)
示例#10
0
def _test_time_stepping_1_sparse(callback_type, integrator_type):
    # Create mesh and define function space
    mesh = IntervalMesh(132, 0, 2*pi)
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Define Dirichlet boundary (x = 0 or x = 2*pi)
    def boundary(x):
        return x[0] < 0 + DOLFIN_EPS or x[0] > 2*pi - 10*DOLFIN_EPS
        
    # Define time step
    dt = 0.01
    T = 1.

    # Define exact solution
    exact_solution_expression = Expression("sin(x[0]+t)", t=0, element=V.ufl_element())
    # ... and interpolate it at the final time
    exact_solution_expression.t = T
    exact_solution = project(exact_solution_expression, V)

    # Define exact solution dot
    exact_solution_dot_expression = Expression("cos(x[0]+t)", t=0, element=V.ufl_element())
    # ... and interpolate it at the final time
    exact_solution_dot_expression.t = T
    exact_solution_dot = project(exact_solution_dot_expression, V)

    # Define variational problem
    du = TrialFunction(V)
    du_dot = TrialFunction(V)
    v = TestFunction(V)
    u = Function(V)
    u_dot = Function(V)
    g = Expression("sin(x[0]+t) + cos(x[0]+t)", t=0., element=V.ufl_element())
    r_u = inner(grad(u), grad(v))*dx
    j_u = derivative(r_u, u, du)
    r_u_dot = inner(u_dot, v)*dx
    j_u_dot = derivative(r_u_dot, u_dot, du_dot)
    r = r_u_dot + r_u - g*v*dx
    x = inner(du, v)*dx
    def bc(t):
        exact_solution_expression.t = t
        return [DirichletBC(V, exact_solution_expression, boundary)]

    # Assemble inner product matrix
    X = assemble(x)
    
    # Define callback function depending on callback type
    assert callback_type in ("form callbacks", "tensor callbacks")
    if callback_type == "form callbacks":
        def callback(arg):
            return arg
    elif callback_type == "tensor callbacks":
        def callback(arg):
            return assemble(arg)
            
    # Define problem wrapper
    class SparseProblemWrapper(TimeDependentProblem1Wrapper):
        # Residual and jacobian functions
        def residual_eval(self, t, solution, solution_dot):
            g.t = t
            return callback(r)
        def jacobian_eval(self, t, solution, solution_dot, solution_dot_coefficient):
            return callback(Constant(solution_dot_coefficient)*j_u_dot + j_u)
            
        # Define boundary condition
        def bc_eval(self, t):
            return bc(t)
            
        # Define initial condition
        def ic_eval(self):
            exact_solution_expression.t = 0.
            return project(exact_solution_expression, V)
            
        # Define custom monitor to plot the solution
        def monitor(self, t, solution, solution_dot):
            if matplotlib.get_backend() != "agg":
                plt.subplot(1, 2, 1).clear()
                plot(solution, title="u at t = " + str(t))
                plt.subplot(1, 2, 2).clear()
                plot(solution_dot, title="u_dot at t = " + str(t))
                plt.show(block=False)
                plt.pause(DOLFIN_EPS)
            else:
                print("||u|| at t = " + str(t) + ": " + str(solution.vector().norm("l2")))
                print("||u_dot|| at t = " + str(t) + ": " + str(solution_dot.vector().norm("l2")))

    # Solve the time dependent problem
    sparse_problem_wrapper = SparseProblemWrapper()
    (sparse_solution, sparse_solution_dot) = (u, u_dot)
    sparse_solver = SparseTimeStepping(sparse_problem_wrapper, sparse_solution, sparse_solution_dot)
    sparse_solver.set_parameters({
        "initial_time": 0.0,
        "time_step_size": dt,
        "final_time": T,
        "exact_final_time": "stepover",
        "integrator_type": integrator_type,
        "problem_type": "linear",
        "linear_solver": "mumps",
        "monitor": sparse_problem_wrapper.monitor,
        "report": True
    })
    all_sparse_solutions_time, all_sparse_solutions, all_sparse_solutions_dot = sparse_solver.solve()
    assert len(all_sparse_solutions_time) == int(T/dt + 1)
    assert len(all_sparse_solutions) == int(T/dt + 1)
    assert len(all_sparse_solutions_dot) == int(T/dt + 1)

    # Compute the error
    sparse_error = Function(V)
    sparse_error.vector().add_local(+ sparse_solution.vector().get_local())
    sparse_error.vector().add_local(- exact_solution.vector().get_local())
    sparse_error.vector().apply("")
    sparse_error_norm = sparse_error.vector().inner(X*sparse_error.vector())
    sparse_error_dot = Function(V)
    sparse_error_dot.vector().add_local(+ sparse_solution_dot.vector().get_local())
    sparse_error_dot.vector().add_local(- exact_solution_dot.vector().get_local())
    sparse_error_dot.vector().apply("")
    sparse_error_dot_norm = sparse_error_dot.vector().inner(X*sparse_error_dot.vector())
    print("SparseTimeStepping error (" + callback_type + ", " + integrator_type + "):", sparse_error_norm, sparse_error_dot_norm)
    assert isclose(sparse_error_norm, 0., atol=1.e-4)
    assert isclose(sparse_error_dot_norm, 0., atol=1.e-4)
    return ((sparse_error_norm, sparse_error_dot_norm), V, dt, T, u, u_dot, g, r, j_u, j_u_dot, X, exact_solution_expression, exact_solution, exact_solution_dot)
示例#11
0
def compute_time_errors(problem, method, mesh_sizes, Dt):

    mesh_generator, solution, f, mu, rho, cell_type = problem()

    # Translate data into FEniCS expressions.
    u = solution['u']
    sol_u = Expression((ccode(u['value'][0]), ccode(u['value'][1])),
                       degree=_truncate_degree(u['degree']),
                       t=0.0)

    p = solution['p']
    sol_p = Expression(ccode(p['value']),
                       degree=_truncate_degree(p['degree']),
                       t=0.0)

    # Deep-copy expression to be able to provide f0, f1 for the Dirichlet-
    # boundary conditions later on.
    fenics_rhs0 = Expression((ccode(f['value'][0]), ccode(f['value'][1])),
                             degree=_truncate_degree(f['degree']),
                             t=0.0,
                             mu=mu,
                             rho=rho)
    fenics_rhs1 = Expression(fenics_rhs0.cppcode,
                             element=fenics_rhs0.ufl_element(),
                             **fenics_rhs0.user_parameters)
    # Create initial states.
    p = Expression(sol_p.cppcode,
                   degree=_truncate_degree(solution['p']['degree']),
                   t=0.0,
                   cell=cell_type)

    # Compute the problem
    errors = {
        'u': numpy.empty((len(mesh_sizes), len(Dt))),
        'p': numpy.empty((len(mesh_sizes), len(Dt)))
    }
    for k, mesh_size in enumerate(mesh_sizes):
        print()
        print()
        print('Computing for mesh size %r...' % mesh_size)
        mesh = mesh_generator(mesh_size)
        mesh_area = assemble(1.0 * dx(mesh))
        W = VectorFunctionSpace(mesh, 'CG', 2)
        P = FunctionSpace(mesh, 'CG', 1)
        u1 = Function(W)
        p1 = Function(P)
        err_p = Function(P)
        divu1 = Function(P)
        for j, dt in enumerate(Dt):
            # Prepare previous states for multistepping.
            u_1 = Expression(sol_u.cppcode,
                             degree=_truncate_degree(solution['u']['degree']),
                             t=-dt,
                             cell=cell_type)
            u_1 = project(u_1, W)
            u0 = Expression(
                sol_u.cppcode,
                degree=_truncate_degree(solution['u']['degree']),
                t=0.0,
                # t=0.5*dt,
                cell=cell_type)
            u0 = project(u0, W)
            sol_u.t = dt
            u_bcs = [DirichletBC(W, sol_u, 'on_boundary')]
            sol_p.t = dt
            p0 = project(p, P)
            p_bcs = []
            fenics_rhs0.t = 0.0
            fenics_rhs1.t = dt
            u1, p1 = method.step(Constant(dt), {
                -1: u_1,
                0: u0
            },
                                 p0,
                                 u_bcs=u_bcs,
                                 p_bcs=p_bcs,
                                 rho=Constant(rho),
                                 mu=Constant(mu),
                                 f={
                                     0: fenics_rhs0,
                                     1: fenics_rhs1
                                 },
                                 verbose=False,
                                 tol=1.0e-10)

            # plot(sol_u, mesh=mesh, title='u_sol')
            # plot(sol_p, mesh=mesh, title='p_sol')
            # plot(u1, title='u')
            # plot(p1, title='p')
            # from dolfin import div
            # plot(div(u1), title='div(u)')
            # plot(p1 - sol_p, title='p_h - p')
            # interactive()

            sol_u.t = dt
            sol_p.t = dt
            errors['u'][k][j] = errornorm(sol_u, u1)
            # The pressure is only determined up to a constant which makes
            # it a bit harder to define what the error is. For our
            # purposes, choose an alpha_0\in\R such that
            #
            #    alpha0 = argmin ||e - alpha||^2
            #
            # with  e := sol_p - p.
            # This alpha0 is unique and explicitly given by
            #
            #     alpha0 = 1/(2|Omega|) \int (e + e*)
            #            = 1/|Omega| \int Re(e),
            #
            # i.e., the mean error in \Omega.
            alpha = (+assemble(sol_p * dx(mesh)) - assemble(p1 * dx(mesh)))
            alpha /= mesh_area
            # We would like to perform
            #     p1 += alpha.
            # To avoid creating a temporary function every time, assume
            # that p1 lives in a function space where the coefficients
            # represent actual function values. This is true for CG
            # elements, for example. In that case, we can just add any
            # number to the vector of p1.
            p1.vector()[:] += alpha
            errors['p'][k][j] = errornorm(sol_p, p1)

            show_plots = False
            if show_plots:
                plot(p1, title='p1', mesh=mesh)
                plot(sol_p, title='sol_p', mesh=mesh)
                err_p.vector()[:] = p1.vector()
                sol_interp = interpolate(sol_p, P)
                err_p.vector()[:] -= sol_interp.vector()
                # plot(sol_p - p1, title='p1 - sol_p', mesh=mesh)
                plot(err_p, title='p1 - sol_p', mesh=mesh)
                # r = Expression('x[0]', degree=1, cell=triangle)
                # divu1 = 1 / r * (r * u1[0]).dx(0) + u1[1].dx(1)
                divu1.assign(project(u1[0].dx(0) + u1[1].dx(1), P))
                plot(divu1, title='div(u1)')
                interactive()
    return errors
示例#12
0
def compute_time_errors(problem, MethodClass, mesh_sizes, Dt):

    mesh_generator, solution, f, mu, rho, cell_type = problem()
    # Translate data into FEniCS expressions.
    sol_u = Expression((smp.printing.ccode(solution['u']['value'][0]),
                        smp.printing.ccode(solution['u']['value'][1])
                        ),
                       degree=_truncate_degree(solution['u']['degree']),
                       t=0.0,
                       cell=cell_type
                       )
    sol_p = Expression(smp.printing.ccode(solution['p']['value']),
                       degree=_truncate_degree(solution['p']['degree']),
                       t=0.0,
                       cell=cell_type
                       )

    fenics_rhs0 = Expression((smp.printing.ccode(f['value'][0]),
                              smp.printing.ccode(f['value'][1])
                              ),
                             degree=_truncate_degree(f['degree']),
                             t=0.0,
                             mu=mu, rho=rho,
                             cell=cell_type
                             )
    # Deep-copy expression to be able to provide f0, f1 for the Dirichlet-
    # boundary conditions later on.
    fenics_rhs1 = Expression(fenics_rhs0.cppcode,
                             degree=_truncate_degree(f['degree']),
                             t=0.0,
                             mu=mu, rho=rho,
                             cell=cell_type
                             )
    # Create initial states.
    p0 = Expression(
        sol_p.cppcode,
        degree=_truncate_degree(solution['p']['degree']),
        t=0.0,
        cell=cell_type
        )

    # Compute the problem
    errors = {'u': numpy.empty((len(mesh_sizes), len(Dt))),
              'p': numpy.empty((len(mesh_sizes), len(Dt)))
              }
    for k, mesh_size in enumerate(mesh_sizes):
        info('')
        info('')
        with Message('Computing for mesh size %r...' % mesh_size):
            mesh = mesh_generator(mesh_size)
            mesh_area = assemble(1.0 * dx(mesh))
            W = VectorFunctionSpace(mesh, 'CG', 2)
            P = FunctionSpace(mesh, 'CG', 1)
            method = MethodClass(W, P,
                                 rho, mu,
                                 theta=1.0,
                                 #theta=0.5,
                                 stabilization=None
                                 #stabilization='SUPG'
                                 )
            u1 = Function(W)
            p1 = Function(P)
            err_p = Function(P)
            divu1 = Function(P)
            for j, dt in enumerate(Dt):
                # Prepare previous states for multistepping.
                u = [Expression(
                    sol_u.cppcode,
                    degree=_truncate_degree(solution['u']['degree']),
                    t=0.0,
                    cell=cell_type
                    ),
                    # Expression(
                    #sol_u.cppcode,
                    #degree=_truncate_degree(solution['u']['degree']),
                    #t=0.5*dt,
                    #cell=cell_type
                    #)
                    ]
                sol_u.t = dt
                u_bcs = [DirichletBC(W, sol_u, 'on_boundary')]
                sol_p.t = dt
                #p_bcs = [DirichletBC(P, sol_p, 'on_boundary')]
                p_bcs = []
                fenics_rhs0.t = 0.0
                fenics_rhs1.t = dt
                method.step(dt,
                            u1, p1,
                            u, p0,
                            u_bcs=u_bcs, p_bcs=p_bcs,
                            f0=fenics_rhs0, f1=fenics_rhs1,
                            verbose=False,
                            tol=1.0e-10
                            )
                sol_u.t = dt
                sol_p.t = dt
                errors['u'][k][j] = errornorm(sol_u, u1)
                # The pressure is only determined up to a constant which makes
                # it a bit harder to define what the error is. For our
                # purposes, choose an alpha_0\in\R such that
                #
                #    alpha0 = argmin ||e - alpha||^2
                #
                # with  e := sol_p - p.
                # This alpha0 is unique and explicitly given by
                #
                #     alpha0 = 1/(2|Omega|) \int (e + e*)
                #            = 1/|Omega| \int Re(e),
                #
                # i.e., the mean error in \Omega.
                alpha = assemble(sol_p * dx(mesh)) \
                    - assemble(p1 * dx(mesh))
                alpha /= mesh_area
                # We would like to perform
                #     p1 += alpha.
                # To avoid creating a temporary function every time, assume
                # that p1 lives in a function space where the coefficients
                # represent actual function values. This is true for CG
                # elements, for example. In that case, we can just add any
                # number to the vector of p1.
                p1.vector()[:] += alpha
                errors['p'][k][j] = errornorm(sol_p, p1)

                show_plots = False
                if show_plots:
                    plot(p1, title='p1', mesh=mesh)
                    plot(sol_p, title='sol_p', mesh=mesh)
                    err_p.vector()[:] = p1.vector()
                    sol_interp = interpolate(sol_p, P)
                    err_p.vector()[:] -= sol_interp.vector()
                    #plot(sol_p - p1, title='p1 - sol_p', mesh=mesh)
                    plot(err_p, title='p1 - sol_p', mesh=mesh)
                    #r = Expression('x[0]', degree=1, cell=triangle)
                    #divu1 = 1 / r * (r * u1[0]).dx(0) + u1[1].dx(1)
                    divu1.assign(project(u1[0].dx(0) + u1[1].dx(1), P))
                    plot(divu1, title='div(u1)')
                    interactive()
    return errors
示例#13
0
def compute_time_errors(problem, MethodClass, mesh_sizes, Dt):

    mesh_generator, solution, f, mu, rho, cell_type = problem()

    # Compute the problem
    errors = {
        "u": numpy.empty((len(mesh_sizes), len(Dt))),
        "p": numpy.empty((len(mesh_sizes), len(Dt))),
    }
    for k, mesh_size in enumerate(mesh_sizes):
        info("")
        info("")
        with Message("Computing for mesh size {}...".format(mesh_size)):
            mesh = mesh_generator(mesh_size)

            # Define all expression with `domain`, see
            # <https://bitbucket.org/fenics-project/ufl/issues/96>.
            #
            # Translate data into FEniCS expressions.
            sol_u = Expression(
                (ccode(solution["u"]["value"][0]), ccode(solution["u"]["value"][1])),
                degree=_truncate_degree(solution["u"]["degree"]),
                t=0.0,
                domain=mesh,
            )
            sol_p = Expression(
                ccode(solution["p"]["value"]),
                degree=_truncate_degree(solution["p"]["degree"]),
                t=0.0,
                domain=mesh,
            )

            fenics_rhs0 = Expression(
                (ccode(f["value"][0]), ccode(f["value"][1])),
                degree=_truncate_degree(f["degree"]),
                t=0.0,
                mu=mu,
                rho=rho,
                domain=mesh,
            )
            # Deep-copy expression to be able to provide f0, f1 for the
            # Dirichlet boundary conditions later on.
            fenics_rhs1 = Expression(
                fenics_rhs0.cppcode,
                degree=_truncate_degree(f["degree"]),
                t=0.0,
                mu=mu,
                rho=rho,
                domain=mesh,
            )
            # Create initial states.
            W = VectorFunctionSpace(mesh, "CG", 2)
            P = FunctionSpace(mesh, "CG", 1)
            p0 = Expression(
                sol_p.cppcode,
                degree=_truncate_degree(solution["p"]["degree"]),
                t=0.0,
                domain=mesh,
            )

            mesh_area = assemble(1.0 * dx(mesh))
            method = MethodClass(
                time_step_method="backward euler",
                # time_step_method='crank-nicolson',
                # stabilization=None
                # stabilization='SUPG'
            )
            u1 = Function(W)
            p1 = Function(P)
            err_p = Function(P)
            divu1 = Function(P)
            for j, dt in enumerate(Dt):
                # Prepare previous states for multistepping.
                u = {
                    0: Expression(
                        sol_u.cppcode,
                        degree=_truncate_degree(solution["u"]["degree"]),
                        t=0.0,
                        cell=cell_type,
                    )
                }
                sol_u.t = dt
                u_bcs = [DirichletBC(W, sol_u, "on_boundary")]
                sol_p.t = dt
                # p_bcs = [DirichletBC(P, sol_p, 'on_boundary')]
                p_bcs = []
                fenics_rhs0.t = 0.0
                fenics_rhs1.t = dt
                u1, p1 = method.step(
                    Constant(dt),
                    u,
                    p0,
                    W,
                    P,
                    u_bcs,
                    p_bcs,
                    Constant(rho),
                    Constant(mu),
                    f={0: fenics_rhs0, 1: fenics_rhs1},
                    verbose=False,
                    tol=1.0e-10,
                )

                sol_u.t = dt
                sol_p.t = dt
                errors["u"][k][j] = errornorm(sol_u, u1)
                # The pressure is only determined up to a constant which makes
                # it a bit harder to define what the error is. For our
                # purposes, choose an alpha_0\in\R such that
                #
                #    alpha0 = argmin ||e - alpha||^2
                #
                # with  e := sol_p - p.
                # This alpha0 is unique and explicitly given by
                #
                #     alpha0 = 1/(2|Omega|) \int (e + e*)
                #            = 1/|Omega| \int Re(e),
                #
                # i.e., the mean error in \Omega.
                alpha = +assemble(sol_p * dx(mesh)) - assemble(p1 * dx(mesh))
                alpha /= mesh_area
                # We would like to perform
                #     p1 += alpha.
                # To avoid creating a temporary function every time, assume
                # that p1 lives in a function space where the coefficients
                # represent actual function values. This is true for CG
                # elements, for example. In that case, we can just add any
                # number to the vector of p1.
                p1.vector()[:] += alpha
                errors["p"][k][j] = errornorm(sol_p, p1)

                show_plots = False
                if show_plots:
                    plot(p1, title="p1", mesh=mesh)
                    plot(sol_p, title="sol_p", mesh=mesh)
                    err_p.vector()[:] = p1.vector()
                    sol_interp = interpolate(sol_p, P)
                    err_p.vector()[:] -= sol_interp.vector()
                    # plot(sol_p - p1, title='p1 - sol_p', mesh=mesh)
                    plot(err_p, title="p1 - sol_p", mesh=mesh)
                    # r = SpatialCoordinate(mesh)[0]
                    # divu1 = 1 / r * (r * u1[0]).dx(0) + u1[1].dx(1)
                    divu1.assign(project(u1[0].dx(0) + u1[1].dx(1), P))
                    plot(divu1, title="div(u1)")
    return errors
示例#14
0
    p.increment(Udiv.cpp_object(), ustar.cpp_object(),
                np.array([1, 2], dtype=np.uintp), theta_p, step)

    if step == 2:
        theta_L.assign(theta_next)

    # Probably can be combined into one file?
    xdmf_u.write(Uh.sub(0), t)
    xdmf_p.write(Uh.sub(1), t)
    del t1

timer.stop()

# Compute errors
u_exact.t = t
p_exact.t = t

u_error = sqrt(assemble(dot(Uh.sub(0) - u_exact, Uh.sub(0) - u_exact) * dx))
p_error = sqrt(assemble(dot(Uh.sub(1) - p_exact, Uh.sub(1) - p_exact) * dx))
udiv = sqrt(assemble(div(Uh.sub(0)) * div(Uh.sub(0)) * dx))

momentum = assemble((dot(Uh.sub(0), ex) + dot(Uh.sub(0), ey)) * dx)

if comm.Get_rank() == 0:
    print("Velocity error " + str(u_error))
    print("Pressure error " + str(p_error))
    print("Momentum " + str(momentum))
    print("Divergence " + str(udiv))
    print("Elapsed time " + str(timer.elapsed()[0]))
示例#15
0
def compute_time_errors(problem, MethodClass, mesh_sizes, Dt):

    mesh_generator, solution, f, mu, rho, cell_type = problem()

    # Compute the problem
    errors = {
        "u": numpy.empty((len(mesh_sizes), len(Dt))),
        "p": numpy.empty((len(mesh_sizes), len(Dt))),
    }
    for k, mesh_size in enumerate(mesh_sizes):
        info("")
        info("")
        with Message("Computing for mesh size {}...".format(mesh_size)):
            mesh = mesh_generator(mesh_size)

            # Define all expression with `domain`, see
            # <https://bitbucket.org/fenics-project/ufl/issues/96>.
            #
            # Translate data into FEniCS expressions.
            sol_u = Expression(
                (ccode(solution["u"]["value"][0]),
                 ccode(solution["u"]["value"][1])),
                degree=_truncate_degree(solution["u"]["degree"]),
                t=0.0,
                domain=mesh,
            )
            sol_p = Expression(
                ccode(solution["p"]["value"]),
                degree=_truncate_degree(solution["p"]["degree"]),
                t=0.0,
                domain=mesh,
            )

            fenics_rhs0 = Expression(
                (ccode(f["value"][0]), ccode(f["value"][1])),
                degree=_truncate_degree(f["degree"]),
                t=0.0,
                mu=mu,
                rho=rho,
                domain=mesh,
            )
            # Deep-copy expression to be able to provide f0, f1 for the
            # Dirichlet boundary conditions later on.
            fenics_rhs1 = Expression(
                fenics_rhs0.cppcode,
                degree=_truncate_degree(f["degree"]),
                t=0.0,
                mu=mu,
                rho=rho,
                domain=mesh,
            )
            # Create initial states.
            W = VectorFunctionSpace(mesh, "CG", 2)
            P = FunctionSpace(mesh, "CG", 1)
            p0 = Expression(
                sol_p.cppcode,
                degree=_truncate_degree(solution["p"]["degree"]),
                t=0.0,
                domain=mesh,
            )

            mesh_area = assemble(1.0 * dx(mesh))
            method = MethodClass(
                time_step_method="backward euler",
                # time_step_method='crank-nicolson',
                # stabilization=None
                # stabilization='SUPG'
            )
            u1 = Function(W)
            p1 = Function(P)
            err_p = Function(P)
            divu1 = Function(P)
            for j, dt in enumerate(Dt):
                # Prepare previous states for multistepping.
                u = {
                    0:
                    Expression(
                        sol_u.cppcode,
                        degree=_truncate_degree(solution["u"]["degree"]),
                        t=0.0,
                        cell=cell_type,
                    )
                }
                sol_u.t = dt
                u_bcs = [DirichletBC(W, sol_u, "on_boundary")]
                sol_p.t = dt
                # p_bcs = [DirichletBC(P, sol_p, 'on_boundary')]
                p_bcs = []
                fenics_rhs0.t = 0.0
                fenics_rhs1.t = dt
                u1, p1 = method.step(
                    Constant(dt),
                    u,
                    p0,
                    W,
                    P,
                    u_bcs,
                    p_bcs,
                    Constant(rho),
                    Constant(mu),
                    f={
                        0: fenics_rhs0,
                        1: fenics_rhs1
                    },
                    verbose=False,
                    tol=1.0e-10,
                )

                sol_u.t = dt
                sol_p.t = dt
                errors["u"][k][j] = errornorm(sol_u, u1)
                # The pressure is only determined up to a constant which makes
                # it a bit harder to define what the error is. For our
                # purposes, choose an alpha_0\in\R such that
                #
                #    alpha0 = argmin ||e - alpha||^2
                #
                # with  e := sol_p - p.
                # This alpha0 is unique and explicitly given by
                #
                #     alpha0 = 1/(2|Omega|) \int (e + e*)
                #            = 1/|Omega| \int Re(e),
                #
                # i.e., the mean error in \Omega.
                alpha = +assemble(sol_p * dx(mesh)) - assemble(p1 * dx(mesh))
                alpha /= mesh_area
                # We would like to perform
                #     p1 += alpha.
                # To avoid creating a temporary function every time, assume
                # that p1 lives in a function space where the coefficients
                # represent actual function values. This is true for CG
                # elements, for example. In that case, we can just add any
                # number to the vector of p1.
                p1.vector()[:] += alpha
                errors["p"][k][j] = errornorm(sol_p, p1)

                show_plots = False
                if show_plots:
                    plot(p1, title="p1", mesh=mesh)
                    plot(sol_p, title="sol_p", mesh=mesh)
                    err_p.vector()[:] = p1.vector()
                    sol_interp = interpolate(sol_p, P)
                    err_p.vector()[:] -= sol_interp.vector()
                    # plot(sol_p - p1, title='p1 - sol_p', mesh=mesh)
                    plot(err_p, title="p1 - sol_p", mesh=mesh)
                    # r = SpatialCoordinate(mesh)[0]
                    # divu1 = 1 / r * (r * u1[0]).dx(0) + u1[1].dx(1)
                    divu1.assign(project(u1[0].dx(0) + u1[1].dx(1), P))
                    plot(divu1, title="div(u1)")
    return errors
示例#16
0
from dolfin import Expression

ccode = '(t-x[0])*(((t-x[0]) < 0) ? 0 : 1)*(((t-x[0]) > tmax) ? 0 : 1)'
foo = Expression(ccode, tmax=20, t=0.0)

for t in (0.1, 0.2, 0.3):
    foo.t = t
    print[foo(x) for x in (-1, -2, -3)]