Beispiel #1
0
    def update(self, uNod, mater):
        """
        update strain and stress tensors of the element from the displacement
        field 'uNod' with the material model 'mater'
        """
        # dshape = np.shape(self.dshape)
        # dshape = (npg, npN, dim)
        #   npg is the number of gauss points to integration
        #   npN is the number of nodes in each element
        #   dim is the dimention of the problem. If 2D -> dim = 2
        npg = self.getNpg()
        for i in range(npg):  # loop on integration points
            # compute CG stretch tensor and GL strain tensor
            G = self.gradient(self.dshape[i], uNod)
            F = G + tensor.I(len(G))
            self.F[i] = F  # store deformation gradient at integration point i
            C = tensor.rightCauchyGreen(F)
            self.E_GL[i] = 0.5 * (C - tensor.I(len(C)))
            # compute spatial description
            # from scipy.linalg.polar() method with u=R and p=V,
            _, V = polar(F, side='left')
            # replace pure zeros by very low values to prevent "nan" in np.log(V)
            V[V < 1e-10] = 1e-15
            self.hencky[i] = np.log(V)  # ln(V) with F = V.R, "true" strain
            b = tensor.leftCauchyGreen(F)
            self.E_EA[i] = 0.5 * (tensor.I(len(b)) - tensor.inv(b))
            ###
            if (mater == 0):  # skip next lines: do not compute stress
                # print("Whahat")
                continue
            # compute PK2 stress tensor and material tangent operator M=2*dS/dC
            # print("type(mater) = " + str(type(mater)))
            # print("mater = " + str(mater))

            (PK2, M) = mater.stress_stiffness(C)

            # compute PK1 stress and lagrangian tangent operator K = dP/dF
            # print("PK2 = ")
            # print(PK2)
            # print("F = ")
            # print(F)
            self.PK1[i] = tensor.PK2toPK1(F, PK2)
            # print("PK1[i] = ")
            # print(self.PK1[i])
            # print("PK1[i] = ")
            # print(self.PK1[i])
            self.K[i] = tensor.MaterialToLagrangian(F, PK2, M)
            # compute cauchy stress (spatial description)
            self.sigma[i] = tensor.PK1toCauchy(F, self.PK1[i])
Beispiel #2
0
 def stress(self, C):
     """
     Compute 2nd Piola-Kirchhoff stress
     PK2 = 2*dphi/dC
         = lambda * tr(E) * I + 2 * mu * E
     """
     dim = len(C)
     PK2 = tensor.tensor(dim)
     lamda = self.get1LAME()
     mu = self.get2LAME()
     E = tensor.tensor(dim)
     E = 0.5 * (C - tensor.I(dim))
     II = tensor.I(dim)
     PK2 = lamda * tensor.trace(E) * II + 2 * mu * E
     return PK2
Beispiel #3
0
 def potential(self, C):
     """
     Compute hyperelastic potential: phi = lamdabda/2 * tr(E)^2 - mu*(E:E)
     """
     lamda = self.get1LAME()
     mu = self.get2LAME()
     EL = 0.5 * (C - tensor.I(len(C)))  # Lagrangian strain E
     phi = lamda / 2. * (tensor.trace(EL))**2 + mu * np.tensordot(EL, EL, 2)
     return phi
Beispiel #4
0
 def stiffness(self, C):
     """
     Compute material tangent M = 2*dS/dC
     """
     dim = len(C)
     lamda = self.get1LAME()
     mu = self.get2LAME()
     I = tensor.I(dim)
     IxI = tensor.outerProd4(I, I)
     IIsym = tensor.IISym(dim)
     M = lamda * IxI + 2 * mu * IIsym
     return M
Beispiel #5
0
    def compute_materialtangent(self):
        # =============================================================================================
        #%% Compute error on material tangent operator by finite (central) difference of stress
        # =============================================================================================
        d = self.FE_model.dim
        DC = 1.e-5
        TOLMAX = 1.e-3
        PRECISION = 1.e-16
        printerror = False
        e = 1  # element
        KerrMax = 1e-30
        for e in range(self.FE_model.nElements()):
            Ed = self.E[e].reshape(d, d)  # Lagrange deformation
            Cd = 2 * Ed + tensor.I(d)  # right Cauchy-Green tensor
            Sp = tensor.tensor(d)  # S(C+DC/2) Piola Kirchhoff II tensor "plus"
            # S(C-DC/2) Piola Kirchhoff II tensor "minus"
            Sm = tensor.tensor(d)
            S = self.FE_model.material.stress(Cd)
            # Lagrangian tangent operator 2*dS/dC
            M = self.FE_model.material.stiffness(Cd)

            for k in range(d):
                for l in range(d):
                    Cd[k, l] += DC / 2.
                    Sp = self.FE_model.material.stress(Cd)

                    Cd[k, l] -= DC
                    Sm = self.FE_model.material.stress(Cd)

                    Cd[k, l] += DC / 2.  # come back to before perturbation
                    for i in range(d):
                        for j in range(d):
                            Knum = (Sp[i, j] - Sm[i, j] + Sp[j, i] -
                                    Sm[j, i]) / DC  # 2*(Sp-Sm + Sp-Sm)/2/DC
                            # K_ijkl = ( S_ij(C_kl+DC/2) - S_ji(C_kl-DC/2) ) SYM
                            if (np.fabs(M[i, j, k, l]) > 1.0):
                                Ktest = np.fabs(M[i, j, k, l])
                            else:
                                Ktest = 1.0
                            Kerr = np.fabs(M[i, j, k, l] - Knum) / Ktest
                            if (Kerr > KerrMax):
                                KerrMax = Kerr
                            if (printerror) and (Kerr > TOLMAX) and (np.fabs(Knum) > PRECISION):
                                print('%d %d %d %d %13.6e %13.6e %13.6e' %
                                      (i, j, k, l, M[i, j, k, l], Knum, Kerr))
        # print('Maximal error = %13.6e' % KerrMax)
        if KerrMax > TOLMAX:
            msg = "Material tangent not valided: KerrMax = %.2e" % KerrMax
            raise Exception(msg)
Beispiel #6
0
    def compute_stress(self):

        # =============================================================================================
        #%% Compute error on stress by finite (central) difference of energy potential
        # =============================================================================================
        d = self.FE_model.getDim()
        DC = 1.e-5
        TOLMAX = 1.e-3
        PRECISION = 1.e-16
        printerror = True
        e = 1  # element
        SerrMax = 1e-30
        nElements = self.FE_model.nElements()
        for e in range(nElements):
            Ed = self.E[e].reshape(d, d)  # Lagrange deformation
            Cd = 2 * Ed + tensor.I(d)  # right Cauchy-Green tensor
            S = self.FE_model.material.stress(Cd)
            for i in range(d):
                for j in range(d):

                    Cd[i, j] += DC / 2.
                    # phi(C_ij + DC/2), potential plus
                    phip = self.FE_model.material.potential(Cd)

                    Cd[i, j] -= DC
                    phim = self.FE_model.material.potential(Cd)

                    Cd[i, j] += DC / 2.  # come back to before perturbation

                    # S_ij = 2*(phi(C_ij+DC/2) - phi(C_ij-DC/2))/DC
                    Snum = 2 * (phip - phim) / DC

                    if (np.fabs(S[i, j]) > 1.0):
                        Stest = np.fabs(S[i, j])
                    else:
                        Stest = 1.0
                    Serr = np.fabs(S[i, j] - Snum) / Stest
                    if (Serr > SerrMax):
                        SerrMax = Serr
                    if (printerror) and (Serr > TOLMAX) and (np.fabs(Snum) > PRECISION):
                        print('%d %d %13.6e %13.6e %13.6e' %
                              (i, j, S[i, j], Snum, Serr))

        # print('Maximal error = %13.6e' % SerrMax)
        if SerrMax > TOLMAX:
            msg = "Stress computation not valided: SerrMax = %.2e" % SerrMax
            raise Exception(msg)
Beispiel #7
0
    def stress(self, C):
        """
        Compute 2nd Piola-Kirchhoff stress
        """

        dim = len(C)
        PK2 = tensor.tensor(dim)
        detC = tensor.det(C)
        detF = np.sqrt(detC)
        lnJ = np.log(detF)
        lamda = self.get1LAME()
        mu = self.get2LAME()
        invC = tensor.inv(C)
        I = tensor.I(dim)
        PK2 = mu * (I - invC) + lamda * lnJ * invC

        return PK2
 def I():
     tensor.I()
Beispiel #9
0
v[0] = 1.0
v[1] = 2.0
#to access the elements of an array you must use brackets. Paranthesis are restricted to the call of functions.
print("v =\n", v)

#
# --- Test methods for 2nd-order tensors
#
print("\nTest methods for 2nd-order tensors")
print("==================================")
# Create a 2nd-order tensor, initialized to zero.
A = tensor.tensor()
print("\nA =\n", A)

# Compute identity 2nd-order tensor
I = tensor.I()
print("\nI =\n", I)

# Tensor product of two vectors
B = tensor.outerProd(v, v)
print("\nB =\n", B)

# Compute determinant
detB = tensor.det(B)
print("\ndetB =\n", detB)

# Compute trace
trB = tensor.trace(B)
print("\ntrB =\n", trB)

# Non symmetrical tensor