Example #1
0
    def update_map(self):
        d_clipped = fe.conditional(fe.gt(self.d_new, 0.5), self.d_new, 0.)
        d_int_full = fe.assemble(self.d_new * fe.det(self.grad_gamma) * fe.dx)
        d_int = fe.assemble(d_clipped * fe.det(self.grad_gamma) * fe.dx)

        print("d_int_clipped {}".format(float(d_int)))
        print("d_int_full {}".format(float(d_int_full)))

        update_flag = False
        if d_int - self.d_integrals[-1] > self.d_integral_interval:
            update_flag = True

        if update_flag and not self.finish_flag:
            print('\n')
            print(
                '================================================================================='
            )
            print('>> Updating map...')
            print(
                '================================================================================='
            )

            new_tip_point = self.identify_crack_tip()
            if self.inside_domain(new_tip_point):
                if len(self.control_points) > 1:
                    v1 = self.control_points[-1] - self.control_points[-2]
                    v2 = new_tip_point - self.control_points[-1]
                    v1 = v1 / np.linalg.norm(v1)
                    v2 = v2 / np.linalg.norm(v2)
                    print("new_tip_point is {}".format(new_tip_point))
                    print("v1 is {}".format(v1))
                    print("v2 is {}".format(v2))
                    print("control points are \n{}".format(
                        self.control_points))
                    print("impact_radii are {}".format(self.impact_radii))
                    assert np.dot(
                        v1, v2
                    ) > np.sqrt(2) / 2, "Crack propogration angle not good"
                self.compute_impact_radii(new_tip_point)
                self.interpolate_H()
                self.d_integrals.append(d_int)
                print(
                    '================================================================================='
                )
            else:
                self.finish_flag = True
            self.update_weak_form = True

        else:
            print("Do not modify map")

        print("d_integrals {}".format(self.d_integrals))
Example #2
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)
Example #3
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
    def _construct_eigenproblem(self, u: ufl.Argument, v: ufl.Argument) \
            -> Tuple[ufl.algebra.Operator, ufl.algebra.Operator]:
        """Construct left- and right-hand sides of eigenvalue problem.

        Parameters
        ----------
        u : ufl.Argument
            A function belonging to the function space under consideration.
        v : ufl.Argument
            A function belonging to the function space under consideration.

        Returns
        -------
        a : ufl.algebra.Operator
            Left hand side form.
        b : ufl.algebra.Operator
            Right hand side form.

        """
        g = self.metric_tensor
        sqrt_g = fenics.sqrt(fenics.det(g))
        inv_g = fenics.inv(g)

        # $a(u, v) = \int_M \nabla u \cdot g^{-1} \nabla v \, \sqrt{\det(g)} \, d x$.
        a = fenics.dot(fenics.grad(u), inv_g * fenics.grad(v)) * sqrt_g
        # $b(u, v) = \int_M u \, v \, \sqrt{\det(g)} \, d x$.
        b = fenics.dot(u, v) * sqrt_g

        return a, b
Example #5
0
 def energy_norm(self, u):
     psi_plus = self.psi_plus(strain(self.mfem_grad(u)))
     psi_minus = self.psi_minus(strain(self.mfem_grad(u)))
     return np.sqrt(
         float(
             fe.assemble((g_d(self.d_exact) * psi_plus + psi_minus) *
                         fe.det(self.grad_gamma) * fe.dx)))
Example #6
0
    def __setup_a_priori(self):
        """Sets up the attributes and petsc solver for the a priori quality check.

		Returns
		-------
		None
		"""

        options = [[['ksp_type', 'preonly'], ['pc_type', 'jacobi'],
                    ['pc_jacobi_type', 'diagonal'], ['ksp_rtol', 1e-16],
                    ['ksp_atol', 1e-20], ['ksp_max_it', 1000]]]
        self.ksp_prior = PETSc.KSP().create()
        _setup_petsc_options([self.ksp_prior], options)

        self.transformation_container = fenics.Function(
            self.form_handler.deformation_space)
        dim = self.mesh.geometric_dimension()

        if not self.volume_change > 1:
            raise ConfigError('MeshQuality', 'volume_change',
                              'This parameter has to be larger than 1.')

        self.a_prior = self.trial_dg0 * self.test_dg0 * self.dx
        self.L_prior = fenics.det(
            fenics.Identity(dim) + fenics.grad(self.transformation_container)
        ) * self.test_dg0 * self.dx
Example #7
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
Example #8
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]
Example #9
0
    def build_weak_form_staggered(self):
        self.x_hat = fe.variable(fe.SpatialCoordinate(self.mesh))
        self.x = fe.variable(
            map_function_ufl(self.x_hat, self.control_points,
                             self.impact_radii, self.map_type,
                             self.boundary_info))
        self.grad_gamma = fe.diff(self.x, self.x_hat)

        def mfem_grad_wrapper(grad):
            def mfem_grad(u):
                return fe.dot(grad(u), fe.inv(self.grad_gamma))

            return mfem_grad

        self.mfem_grad = mfem_grad_wrapper(fe.grad)

        self.psi_plus = partial(self.psi_plus_linear_elasticity,
                                lamda=self.lamda,
                                mu=self.mu)
        self.psi_minus = partial(self.psi_minus_linear_elasticity,
                                 lamda=self.lamda,
                                 mu=self.mu)
        self.psi = partial(psi_linear_elasticity, lamda=self.lamda, mu=self.mu)

        sigma_plus = cauchy_stress_plus(strain(self.mfem_grad(self.x_new)),
                                        self.psi_plus)
        sigma_minus = cauchy_stress_minus(strain(self.mfem_grad(self.x_new)),
                                          self.psi_minus)

        self.u_exact, self.d_exact = self.compute_analytical_solutions_fully_broken(
            self.x)

        self.G_u = (g_d(self.d_exact) * fe.inner(sigma_plus, strain(self.mfem_grad(self.eta))) \
            + fe.inner(sigma_minus, strain(self.mfem_grad(self.eta)))) * fe.det(self.grad_gamma) * fe.dx

        self.G_d = (self.d_new - self.d_exact) * self.zeta * fe.det(
            self.grad_gamma) * fe.dx

        self.u_initial = self.nonzero_initial_guess(self.x)
        self.x_new.assign(fe.project(self.u_initial, self.U))
Example #10
0
    def build_weak_form_staggered(self):
        self.x_hat = fe.variable(fe.SpatialCoordinate(self.mesh))
        self.x = map_function_ufl(self.x_hat, self.control_points,
                                  self.impact_radii, self.map_type,
                                  self.boundary_info)
        self.grad_gamma = fe.diff(self.x, self.x_hat)

        def mfem_grad_wrapper(grad):
            def mfem_grad(u):
                return fe.dot(grad(u), fe.inv(self.grad_gamma))

            return mfem_grad

        self.mfem_grad = mfem_grad_wrapper(fe.grad)

        # A special note (Tianju): We hope to use Model C, but Newton solver fails without the initial guess by Model A
        if self.i < 2:
            self.psi_plus = partial(psi_plus_linear_elasticity_model_A,
                                    lamda=self.lamda,
                                    mu=self.mu)
            self.psi_minus = partial(psi_minus_linear_elasticity_model_A,
                                     lamda=self.lamda,
                                     mu=self.mu)
        else:
            self.psi_plus = partial(psi_plus_linear_elasticity_model_C,
                                    lamda=self.lamda,
                                    mu=self.mu)
            self.psi_minus = partial(psi_minus_linear_elasticity_model_C,
                                     lamda=self.lamda,
                                     mu=self.mu)
            print("use model C")

        self.psi = partial(psi_linear_elasticity, lamda=self.lamda, mu=self.mu)

        self.sigma_plus = cauchy_stress_plus(
            strain(self.mfem_grad(self.x_new)), self.psi_plus)
        self.sigma_minus = cauchy_stress_minus(
            strain(self.mfem_grad(self.x_new)), self.psi_minus)

        # self.sigma = cauchy_stress_plus(strain(self.mfem_grad(self.x_new)), self.psi)
        # self.sigma_degraded = g_d(self.d_new) * self.sigma_plus + self.sigma_minus

        self.G_u = (g_d(self.d_new) * fe.inner(self.sigma_plus, strain(self.mfem_grad(self.eta))) \
            + fe.inner(self.sigma_minus, strain(self.mfem_grad(self.eta)))) * fe.det(self.grad_gamma) * fe.dx

        if self.solution_scheme == 'explicit':
            self.G_d = (self.H_old * self.zeta * g_d_prime(self.d_new, g_d) \
                    + self.G_c / self.l0 * (self.zeta * self.d_new + self.l0**2 * fe.inner(self.mfem_grad(self.zeta), self.mfem_grad(self.d_new)))) * fe.det(self.grad_gamma) * fe.dx
        else:
            self.G_d = (history(self.H_old, self.psi_plus(strain(self.mfem_grad(self.x_new))), self.psi_cr) * self.zeta * g_d_prime(self.d_new, g_d) \
                    + self.G_c / self.l0 * (self.zeta * self.d_new + self.l0**2 * fe.inner(self.mfem_grad(self.zeta), self.mfem_grad(self.d_new)))) * fe.det(self.grad_gamma) * fe.dx
    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
Example #12
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
Example #13
0
        def obj(x):
            p = fe.Constant(x)
            x_coo = fe.SpatialCoordinate(self.mesh)
            control_points = list(self.control_points)
            control_points.append(p)
            pseudo_radii = np.zeros(len(control_points))
            distance_field, _ = distance_function_segments_ufl(
                x_coo, control_points, pseudo_radii)
            d_artificial = fe.exp(-distance_field / self.l0)

            d_clipped = fe.conditional(fe.gt(self.d_new, 0.5), self.d_new, 0.)

            L_tape = fe.assemble((d_clipped - d_artificial)**2 *
                                 fe.det(self.grad_gamma) * fe.dx)
            # L_tape = fe.assemble((self.d_new - d_artificial)**2 * fe.det(self.grad_gamma) * fe.dx)

            L = float(L_tape)
            return L
Example #14
0
    def __init__(self,
                 mesh: fe.Mesh,
                 constitutive_model: ConstitutiveModelBase,
                 u_order=1,
                 p_order=0):

        # TODO a lot here...

        element_v = fe.VectorElement("P", mesh.ufl_cell(), u_order)
        element_s = fe.FiniteElement("DG", mesh.ufl_cell(), p_order)
        # mixed_element = fe.MixedElement([element_v, element_v, element_s])
        mixed_element = fe.MixedElement([element_v, element_s])

        self.W = fe.FunctionSpace(mesh, mixed_element)

        self.V, self.Q = self.W.split()

        self.w = fe.Function(self.W)
        self.u, self.p = fe.split(self.w)
        w0 = fe.Function(self.W)
        self.u0, self.p0 = fe.split(w0)
        self.ut, self.pt = fe.TestFunctions(self.W)

        self.F = kin.def_grad(self.u)
        self.F0 = kin.def_grad(self.u0)

        S_iso = constitutive_model.iso_stress(self.u)
        mod_p = constitutive_model.p(self.u)
        J = fe.det(self.F)
        F_inv = fe.inv(self.F)

        if mod_p is None:
            mod_p = J**2 - 1.
        else:
            mod_p -= self.p

        S = S_iso + J * self.p * F_inv * F_inv.T

        self.d_LHS = fe.inner(fe.grad(self.ut), self.F * S) * fe.dx \
                     + fe.inner(mod_p, self.pt) * fe.dx
        # + fe.inner(mod_p, fe.tr(fe.nabla_grad(self.ut)*fe.inv(self.F))) * fe.dx

        self.d_RHS = (fe.inner(fe.Constant((0., 0., 0.)), self.ut) * fe.dx)
Example #15
0
    def evaluate_errors(self):
        print("Evaluate L2 errors...")
        print("Model {}, map {}, refinement {}".format(self.model_flag),
              self.map_type, self.local_refinement_iteration)
        u_error_l2 = np.sqrt(
            float(
                fe.assemble(
                    fe.inner(self.x_new - self.u_exact, self.x_new -
                             self.u_exact) * fe.det(self.grad_gamma) * fe.dx)))
        u_error_semi_h1 = np.sqrt(float(fe.assemble(fe.inner(self.mfem_grad(self.x_new - self.u_exact), \
                                                             self.mfem_grad(self.x_new - self.u_exact)) * fe.det(self.grad_gamma) * fe.dx)))

        # d_error_l2 = np.sqrt(float(fe.assemble((self.d_new - self.d_exact)**2 * fe.det(self.grad_gamma) * fe.dx)))
        print("Displacement error l2 is {}".format(u_error_l2))
        print("Displacement error semi h1 is {}".format(u_error_semi_h1))
        # print("Damage error is {}".format(d_error_l2))

        self.u_energy_error = self.energy_norm(self.x_new - self.u_exact)
        print("Displacement error energy_norm is {}".format(
            self.u_energy_error))
                  element=element_3)  # Body force per unit volume
t_bar = fe.Constant((0.0, 0.0, 0.0))  # Traction force on the boundary

# Define test and trial functions
w = fe.Function(V)  # most recently computed solution
(u, p) = fe.split(w)
(v, q) = fe.TestFunctions(V)
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(F)

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

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

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

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

# parameters taken from O. Roehrle and Heidlauf

# Mooney-Rivlin parameters (in Pa)
Example #17
0
def psi_minus_Borden(F, mu, kappa):
    J = fe.det(F)
    U, Wbar = psi_aux_Borden(F, mu, kappa)
    return fe.conditional(fe.lt(J, 1), U, 0)
Example #18
0
def psi_Borden(F, mu, kappa):
    J = fe.det(F)
    U, Wbar = psi_aux_Borden(F, mu, kappa)
    return U + Wbar
Example #19
0
 def I3(C):
     return fe.det(C)
Example #20
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
Example #21
0
w0 = Solution()
w0.up = w
w0.t = 0

dt = 2.e-5
sol, W = half_exp_dyn(w0, dt=dt, t_end=500 * dt, show_plots=False)
# dif = explicit_relax_dyn(w0, kappa=1e4, dt=dt, t_end=1000*dt, show_plots=False)

(u0, p0, v0) = fe.split(w0)
T = 0.5 * rho * inner(v0, v0)

plot_form(sol, w0, W * dx)
plot_form(sol, w0, T * dx)
plot_form(sol, w0, (T + W) * dx)
plot_form(sol, w0, (det(deformation_grad(u0))) * dx)

save_to_vtk(sol)
"""
# def solve_dynamics():

u0 =  w.split(deepcopy=True)[0]
# p = w.sub(1, deepcopy=True)
v0 = fe.Function(V_v)


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

bcs_u, bcs_p, bcs_v = load_2d_muscle_bc(V_u, V_pv.sub(0), V_pv.sub(1), boundaries)
    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
Example #23
0
def J_(U):
    return det(F_(U))
Example #24
0
b = fe.Constant((0.0, 0.0, 0.0))  # Body force per unit volume
t_bar = fe.Constant((0.0, 0.0, 0.0))  # Traction force on the boundary

# Define test and trial functions
w = fe.Function(V)  # most recently computed solution
(u, p) = fe.split(w)
(v, q) = fe.TestFunctions(V)
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
Example #25
0
def iso_def_grad(u):
    F = def_grad(u)
    F /= fe.det(F)**(1. / 3.)
    return F