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
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 A12(w): u = w["disp"] F = zeros_like(grad(u)) for i in range(3): F[i, i] += 1. F += grad(u) J = det(F) Finv = inv(F) return J * transpose(Finv)
def F1(w): u = w["disp"] p = w["press"] F = zeros_like(grad(u)) for i in range(3): F[i, i] += 1. F += grad(u) J = det(F) Finv = inv(F) return p * J * transpose(Finv) + mu * F
def a(u, v, w): F, iF = deformation_gradient(w) DF = grad(u) dF = grad(v) dFiF = mul(dF, iF) DFiF = mul(DF, iF) tr_DFiF_dFiF = ddot(transpose(dFiF), DFiF) lnJ = np.log(det(F)) return (mu * ddot(DF, dF) - (lmbda * lnJ - mu) * tr_DFiF_dFiF + lmbda * trace(dFiF) * trace(DFiF))
def F2(w): u = w["disp"] p = w["press"].value F = zeros_like(grad(u)) for i in range(3): F[i, i] += 1. F += grad(u) J = det(F) Js = .5 * (lmbda + p + 2. * sqrt(lmbda * mu + .25 * (lmbda + p) ** 2)) / lmbda dJsdp = ((.25 * lmbda + .25 * p + .5 * sqrt(lmbda * mu + .25 * (lmbda + p) ** 2)) / (lmbda * sqrt(lmbda * mu + .25 * (lmbda + p) ** 2))) return J - (Js + (p + mu / Js - lmbda * (Js - 1)) * dJsdp)
def A11(w): u = w["disp"] p = w["press"] F = zeros_like(grad(u)) eye = zeros_like(grad(u)) for i in range(3): F[i, i] += 1. eye[i, i] += 1. F += grad(u) J = det(F) Finv= inv(F) L = (p * J * einsum("lk...,ji...->ijkl...", Finv, Finv) - p * J * einsum("jk...,li...->ijkl...", Finv, Finv) + mu * einsum("ik...,jl...->ijkl...", eye, eye)) return L
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 F1(w): u = w["disp"] p = w["press"] F = grad(u) + identity(u) J = det(F) Finv = inv(F) return p * J * transpose(Finv) + mu * F
def F2(w): u = w["disp"] p = w["press"].value F = grad(u) + identity(u) J = det(F) Js = .5 * (lmbda + p + 2. * np.sqrt(lmbda * mu + .25 * (lmbda + p) ** 2)) / lmbda dJsdp = ((.25 * lmbda + .25 * p + .5 * np.sqrt(lmbda * mu + .25 * (lmbda + p) ** 2)) / (lmbda * np.sqrt(lmbda * mu + .25 * (lmbda + p) ** 2))) return J - (Js + (p + mu / Js - lmbda * (Js - 1)) * dJsdp)
def A11(w): u = w["disp"] p = w["press"] eye = identity(u) F = grad(u) + eye J = det(F) Finv = inv(F) L = (p * J * np.einsum("lk...,ji...->ijkl...", Finv, Finv) - p * J * np.einsum("jk...,li...->ijkl...", Finv, Finv) + mu * np.einsum("ik...,jl...->ijkl...", eye, eye)) return L
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(v, w): """Compute the vector (v, u . grad u) for given velocity u passed in via `wind` after having been interpolated onto its quadrature points. In Cartesian tensorial indicial notation, the integrand is .. math:: u_j u_{i,j} v_i. """ return np.einsum('j...,ij...,i...', w['wind'], grad(w['wind']), v)
def laplace(u, v, _): return dot(grad(u), grad(v))
def conduction(u, v, w): return dot(w['conductivity'] * grad(u), grad(v))
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 b11(u, v, w): return einsum("ijkl...,ij...,kl...", A11(w), grad(u), grad(v))
def b12(u, v, w): return einsum("ij...,ij...", A12(w), grad(v)) * u
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)
def a1(v, w): return einsum("ij...,ij...", F1(w), grad(v))
def wv_load(u, v, w): ''' for $(\nabla \chi_{h}, \nabla_{h} v_{h})$ ''' return dot(grad(u), grad(v))
def b_load(u, v, w): ''' for $b_{h}$ ''' return dot(grad(u), grad(v))
def feqx(w): from skfem.helpers import grad f = w['func'] # f(x, y) = x g = w['gunc'] # g(x, y) = y return grad(f)[0] + grad(g)[1]
def feqx(w): from skfem.helpers import grad f = w['func'] # f(x) = x return grad(f)[0] # f'(x) = 1
def penalty_2(u, v, w): return ddot(-dd(v), prod(w.n, w.n)) * dot(grad(u), 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 penalty_3(u, v, w): return (sigma / w.h) * dot(grad(u), w.n) * dot(grad(v), w.n)
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 advection(u, v, w): velocity_x = 1 - (w.x[1] / halfheight)**2 # plane Poiseuille return v * velocity_x * grad(u)[0]