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
示例#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
示例#3
0
def CompressibleNeoHookean(Mu, Lambda, Ic, J):
        
    Psi = (Mu/2)*(Ic - 3) - Mu*fe.ln(J) + (Lambda/2)*(fe.ln(J))**2
    
    return Psi
    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
示例#5
0
 def Vfunc(U):
     return -params['beta']*fe.ln(U + params['alpha'])