예제 #1
0
def get_poisson_steps_scikitfem(points, cells, tol):
    from skfem import (
        MeshTri,
        MeshTet,
        InteriorBasis,
        ElementTriP1,
        ElementTetP1,
        asm,
        condense,
    )
    from skfem.models.poisson import laplace, unit_load
    import krypy

    if cells.shape[1] == 3:
        mesh = MeshTri(points.T, cells.T)
        e = ElementTriP1()
    else:
        assert cells.shape[1] == 4
        mesh = MeshTet(points.T, cells.T)
        e = ElementTetP1()

    basis = InteriorBasis(mesh, e)

    # assemble
    A = asm(laplace, basis)
    b = asm(unit_load, basis)

    A, b = condense(A, b, I=mesh.interior_nodes(), expand=False)
    _, info = krypy.cg(A, b, tol=tol)

    return info.iter
예제 #2
0
def laplace(m, **params):
    """Solve the Laplace equation using the FEM.

    Parameters
    ----------
    m
        A Mesh object.

    """
    e = ElementTriP1()
    basis = InteriorBasis(m, e)
    A = laplacian.assemble(basis)
    b = unit_load.assemble(basis)
    u = solve(*condense(A, b, I=m.interior_nodes()))

    # evaluate the error estimators
    fbasis = [FacetBasis(m, e, side=i) for i in [0, 1]]
    w = {"u" + str(i + 1): fbasis[i].interpolate(u) for i in [0, 1]}

    @Functional
    def interior_residual(w):
        h = w.h
        return h**2

    eta_K = interior_residual.elemental(basis)

    @Functional
    def edge_jump(w):
        h = w.h
        n = w.n
        dw1 = grad(w["u1"])
        dw2 = grad(w["u2"])
        return h * ((dw1[0] - dw2[0]) * n[0] + (dw1[1] - dw2[1]) * n[1])**2

    eta_E = edge_jump.elemental(fbasis[0], **w)

    tmp = np.zeros(m.facets.shape[1])
    np.add.at(tmp, fbasis[0].find, eta_E)
    eta_E = np.sum(0.5 * tmp[m.t2f], axis=0)

    return eta_E + eta_K
예제 #3
0
 def create_basis(self, m):
     e = ElementTetRT0()
     e0 = ElementTetP0()
     return (InteriorBasis(m, e,
                           intorder=2), InteriorBasis(m, e0, intorder=2))
예제 #4
0
 def create_basis(self, m, p):
     e = ElementQuadP(p)
     return InteriorBasis(m, e, intorder=p * p)
예제 #5
0
 def create_basis(self, m, p):
     e = ElementLinePp(p)
     return InteriorBasis(m, e)
예제 #6
0
R = CoordSys3D("R")


def apply(f, coords):
    x, y = symbols("x y")
    return lambdify((x, y), f.subs({R.x: x, R.y: y}))(*coords)


u_exact = 1 + R.x + 2 * R.y  # exact solution
f = -divergence(q(u_exact) * gradient(u_exact))  # manufactured RHS

mesh = MeshTri()
mesh.refine(3)

V = InteriorBasis(mesh, ElementTriP1())

boundary = V.get_dofs().all()
interior = V.complement_dofs(boundary)


@LinearForm
def load(v, w):
    return v * apply(f, w.x)


b = asm(load, V)


@BilinearForm
def diffusion_form(u, v, w):
예제 #7
0
 def create_basis(self, m):
     e = ElementTriBDM1()
     e0 = ElementTriP0()
     return (InteriorBasis(m, e,
                           intorder=4), InteriorBasis(m, e0, intorder=4))
from skfem.models.elasticity import linear_elasticity

L = 1.0
W = 0.2
mu = 1.0
rho = 1.0
delta = W / L
gamma = 0.4 * delta**2
beta = 1.25
lambda_ = beta
g = gamma

mesh = MeshTet.init_tensor(np.linspace(0, L, 10 + 1), np.linspace(0, W, 3 + 1),
                           np.linspace(0, W, 3 + 1))

basis = InteriorBasis(mesh, ElementVectorH1(ElementTetP1()))

clamped = basis.get_dofs(lambda x: x[0] == 0.0).all()
free = basis.complement_dofs(clamped)

K = asm(linear_elasticity(lambda_, mu), basis)


@LinearForm
def load(v, w):
    return -rho * g * v.value[2]


f = asm(load, basis)

u = solve(*condense(K, f, I=free))