Пример #1
0
    def runTest(self):
        m = self.case[0].refined()

        if self.intorder is not None:
            basis = FacetBasis(m, self.case[1], intorder=self.intorder)
        else:
            basis = FacetBasis(m, self.case[1])

        @LinearForm
        def linf(v, w):
            return np.sum(w.n**2, axis=0) * v

        b = asm(linf, basis)
        ones = projection(lambda x: 1.0 + x[0] * 0.,
                          basis,
                          I=basis.get_dofs().flatten(),
                          expand=True)

        self.assertAlmostEqual(b @ ones, 2 * m.p.shape[0], places=10)

        if self.test_integrate_volume:
            # by Gauss theorem this integrates to one
            for itr in range(m.p.shape[0]):

                @LinearForm
                def linf(v, w):
                    return w.n[itr] * v

                b = asm(linf, basis)
                self.assertAlmostEqual(b @ m.p[itr, :], 1.0, places=5)
Пример #2
0
def test_adaptive_splitting_3d_3():
    # adaptively refine one face of a cube, check that the mesh parameter h
    # is approximately linear w.r.t to distance from the face
    m = MeshTet.init_tensor(np.linspace(0, 1, 3), np.linspace(0, 1, 3),
                            np.linspace(0, 1, 3))

    for itr in range(15):
        m = m.refined(m.f2t[0, m.facets_satisfying(lambda x: x[0] == 0)])

    @LinearForm
    def hproj(v, w):
        return w.h * v

    basis = Basis(m, ElementTetP1())
    h = projection(hproj, basis)

    funh = basis.interpolator(h)

    xs = np.vstack((
        np.linspace(0, .5, 20),
        np.zeros(20) + .5,
        np.zeros(20) + .5,
    ))
    hs = funh(xs)

    assert np.max(np.abs(hs - xs[0])) < 0.063
Пример #3
0
def test_matrix_element_projection(m, e):

    E1 = ElementVector(e)
    E2 = ElementVector(ElementVector(e))
    basis0 = Basis(m, E1)
    basis1 = basis0.with_element(E2)
    C = linear_stress()

    x = basis0.interpolate(np.random.random(basis0.N))

    @LinearForm
    def proj(v, _):
        return ddot(C(sym_grad(x)), v)

    y = projection(proj, basis1, basis0)
Пример #4
0
    def runTest(self):

        mesh = MeshTri().refined(5)
        basis = CellBasis(mesh, ElementTriP1())

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

        x = projection(fun, basis)
        y = fun(mesh.p)

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

        self.assertTrue(normest < 0.011, msg="|x-y| = {}".format(normest))
Пример #5
0
    def _trace_project(self, x: ndarray, elem: Element) -> ndarray:
        from skfem.utils import projection

        fbasis = FacetBasis(self.mesh,
                            elem,
                            facets=self.find,
                            quadrature=(self.X, self.W))
        I = fbasis.get_dofs(self.find).all()
        if len(I) == 0:  # special case: no facet DOFs
            if fbasis.dofs.interior_dofs is not None:
                if fbasis.dofs.interior_dofs.shape[0] > 1:
                    # no one-to-one restriction: requires interpolation
                    raise NotImplementedError
                # special case: piecewise constant elem
                I = fbasis.dofs.interior_dofs[:, self.tind].flatten()
            else:
                raise ValueError
        return projection(x, fbasis, self, I=I)
Пример #6
0
# use dummy value for permittivity, uniform U in conductor
K_elec_inner_conductor = asm(laplace, inner_conductor_basis) * eps0
# use dummy value for permittivity, uniform U in conductor
K_elec_outer_conductor = asm(laplace, outer_conductor_basis) * eps0

# global stiffness matrix is the sum of the subdomain contributions
K_elec = (K_elec_inner_insulator + K_elec_outer_insulator +
          K_elec_inner_conductor + K_elec_outer_conductor)

# set a 1V potential difference between the conductors
voltage = 1

# initialize the non-homogeneous Dirichlet conditions on the conductor surfaces
U = np.zeros(K_elec.shape[0])
U[dofs['inner_conductor_outer_surface'].all()] = projection(
    lambda x: voltage / 2,
    inner_conductor_outer_surface_basis,
    I=dofs['inner_conductor_outer_surface'])
U[dofs['outer_conductor_inner_surface'].all()] = projection(
    lambda x: -voltage / 2,
    outer_conductor_inner_surface_basis,
    I=dofs['outer_conductor_inner_surface'])

U = solve(*condense(K_elec,
                    x=U,
                    D=dofs['inner_conductor_outer_surface']
                    | dofs['outer_conductor_inner_surface']))

# electric field energy
E_elec = 0.5 * np.dot(U, K_elec * U)
# energy stored in a capacitor: E = 0.5*C*U^2
# thus, C = 2*E/(U^2)
    def trace(
            self,
            x: ndarray,
            projection: Callable[[ndarray], ndarray],
            target_elem: Optional[Element] = None
    ) -> Tuple[CellBasis, ndarray]:
        """Restrict solution to :math:`d-1` dimensional trace mesh.

        The parameter ``projection`` defines how the boundary points are
        projected to :math:`d-1` dimensional space.  For example,

        >>> projection = lambda p: p[0]

        will keep only the `x`-coordinate in the trace mesh.

        Parameters
        ----------
        x
            The solution vector.
        projection
            A function defining the projection of the boundary points.  See
            above for an example.
        target_elem
            Optional finite element to project to before restriction.  If not
            given, a piecewise constant element is used.

        Returns
        -------
        CellBasis
            An object corresponding to the trace mesh.
        ndarray
            A projected solution vector defined on the trace mesh.

        """
        DEFAULT_TARGET = {
            MeshTri: ElementTriP0,
            MeshQuad: ElementQuad0,
            MeshTet: ElementTetP0,
            MeshHex: ElementHex0,
        }

        meshcls = type(self.mesh)
        if meshcls not in DEFAULT_TARGET:
            raise NotImplementedError("Mesh type not supported.")
        if target_elem is None:
            target_elem = DEFAULT_TARGET[meshcls]()

        if type(target_elem) not in BOUNDARY_ELEMENT_MAP:
            raise Exception("The specified element not supported.")
        elemcls = BOUNDARY_ELEMENT_MAP[type(target_elem)]
        target_meshcls = {
            MeshTri: MeshLine,
            MeshQuad: MeshLine,
            MeshTet: MeshTri,
            MeshHex: MeshQuad,
        }[meshcls]

        assert callable(target_meshcls)  # to satisfy mypy

        p, t = self.mesh._reix(self.mesh.facets[:, self.find])

        return (CellBasis(target_meshcls(projection(p), t),
                          elemcls()), self._trace_project(x, target_elem))