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
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
def create_basis(self, m): e = ElementTetRT0() e0 = ElementTetP0() return (InteriorBasis(m, e, intorder=2), InteriorBasis(m, e0, intorder=2))
def create_basis(self, m, p): e = ElementQuadP(p) return InteriorBasis(m, e, intorder=p * p)
def create_basis(self, m, p): e = ElementLinePp(p) return InteriorBasis(m, e)
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):
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))