コード例 #1
0
def ErrorNorm_CompressionBar():
    """ 
    Calculate and print the error norm (L2 and energy norm) of the elastic 
    bar under compression for convergence study
    """

    ngp = 3
    [w, gp] = gauss(ngp)
    # extract Gauss points and weights

    L2Norm = 0
    EnNorm = 0

    L2NormEx = 0
    EnNormEx = 0

    for e in range(model.nel):

        de = model.d[model.LM[:, e] - 1]  # extract element nodal displacements
        IENe = model.IEN[:, e] - 1  # extract local connectivity information
        xe = model.x[IENe]  # extract element x coordinates
        J = (xe[-1] - xe[0]) / 2  # compute Jacobian

        for i in range(ngp):
            xt = 0.5 * (xe[0] + xe[-1]
                        ) + J * gp[i]  # Gauss points in physical coordinates

            N = Nmatrix1D(xt, xe)  # shape functions matrix
            B = Bmatrix1D(xt, xe)  # derivative of shape functions matrix

            Ee = N @ model.E[IENe]  # Young's modulus at element gauss points

            uh = N @ de  # displacement at gauss point
            uex = (-xt**3 / 6 + xt) / Ee  # Exact displacement
            L2Norm += J * w[i] * (uex - uh)**2
            L2NormEx += J * w[i] * (uex)**2

            sh = B @ de  # strain at Gauss points
            sex = (-xt**2 / 2 + 1) / Ee  # Exact strain
            EnNorm += 0.5 * J * w[i] * Ee * (sex - sh)**2
            EnNormEx += 0.5 * J * w[i] * Ee * (sex)**2

    L2Norm = sqrt(L2Norm)
    L2NormEx = sqrt(L2NormEx)

    EnNorm = sqrt(EnNorm)
    EnNormEx = sqrt(EnNormEx)

    # print stresses at element gauss points
    print('\nError norms')
    print('%13s %13s %13s %13s %13s' %
          ('h', 'L2Norm', 'L2NormRel', 'EnNorm', 'EnNormRel'))
    print(
        '%13.6E %13.6E %13.6E %13.6E %13.6E\n' %
        (2 / model.nel, L2Norm, L2Norm / L2NormEx, EnNorm, EnNorm / EnNormEx))

    return 2 / model.nel, L2Norm, EnNorm
コード例 #2
0
def disp_and_stress(e, d, ax1, ax2):
    """
    Print stresses at Gauss points, plot displacements and stress 
    distributions obtained by FE analysiss

    Args:
        e : (int) element number
        d : (numnp.array(neq,1)) solution vector
        ax1 : axis to draw displacement distribution
        ax2 : axis to draw stress distribution
    """
    de = model.d[model.LM[:, e] - 1]  # extract element nodal displacements
    IENe = model.IEN[:, e] - 1  # extract element connectivity information
    xe = model.x[IENe]  # extract element coordinates
    J = (xe[-1] - xe[0]) / 2  # Jacobian
    w, gp = gauss(model.ngp)  # Gauss points and weights

    # compute stresses at Gauss points
    gauss_pt = np.zeros(model.ngp)
    stress_gauss = np.zeros(model.ngp)
    for i in range(model.ngp):
        xt = 0.5 * (xe[0] + xe[-1]
                    ) + J * gp[i]  # Gauss point in the physical coordinates
        gauss_pt[i] = xt  # store gauss point information

        N = Nmatrix1D(xt, xe)  # extract shape functions
        B = Bmatrix1D(xt, xe)  # extract derivative of shape functions

        Ee = N @ model.E[IENe]  # Young's modulus at element Gauss points
        stress_gauss[i] = Ee * B @ de  # compute stresses at Gauss points

    # print stresses at element gauss points
    print("%8d %12.6f %12.6f %16.6f %16.6f" %
          (e, gauss_pt[0], gauss_pt[1], stress_gauss[0], stress_gauss[1]))

    # equally distributed coordinate within an element
    xplot = np.linspace(xe[0], xe[-1], model.nplot)

    # compute displacements and stresses
    displacement = np.zeros(model.nplot)
    stress = np.zeros(model.nplot)
    for i in range(model.nplot):
        xi = xplot[i]  # current coordinate
        N = Nmatrix1D(xi, xe)  # shape functions
        B = Bmatrix1D(xi, xe)  # derivative of shape functions

        Ee = N @ model.E[IENe]  # Young's modulus
        displacement[i] = N @ de  # displacement output
        stress[i] = Ee * B @ de  # stress output s

    # plot displacements and stresses
    line1, = ax1.plot(xplot, displacement)
    line2, = ax2.plot(xplot, stress)
    if e == 0:
        line1.set_label('FE')
        line2.set_label('FE')
コード例 #3
0
def BarElem(e):
    """ 
    Calculate element stiffness matrix and element nodal body force vector
    
    Args:
        e : (int) element number
        
    Returns: ke, fe
        ke : (numpy(nen,nen)) element stiffness matrix
        fe : (numpy(nen,1)) element nodal force vector
    """

    IENe = model.IEN[:, e] - 1  # extract local connectivity information
    xe = model.x[IENe]  # extract element x coordinates
    J = (xe[model.nen - 1] - xe[0]) / 2  # compute Jacobian
    [w, gp] = gauss(model.ngp)  # extract Gauss points and weights

    ke = np.zeros(
        (model.nen, model.nen))  # initialize element stiffness matrix
    fe = np.zeros((model.nen, 1))  # initialize element nodal force vector

    for i in range(model.ngp):
        # Compute Gauss points in physical coordinates
        xt = 0.5 * (xe[0] + xe[-1]) + J * gp[i]

        # Calculate the element shape function matrix and its derivative
        N = Nmatrix1D(xt, xe)
        B = Bmatrix1D(xt, xe)

        # cross-sectional area,Young's modulus and body force at gauss points
        Ae = N @ model.CArea[IENe]
        Ee = N @ model.E[IENe]
        be = N @ model.body[IENe]

        # compute element stiffness matrix and nodal body force vector
        ke = ke + w[i] * Ae * Ee * (B.T @ B)
        fe = fe + w[i] * N.T * be

    ke = J * ke
    fe = J * fe

    # check for point forces in this element
    for i in range(model.np):  # loop over all point forces
        Pi = model.P[i]  # extract point force
        xpi = model.xp[
            i]  # extract the location of point force within an element
        if xe[0] <= xpi < xe[-1]:
            # add to the nodal force vector
            fe = fe + Pi * np.transpose(Nmatrix1D(xpi, xe))

    return ke, fe
コード例 #4
0
def point_and_trac():
	"""
	Add the nodal forces and natural B.C. to the global force vector.
	"""
	# Assemble point forces
	model.f = model.f + model.P[model.ID - 1]

	# Compute nodal boundary force vector
	for i in range(model.nbe):
		ft = np.zeros((4, 1))							# initialize nodal boundary force vector
		node1 = int(model.n_bc[0, i])					# first node
		node2 = int(model.n_bc[1, i])					# second node
		n_bce = model.n_bc[2:, i].reshape((-1, 1))		# traction value at node1

		# coordinates
		x1 = model.x[node1 - 1]
		y1 = model.y[node1 - 1]
		x2 = model.x[node2 - 1]
		y2 = model.y[node2 - 1]

		# edge length
		leng = np.sqrt((x2 - x1)**2 + (y2 - y1)**2)
		J = leng/2.0

		w, gp = gauss(model.ngp)

		for j in range(model.ngp):
			psi = gp[j]
			N = 0.5*np.array([[1-psi, 0, 1+psi, 0],
							  [0, 1-psi, 0, 1+psi]])

			traction = N@n_bce
			ft = ft + w[j]*J*(N.T@traction)

		# Assemble nodal boundary force vector
		ind1 = model.ndof*(node1 - 1)
		ind2 = model.ndof*(node2 - 1)

		model.f[model.ID[ind1] - 1, 0] += ft[0]
		model.f[model.ID[ind1 + 1] - 1, 0] += ft[1]
		model.f[model.ID[ind2] - 1, 0] += ft[2]
		model.f[model.ID[ind2 + 1] - 1, 0] += ft[3]
コード例 #5
0
def get_stress(e):
	"""
	Print the element stress on Gauss Point.

	Args:
		e   : The element number
	"""
	de = model.d[model.LM[:, e] - 1]		# extract element nodal displacements

	# get coordinates of element nodes
	je = model.IEN[:, e] - 1
	C = np.array([model.x[je], model.y[je]]).T

	# get gauss points and weights
	w, gp = gauss(model.ngp)

	# compute strains and stress at the gauss points
	ind = 0
	number_gp = model.ngp*model.ngp
	X = np.zeros((number_gp, 2))
	strain = np.zeros((3, number_gp))
	stress = np.zeros((3, number_gp))
	for i in range(model.ngp):
		for j in range(model.ngp):
			eta = gp[i]
			psi = gp[j]
			# shape functions matrix
			N = NmatElast2D(eta, psi)
			# derivative of the shape functions
			B, detJ = BmatElast2D(eta, psi, C)

			Na = np.array([N[0, 0], N[0, 2], N[0, 4], N[0, 6]])
			X[ind, :] = Na@C
			strain[:, ind] = (B@de).T.squeeze()
			stress[:, ind] = (model.D@(strain[:, ind].reshape((-1, 1)))).T.squeeze()

			ind += 1

	print("\tx-coord\t\t\ty-coord\t\t\ts_xx\t\t\ts_yy\t\t\ts_xy")
	for i in range(number_gp):
		print("\t{}\t\t{}\t\t{}\t\t{}\t\t{}".format(X[i, 0], X[i, 1], stress[0, i], stress[1, i], stress[2, i]))
コード例 #6
0
def Elast2DElem(e):
    """
	Calculate element stiffness matrix and element nodal body force vector

	Args:
		e : (int) element number

	Returns: ke, fe
		ke : (numpy(nen,nen)) element stiffness matrix
		fe : (numpy(nen,1)) element nodal force vector
	"""
    ke = np.zeros((model.nen * model.ndof, model.nen * model.ndof))
    fe = np.zeros((model.nen * model.ndof, 1))

    # get coordinates of element nodes
    je = model.IEN[:, e] - 1
    C = np.array([model.x[je], model.y[je]]).T

    # get gauss points and weights
    w, gp = gauss(model.ngp)

    # compute element stiffness matrix and element nodal force vector
    for i in range(model.ngp):
        for j in range(model.ngp):
            eta = gp[i]
            psi = gp[j]
            # shape functions matrix
            N = NmatElast2D(eta, psi)
            # derivative of the shape functions
            B, detJ = BmatElast2D(eta, psi, C)

            # element stiffness matrix
            ke = ke + w[i] * w[j] * detJ * (B.T @ model.D @ B)
            be = N @ (model.b[:, e].reshape((-1, 1)))
            fe = fe + w[i] * w[j] * detJ * (N.T @ be)
    return ke, fe
コード例 #7
0
ファイル: Exact.py プロジェクト: yibaohu-outlook/FEM-Python
def ErrorNorm_ConcentratedForce(flag):
    """
    Calculate and print the error norm (L2 and energy norm) of the elastic
    bar under concentrated force and body force for convergence study

    Args:
        flag: (bool) whether x0 = 15*l/16 is the node or not
    """
    ngp = 3
    [w, gp] = gauss(ngp)  # extract Gauss points and weights

    E = 10000.0
    A = 1.0
    l = 16.0  # the length of the bar is 2*l
    c = 1.0  # body force
    P1 = 100.0  # The concentrated force at the right end of the bar
    P2 = 100.0  # The concentrated force at x0 = 15l/16
    x0 = 15 * l / 16

    L2Norm = 0
    EnNorm = 0

    L2NormEx = 0
    EnNormEx = 0

    P_element_index = int(x0 / (2 * l / model.nel))

    for e in range(model.nel):

        if not flag:
            # The element which contains the concentrated force needs to be
            # handled individually when the force is not on a node
            if e == P_element_index:
                continue

        de = model.d[model.LM[:, e] - 1]  # extract element nodal displacements
        IENe = model.IEN[:, e] - 1  # extract local connectivity information
        xe = model.x[IENe]  # extract element x coordinates
        J = (xe[-1] - xe[0]) / 2  # compute Jacobian

        for i in range(ngp):
            xt = 0.5 * (xe[0] + xe[-1]
                        ) + J * gp[i]  # Gauss points in physical coordinates

            N = Nmatrix1D(xt, xe)  # shape functions matrix
            B = Bmatrix1D(xt, xe)  # derivative of shape functions matrix

            Ee = N @ model.E[IENe]  # Young's modulus at element gauss points

            uh = N @ de  # displacement at gauss point
            # Exact displacement
            if xt < x0:
                uex = c * (-xt**3 / 6 +
                           2 * l**2 * xt) / A / E + (P1 + P2) * xt / A / E
            else:
                uex = c * (
                    -xt**3 / 6 + 2 * l**2 *
                    xt) / A / E + P1 * xt / A / E + 15 * P2 * l / 16 / A / E
            L2Norm += J * w[i] * (uex - uh)**2
            L2NormEx += J * w[i] * (uex)**2

            sh = B @ de  # strain at Gauss points
            # Exact strain
            if xt < x0:
                sex = c * (-xt**2 / 2 + 2 * l**2) / A / E + (P1 + P2) / A / E
            else:
                sex = c * (-xt**2 / 2 + 2 * l**2) / A / E + P1 / A / E
            EnNorm += 0.5 * J * w[i] * Ee * (sex - sh)**2
            EnNormEx += 0.5 * J * w[i] * Ee * (sex)**2

    if not flag:
        # handle the element of P_element_index
        de = model.d[model.LM[:, P_element_index] -
                     1]  # extract element nodal displacements
        IENe = model.IEN[:,
                         P_element_index] - 1  # extract local connectivity information
        xe = model.x[IENe]  # extract element x coordinates

        for i in range(ngp):
            J = (x0 - xe[0]) / 2  # compute Jacobian
            xt = 0.5 * (xe[0] +
                        x0) + J * gp[i]  # Gauss points in physical coordinates

            N = Nmatrix1D(xt, xe)  # shape functions matrix
            B = Bmatrix1D(xt, xe)  # derivative of shape functions matrix

            Ee = N @ model.E[IENe]  # Young's modulus at element gauss points

            uh = N @ de  # displacement at gauss point
            uex = c * (-xt**3 / 6 + 2 * l**2 * xt) / A / E + (P1 +
                                                              P2) * xt / A / E
            L2Norm += J * w[i] * (uex - uh)**2
            L2NormEx += J * w[i] * (uex)**2

            sh = B @ de  # strain at Gauss points
            sex = c * (-xt**2 / 2 + 2 * l**2) / A / E + (P1 + P2) / A / E
            EnNorm += 0.5 * J * w[i] * Ee * (sex - sh)**2
            EnNormEx += 0.5 * J * w[i] * Ee * (sex)**2

        for i in range(ngp):
            J = (xe[-1] - x0) / 2  # compute Jacobian
            xt = 0.5 * (x0 + xe[-1]
                        ) + J * gp[i]  # Gauss points in physical coordinates

            N = Nmatrix1D(xt, xe)  # shape functions matrix
            B = Bmatrix1D(xt, xe)  # derivative of shape functions matrix

            Ee = N @ model.E[IENe]  # Young's modulus at element gauss points

            uh = N @ de  # displacement at gauss point
            uex = c * (-xt**3 / 6 + 2 * l**2 *
                       xt) / A / E + P1 * xt / A / E + 15 * P2 * l / 16 / A / E
            L2Norm += J * w[i] * (uex - uh)**2
            L2NormEx += J * w[i] * (uex)**2

            sh = B @ de  # strain at Gauss points
            sex = c * (-xt**2 / 2 + 2 * l**2) / A / E + P1 / A / E
            EnNorm += 0.5 * J * w[i] * Ee * (sex - sh)**2
            EnNormEx += 0.5 * J * w[i] * Ee * (sex)**2

    L2Norm = sqrt(L2Norm)
    L2NormEx = sqrt(L2NormEx)

    EnNorm = sqrt(EnNorm)
    EnNormEx = sqrt(EnNormEx)

    # print stresses at element gauss points
    print('\nError norms')
    print('%13s %13s %13s %13s %13s' %
          ('h', 'L2Norm', 'L2NormRel', 'EnNorm', 'EnNormRel'))
    print(
        '%13.6E %13.6E %13.6E %13.6E %13.6E\n' %
        (2 / model.nel, L2Norm, L2Norm / L2NormEx, EnNorm, EnNorm / EnNormEx))

    return 2 * l / model.nel, L2Norm, EnNorm