Exemplo n.º 1
0
def invariants(F):
    C = F.T * F

    # Invariants
    I_1 = tr(C) + (3 - dim)
    I_2 = 0.5 * ((tr(C) + (3 - dim))**2 - (tr(C * C) + (3 - dim)))
    J = det(F)  # this is a third invariant 'I_3'

    return I_1, I_2, J
Exemplo n.º 2
0
def psi_aux_Borden(F, mu, kappa):
    J = fe.det(F)
    C = F.T * F
    Jinv = J**(-2 / 3)
    U = 0.5 * kappa * (0.5 * (J**2 - 1) - fe.ln(J))
    Wbar = 0.5 * mu * (Jinv * (fe.tr(C) + 1) - 3)
    return U, Wbar
Exemplo n.º 3
0
def Piola1(d_, w_, lambda_, mu_s, E_func=None):
    I = Identity(2)
    if callable(E_func):
        E = E_func(d_, w_)
    else:
        F = I + grad(d_["n"])
        E = 0.5 * ((F.T * F) - I)

    return F * (lambda_ * tr(E) * I + 2 * mu_s * E)
Exemplo n.º 4
0
def Kinematics(u):
    # Kinematics
    d = u.geometric_dimension()
    I = fe.Identity(d)                    # Identity tensor
    F = I + fe.grad(u)                    # Deformation gradient
    F = fe.variable(F)                    # To differentiate Psi(F)
    J = fe.det(F)                         # Jacobian of F
    C = F.T*F                             # Right Cauchy-Green deformation tensor
    Ic = fe.tr(C)                         # Trace of C
    
    return [F, J, C, Ic]
    def _solve(self, z, x=None):
        # problem variables
        du = TrialFunction(self.V)                          # incremental displacement
        v = TestFunction(self.V)                            # test function
        u = Function(self.V)                                # displacement from previous iteration

        # kinematics
        ii = Identity(3)                                    # identity tensor dimension 3
        f = ii + grad(u)                                    # deformation gradient
        c = f.T * f                                         # right Cauchy-Green tensor

        # invariants of deformation tensors
        ic = tr(c)
        j = det(f)

        # elasticity parameters
        if type(z) in [list, np.ndarray]:
            param = self.param_remapper(z[0]) if self.param_remapper is not None else z[0]
        else:
            param = self.param_remapper(z) if self.param_remapper is not None else z

        e_var = variable(Constant(param))                   # Young's modulus
        nu = Constant(.3)                                   # Shear modulus (Lamè's second parameter)
        mu, lmbda = e_var / (2 * (1 + nu)), e_var * nu / ((1 + nu) * (1 - 2 * nu))

        # strain energy density, total potential energy
        psi = (mu / 2) * (ic - 3) - mu * ln(j) + (lmbda / 2) * (ln(j)) ** 2
        pi = psi * dx - self.time * dot(self.f, u) * self.ds(3)

        ff = derivative(pi, u, v)                           # compute first variation of pi
        jj = derivative(ff, u, du)                          # compute jacobian of f

        # solving
        if x is not None:
            numeric_evals = np.zeros(shape=(x.shape[1], len(self.times)))
            evals = np.zeros(shape=(x.shape[1], len(self.eval_times)))
        else:
            numeric_evals = None
            evals = None
        for it, t in enumerate(self.times):
            self.time.t = t
            self.solver(ff == 0, u, self.bcs, J=jj, bcs=self.bcs, solver_parameters=self.solver_parameters)
            if x is not None:
                numeric_evals[:, it] = np.log(np.array([-u(x_)[2] for x_ in x.T]).T)

        # time-interpolation
        if x is not None:
            for i in range(evals.shape[0]):
                evals[i, :] = np.interp(self.eval_times, self.times, numeric_evals[i, :])
        return (evals, u) if x is not None else u
Exemplo n.º 6
0
    def _energy_density(self, u):
        young_mod = 100
        poisson_ratio = 0.3
        shear_mod = young_mod / (2 * (1 + poisson_ratio))
        bulk_mod = young_mod / (3 * (1 - 2 * poisson_ratio))
        d = u.geometric_dimension()
        F = self.DeformationGradient(u)
        F = fa.variable(F)
        J = fa.det(F)
        I1 = fa.tr(self.RightCauchyGreen(F))

        # Plane strain assumption
        Jinv = J**(-2 / 3)
        energy = ((shear_mod / 2) * (Jinv * (I1 + 1) - 3) +
                  (bulk_mod / 2) * (J - 1)**2)
        return energy
Exemplo n.º 7
0
def psi_minus_linear_elasticity_model_C(epsilon, lamda, mu):
    sqrt_delta = fe.conditional(
        fe.gt(fe.tr(epsilon)**2 - 4 * fe.det(epsilon), 0),
        fe.sqrt(fe.tr(epsilon)**2 - 4 * fe.det(epsilon)), 0)
    eigen_value_1 = (fe.tr(epsilon) + sqrt_delta) / 2
    eigen_value_2 = (fe.tr(epsilon) - sqrt_delta) / 2
    tr_epsilon_minus = fe.conditional(fe.lt(fe.tr(epsilon), 0.),
                                      fe.tr(epsilon), 0.)
    eigen_value_1_minus = fe.conditional(fe.lt(eigen_value_1, 0.),
                                         eigen_value_1, 0.)
    eigen_value_2_minus = fe.conditional(fe.lt(eigen_value_2, 0.),
                                         eigen_value_2, 0.)
    return lamda / 2 * tr_epsilon_minus**2 + mu * (eigen_value_1_minus**2 +
                                                   eigen_value_2_minus**2)
Exemplo n.º 8
0
 def get_new_value(self, r: fenics.Function) -> fenics.Expression:
     return 2.0*self.lame_mu*fenics.sym(fenics.grad(r)) \
            + self.lame_lambda*fenics.tr(fenics.sym(fenics.grad(r)))*fenics.Identity(len(r))
Exemplo n.º 9
0
def psi_Miehe(F, mu, beta):
    J = fe.det(F)
    C = F.T * F
    W = mu / 2 * (fe.tr(C) + 1 - 3) + mu / beta * (J**(-beta) - 1)
    return W
Exemplo n.º 10
0
def strainDensityFunction(E, Ey, nu):
    mu = Ey / (2. * (1 + nu))
    lambda_ = Ey * nu / ((1 + nu) * (1 - 2 * nu))
    return lambda_ / 2. * (fe.tr(E))**2. + mu * fe.tr(E * E)
v = fs.TestFunction(V)
f = fs.Constant((0, 0, -rho * g))
T = fs.Constant((0, 0, 0))
a = fs.inner(sigma(u), epsilon(v)) * fs.dx
L = fs.dot(f, v) * fs.dx + fs.dot(T, v) * fs.ds

# Compute solution
u = fs.Function(V)
fs.solve(a == L, u, bc)

# Plot solution
plt.figure()
fs.plot(u, title='Displacement', mode='displacement')

# Plot stress
s = sigma(u) - (1. / 3) * fs.tr(sigma(u)) * fs.Identity(d)  # deviatoric stress
von_Mises = fs.sqrt(3. / 2 * fs.inner(s, s))
V = fs.FunctionSpace(mesh, 'P', 1)
von_Mises = fs.project(von_Mises, V)
plt.figure()
fs.plot(von_Mises, title='Stress intensity')

# Compute magnitude of displacement
u_magnitude = fs.sqrt(fs.dot(u, u))
u_magnitude = fs.project(u_magnitude, V)
plt.figure()
fs.plot(u_magnitude, title='Displacement magnitude')
print('min/max u:', u_magnitude.vector().min(), u_magnitude.vector().max())

# Save solution to file in VTK format
fs.File('results/displacement.pvd') << u
Exemplo n.º 12
0
 def tr(self, A):
     return FEN.tr(A)
Exemplo n.º 13
0
def psi_minus_linear_elasticity_model_B(epsilon, lamda, mu):
    dim = 2
    bulk_mod = lamda + 2. * mu / dim
    tr_epsilon_minus = ufl.Min(fe.tr(epsilon), 0)
    return bulk_mod / 2. * tr_epsilon_minus**2
Exemplo n.º 14
0
def psi_plus_linear_elasticity_model_B(epsilon, lamda, mu):
    dim = 2
    bulk_mod = lamda + 2. * mu / dim
    tr_epsilon_plus = ufl.Max(fe.tr(epsilon), 0)
    return bulk_mod / 2. * tr_epsilon_plus**2 + mu * fe.inner(
        fe.dev(epsilon), fe.dev(epsilon))
    def compute_static_deformation(self):

        assert self.mesh is not None

        # now we define subdomains on the mesh

        bottom = fe.CompiledSubDomain('near(x[2], 0) && on_boundary')
        top = fe.CompiledSubDomain('near(x[2], 1) && on_boundary')
        # middle = fe.CompiledSubDomain('x[2] > 0.3 && x[2] < 0.7')

        # Initialize mesh function for interior domains
        self.domains = fe.MeshFunction('size_t', self.mesh, 3)
        self.domains.set_all(0)
        # middle.mark(self.domains, 1)

        # Initialize mesh function for boundary domains
        self.boundaries = fe.MeshFunction('size_t', self.mesh, 2)
        self.boundaries.set_all(0)
        bottom.mark(self.boundaries, 1)
        top.mark(self.boundaries, 2)

        # Define new measures associated with the interior domains and
        # exterior boundaries

        self.dx = fe.Measure('dx',
                             domain=self.mesh,
                             subdomain_data=self.domains)
        self.ds = fe.Measure('ds',
                             domain=self.mesh,
                             subdomain_data=self.boundaries)

        # define function spaces
        V = fe.VectorFunctionSpace(self.mesh, "Lagrange", 1)
        # now we define subdomains on the mesh

        bottom = fe.CompiledSubDomain('near(x[2], 0) && on_boundary')
        top = fe.CompiledSubDomain('near(x[2], 1) && on_boundary')
        # middle = fe.CompiledSubDomain('x[2] > 0.3 && x[2] < 0.7')

        d = self.mesh.geometry().dim()

        # Initialize mesh function for interior domains
        self.domains = fe.MeshFunction('size_t', self.mesh, d)
        self.domains.set_all(0)
        # middle.mark(self.domains, 1)

        # Initialize mesh function for boundary domains
        self.boundaries = fe.MeshFunction('size_t', self.mesh, d - 1)
        self.boundaries.set_all(0)
        bottom.mark(self.boundaries, 1)
        top.mark(self.boundaries, 2)

        # Define new measures associated with the interior domains and
        # exterior boundaries

        self.dx = fe.Measure('dx',
                             domain=self.mesh,
                             subdomain_data=self.domains)
        self.ds = fe.Measure('ds',
                             domain=self.mesh,
                             subdomain_data=self.boundaries)

        c_zero = fe.Constant((0, 0, 0))

        # define boundary conditions
        bc_bottom = fe.DirichletBC(V, c_zero, bottom)
        bc_top = fe.DirichletBC(V, c_zero, top)

        bcs = [bc_bottom]  # , bc_top]

        # define functions
        du = TrialFunction(V)
        v = TestFunction(V)
        u = Function(V)
        B = fe.Constant((0., 2.0, 0.))
        T = fe.Constant((0.0, 0.0, 0.0))

        d = u.geometric_dimension()
        I = fe.Identity(d)
        F = I + grad(u)
        C = F.T * F

        I_1 = tr(C)
        J = det(F)

        E, mu = 10., 0.3
        mu, lmbda = fe.Constant(E / (2 * (1 + mu))), fe.Constant(
            E * mu / ((1 + mu) * (1 - 2 * mu)))

        # stored energy (comp. neo-hookean model)
        psi = (mu / 2.) * (I_1 - 3) - mu * fe.ln(J) + (lmbda /
                                                       2.) * (fe.ln(J))**2

        dx = self.dx
        ds = self.ds

        Pi = psi * fe.dx - dot(B, u) * fe.dx - dot(T, u) * fe.ds

        F = fe.derivative(Pi, u, v)
        J = fe.derivative(F, u, du)

        fe.solve(F == 0, u, bcs, J=J)

        # save results
        self.u = u

        # write to disk
        output = fe.File("/tmp/static.pvd")
        output << u
Exemplo n.º 16
0
def sigma(u):
    return (lmbda * fn.tr(eps(u)) * fn.Identity(2) + 2 * mu * eps(u))
Exemplo n.º 17
0
def half_exp_dyn(w0, dt=1.e-5, t_end=1.e-4, show_plots=False):

    u0 = w0.u
    p0 = w0.p
    v0 = w0.v

    bcs_u, bcs_p, bcs_v = load_2d_muscle_bc(V_u, V_pv.sub(0), V_pv.sub(1),
                                            boundaries)

    F = deformation_grad(u0)
    I_1, I_2, J = invariants(F)
    F_iso = isochronic_deformation_grad(F, J)
    #I_1_iso, I_2_iso  = invariants(F_iso)[0:2]
    W = material_mooney_rivlin(I_1, I_2, c_10, c_01)
    g = incompr_constr(J)
    # Lagrange function (without constraint)
    L = -W
    P = first_piola_stress(L, F)
    G = incompr_stress(g, F)

    # a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v1, eta) * dx

    u1 = fe.TrialFunction(V_u)
    eta = fe.TestFunction(V_u)

    #u11 = fe.Function(V_u)
    #F1 = deformation_grad(u11)
    #g1 = incompr_constr(fe.det(F1))
    #G1 = incompr_stress(g1, F1)

    (p1, v1) = fe.TrialFunctions(V_pv)
    (q, xi) = fe.TestFunctions(V_pv)

    a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v0, eta) * dx

    a_dyn_p = fe.tr(G * grad(v1)) * q * dx
    #a_dyn_v = rho*inner(v1-v0, xi)*dx + dt*(inner(P + p0*G, grad(xi))*dx - inner(B, xi)*dx)
    a_dyn_v = rho * inner(v1 - v0, xi) * dx + dt * (inner(
        P, grad(xi)) * dx + inner(p1 * G, grad(xi)) * dx - inner(B, xi) * dx)

    a_u = fe.lhs(a_dyn_u)
    l_u = fe.rhs(a_dyn_u)

    a_pv = fe.lhs(a_dyn_p + a_dyn_v)
    l_pv = fe.rhs(a_dyn_p + a_dyn_v)

    u1 = fe.Function(V_u)
    pv1 = fe.Function(V_pv)

    sol = []

    vol = fe.assemble(1. * dx)

    A_u = fe.assemble(a_u)
    A_pv = fe.assemble(a_pv)

    for bc in bcs_u:
        bc.apply(A_u)

    t = 0
    while t < t_end:
        print("progress: %f" % (100. * t / t_end))

        # update displacement u
        L_u = fe.assemble(l_u)
        fe.solve(A_u, u1.vector(), L_u)
        u0.assign(u1)

        L_pv = fe.assemble(l_pv)
        for bc in bcs_p + bcs_v:
            bc.apply(A_pv, L_pv)

        fe.solve(A_pv, pv1.vector(), L_pv)

        if fe.norm(pv1.vector()) > 1e8:
            print('ERROR: norm explosion')
            break

        # update initial values for next step
        w0.u = u1
        w0.pv = pv1
        p0.assign(w0.p)
        v0.assign(w0.v)

        t += dt

        if show_plots:
            # plot result
            fe.plot(w0.sub(0), mode='displacement')
            plt.show()

        # save solutions
        sol.append(Solution(t=t))
        sol[-1].upv.assign(w0)

    return sol, W
Exemplo n.º 18
0
 def I1(C):
     return fe.tr(C)
Exemplo n.º 19
0
    def stress(self, u):
        E = kin.green_lagrange_strain(u)
        I = kin.identity(u)

        return self._parameters['lambda'] * fe.tr(
            E) * I + 2 * self._parameters['mu'] * E
Exemplo n.º 20
0
uViewer << u

# Maximum and minimum displacement
u_magnitude = fe.sqrt(fe.dot(u, u))
u_magnitude = fe.project(u_magnitude, W)
print('Min/Max displacement:',
      u_magnitude.vector().array().min(),
      u_magnitude.vector().array().max())

# Computation of the large deformation strains
#cprint("Computing the deformation tensor and saving to file...", 'green')
epsilon_u = largeKinematics(u)
epsilon_u_project = fe.project(epsilon_u, Z)
epsilonViewer = fe.File('paraview/strain.pvd')
epsilonViewer << epsilon_u_project

# Computation of the stresses
#cprint("Stress derivation and saving to file...", 'green')
S = fe.diff(psi, E)
S_project = fe.project(S, Z)
sigmaViewer = fe.File('paraview/stress.pvd')
sigmaViewer << S_project

# Computation of an equivalent stress
s = S - (1. / 3) * fe.tr(S) * fe.Identity(u.geometric_dimension())
von_Mises = fe.sqrt(3. / 2 * fe.inner(s, s))
von_Mises_project = fe.project(von_Mises, W)
misesViewer = fe.File('paraview/mises.pvd')
misesViewer << von_Mises_project
print("Maximum equivalent stress:", von_Mises_project.vector().array().max())
Exemplo n.º 21
0
def sigma(r):
    return 2.0 * mu * fnc.sym(fnc.grad(r)) + lmbda * fnc.tr(
        fnc.sym(fnc.grad(r))) * fnc.Identity(len(r))
Exemplo n.º 22
0
dw = fe.TrialFunction(V)

# Kinematics
d = u.geometric_dimension()
I = fe.Identity(d)  # Identity tensor

F = fe.variable(I + grad(u))  # Deformation gradient
C = fe.variable(F.T * F)  # Right Cauchy-Green tensor
J = fe.det(C)

DE = lambda v: 0.5 * (F.T * grad(v) + grad(v).T * F)

a_0 = fe.as_vector([[1.0], [0.], [0.]])

# Invariants
I_1 = tr(C)
I_2 = 0.5 * (tr(C)**2 - tr(C * C))

I_4 = dot(a_0.T, C * a_0)

# Continuation parameter
lmbda = 0.01

# parameters taken from O. Roehrle and Heidlauf

# Mooney-Rivlin parameters (in kPa)

b_1 = 2.756e-5
d_1 = 43.373

p_max = 73.0
Exemplo n.º 23
0
def psi_linear_elasticity(epsilon, lamda, mu):
    return lamda / 2 * fe.tr(epsilon)**2 + mu * fe.inner(epsilon, epsilon)