Beispiel #1
0
    def Hessian(self, StrainTensors, elem=0, gcounter=0):

        mu = self.mu
        k1 = self.k1
        k2 = self.k2

        I = StrainTensors['I']
        J = StrainTensors['J'][gcounter]
        b = StrainTensors['b'][gcounter]
        F = StrainTensors['F'][gcounter]

        if self.ndim == 3:
            trb = trace(b)
        elif self.ndim == 2:
            trb = trace(b) + 1

        # ISOCHORIC PART
        H_Voigt = 2.*mu*J**(-5./3.) * (1./9.*trb*einsum('ij,kl',I,I) - \
                1./3.*einsum('ij,kl',I,b) - 1./3.*einsum('ij,kl',b,I) + \
                1./6.*trb*(einsum('il,jk',I,I) + einsum('ik,jl',I,I)) )

        # VOLUMETRIC PART
        if self.is_nearly_incompressible:
            H_Voigt += self.pressure * (
                einsum('ij,kl', I, I) -
                (einsum('ik,jl', I, I) + einsum('il,jk', I, I)))
        else:
            H_Voigt += self.kappa * (
                (2. * J - 1.) * einsum('ij,kl', I, I) - (J - 1.) *
                (einsum('ik,jl', I, I) + einsum('il,jk', I, I)))

        # Anisotropic contibution
        nfibres = self.anisotropic_orientations.shape[1]
        for i_fibre in range(nfibres):
            N = self.anisotropic_orientations[elem][i_fibre][:, None]
            FN = np.dot(F, N)[:, 0]
            innerFN = einsum('i,i', FN, FN)
            outerFN = einsum('i,j', FN, FN)
            expo = np.exp(k2 * (innerFN - 1.)**2)
            H_Voigt += 4. * k1 / J * (1. + 2. * k2 *
                                      (innerFN - 1.)**2) * expo * einsum(
                                          'ij,kl', outerFN, outerFN)

        H_Voigt = Voigt(H_Voigt, 1)

        return H_Voigt
Beispiel #2
0
    def Hessian(self, StrainTensors, elem=0, gcounter=0):
        """Hessian split into isochoroic and volumetric parts"""

        I = StrainTensors['I']
        b = StrainTensors['b'][gcounter]
        J = StrainTensors['J'][gcounter]

        mu = self.mu

        # ISOCHORIC
        H_Voigt = 2*mu*J**(-5./3.)*(1./9.*trace(b)*einsum('ij,kl',I,I) - \
            1./3.*(einsum('ij,kl',b,I) + einsum('ij,kl',I,b)) +\
            1./6.*trace(b)*(einsum('ik,jl',I,I) + einsum('il,jk',I,I)) )
        # VOLUMETRIC CHANGES
        if self.is_nearly_incompressible:
            H_Voigt += self.pressure*(einsum('ij,kl',I,I) - (einsum('ik,jl',I,I) + einsum('il,jk',I,I)))
        else:
            H_Voigt += self.kappa*((2.*J-1.)*einsum('ij,kl',I,I) - (J-1.)*(einsum('ik,jl',I,I) + einsum('il,jk',I,I)))

        H_Voigt = Voigt(H_Voigt,1)

        self.H_VoigtSize = H_Voigt.shape[0]

        return H_Voigt
Beispiel #3
0
    def CauchyStress(self, StrainTensors, elem=0, gcounter=0):

        mu = self.mu
        k1 = self.k1
        k2 = self.k2

        I = StrainTensors['I']
        J = StrainTensors['J'][gcounter]
        b = StrainTensors['b'][gcounter]
        F = StrainTensors['F'][gcounter]

        if self.ndim == 3:
            trb = trace(b)
        elif self.ndim == 2:
            trb = trace(b) + 1

        # ISOCHORIC PART
        stress = mu * J**(-5. / 3.) * (b - 1. / 3. * trb * I)

        # VOLUMETRIC PART
        if self.is_nearly_incompressible:
            stress += self.pressure * I
        else:
            stress += self.kappa * (J - 1.) * I

        # Anisotropic contibution
        nfibres = self.anisotropic_orientations.shape[1]
        for i_fibre in range(nfibres):
            N = self.anisotropic_orientations[elem, i_fibre, :, None]
            FN = np.dot(F, N)[:, 0]
            innerFN = einsum('i,i', FN, FN)
            outerFN = einsum('i,j', FN, FN)
            expo = np.exp(k2 * (innerFN - 1.)**2)
            stress += 2. * k1 / J * (innerFN - 1.) * expo * outerFN

        return stress
Beispiel #4
0
    def CauchyStress(self,StrainTensors,elem=0,gcounter=0):

        I = StrainTensors['I']
        J = StrainTensors['J'][gcounter]
        b = StrainTensors['b'][gcounter]

        mu = self.mu

        # ISOCHORIC PART
        stress = mu*J**(-5./3.)*(b - 1./3.*trace(b)*I)
        # VOLUMETRIC PART
        if self.is_nearly_incompressible:
            stress += self.pressure*I
        else:
            stress += self.kappa*(J-1.)*I

        return stress
Beispiel #5
0
    def Hessian(self, StrainTensors, elem=0, gcounter=0):

        #print(np.finfo(np.float64).eps)
        I = StrainTensors['I']
        J = StrainTensors['J'][gcounter]
        F = StrainTensors['F'][gcounter]
        # Directional vector for element
        Normal = self.anisotropic_orientations[elem][0][:, None]
        Normal = np.dot(I, Normal)[:, 0]
        Tangential = self.anisotropic_orientations[elem][1][:, None]
        Tangential = np.dot(I, Tangential)[:, 0]
        Axial = self.anisotropic_orientations[elem][2][:, None]
        Axial = np.dot(I, Axial)[:, 0]
        Rotation = np.eye(3, 3, dtype=np.float64)
        for i in range(3):
            Rotation[0, i] = Normal[i]
            Rotation[1, i] = Tangential[i]
            Rotation[2, i] = Axial[i]

        # Growth tensor (same for all constituent)
        outerNormal = einsum('i,j', Normal, Normal)
        outerTangential = I - outerNormal
        F_g = self.StateVariables[gcounter][20] * outerNormal + outerTangential
        # Remodeling tensor for elastin
        F_r = I + (self.StateVariables[gcounter][0:9].reshape(3, 3) -
                   I) * self.factor_increment
        F_r = np.dot(Rotation.T, np.dot(F_r, Rotation))
        # Elastin Growth and Remodeling tensor
        F_gr = np.dot(F_r, F_g)
        F_gr_inv = np.linalg.inv(F_gr)

        # ELASTIN
        F_e = np.dot(F, F_gr_inv)
        J_e = np.linalg.det(F_e)
        b_e = np.dot(F_e, F_e.T)

        if self.ndim == 3:
            trb = trace(b_e)
        elif self.ndim == 2:
            trb = trace(b_e) + 1.

        H_Voigt = 2.*self.mu*J_e**(-2./3.)*(1./9.*trb*einsum('ij,kl',I,I) - \
                1./3.*(einsum('ij,kl',I,b_e) + einsum('ij,kl',b_e,I)) + \
                1./6.*trb*(einsum('ik,jl',I,I) + einsum('il,jk',I,I)) )*self.StateVariables[gcounter][14]/J

        if self.is_nearly_incompressible:
            H_Voigt += self.pressure*J_e*(einsum('ij,kl',I,I) - \
                (einsum('ik,jl',I,I) + einsum('il,jk',I,I)))*self.StateVariables[gcounter][14]/J
        else:
            H_Voigt += self.kappa*J_e*((2.*J_e-1.)*einsum('ij,kl',I,I) - \
                (J_e-1.)*(einsum('ik,jl',I,I) + einsum('il,jk',I,I)))*self.StateVariables[gcounter][14]/J

        #SMC AND COLLAGEN FIBRES
        for fibre_i in [1, 2, 3, 4, 5]:
            # Fibre direction
            N = self.anisotropic_orientations[elem][fibre_i][:, None]
            N = np.dot(I, N)[:, 0]
            FN = np.dot(F, N)
            # Remodeling stretch in fibre direction
            lambda_r = 1. + (self.StateVariables[gcounter][fibre_i + 8] -
                             1.) * self.factor_increment
            # TOTAL deformation
            innerFN = einsum('i,i', FN, FN)
            outerFN = einsum('i,j', FN, FN)
            # ELASTIC deformation
            innerFN_e = innerFN / lambda_r**2
            outerFN_e = outerFN / lambda_r**2
            if fibre_i is 1:
                k1 = self.k1m * self.StateVariables[gcounter][15] / J
                k2 = self.k2m
                # Anisotropic Stiffness for this key
                H_Voigt += 4. * k1 * (1. + 2. * k2 *
                                      (innerFN_e - 1.)**2) * np.exp(
                                          k2 * (innerFN_e - 1.)**2) * einsum(
                                              'ij,kl', outerFN_e, outerFN_e)
                # Active stress for SMC
                s_act = self.maxi_active_stress * self.StateVariables[
                    gcounter][15] / J
                stretch_m = self.maxi_active_stretch
                stretch_0 = self.zero_active_stretch
                stretch_a = self.active_stretch
                H_Voigt += -2.*(s_act/(self.rho0*innerFN**2))*\
                        (1.-((stretch_m-stretch_a)/(stretch_m-stretch_0))**2)*einsum('ij,kl',outerFN,outerFN)
            elif fibre_i is not 1:
                k1 = self.k1c if (innerFN_e - 1.0) >= 0.0 else 0.075 * self.k1c
                k1 = k1 * self.StateVariables[gcounter][14 + fibre_i] / J
                k2 = self.k2c
                # Anisotropic Stiffness for this key
                H_Voigt += 4. * k1 * (1. + 2. * k2 *
                                      (innerFN_e - 1.)**2) * np.exp(
                                          k2 * (innerFN_e - 1.)**2) * einsum(
                                              'ij,kl', outerFN_e, outerFN_e)

        H_Voigt = Voigt(H_Voigt, 1)

        return H_Voigt