def bilin_mortar(u, v, w): # jumps ju, jv = jump(w, dot(u, w.n), dot(v, w.n)) mu = .5 * dot(w.n, mul(C(sym_grad(u)), w.n)) mv = .5 * dot(w.n, mul(C(sym_grad(v)), w.n)) return ((1. / (alpha * w.h) * ju * jv - mu * jv - mv * ju) * (np.abs(w.x[1]) <= limit))
def bilin_int(u, v, w): ju = (-1.0)**i * u jv = (-1.0)**j * v n = w.n h = w.h return (ju * jv) / alpha / h - (dot(grad(u), n) * jv + dot(grad(v), n) * ju) / 2
def bilin_mortar(u, v, w): ju = (-1.)**j * dot(u, w.n) jv = (-1.)**i * dot(v, w.n) nxn = prod(w.n, w.n) mu = .5 * ddot(nxn, C(sym_grad(u))) mv = .5 * ddot(nxn, C(sym_grad(v))) return ((1. / (alpha * w.h) * ju * jv - mu * jv - mv * ju) * (np.abs(w.x[1]) <= limit))
def test_oriented_interface_integral2(m, e, facets, normal): fb = FacetBasis(m, e, facets=m.facets_satisfying(facets, normal=normal)) assert_almost_equal( Functional(lambda w: dot(w.fun.grad, w.n)).assemble(fb, fun=m.p[0]), 1.0, )
def test_oriented_interface_integral(m, e, facets, fun): fb = FacetBasis(m, e, facets=facets) assert_almost_equal( Functional(lambda w: dot(w.fun.grad, w.n)).assemble(fb, fun=fun(m)), 1.0, )
def __init__(self, state_n, state_np1, solver_options, set_strain=None): """ Setup solver Parameters: state_n previous state state_np1 current state solver_options various 'how to solve' parameters Additional parameters: set_strain set the zz strain to this value, if given """ self.state_n = state_n self.state_np1 = state_np1 self.options = solver_options self.set_strain = set_strain self.ebcs = [] self.edofs = [] self.evalues = [] # Initialize the guess self.setup_guess() # The operators! if self.ndim == 1: # 1D axisymmetric is different than 2D/3D cartesian self.internal = LinearForm( lambda v, w: ( v.grad[0][0] * w["radial"] - v.value[0] * w["radial"] / w.x[0] + v.value[0] * w["hoop"] / w.x[0] ) ) self.jac = BilinearForm( lambda u, v, w: v.grad[0][0] * w["Crr"] * u.grad[0][0] + v.grad[0][0] * w["Crt"] * u.value[0] / w.x[0] - v.value[0] * (w["Crr"] * u.grad[0][0] + w["Crt"] * u.value[0] / w.x[0]) / w.x[0] + v.value[0] * (w["Ctr"] * u.grad[0][0] + w["Ctt"] * u.value[0] / w.x[0]) / w.x[0] ) else: self.internal = LinearForm( lambda v, w: helpers.ddot(helpers.sym_grad(v), w["stress"]) ) self.jac = BilinearForm( lambda u, v, w: helpers.ddot( helpers.sym_grad(v), helpers.ddot(w["C"], helpers.sym_grad(u)) ) ) self.external = LinearForm( lambda v, w: helpers.dot((-1.0) * w["pressure"] * w.n, v) )
def mass(u, v, w): from skfem.helpers import dot, ddot p = 0 if len(u.shape) == 2: p = u * v elif len(u.shape) == 3: p = dot(u, v) elif len(u.shape) == 4: p = ddot(u, v) return p
def test_trilinear_form(m, e): basis = Basis(m, e) out = (TrilinearForm( lambda u, v, w, p: dot(w * grad(u), grad(v))).assemble(basis)) kp = np.random.rand(100, basis.N) # transform to a dense 3-tensor (slow) A = out.toarray() # # initialize a sparse tensor instead # import sparse # arr = sparse.COO(*out.astuple(), has_duplicates=True) opt1 = np.einsum('ijk,li->ljk', A, kp) for i in range(kp.shape[0]): opt2 = (BilinearForm( lambda u, v, p: dot(p['kp'] * grad(u), grad(v))).assemble( basis, kp=kp[i])) assert abs((opt1[i] - opt2).min()) < 1e-10 assert abs((opt1[i] - opt2).max()) < 1e-10
def acceleration_jacobian(u, v, w): """Compute (v, w . grad u + u . grad w) for given velocity w passed in via w after having been interpolated onto its quadrature points. In Cartesian tensorial indicial notation, the integrand is .. math:: (w_j du_{i,j} + u_j dw_{i,j}) v_i """ return dot(np.einsum('j...,ij...->i...', w['wind'], grad(u)) + np.einsum('j...,ij...->i...', u, grad(w['wind'])), v)
def fv(v, w): from skfem.helpers import dot return dot(f(*w.x), v)
def bilinf_ev(u, v, w): from skfem.helpers import dot return dot(u, v)
def conduction(u, v, w): return dot(w['conductivity'] * grad(u), grad(v))
def dudv(E, v, w): from skfem.helpers import curl, dot return dot(curl(E), curl(v)) + dot(E, v)
def penalty_2(u, v, w): return ddot(-dd(v), prod(w.n, w.n)) * dot(grad(u), w.n)
def penalty_3(u, v, w): return (sigma / w.h) * dot(grad(u), w.n) * dot(grad(v), w.n)
def dgform(u, v, p): ju, jv = jump(p, u, v) h = p.h n = p.n return ju * jv / (alpha * h) - dot(grad(u), n) * jv - dot(grad(v), n) * ju
def facetbilinf(u, v, w): n = w.n x = w.x return -dot(grad(u), n) * v * (x[0] == 1.0)
def flux(u, v, w): return dot(w.n, u.grad) * v
def facetlinf(v, w): n = w.n x = w.x return -dot(grad(v), n) * (x[0] == 1.0)
def bilin_bnd(u, v, w): h = w.h n = w.n return (u * v) / alpha / h - dot(grad(u), n) * v - u * dot(grad(v), n)
def port_flux(w): from skfem.helpers import dot, grad return dot(w.n, grad(w['u']))
def _fit_dolfin(x0, y0, points, cells, lmbda: float, degree: int = 1, solver: str = "lsqr"): from dolfin import ( BoundingBoxTree, Cell, EigenMatrix, FacetNormal, Function, FunctionSpace, Mesh, MeshEditor, Point, TestFunction, TrialFunction, assemble, dot, ds, dx, grad, ) def _assemble_eigen(form): L = EigenMatrix() assemble(form, tensor=L) return L def _build_eval_matrix(V, points): """Build the sparse m-by-n matrix that maps a coefficient set for a function in V to the values of that function at m given points.""" # See <https://www.allanswered.com/post/lkbkm/#zxqgk> mesh = V.mesh() bbt = BoundingBoxTree() bbt.build(mesh) dofmap = V.dofmap() el = V.element() sdim = el.space_dimension() rows = [] cols = [] data = [] for i, x in enumerate(points): cell_id = bbt.compute_first_entity_collision(Point(*x)) cell = Cell(mesh, cell_id) coordinate_dofs = cell.get_vertex_coordinates() rows.append(np.full(sdim, i)) cols.append(dofmap.cell_dofs(cell_id)) v = el.evaluate_basis_all(x, coordinate_dofs, cell_id) data.append(v) rows = np.concatenate(rows) cols = np.concatenate(cols) data = np.concatenate(data) m = len(points) n = V.dim() matrix = sparse.csr_matrix((data, (rows, cols)), shape=(m, n)) return matrix editor = MeshEditor() mesh = Mesh() # Convert points, cells to dolfin mesh if cells.shape[1] == 2: editor.open(mesh, "interval", 1, 1, 1) else: # can only handle triangles for now assert cells.shape[1] == 3 # topological and geometrical dimension 2 editor.open(mesh, "triangle", 2, 2, 1) editor.init_vertices(len(points)) editor.init_cells(len(cells)) for k, point in enumerate(points): editor.add_vertex(k, point) for k, cell in enumerate(cells.astype(np.uintp)): editor.add_cell(k, cell) editor.close() V = FunctionSpace(mesh, "CG", degree) u = TrialFunction(V) v = TestFunction(V) mesh = V.mesh() n = FacetNormal(mesh) # omega = assemble(1 * dx(mesh)) A = _assemble_eigen(dot(grad(u), grad(v)) * dx - dot(n, grad(u)) * v * ds).sparray() A *= lmbda E = _build_eval_matrix(V, x0) # mass matrix M = _assemble_eigen(u * v * dx).sparray() x = _solve(A, M, E, y0, solver) u = Function(V) u.vector().set_local(x) return u
def rhs(v, p): w = p['prev'] return dot(grad(w), grad(v)) / np.sqrt(1 + dot(grad(w), grad(w)))
def jacobian(u, v, p): w = p['prev'] return (1 / np.sqrt(1 + dot(grad(w), grad(w))) * dot(grad(u), grad(v)) - 2 * dot(grad(u), grad(w)) * dot(grad(w), grad(v)) / 2 / (1 + dot(grad(w), grad(w)))**(3 / 2))
def laplace(u, v, _): return dot(grad(u), grad(v))
def b_load(u, v, w): ''' for $b_{h}$ ''' return dot(grad(u), grad(v))
def nitscheform(u, v, p): h = p.h n = p.n return u * v / (alpha * h) - dot(grad(u), n) * v - dot(grad(v), n) * u
def wv_load(u, v, w): ''' for $(\nabla \chi_{h}, \nabla_{h} v_{h})$ ''' return dot(grad(u), grad(v))
def gradu(w): gradu = w['sol'].grad return dot(gradu, gradu)
def mass(u, v, w): from skfem.helpers import dot return dot(rho * u, v)