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')
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()