Esempio n. 1
0
    def runTest(self):
        # Mesh.remove_elements
        m = MeshTri()
        m.refine()
        M = m.remove_elements(np.array([0]))
        self.assertEqual(M.t.shape[1], 7)

        # Mesh.define_boundary
        m.define_boundary('foo', lambda x: x[0] == 0.)
        self.assertEqual(m.boundaries['foo'].size, 2)

        # Mesh.define_boundary (internal)
        m.define_boundary('bar',
                          lambda x: x[0] == 1. / 2,
                          boundaries_only=False)
        self.assertEqual(m.boundaries['bar'].size, 2)

        # Mesh.scale, Mesh.translate
        m = MeshHex()
        m.scale(0.5)
        m.translate((0.5, 0.5, 0.5))
        self.assertGreater(np.min(m.p), 0.4999)

        # Mesh3D.facets_satisfying
        self.assertEqual(len(m.facets_satisfying(lambda x: x[0] == 0.5)), 1)
Esempio n. 2
0
    def runTest(self):
        mesh = MeshTri()
        mesh.refine(5)
        basis = InteriorBasis(mesh, ElementTriP1())

        def fun(x, y):
            return x**2 + y**2

        x = L2_projection(fun, basis)
        y = fun(*mesh.p)

        normest = np.linalg.norm(x - y)

        self.assertTrue(normest < 0.011, msg="|x-y| = {}".format(normest))
Esempio n. 3
0
    def runTest(self):
        """Solve Stokes problem, try splitting and other small things."""

        m = MeshTri()
        m.refine()
        m.define_boundary('centreline',
                          lambda x: x[0] == .5,
                          boundaries_only=False)
        m.refine(3)

        e = ElementVectorH1(ElementTriP2()) * ElementTriP1()

        m.define_boundary('up', lambda x: x[1] == 1.)
        m.define_boundary('rest', lambda x: x[1] != 1.)

        basis = InteriorBasis(m, e)
        self.assertEqual(
            basis.get_dofs(m.boundaries['centreline']).all().size,
            (2 + 1) * (2**(1 + 3) + 1) + 2 * 2**(1 + 3))
        self.assertEqual(basis.find_dofs()['centreline'].all().size,
                         (2 + 1) * (2**(1 + 3) + 1) + 2 * 2**(1 + 3))

        @BilinearForm
        def bilinf(u, p, v, q, w):
            from skfem.helpers import grad, ddot, div
            return (ddot(grad(u), grad(v)) - div(u) * q - div(v) * p -
                    1e-2 * p * q)

        S = asm(bilinf, basis)

        D = basis.find_dofs(skip=['u^2'])
        x = basis.zeros()
        x[D['up'].all('u^1^1')] = .1

        x = solve(*condense(S, basis.zeros(), x=x, D=D))

        (u, u_basis), (p, p_basis) = basis.split(x)

        self.assertEqual(len(u), m.p.shape[1] * 2 + m.facets.shape[1] * 2)
        self.assertEqual(len(p), m.p.shape[1])

        self.assertTrue(np.sum(p - x[basis.nodal_dofs[2]]) < 1e-8)

        U, P = basis.interpolate(x)
        self.assertTrue(isinstance(U.value, np.ndarray))
        self.assertTrue(isinstance(P.value, np.ndarray))

        self.assertTrue((basis.doflocs[:, D['up'].all()][1] == 1.).all())
Esempio n. 4
0
class ConvergenceRaviartThomas(unittest.TestCase):
    rateL2 = 1.0
    rateHdiv = 1.0
    eps = 0.1
    Hdivbound = 0.04
    L2bound = 0.01

    def runTest(self):
        @BilinearForm
        def bilinf_A(sigma, tau, w):
            from skfem.models.helpers import dot
            return dot(sigma, tau)

        @BilinearForm
        def bilinf_B(sigma, v, w):
            return sigma.df * v

        @LinearForm
        def load(v, w):
            x = w.x
            if x.shape[0] == 1:
                return (np.sin(np.pi * x[0]) * (np.pi**2) * v)
            elif x.shape[0] == 2:
                return (np.sin(np.pi * x[0]) * np.sin(np.pi * x[1]) *
                        (2.0 * np.pi**2) * v)
            elif x.shape[0] == 3:
                return (np.sin(np.pi * x[0]) * np.sin(np.pi * x[1]) *
                        np.sin(np.pi * x[2]) * (3.0 * np.pi**2) * v)
            else:
                raise Exception("The dimension not supported")

        m = self.mesh
        Nitrs = 3
        L2s = np.zeros(Nitrs)
        Hdivs = np.zeros(Nitrs)
        hs = np.zeros(Nitrs)

        for itr in range(Nitrs):
            ib1, ib2 = self.create_basis(m)

            A = asm(bilinf_A, ib1)
            B = asm(bilinf_B, ib1, ib2)
            b = np.concatenate((np.zeros(A.shape[0]), -asm(load, ib2)))

            from scipy.sparse import bmat
            K = bmat([[A, B.T], [B, None]]).tocsr()

            x = solve(K, b)

            # calculate error
            sigma, u = np.split(x, [A.shape[0]])

            L2s[itr] = self.compute_L2(m, ib2, u)
            Hdivs[itr] = self.compute_Hdiv(m, ib1, sigma)
            hs[itr] = m.param()

            m.refine()

        rateL2 = np.polyfit(np.log(hs), np.log(L2s), 1)[0]
        rateHdiv = np.polyfit(np.log(hs), np.log(Hdivs), 1)[0]

        self.assertLess(np.abs(rateL2 - self.rateL2),
                        self.eps,
                        msg='observed L2 rate: {}'.format(rateL2))
        self.assertLess(np.abs(rateHdiv - self.rateHdiv),
                        self.eps,
                        msg='observed Hdiv rate: {}'.format(rateHdiv))
        self.assertLess(Hdivs[-1], self.Hdivbound)
        self.assertLess(L2s[-1], self.L2bound)

    def compute_L2(self, m, basis, U):
        uh, *_ = basis.interpolate(U)
        dx = basis.dx
        x = basis.global_coordinates()

        def u(y):
            if y.shape[0] == 1:
                return np.sin(np.pi * y[0])
            elif y.shape[0] == 2:
                return (np.sin(np.pi * y[0]) * np.sin(np.pi * y[1]))
            return (np.sin(np.pi * y[0]) * np.sin(np.pi * y[1]) *
                    np.sin(np.pi * y[2]))

        return np.sqrt(np.sum(np.sum((uh - u(x.f))**2 * dx, axis=1)))

    def compute_Hdiv(self, m, basis, U):
        uh, duh, *_ = basis.interpolate(U)
        dx = basis.dx
        x = basis.global_coordinates()

        def divu(y):
            if y.shape[0] == 1:
                return np.pi * np.cos(np.pi * y[0])
            elif y.shape[0] == 2:
                return (np.pi * np.cos(np.pi * y[0]) * np.sin(np.pi * y[1]) +
                        np.pi * np.sin(np.pi * y[0]) * np.cos(np.pi * y[1]))
            return np.pi * (np.cos(np.pi * y[0]) * np.sin(np.pi * y[1]) *
                            np.sin(np.pi * y[2]) + np.sin(np.pi * y[0]) *
                            np.cos(np.pi * y[1]) * np.sin(np.pi * y[2]) +
                            np.sin(np.pi * y[0]) * np.sin(np.pi * y[1]) *
                            np.cos(np.pi * y[2]))

        divuh = sum(uh)

        return np.sqrt(np.sum(np.sum(((divuh - divu(x.f))**2) * dx, axis=1)))

    def create_basis(self, m):
        e = ElementTriRT0()
        e0 = ElementTriP0()
        return (InteriorBasis(m, e,
                              intorder=2), InteriorBasis(m, e0, intorder=2))

    def setUp(self):
        self.mesh = MeshTri()
        self.mesh.refine(4)