Пример #1
0
def test():
    class Bratu:
        def apply(self, u):
            return integrate(lambda x: -n_dot_grad(u(x)), dS) - integrate(
                lambda x: 2.0 * exp(u(x)), dV)

        def dirichlet(self, u):
            return [(u, Boundary())]

    vertices, cells = meshzoo.rectangle(0.0, 2.0, 0.0, 1.0, 101, 51)
    mesh = meshplex.MeshTri(vertices, cells)

    f, jac_u = pyfvm.discretize(Bratu(), mesh)

    def jacobian_solver(u0, rhs):
        from scipy.sparse import linalg

        jac = jac_u.get_linear_operator(u0)
        return linalg.spsolve(jac, rhs)

    u0 = numpy.zeros(len(vertices))
    u = pyfvm.newton(lambda u: f.eval(u), jacobian_solver, u0)
    # import scipy.optimize
    # u = scipy.optimize.newton_krylov(f_eval, u0)

    mesh.write("out.vtk", point_data={"u": u})
    return
Пример #2
0
    def poisson(self, mesh, alpha, beta):
        from scipy.sparse import linalg

        # Define the problem
        class Poisson(LinearFvmProblem):
            def apply(self, u):
                return integrate(lambda x: - n_dot_grad(u(x)), dS) \
                       - integrate(lambda x: 1.0, dV)

            def dirichlet(self, u):
                return [(u, 'boundary')]

        linear_system = pyfvm.discretize(Poisson(), mesh)

        x = linalg.spsolve(linear_system.matrix, linear_system.rhs)

        k0 = -1
        for k, coord in enumerate(mesh.node_coords):
            # print(coord - [0.5, 0.5, 0.0])
            if numpy.linalg.norm(coord - [0.5, 0.5, 0.0]) < 1.0e-5:
                k0 = k
                break

        self.assertNotEqual(k0, -1)
        self.assertAlmostEqual(x[k0], alpha, delta=1.0e-7)

        x_dot_x = numpy.dot(x, mesh.control_volumes * x)
        self.assertAlmostEqual(x_dot_x, beta, delta=1.0e-7)

        return
Пример #3
0
def test():
    class Bratu(object):
        def apply(self, u):
            return integrate(lambda x: -n_dot_grad(u(x)), dS) - integrate(
                lambda x: 2.0 * exp(u(x)), dV
            )

        def dirichlet(self, u):
            return [(u, Boundary())]

    vertices, cells = meshzoo.rectangle(0.0, 2.0, 0.0, 1.0, 101, 51)
    mesh = meshplex.MeshTri(vertices, cells)

    f, jac_u = pyfvm.discretize(Bratu(), mesh)

    def jacobian_solver(u0, rhs):
        from scipy.sparse import linalg

        jac = jac_u.get_linear_operator(u0)
        return linalg.spsolve(jac, rhs)

    u0 = numpy.zeros(len(vertices))
    u = pyfvm.newton(lambda u: f.eval(u), jacobian_solver, u0)
    # import scipy.optimize
    # u = scipy.optimize.newton_krylov(f_eval, u0)

    mesh.write("out.vtk", point_data={"u": u})
    return
Пример #4
0
    def test_boundaries(self):
        import meshzoo
        from scipy.sparse import linalg

        class Gamma0(Subdomain):
            def is_inside(self, x): return x[1] < 0.5
            is_boundary_only = True

        class Gamma1(Subdomain):
            def is_inside(self, x): return x[1] >= 0.5
            is_boundary_only = True

        # Define the problem
        class Poisson(LinearFvmProblem):
            def apply(self, u):
                return integrate(lambda x: -n_dot_grad(u(x)), dS) \
                       - integrate(lambda x: 1.0, dV)

            def dirichlet(self, u):
                return [
                    (lambda x: u(x) - 0.0, Gamma0()),
                    (lambda x: u(x) - 1.0, Gamma1())
                    ]

        # Create mesh using meshzoo
        vertices, cells = meshzoo.rectangle.create_mesh(
                0.0, 1.0, 0.0, 1.0,
                21, 21,
                zigzag=True
                )
        mesh = pyfvm.meshTri.meshTri(vertices, cells)

        linear_system = pyfvm.discretize(Poisson(), mesh)

        x = linalg.spsolve(linear_system.matrix, linear_system.rhs)

        import meshio
        meshio.write('test.vtu', mesh.node_coords, {'triangle':
            mesh.cells['nodes']}, point_data={'x': x})

        k0 = -1
        for k, coord in enumerate(mesh.node_coords):
            # print(coord - [0.5, 0.5, 0.0])
            if numpy.linalg.norm(coord - [0.5, 0.5, 0.0]) < 1.0e-5:
                k0 = k
                break

        self.assertNotEqual(k0, -1)
        self.assertAlmostEqual(x[k0], 0.59455184740329481, delta=1.0e-7)

        x_dot_x = numpy.dot(x, mesh.control_volumes * x)
        self.assertAlmostEqual(x_dot_x, 0.42881926935620163, delta=1.0e-7)

        return
Пример #5
0
    def solver(mesh):
        f, jacobian = pyfvm.discretize(problem, mesh)

        def jacobian_solver(u0, rhs):
            from scipy.sparse import linalg

            jac = jacobian.get_linear_operator(u0)
            return linalg.spsolve(jac, rhs)

        u0 = numpy.zeros(len(mesh.node_coords))
        u = pyfvm.newton(f.eval, jacobian_solver, u0, verbose=False)
        return u
Пример #6
0
    def solver(mesh):
        f, jacobian = pyfvm.discretize(problem, mesh)

        def jacobian_solver(u0, rhs):
            from scipy.sparse import linalg

            jac = jacobian.get_linear_operator(u0)
            return linalg.spsolve(jac, rhs)

        u0 = numpy.zeros(len(mesh.node_coords))
        u = pyfvm.newton(f.eval, jacobian_solver, u0, verbose=False)
        return u
Пример #7
0
    def test_neumann(self):
        import meshzoo
        from scipy.sparse import linalg

        class D1(Subdomain):
            def is_inside(self, x): return x[1] < 0.5
            is_boundary_only = True

        # Define the problem
        class Poisson(LinearFvmProblem):
            def apply(self, u):
                return integrate(lambda x: - n_dot_grad(u(x)), dS) \
                       + integrate(lambda x: 3.0, dGamma) \
                       - integrate(lambda x: 1.0, dV)

            def dirichlet(self, u):
                return [(u, D1())]

        # Create mesh using meshzoo
        vertices, cells = meshzoo.rectangle.create_mesh(
                0.0, 1.0, 0.0, 1.0,
                21, 21,
                zigzag=True
                )
        mesh = pyfvm.meshTri.meshTri(vertices, cells)

        linear_system = pyfvm.discretize(Poisson(), mesh)

        x = linalg.spsolve(linear_system.matrix, linear_system.rhs)

        k0 = -1
        for k, coord in enumerate(mesh.node_coords):
            # print(coord - [0.5, 0.5, 0.0])
            if numpy.linalg.norm(coord - [0.5, 0.5, 0.0]) < 1.0e-5:
                k0 = k
                break

        self.assertNotEqual(k0, -1)
        self.assertAlmostEqual(x[k0], -1.3249459366260112, delta=1.0e-7)

        x_dot_x = numpy.dot(x, mesh.control_volumes * x)
        self.assertAlmostEqual(x_dot_x, 3.1844205150779601, delta=1.0e-7)

        return
Пример #8
0
    def test_singular_perturbation(self):
        import meshzoo
        from scipy.sparse import linalg

        # Define the problem
        class Poisson(LinearFvmProblem):
            def apply(self, u):
                return integrate(lambda x: - 1.0e-2 * n_dot_grad(u(x)), dS) \
                       + integrate(lambda x: u(x), dV) \
                       - integrate(lambda x: 1.0, dV)

            def dirichlet(self, u):
                return [(u, 'boundary')]

        # Create mesh using meshzoo
        vertices, cells = meshzoo.rectangle.create_mesh(
                0.0, 1.0, 0.0, 1.0,
                21, 21,
                zigzag=True
                )
        mesh = pyfvm.meshTri.meshTri(vertices, cells)

        linear_system = pyfvm.discretize(Poisson(), mesh)

        x = linalg.spsolve(linear_system.matrix, linear_system.rhs)

        k0 = -1
        for k, coord in enumerate(mesh.node_coords):
            # print(coord - [0.5, 0.5, 0.0])
            if numpy.linalg.norm(coord - [0.5, 0.5, 0.0]) < 1.0e-5:
                k0 = k
                break

        self.assertNotEqual(k0, -1)
        self.assertAlmostEqual(x[k0], 0.97335485230869123, delta=1.0e-7)

        x_dot_x = numpy.dot(x, mesh.control_volumes * x)
        self.assertAlmostEqual(x_dot_x, 0.49724636865618776, delta=1.0e-7)

        return
Пример #9
0
    def test_convection(self):
        import meshzoo
        from scipy.sparse import linalg

        # Define the problem
        class Poisson(LinearFvmProblem):
            def apply(self, u):
                a = sympy.Matrix([2, 1, 0])
                return integrate(lambda x: - n_dot_grad(u(x)) + dot(a.T, n) * u(x), dS) - \
                       integrate(lambda x: 1.0, dV)

            def dirichlet(self, u):
                return [(u, 'boundary')]

        # Create mesh using meshzoo
        vertices, cells = meshzoo.rectangle.create_mesh(
                0.0, 1.0, 0.0, 1.0,
                21, 21,
                zigzag=True
                )
        mesh = pyfvm.meshTri.meshTri(vertices, cells)

        linear_system = pyfvm.discretize(Poisson(), mesh)

        x = linalg.spsolve(linear_system.matrix, linear_system.rhs)

        k0 = -1
        for k, coord in enumerate(mesh.node_coords):
            if numpy.linalg.norm(coord - [0.5, 0.5, 0.0]) < 1.0e-5:
                k0 = k
                break

        self.assertNotEqual(k0, -1)
        self.assertAlmostEqual(x[k0], 0.07041709172659899, delta=1.0e-7)

        x_dot_x = numpy.dot(x, mesh.control_volumes * x)
        self.assertAlmostEqual(x_dot_x, 0.0016076431631658172, delta=1.0e-7)

        return
Пример #10
0
#         25, 25, 25
#         )
# mesh = pyfvm.meshTetra.meshTetra(vertices, cells)
# vertices, cells = meshzoo.rectangle.create_mesh(
#         0.0, 2.0,
#         0.0, 1.0,
#         401, 201,
#         zigzag=True
#         )
# mesh = pyfvm.meshTri.meshTri(vertices, cells)

import mshr
import dolfin
h = 2.5e-2
# cell_size = 2 * pi / num_boundary_points
c = mshr.Circle(dolfin.Point(0., 0., 0.), 1, int(2*pi / h))
# cell_size = 2 * bounding_box_radius / res
m = mshr.generate_mesh(c, 2.0 / h)
coords = m.coordinates()
coords = numpy.c_[coords, numpy.zeros(len(coords))]
mesh = pyfvm.meshTri.meshTri(coords, m.cells())

linear_system = pyfvm.discretize(Poisson(), mesh)

ml = pyamg.ruge_stuben_solver(linear_system.matrix)
x = ml.solve(linear_system.rhs, tol=1e-10)
# from scipy.sparse import linalg
# x = linalg.spsolve(linear_system.matrix, linear_system.rhs)

mesh.write('out.vtu', point_data={'x': x})
Пример #11
0
def perform_convergence_tests(
        problem, exact_sol, get_mesh, rng, verbose=False
        ):
    n = len(rng)
    H = numpy.empty(n)
    error_norm_1 = numpy.empty(n)
    order_1 = numpy.empty(n-1)
    error_norm_inf = numpy.empty(n)
    order_inf = numpy.empty(n-1)

    if verbose:
        print(79 * '-')
        print('k' + 5*' ' + 'num verts' + 4*' ' + 'max edge length' + 4*' ' +
              '||error||_1' + 8*' ' + '||error||_inf'
              )
        print(38*' ' + '(order)' + 12*' ' + '(order)')
        print(79 * '-')

    # Add "zero" to all entities. This later gets translated into
    # np.zeros with the appropriate length, making sure that scalar
    # terms in the lambda expression correctly return np.arrays.
    zero = sympy.Symbol('zero')
    x = sympy.DeferredVector('x')
    # See <http://docs.sympy.org/dev/modules/utilities/lambdify.html>.
    array2array = [{'ImmutableMatrix': numpy.array}, 'numpy']
    exact_eval = sympy.lambdify((x, zero), exact_sol(x), modules=array2array)

    for k in rng:
        mesh = get_mesh(k)
        H[k] = max(mesh.edge_lengths)

        linear_system = pyfvm.discretize(problem, mesh)

        # x = linalg.spsolve(linear_system.matrix, linear_system.rhs)
        ml = pyamg.ruge_stuben_solver(linear_system.matrix)
        x = ml.solve(linear_system.rhs, tol=1e-10)

        zero = numpy.zeros(len(mesh.node_coords))
        error = x - exact_eval(mesh.node_coords.T, zero)

        # import meshio
        # meshio.write(
        #     'sol%d.vtu' % k,
        #     mesh.node_coords, {'triangle': mesh.cells['nodes']},
        #     point_data={'x': x, 'error': error},
        #     )

        error_norm_1[k] = numpy.sum(abs(mesh.control_volumes * error))
        error_norm_inf[k] = max(abs(error))

        # numerical orders of convergence
        if k > 0:
            order_1[k-1] = \
                numpy.log(error_norm_1[k-1] / error_norm_1[k]) / \
                numpy.log(H[k-1] / H[k])
            order_inf[k-1] = \
                numpy.log(error_norm_inf[k-1] / error_norm_inf[k]) / \
                numpy.log(H[k-1] / H[k])
            if verbose:
                print
                print((38*' ' + '%0.5f' + 12*' ' + '%0.5f') %
                      (order_1[k-1], order_inf[k-1])
                      )
                print

        if verbose:
            num_nodes = len(mesh.control_volumes)
            print('%2d    %5.3e    %0.10e   %0.10e   %0.10e' %
                  (k, num_nodes, H[k], error_norm_1[k], error_norm_inf[k])
                  )

    return H, error_norm_1, error_norm_inf, order_1, order_inf
Пример #12
0
import pyfvm
from pyfvm.form_language import *
import meshzoo
from scipy.sparse import linalg


class DC(LinearFvmProblem):
    def apply(self, u):
        a = sympy.Matrix([2, 1, 0])
        return \
            integrate(lambda x: -n_dot_grad(u(x)) + dot(a.T, n) * u(x), dS) - \
            integrate(lambda x: 1.0, dV)

    def dirichlet(self, u):
        return [(u, 'boundary')]


vertices, cells = meshzoo.rectangle.create_mesh(
        0.0, 1.0,
        0.0, 1.0,
        51, 51,
        zigzag=True
        )
mesh = pyfvm.meshTri.meshTri(vertices, cells)

linear_system = pyfvm.discretize(DC(), mesh)

x = linalg.spsolve(linear_system.matrix, linear_system.rhs)

mesh.write('out.vtu', point_data={'x': x})
Пример #13
0
#
import meshzoo
import pyfvm
from pyfvm.form_language import *
from scipy.sparse import linalg


class Singular(LinearFvmProblem):
    def apply(self, u):
        return integrate(lambda x: - 1.0e-2 * n_dot_grad(u(x)), dS) \
               + integrate(u, dV) \
               - integrate(lambda x: 1.0, dV)

    def dirichlet(self, u):
        return [(u, 'boundary')]

# Create mesh using meshzoo
vertices, cells = meshzoo.rectangle.create_mesh(
        0.0, 1.0,
        0.0, 1.0,
        51, 51,
        zigzag=True
        )
mesh = pyfvm.meshTri.meshTri(vertices, cells)

linear_system = pyfvm.discretize(Singular(), mesh)

x = linalg.spsolve(linear_system.matrix, linear_system.rhs)

mesh.write('out.vtu', point_data={'x': x})