Esempio n. 1
0
        def __init__(self, deg, basis_type):
            deg = int(deg)
            if basis_type == 'L':  #1D Lagrange basis of degree deg
                z = Symbol('z', real=True)
                Xi = np.linspace(-1, 1, deg + 1)

                def lag_basis(k):
                    n = 1.
                    for i in range(len(Xi)):
                        if k != i:
                            n *= (z - Xi[i]) / (Xi[k] - Xi[i])
                    return n

                N = Array([lag_basis(m) for m in range(deg + 1)])
                dfN = diff(N, z) + 1.e-25 * N
                self.Ns = lambdify(z, N, 'numpy')
                self.dN = lambdify(z, dfN, 'numpy')
                self.enrich = enrch
                ue = z**0.65 + sin(3 * pi * z / 2)
                uep = ue.diff(z)
                uepp = uep.diff(z)
                self.Tf = lambdify(z, -uepp, 'numpy')
                self.dE = float(integrate(0.5 * uep**2, (z, 0, 1)).evalf(20))
            elif basis_type == 'M':  #1D Legendre Polynomials (Fischer calls this spectral)
                z = Symbol('z', real=True)
                x = Symbol('x')

                def gen_legendre_basis(n):
                    if n == -2:
                        return (1 - 1 * z) / 2
                    elif n == -1:
                        return (1 + 1 * z) / 2
                    else:
                        return ((2 * (n + 3) - 3) / 2.)**0.5 * integrate(
                            legendre((n + 1), x), (x, -1, z))

                N = Array([gen_legendre_basis(i - 2) for i in range(deg + 1)])
                N2 = N.tolist()
                N2[-1] = N[1]
                N2[1] = N[-1]
                N = Array(N2)
                dfN = diff(N, z) + 1.e-25 * N
                #            print(N)
                self.Ns = lambdify(z, N, 'numpy')
                self.dN = lambdify(z, dfN, 'numpy')
                self.enrich = enrch
                ue = z**0.65 + sin(3 * pi * z / 2)
                uep = ue.diff(z)
                uepp = uep.diff(z)
                self.Tf = lambdify(z, -uepp, 'numpy')
                self.dE = float(integrate(0.5 * uep**2, (z, 0, 1)).evalf(20))
            elif basis_type == 'G':  #1D GFEM Functions (degree denotes the total approximation space)
                z = Symbol('z', real=True)
                Xi = np.linspace(-1, 1, deg + 1)

                def lag_basis(k):
                    n = 1.
                    for i in range(len(Xi)):
                        if k != i:
                            n *= (z - Xi[i]) / (Xi[k] - Xi[i])
                    return n

                N = Array([simplify(lag_basis(m)) for m in range(deg + 1)])
                dfN = diff(N, z) + 1.e-25 * N
                self.Ns = lambdify(z, N, 'numpy')
                self.dN = lambdify(z, dfN, 'numpy')
                self.enrich = enrch  #Enrichment order corresponding to GFEM shape functions
                ue = z**0.65 + sin(3 * pi * z / 2)
                uep = ue.diff(z)
                uepp = uep.diff(z)
                self.Tf = lambdify(z, -uepp, 'numpy')
                self.dE = float(integrate(0.5 * uep**2, (z, 0, 1)).evalf(20))
            elif basis_type == 'Singl' or basis_type == 'SGFEMSingl' or basis_type == 'GeomSingl' or basis_type == 'GeomSGFEM':
                z = Symbol('z', real=True)
                xalph = Symbol('xalph', real=True)
                halph = Symbol('halph', real=True)
                Xi = np.linspace(-1, 1, deg + 1)

                def lag_basis(k):
                    n = 1.
                    for i in range(len(Xi)):
                        if k != i:
                            n *= (z - Xi[i]) / (Xi[k] - Xi[i])
                    return n

                N = Array([simplify(lag_basis(m)) for m in range(deg + 1)])
                dfN = diff(N, z) + 1.e-27 * N

                #                Manufactured solution

                ue = z**0.65 + sin(3 * pi * z / 2)
                uep = ue.diff(z)
                uepp = uep.diff(z)
                Nf2 = Array([
                    (ue)**m * ((z - xalph) / halph)**n + 1.e-27 *
                    (z - xalph) / halph for m in range(2)
                    for n in range(enrch + 1)
                ])  # Enrichment by non-polynomials (for interfaces)
                dfN2 = Nf2.diff(z) + 1.e-26 * Nf2

                #                Convert to numpy functions to do array operations (vectorized)
                self.Ns = lambdify(z, N, 'numpy')
                self.dN = lambdify(z, dfN, 'numpy')
                self.enrich = enrch
                self.Tf = lambdify(z, -uepp, 'numpy')
                self.dE = float(integrate(0.5 * uep**2, (z, 0, 1)).evalf(20))
                self.uexact = lambdify(z, ue, 'numpy')
                self.NIF = lambdify(
                    (z, xalph, halph), Nf2, 'numpy'
                )  # Final enrichment functions including both polynomial and exact soln
                self.DNIF = lambdify((z, xalph, halph), dfN2, 'numpy')
                self.enrich = enrch
            else:
                raise Exception('Element type not implemented yet')
Esempio n. 2
0
    def ge_singl_stiff_matrx(eflag, etypes,
                             znodes):  # znodes = nodes of current elements
        eabs = 1.e-12
        limits = 10000
        xi = Symbol('xi', real=True)
        z = Symbol('z', real=True)
        x = 0.5 * ((1 - xi) * znodes[0] + (1 + xi) * znodes[-1])
        Je = znodes[-1] - znodes[0]
        Je /= 2.
        #        print(Je)
        ue = x**0.65 + sin(3 * pi * x / 2)
        uez = z**0.65 + sin(3 * pi * z / 2)
        Tx = -1. * uez.diff(z, 2)
        Tx_xi = Tx.subs([
            (z, 0.5 * ((1 - xi) * znodes[0] + (1 + xi) * znodes[-1]))
        ])
        phi1 = 0.5 * (1 - xi)
        phi2 = 0.5 * (1 + xi)
        if elflag == 'nn':
            Nshp = Array([phi1, phi2])
            dNshp = Nshp.diff(xi)
        elif elflag == 'repr' or elflag == 'bll':
            if etypes == 'Singl':
                Nshp = Array([phi1, phi1 * ue, phi2])
                dNshp = Nshp.diff(xi)

            elif etypes == 'SGFEMSingl':
                ue_interp = ue - phi1 * uez.subs(
                    z, znodes[0]) - phi2 * uez.subs(z, znodes[-1])
                Nshp = Array([phi1, phi1 * ue_interp, phi2])
                dNshp = Nshp.diff(xi)

            elif etypes == 'GeomSGFEM':
                ue_interp = ue - phi1 * uez.subs(
                    z, znodes[0]) - phi2 * uez.subs(z, znodes[-1])
                if elflag == 'repr':
                    Nshp = Array(
                        [phi1, phi1 * ue_interp, phi2, phi2 * ue_interp])
                    dNshp = Nshp.diff(xi)
                elif elflag == 'bll':
                    Nshp = Array([phi1, phi1 * ue_interp, phi2])
                    dNshp = Nshp.diff(xi)

            elif etypes == 'GeomSingl':
                ue_interp = ue - phi1 * uez.subs(
                    z, znodes[0]) - phi2 * uez.subs(z, znodes[-1])
                if elflag == 'repr':
                    Nshp = Array([phi1, phi1 * ue, phi2, phi2 * ue])
                    dNshp = Nshp.diff(xi)
                elif elflag == 'bll':
                    Nshp = Array([phi1, phi1 * ue, phi2])
                    dNshp = Nshp.diff(xi)

        stiffM = Matrix(dNshp) * Matrix(
            dNshp).T * geom.E * geom.A / Je + Matrix(Nshp) * Matrix(
                Nshp).T * geom.C * geom.A * Je
        forvec = Nshp * Tx_xi * Je
        #        mat = np.array([[quad(lambdify(xi,stiffM[i,j],'numpy'),-1.,1.,points=[-1.])[0] for i in range(stiffM.shape[0])] for j in range(stiffM.shape[1])],float)
        mat = np.array([[
            quad(lambdify(xi, stiffM[i, j], 'numpy'),
                 -1.,
                 1.,
                 epsabs=eabs,
                 limit=limits,
                 points=[-1.])[0] for i in range(stiffM.shape[0])
        ] for j in range(stiffM.shape[0])], float)
        #        elemF = np.array([quad(lambdify(xi,forvec[i],'numpy'),-1.,1.,points=[-1.])[0] for i in range(len(forvec))],float)
        elemF = np.array([
            quad(lambdify(xi, forvec[i], 'numpy'),
                 -1.,
                 1.,
                 epsabs=eabs,
                 limit=limits,
                 points=[1.])[0] for i in range(len(forvec))
        ], float)
        return mat, elemF.flatten()