Пример #1
0
def error_function(u_e, u, norm="L2"):
    """
    Compute the error between estimated solution u and exact solution u_e
    in the specified norm.
    """
    # Get function space
    V = u.function_space()

    if norm == "L2":  # L2 norm
        # Explicit computation of L2 norm
        # E = ((u_e - u) ** 2) * F.dx
        # error = np.sqrt(np.abs(F.assemble(E)))

        # Implicit interpolation of u_e to higher-order elements.
        # u will also be interpolated to the space Ve before integration
        error = F.errornorm(u_e, u, norm_type="L2", degree_rise=3)

    elif norm == "H10":  # H^1_0 seminorm
        error = F.errornorm(u_e, u, norm_type="H10", degree_rise=3)

    elif norm == "max":  # max/infinity norm
        u_e_ = F.interpolate(u_e, V)
        error = np.abs(np.array(u_e_.vector()) - np.array(u.vector())).max()

    return error
Пример #2
0
def problem(f, nx=8, ny=8, degrees=[1,2]):
    """
    Plot u along x=const or y=const for Lagrange elements,
    of given degrees, on a nx times ny mesh. f is a SymPy expression.
    """
    f = sym.printing.ccode(f)
    f = fe.Expression(f)
    mesh = fe.RectangleMesh(
        fe.Point(-1, 0), fe.Point(1, 2), 2, 2)
    for degree in degrees:
        if degree == 0:
            # The P0 element is specified like this in FEniCS
            V = fe.FunctionSpace(mesh, 'DG', 0)
        else:
            # The Lagrange Pd family of elements, d=1,2,3,...
            V = fe.FunctionSpace(mesh, 'P', degree)
        u = fe.project(f, V)
        u_error = fe.errornorm(f, u, 'L2')
        print '||u-f||=%g' % u_error, degree
        comparison_plot2D(
            u, f,
            n=50,
            value=0.4, variation='x',
            plottitle='Approximation by P%d elements' % degree,
            filename='approx_fenics_by_P%d' % degree,
            tol=1E-3)
Пример #3
0
def problem(f, nx=8, ny=8, degrees=[1, 2]):
    """
    Plot u along x=const or y=const for Lagrange elements,
    of given degrees, on a nx times ny mesh. f is a SymPy expression.
    """
    f = sym.printing.ccode(f)
    f = fe.Expression(f, degree=2)
    mesh = fe.RectangleMesh(fe.Point(-1, 0), fe.Point(1, 2), 2, 2)
    for degree in degrees:
        if degree == 0:
            # The P0 element is specified like this in FEniCS
            V = fe.FunctionSpace(mesh, 'DG', 0)
        else:
            # The Lagrange Pd family of elements, d=1,2,3,...
            V = fe.FunctionSpace(mesh, 'P', degree)
        u = fe.project(f, V)
        u_error = fe.errornorm(f, u, 'L2')
        print('||u-f||=%g' % u_error, degree)
        comparison_plot2D(u,
                          f,
                          n=50,
                          value=0.4,
                          variation='x',
                          plottitle='Approximation by P%d elements' % degree,
                          filename='approx_fenics_by_P%d' % degree,
                          tol=1E-3)
Пример #4
0
def solve_poisson_eps(h, eps, plot=False):
    eps = fe.Constant(eps)
    n = int(1 / h)
    # Create mesh and define function space
    mesh = fe.UnitIntervalMesh(n)
    V = fe.FunctionSpace(mesh, 'P', 1)

    # Define boundary condition
    u_D = fe.Constant(0.0)

    # Find exact solution:
    u_exact = fe.Expression(
        "(1./2 - x[0]) * (2 * x[0] + eps/(2*pi) * sin(2*pi*x[0]/eps)) "
        "+ eps*eps/(2*pi*2*pi) * (1 - cos(2*pi*x[0]/eps)) + x[0]*x[0]",
        eps=eps,
        degree=4)

    def boundary(x, on_boundary):
        return on_boundary

    bc = fe.DirichletBC(V, u_D, boundary)

    # Define variational problem

    u = fe.TrialFunction(V)
    v = fe.TestFunction(V)
    f = fe.Constant(1)
    A = fe.Expression('1./(2+cos(2*pi*x[0]/eps))', eps=eps, degree=2)
    a = A * fe.dot(fe.grad(u), fe.grad(v)) * fe.dx
    L = f * v * fe.dx

    # Compute solution
    u = fe.Function(V)
    fe.solve(a == L, u, bc)

    if plot:
        # Plot solution
        fe.plot(u)
        fe.plot(u_exact, mesh=mesh)
        # Hold plot
        fe.interactive()

    # # Save solution to file in VTK format
    # vtkfile = fe.File('poisson/solution.pvd')
    # vtkfile << u

    # Compute error
    err_norm = fe.errornorm(u_exact, u, 'L2')
    return err_norm
Пример #5
0
    def compute_error(self):

        if self.mode != 'test':
            return

        error_L2 = fe.errornorm(self.boundary_fun, self.u_n, 'L2')
        error_LI = np.abs(\
                fe.interpolate(\
                self.boundary_fun,self.function_space).vector().get_local() -\
                self.u_n.vector().get_local()\
                ).max()

        print('L2 error at t = {:.3f}: {:.2e}'.format(\
                self.current_time, error_L2))

        print('LI error at t = {:.3f}: {:.2e}'.format(\
                self.current_time, error_LI))

        self.error_list.append(error_L2)
Пример #6
0
u = fex.Function(V)
fex.solve(a == L, u, bc)
print(u)
# Plot solution and mesh
plt.subplot(2, 1, 1)
fex.plot(u)
#define the boundary conditions
plt.subplot(2, 1, 2)
fex.plot(mesh)
plt.savefig('possion_fex2.png')
#define the boundary conditions
# Save solution to file in VTK format
vtkfile = fex.File('poisson/solution.pvd')
vtkfile << u

# Compute error in L2 norm
error_L2 = fex.errornorm(u_D, u, 'L2')

# Compute maximum error at vertices
vertex_values_u_D = u_D.compute_vertex_values(mesh)
vertex_values_u = u.compute_vertex_values(mesh)
import numpy as np
error_max = np.max(np.abs(vertex_values_u_D - vertex_values_u))

# Print errors
print('error_L2  =', error_L2)
print('error_max =', error_max)

# Hold plot
#plt.show()
Пример #7
0
    def staggered_solve(self):
        self.U = fe.VectorFunctionSpace(self.mesh, 'CG', 1)
        self.W = fe.FunctionSpace(self.mesh, 'CG', 1)

        self.WW = fe.FunctionSpace(self.mesh, 'DG', 0)
        self.EE = fe.TensorFunctionSpace(self.mesh, 'DG', 0)
        self.MM = fe.VectorFunctionSpace(self.mesh, 'CG', 1)

        self.eta = fe.TestFunction(self.U)
        self.zeta = fe.TestFunction(self.W)
        q = fe.TestFunction(self.WW)

        del_x = fe.TrialFunction(self.U)
        del_d = fe.TrialFunction(self.W)
        p = fe.TrialFunction(self.WW)

        self.x_new = fe.Function(self.U, name="u")
        self.d_new = fe.Function(self.W, name="d")
        self.d_pre = fe.Function(self.W)
        self.x_pre = fe.Function(self.U)

        x_old = fe.Function(self.U)
        d_old = fe.Function(self.W)

        self.H_old = fe.Function(self.WW)

        self.map_plot = fe.Function(self.MM, name="m")
        e = fe.Function(self.EE, name="e")

        self.create_custom_xdmf_files()

        self.file_results = fe.XDMFFile('data/xdmf/{}/u.xdmf'.format(
            self.case_name))
        self.file_results.parameters["functions_share_mesh"] = True

        vtkfile_e = fe.File('data/pvd/simulation/{}/e.pvd'.format(
            self.case_name))
        vtkfile_u = fe.File('data/pvd/simulation/{}/u.pvd'.format(
            self.case_name))
        vtkfile_d = fe.File('data/pvd/simulation/{}/d.pvd'.format(
            self.case_name))

        for i, (disp, rp) in enumerate(
                zip(self.displacements, self.relaxation_parameters)):
            print('\n')
            print(
                '================================================================================='
            )
            print('>> Step {}, disp boundary condition = {} [mm]'.format(
                i, disp))
            print(
                '================================================================================='
            )
            self.i = i
            self.update_weak_form_due_to_Model_C_bug()

            if self.update_weak_form:
                self.set_bcs_staggered()
                print("Update weak form...")
                self.build_weak_form_staggered()

                print("Taking derivatives of weak form...")
                J_u = fe.derivative(self.G_u, self.x_new, del_x)
                J_d = fe.derivative(self.G_d, self.d_new, del_d)
                print("Define nonlinear problems...")
                p_u = fe.NonlinearVariationalProblem(self.G_u, self.x_new,
                                                     self.BC_u, J_u)
                p_d = fe.NonlinearVariationalProblem(self.G_d, self.d_new,
                                                     self.BC_d, J_d)
                print("Define solvers...")
                solver_u = fe.NonlinearVariationalSolver(p_u)
                solver_d = fe.NonlinearVariationalSolver(p_d)
                self.update_weak_form = False

                print("Update history weak form")
                a = p * q * fe.dx
                L = history(self.H_old, self.update_history(),
                            self.psi_cr) * q * fe.dx

                if self.map_flag:
                    self.interpolate_map()
                    # delta_x = self.x - self.x_hat
                    # self.map_plot.assign(fe.project(delta_x, self.MM))

            self.presLoad.t = disp

            newton_prm = solver_u.parameters['newton_solver']
            newton_prm['maximum_iterations'] = 100
            # newton_prm['absolute_tolerance'] = 1e-8
            newton_prm['relaxation_parameter'] = rp

            newton_prm = solver_d.parameters['newton_solver']
            newton_prm['maximum_iterations'] = 100
            # newton_prm['absolute_tolerance'] = 1e-8
            newton_prm['relaxation_parameter'] = rp

            vtkfile_e_staggered = fe.File(
                'data/pvd/simulation/{}/step{}/e.pvd'.format(
                    self.case_name, i))
            vtkfile_u_staggered = fe.File(
                'data/pvd/simulation/{}/step{}/u.pvd'.format(
                    self.case_name, i))
            vtkfile_d_staggered = fe.File(
                'data/pvd/simulation/{}/step{}/d.pvd'.format(
                    self.case_name, i))
            iteration = 0
            err = 1.
            while err > self.staggered_tol:
                iteration += 1

                solver_d.solve()

                solver_u.solve()

                if self.solution_scheme == 'explicit':
                    break

                # # Remarks(Tianju): self.x_new.vector() does not behave as expected: producing nan values
                # The following lines of codes cause issues
                # We use an error measure similar in https://doi.org/10.1007/s10704-019-00372-y
                # np_x_new = np.asarray(self.x_new.vector())
                # np_d_new = np.asarray(self.d_new.vector())
                # np_x_old = np.asarray(x_old.vector())
                # np_d_old = np.asarray(d_old.vector())
                # err_x = np.linalg.norm(np_x_new - np_x_old) / np.sqrt(len(np_x_new))
                # err_d = np.linalg.norm(np_d_new - np_d_old) / np.sqrt(len(np_d_new))
                # err = max(err_x, err_d)

                # # Remarks(Tianju): dolfin (2019.1.0) errornorm function has severe bugs not behave as expected
                # The bug seems to be fixed in later versions
                # The following sometimes produces nonzero results in dolfin (2019.1.0)
                # print(fe.errornorm(self.d_new, self.d_new, norm_type='l2'))

                err_x = fe.errornorm(self.x_new, x_old, norm_type='l2')
                err_d = fe.errornorm(self.d_new, d_old, norm_type='l2')
                err = max(err_x, err_d)

                x_old.assign(self.x_new)
                d_old.assign(self.d_new)
                e.assign(
                    fe.project(strain(self.mfem_grad(self.x_new)), self.EE))

                print(
                    '---------------------------------------------------------------------------------'
                )
                print(
                    '>> iteration. {}, err_u = {:.5}, err_d = {:.5}, error = {:.5}'
                    .format(iteration, err_x, err_d, err))
                print(
                    '---------------------------------------------------------------------------------'
                )

                # vtkfile_e_staggered << e
                # vtkfile_u_staggered << self.x_new
                # vtkfile_d_staggered << self.d_new

                if err < self.staggered_tol or iteration >= self.staggered_maxiter:
                    print(
                        '================================================================================='
                    )
                    print('\n')
                    break

            print("L2 projection to update the history function...")
            fe.solve(a == L, self.H_old, [])

            # self.d_pre.assign(self.d_new)
            # self.H_old.assign(fe.project(history(self.H_old, self.update_history(), self.psi_cr), self.WW))

            if self.map_flag and not self.finish_flag:
                self.update_map()

            if self.compute_and_save_intermediate_results:
                print("Save files...")
                self.file_results.write(e, i)
                self.file_results.write(self.x_new, i)
                self.file_results.write(self.d_new, i)
                self.file_results.write(self.map_plot, i)

                vtkfile_e << e
                vtkfile_u << self.x_new
                vtkfile_d << self.d_new

                # Assume boundary is not affected by the map.
                # There's no need to use the mfem_grad wrapper so that fe.grad is used for speed-up
                print("Define forces...")
                sigma = cauchy_stress_plus(strain(fe.grad(self.x_new)),
                                           self.psi)
                sigma_minus = cauchy_stress_minus(strain(fe.grad(self.x_new)),
                                                  self.psi_minus)
                sigma_plus = cauchy_stress_plus(strain(fe.grad(self.x_new)),
                                                self.psi_plus)
                sigma_degraded = g_d(self.d_new) * sigma_plus + sigma_minus

                print("Compute forces...")
                if self.case_name == 'pure_shear':
                    f_full = float(fe.assemble(sigma[0, 1] * self.ds(1)))
                    f_degraded = float(
                        fe.assemble(sigma_degraded[0, 1] * self.ds(1)))
                else:
                    f_full = float(fe.assemble(sigma[1, 1] * self.ds(1)))
                    f_degraded = float(
                        fe.assemble(sigma_degraded[1, 1] * self.ds(1)))

                print("Force full is {}".format(f_full))
                print("Force degraded is {}".format(f_degraded))
                self.delta_u_recorded.append(disp)
                self.force_full.append(f_full)
                self.force_degraded.append(f_degraded)

                # if force_upper < 0.5 and i > 10:
                #     break

                if self.display_intermediate_results and i % 10 == 0:
                    self.show_force_displacement()

                self.save_data_in_loop()

        if self.display_intermediate_results:
            plt.ioff()
            plt.show()
Пример #8
0
x = ufl.SpatialCoordinate(mesh)
w = ufl.sin(ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1])
f_analytic = 1 / (1 + alpha * 4 * ufl.pi ** 4) * w
u_analytic = 1 / (2 * ufl.pi ** 2) * f_analytic

f_opt = from_numpy(res.x, fn.Function(W))
u = fn.Function(V)
v = fn.TestFunction(V)
F = (ufl.inner(ufl.grad(u), ufl.grad(v)) - f_opt * v) * ufl.dx
bc = fn.DirichletBC(V, 0.0, "on_boundary")
fn.solve(F == 0, u, bc)
print(f"norm of f_opt is {fn.norm(f_opt)}")

# interpolatation of UFL forms does not work in FEniCS, hence projection
CG3 = fn.FunctionSpace(mesh, "CG", 3)
control_error = fn.errornorm(fn.project(f_analytic, CG3), f_opt)
state_error = fn.errornorm(fn.project(u_analytic, CG3), u)
print("h(min):           %e." % mesh.hmin())
print("Error in state:   %e." % state_error)
print("Error in control: %e." % control_error)

# Write solutions to XDMFFile, can be visualized with paraview
# First time step is approximated solution, second timestep is analytic
# solution

out_f = fn.XDMFFile("output/f_jax_scipy.xdmf")
out_f.write_checkpoint(f_opt, "f", 0.0, fn.XDMFFile.Encoding.HDF5, True)
out_f.write_checkpoint(
    fn.project(f_analytic, W), "f", 1.0, fn.XDMFFile.Encoding.HDF5, True
)
u = fs.TrialFunction(V)
v = fs.TestFunction(V)
f = fs.Constant(-6.0)
a = fs.dot(fs.grad(u), fs.grad(v)) * fs.dx
L = f * v * fs.dx

# compute solution
u = fs.Function(V)
fs.solve(a == L, u, bc)

# plot solution and mesh
fs.plot(u)
fs.plot(mesh)

# save solution to file in VTK format
vtkfile = fs.File('solution.pvd')
vtkfile << u

# compute error in L2 norm
error_L2 = fs.errornorm(u_D, u, 'L2')

# #compute maximum error at vertices
vertex_values_u_D = u_D.compute_vertex_values(mesh)
vertex_values_u = u.compute_vertex_values(mesh)
error_max = np.max(np.abs(vertex_values_u_D - vertex_values_u))

# print errors
print('error_L2 =', error_L2)
print('error_max = ', error_max)

plt.savefig('newtest', Format='png')
Пример #10
0
    def staggered_solve(self):
        self.U = fe.VectorFunctionSpace(self.mesh, 'CG', 1)
        self.W = fe.FunctionSpace(self.mesh, 'CG', 1)
        self.WW = fe.FunctionSpace(self.mesh, 'DG', 0)

        self.eta = fe.TestFunction(self.U)
        self.zeta = fe.TestFunction(self.W)

        del_x = fe.TrialFunction(self.U)
        del_d = fe.TrialFunction(self.W)

        self.x_new = fe.Function(self.U)
        self.d_new = fe.Function(self.W)

        x_old = fe.Function(self.U)
        d_old = fe.Function(self.W)

        self.H_old = fe.Function(self.WW)

        self.build_weak_form_staggered()
        J_u = fe.derivative(self.G_u, self.x_new, del_x)
        J_d = fe.derivative(self.G_d, self.d_new, del_d)

        self.set_bcs_staggered()
        p_u = fe.NonlinearVariationalProblem(self.G_u, self.x_new, self.BC_u,
                                             J_u)
        p_d = fe.NonlinearVariationalProblem(self.G_d, self.d_new, self.BC_d,
                                             J_d)
        solver_u = fe.NonlinearVariationalSolver(p_u)
        solver_d = fe.NonlinearVariationalSolver(p_d)

        vtkfile_u = fe.File('data/pvd/{}/u.pvd'.format(self.case_name))
        vtkfile_d = fe.File('data/pvd/{}/d.pvd'.format(self.case_name))

        for i, (disp, rp) in enumerate(
                zip(self.displacements, self.relaxation_parameters)):

            print('\n')
            print(
                '================================================================================='
            )
            print('>> Step {}, disp boundary condition = {} [mm]'.format(
                i, disp))
            print(
                '================================================================================='
            )

            self.H_old.assign(
                fe.project(
                    history(self.H_old, self.psi(strain(fe.grad(self.x_new))),
                            self.psi_cr), self.WW))

            self.presLoad.t = disp

            newton_prm = solver_u.parameters['newton_solver']
            newton_prm['maximum_iterations'] = 100
            newton_prm['absolute_tolerance'] = 1e-4
            newton_prm['relaxation_parameter'] = rp

            iteration = 0
            err = 1.

            while err > self.staggered_tol:
                iteration += 1

                solver_d.solve()

                solver_u.solve()

                err_u = fe.errornorm(self.x_new,
                                     x_old,
                                     norm_type='l2',
                                     mesh=None)
                err_d = fe.errornorm(self.d_new,
                                     d_old,
                                     norm_type='l2',
                                     mesh=None)
                err = max(err_u, err_d)

                x_old.assign(self.x_new)
                d_old.assign(self.d_new)

                print(
                    '---------------------------------------------------------------------------------'
                )
                print('>> iteration. {}, error = {:.5}'.format(iteration, err))
                print(
                    '---------------------------------------------------------------------------------'
                )

                if err < self.staggered_tol or iteration >= self.staggered_maxiter:
                    print(
                        '================================================================================='
                    )
                    print('\n')

                    self.x_new.rename("u", "u")
                    self.d_new.rename("d", "d")
                    vtkfile_u << self.x_new
                    vtkfile_d << self.d_new
                    break

            force_upper = float(fe.assemble(self.sigma[1, 1] * self.ds(1)))
            print("Force upper {}".format(force_upper))
            self.delta_u_recorded.append(disp)
            self.sigma_recorded.append(force_upper)
    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    f = Constant(-6.0)
    a = dot(grad(u), grad(v)) * dx
    L = f * v * dx

    # Compute solution
    u = Function(V)
    solve(a == L, u, bc)
    # since u is created as a Function object, it can be evaluated at any new point - although
    # this is an expensive operation!

    # Compute error in L2 norm
    error_L2 = errornorm(u_D, u, 'L2')

    # Compute maximum error at vertices
    vertex_values_u_D = u_D.compute_vertex_values(mesh)
    vertex_values_u = u.compute_vertex_values(mesh)

    # plot solution
    plt.figure()
    plt.contourf(vertex_values_u.reshape(*(grid_shape + 1)), cmap='viridis')
    plt.show()

    error_max = np.max(np.abs(vertex_values_u_D - vertex_values_u))
    # Print errors
    print('error_L2 =', error_L2)
    print('error_max =', error_max)
Пример #12
0
bc = fe.DirichletBC(V, u_D, boundary)

#define variational problem
u = fe.TrialFunction(V)
v = fe.TestFunction(V)
f = fe.Constant(-6.0)
a = (fe.dot(fe.grad(u), fe.grad(v))) * fe.dx
L = f * v * fe.dx

#compute the solution
u = fe.Function(V)
fe.solve(a == L, u, bc)

#plot solution and mesh
fe.plot(u)
fe.plot(mesh)

#save the solution into a vtk file
vtkfile = fe.File("poisson/solution.pvd")
vtkfile << u

#compute the error
error_l2 = fe.errornorm(u_D, u, "L2")
print("The overall L2 error is given by: " + str(error_l2) + "\n")

#maximum error at vertices
vertex_values_u_D = u_D.compute_vertex_values(mesh)
vertex_values_u = u.compute_vertex_values(mesh)
max_vertex_error = np.max(np.abs(vertex_values_u_D - vertex_values_u))
print("Maximum vertex error given by: " + str(max_vertex_error) + "\n")