def addCoord(coord, edge, coordinates): twinEdge = edge.twin numbering = twinEdge.incidentFace.element.numbering if len(numbering) > 4: if len(numbering) == 6: temp = [1, 2, 0] ind = 0 for i in range(3): if AMORE.isEqual(twinEdge.origin,coordinates[numbering[i]]) and \ AMORE.isEqual(twinEdge.destination,coordinates[numbering[temp[i]]]): if coordinates[numbering[i + 3]] is not None: tempCoord = np.array([ coordinates[numbering[temp[i]]], coordinates[numbering[i]], coordinates[numbering[i + 3]] ]) tempCoord = pM.quadInterpolation(tempCoord, 5) for j in range(1, len(tempCoord)): coord.append([tempCoord[j, 0], tempCoord[j, 1]]) else: coord.append([edge.destination.x, edge.destination.y]) ind = 1 break if ind == 0: coord.append([edge.destination.x, edge.destination.y]) elif len(numbering) == 9: temp = [1, 2, 3, 0] ind = 0 for i in range(4): if AMORE.isEqual(twinEdge.origin,coordinates[numbering[i]]) and \ AMORE.isEqual(twinEdge.destination,coordinates[numbering[temp[i]]]): if coordinates[numbering[i + 4]] is not None: tempCoord = np.array([ coordinates[numbering[temp[i]]], coordinates[numbering[i]], coordinates[numbering[i + 4]] ]) tempCoord = pM.quadInterpolation(tempCoord, 5) for j in range(1, len(tempCoord)): coord.append([tempCoord[j, 0], tempCoord[j, 1]]) else: coord.append([edge.destination.x, edge.destination.y]) ind = 1 break if ind == 0: coord.append([edge.destination.x, edge.destination.y]) else: raise ValueError else: coord.append([edge.destination.x, edge.destination.y])
def plotMesh(coordinates, meshes, fmt, lineWidth, markerSize): """Plot a two-dimensional mesh.""" # fmt: The format string # lineWidth # markerSize plt.rc('text', usetex=True) plt.rc('font', family='serif') if len(meshes) == 1: elements = meshes[0] for i in elements: coord = AMORE.getCoord(coordinates, i) plotElement(coord, fmt, lineWidth, markerSize) else: colorList = ['b', 'r', 'g', 'c', 'm'] assert len(colorList) >= len( meshes) # I don't see any need for using more than 5 meshes. count = 0 for i in range(len(colorList)): if colorList[i] == fmt[0]: count = i break if count != 0: colorList[0], colorList[count] = colorList[count], colorList[0] fmtList = [None] * len(meshes) fmtList[0] = fmt for i in range(1, len(fmtList)): fmtList[i] = colorList[i] + fmt[1:len(fmt)] for k in range(len(meshes)): newMarkerSize = markerSize * (0.7)**(k > 0) elements = meshes[k] for i in elements: coord = AMORE.getCoord(coordinates, i) plotElement(coord, fmtList[k], lineWidth, newMarkerSize) plt.axis('off') plt.axis('equal') plt.title('Input Mesh') plt.savefig('Input Mesh.pdf', bbox_inches='tight') plt.show()
def quadraticFE(inputData): """The solver for second order finite elements (9-node quads & 6-node triangles).""" startTime=time.time() parameters=inputData[0] # Material matrices. materialList=inputData[6] materialMatrix=[None]*len(materialList) for i in range(len(materialList)): materialMatrix[i]=twoDMaterialMatrix(materialList[i],parameters[1]) # Assemble stiffness matrix. coordinates=inputData[5] meshes=inputData[3] materialMeshList=inputData[4] nodeElements=toDC.nodeElementList(coordinates,meshes) Iglo=[] Jglo=[] Vglo=[] for i in range(len(meshes[0])): coord=AMORE.getCoord(coordinates,meshes[0][i]) if len(meshes[0][i])==6: Kloc=stiffnessMatrix.triQuadFE(coord,materialMatrix[materialMeshList[0][i]]) elif len(meshes[0][i])==9: Kloc=stiffnessMatrix.quadQuadFE(coord,materialMatrix[materialMeshList[0][i]]) else: raise ValueError("Wrong element numbering!") Iloc,Jloc,Vloc=stiffnessMatrix.sparsifyElementMatrix(Kloc,meshes[0][i]) Iglo.extend(Iloc) Jglo.extend(Jloc) Vglo.extend(Vloc) Iglo=np.array(Iglo,dtype=int) Jglo=np.array(Jglo,dtype=int) Vglo=np.array(Vglo,dtype='d') Kglo=scipy.sparse.coo_matrix((Vglo,(Iglo,Jglo)),shape=(2*len(coordinates),2*len(coordinates))).tocsr() print("Assembling stiffness matrix costs %s seconds."%(time.time()-startTime)) startTime=time.time() # Force term. indForce=inputData[-2] if indForce[0]: # Body force is imposed. pass forceList=inputData[-1] nInt=3 if indForce[1]: nInt+=2 # Customized boundary force. pos,wei=numericalIntegration.gaussQuad(nInt) fglo=np.zeros((2*len(coordinates),1)) for i in range(len(forceList)//2): node1=forceList[2*i][0] node2=forceList[2*i+1][0] # length=lenEdge(coordinates[node1],coordinates[node2]) # Find the element. elementPosition=(set(nodeElements[node1]) & set(nodeElements[node2])).pop() numbering=meshes[elementPosition[0]][elementPosition[1]] node3=findMidNode(numbering,node1,node2) force1=np.array([forceList[2*i][1:3]]).transpose() force2=np.array([forceList[2*i+1][1:3]]).transpose() floc=np.zeros((6,1)) coord=np.array([coordinates[node1],coordinates[node2],[0.0,0.0]]) if coordinates[node3]: coord[2,:]=np.array(coordinates[node3]) else: coord[2,:]=0.5*(coord[0,:]+coord[1,:]) for j in range(nInt): # Only support linear force distribution. # Otherwise, use customized boundary force. Nmat=shapeFunction.oneDLinear(pos[j]) force=Nmat[0,0]*force1+Nmat[0,2]*force2 quadNmat,Jacobian=shapeFunction.oneDQuadratic(pos[j],coord) floc+=wei[j]*Jacobian*np.matmul(quadNmat.transpose(),force) fglo[2*node1:2*node1+2,0]+=floc[0:2,0] fglo[2*node2:2*node2+2,0]+=floc[2:4,0] fglo[2*node3:2*node3+2,0]+=floc[4:6,0] print("Calculating force term costs %s seconds."%(time.time()-startTime)) startTime=time.time() # Impose constraints. fixList=np.zeros((2*len(coordinates),1)) fixIndexList=np.zeros((2*len(coordinates),1),dtype=int) constraintList=inputData[-3] # Very important!!! Sort the constraints!!! constraintList.sort(key=lambda item:item[0]) for i in constraintList: if i[1]: fixList[2*i[0]]=i[3] fixIndexList[2*i[0]]=1 if i[2]: fixList[2*i[0]+1]=i[4] fixIndexList[2*i[0]+1]=1 # Solve. fglo-=(Kglo.dot(fixList)) Kglo_complete=Kglo.copy() Kglo=Kglo.tolil() count=0 for i in constraintList: if i[1]: delete_row_lil(Kglo,2*i[0]-count) fglo=np.delete(fglo,2*i[0]-count) count+=1 if i[2]: delete_row_lil(Kglo,2*i[0]+1-count) fglo=np.delete(fglo,2*i[0]+1-count) count+=1 Kglo=Kglo.transpose() count=0 for i in constraintList: if i[1]: delete_row_lil(Kglo,2*i[0]-count) count+=1 if i[2]: delete_row_lil(Kglo,2*i[0]+1-count) count+=1 print("Imposing constraints costs %s seconds."%(time.time()-startTime)) startTime=time.time() Kglo=Kglo.tocsc() # factor=cholesky(Kglo) # disp=factor(fglo) disp=spsolve(Kglo,fglo) print("Solving the linear system costs %s seconds."%(time.time()-startTime)) # The complete displacement solution: displacement=np.zeros((2*len(coordinates),1)) count=0 for i in range(2*len(coordinates)): if fixIndexList[i]: displacement[i]=fixList[i] count+=1 else: displacement[i]=disp[i-count] energy=0.5*displacement.transpose()@Kglo_complete@displacement return displacement,energy
def ICMFE(inputData): """The solver for (4-node) ICM finite elements. Warning: The code is only for squares. For general quadrilaterals, the formulation needs to be modified to pass patch tests.""" startTime=time.time() parameters=inputData[0] # Material matrices. materialList=inputData[6] materialMatrix=[None]*len(materialList) for i in range(len(materialList)): materialMatrix[i]=twoDMaterialMatrix(materialList[i],parameters[1]) # Assemble stiffness matrix. coordinates=inputData[5] meshes=inputData[3] materialMeshList=inputData[4] Iglo=[] Jglo=[] Vglo=[] for i in range(len(meshes[0])): coord=AMORE.getCoord(coordinates,meshes[0][i]) if len(meshes[0][i])==4: Kloc,_,_=stiffnessMatrix.ICMFE(coord,materialMatrix[materialMeshList[0][i]]) else: raise ValueError("Wrong element numbering!") Iloc,Jloc,Vloc=stiffnessMatrix.sparsifyElementMatrix(Kloc,meshes[0][i]) Iglo.extend(Iloc) Jglo.extend(Jloc) Vglo.extend(Vloc) Iglo=np.array(Iglo,dtype=int) Jglo=np.array(Jglo,dtype=int) Vglo=np.array(Vglo,dtype='d') Kglo=scipy.sparse.coo_matrix((Vglo,(Iglo,Jglo)),shape=(2*len(coordinates),2*len(coordinates))).tocsr() print("Assembling stiffness matrix costs %s seconds."%(time.time()-startTime)) startTime=time.time() # Force term. indForce=inputData[-2] if indForce[0]: # Body force is imposed. pass forceList=inputData[-1] nInt=2 if indForce[1]: nInt+=3 # Customized boundary force. pos,wei=numericalIntegration.gaussQuad(nInt) fglo=np.zeros((2*len(coordinates),1)) for i in range(len(forceList)//2): node1=forceList[2*i][0] node2=forceList[2*i+1][0] length=lenEdge(coordinates[node1],coordinates[node2]) force1=np.array([forceList[2*i][1:3]]).transpose() force2=np.array([forceList[2*i+1][1:3]]).transpose() floc=np.zeros((4,1)) for j in range(nInt): Nmat=shapeFunction.oneDLinear(pos[j]) force=Nmat[0,0]*force1+Nmat[0,2]*force2 floc+=0.5*wei[j]*length*np.matmul(Nmat.transpose(),force) fglo[2*node1:2*node1+2,0]+=floc[0:2,0] fglo[2*node2:2*node2+2,0]+=floc[2:4,0] print("Calculating force term costs %s seconds."%(time.time()-startTime)) startTime=time.time() # Impose constraints. fixList=np.zeros((2*len(coordinates),1)) fixIndexList=np.zeros((2*len(coordinates),1),dtype=int) constraintList=inputData[-3] # Very important!!! Sort the constraints!!! constraintList.sort(key=lambda item:item[0]) for i in constraintList: if i[1]: fixList[2*i[0]]=i[3] fixIndexList[2*i[0]]=1 if i[2]: fixList[2*i[0]+1]=i[4] fixIndexList[2*i[0]+1]=1 # Solve. fglo-=(Kglo.dot(fixList)) Kglo_complete=Kglo.copy() Kglo=Kglo.tolil() count=0 for i in constraintList: if i[1]: delete_row_lil(Kglo,2*i[0]-count) fglo=np.delete(fglo,2*i[0]-count) count+=1 if i[2]: delete_row_lil(Kglo,2*i[0]+1-count) fglo=np.delete(fglo,2*i[0]+1-count) count+=1 Kglo=Kglo.transpose() count=0 for i in constraintList: if i[1]: delete_row_lil(Kglo,2*i[0]-count) count+=1 if i[2]: delete_row_lil(Kglo,2*i[0]+1-count) count+=1 print("Imposing constraints costs %s seconds."%(time.time()-startTime)) startTime=time.time() Kglo=Kglo.tocsc() print("Number of non-zero sparse matrix entries = %s."%Kglo.count_nonzero()) # factor=cholesky(Kglo) # disp=factor(fglo) disp=spsolve(Kglo,fglo) print("Solving the linear system costs %s seconds."%(time.time()-startTime)) # The complete displacement solution: displacement=np.zeros((2*len(coordinates),1)) count=0 for i in range(2*len(coordinates)): if fixIndexList[i]: displacement[i]=fixList[i] count+=1 else: displacement[i]=disp[i-count] energy=0.5*displacement.transpose()@Kglo_complete@displacement return displacement,energy
numberOfMesh) planeSweepMeshes.rhoCalculation(polygons) for i in polygons: triangulation.polygonTriangulation(i) print("Overlapping calculation costs %s seconds." % (time.time() - startTime)) startTime = time.time() if parameters[0] == 1: # We use 3-node FE or 4-node FE for the boundary meshes. print( "Using 4-node finite elements for the interior and lower-order finite elements for the boundary meshes." ) displacement, energy = AMORE.lowerOrderAMORE( inputData, overlappingMesh, polygons, nodeElementsPartial) print("FE solver costs %s seconds in total." % (time.time() - startTime)) writeSolution.writeDisplacement(displacement, energy, inputFileName) elif parameters[0] == 2: # We use 6-node FE or 9-node FE for the boundary meshes. print( "Using 4-node finite elements for the interior and quadratic finite elements for the boundary meshes." ) displacement, energy, materialMatrix = AMORE.quadraticAMORE( inputData, overlappingMesh, polygons, nodeElementsPartial) print("FE solver costs %s seconds in total." % (time.time() - startTime)) writeSolution.writeDisplacement(displacement, energy,
def writeSampleData2D(coordinates, meshes, polygons, displacement, materialMatrix, materialMeshList, component='u', nSampling=None, solver=3): """If component='u', write down the u-displacements; If component='v', write down the v-displacements; If component='Sxx', write down stress_xx; ... 'Sxy', ... stress_xy; ... 'Syy', ... stress_yy; ... 'All', ... all displacement and stress components. """ if nSampling is None: nSampling = 5 file = open("SampleData.txt", "w") print("%s sampling points are used in each direction." % nSampling) limit = [math.inf, -math.inf] minCoord = [0.0, 0.0] maxCoord = [0.0, 0.0] if component == 'u': for i in range(len(meshes)): for j in range(len(meshes[i])): if meshes[i][j]: DMatrix = materialMatrix[materialMeshList[i][j]] coord = AMORE.getCoord(coordinates, meshes[i][j]) X, Y, Z, _, _, _, _ = plotResults.getGraphDataFE( coord, meshes[i][j], displacement, DMatrix, nSampling, solver) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) if polygons: for i in polygons: if i.triangles: for j in i.triangles: for k in i.incidentElements: if k: position = k.position break DMatrix = materialMatrix[materialMeshList[position[0]][ position[1]]] coord = AMORE.coordCurvedTriangle( j, i.incidentElements, coordinates) X, Y, Z, _, _, _, _ = plotResults.getGraphDataOFE( coord, coordinates, i.incidentElements, j, displacement, DMatrix, nSampling) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) else: for k in i.incidentElements: if k: position = k.position break DMatrix = materialMatrix[materialMeshList[position[0]][ position[1]]] numbering = plotResults.getNumbering(i.incidentElements) coord = AMORE.getCoord(coordinates, numbering) X, Y, Z, _, _, _, _ = plotResults.getGraphDataFE( coord, numbering, displacement, DMatrix, nSampling, solver) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) elif component == 'v': for i in range(len(meshes)): for j in range(len(meshes[i])): if meshes[i][j]: DMatrix = materialMatrix[materialMeshList[i][j]] coord = AMORE.getCoord(coordinates, meshes[i][j]) X, Y, _, Z, _, _, _ = plotResults.getGraphDataFE( coord, meshes[i][j], displacement, DMatrix, nSampling, solver) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) if polygons: for i in polygons: if i.triangles: for j in i.triangles: for k in i.incidentElements: if k: position = k.position break DMatrix = materialMatrix[materialMeshList[position[0]][ position[1]]] coord = AMORE.coordCurvedTriangle( j, i.incidentElements, coordinates) X, Y, _, Z, _, _, _ = plotResults.getGraphDataOFE( coord, coordinates, i.incidentElements, j, displacement, DMatrix, nSampling) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) else: for k in i.incidentElements: if k: position = k.position break DMatrix = materialMatrix[materialMeshList[position[0]][ position[1]]] numbering = plotResults.getNumbering(i.incidentElements) coord = AMORE.getCoord(coordinates, numbering) X, Y, _, Z, _, _, _ = plotResults.getGraphDataFE( coord, numbering, displacement, DMatrix, nSampling, solver) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) elif component == 'Sxx': for i in range(len(meshes)): for j in range(len(meshes[i])): if meshes[i][j]: DMatrix = materialMatrix[materialMeshList[i][j]] coord = AMORE.getCoord(coordinates, meshes[i][j]) X, Y, _, _, Z, _, _ = plotResults.getGraphDataFE( coord, meshes[i][j], displacement, DMatrix, nSampling, solver) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) if polygons: for i in polygons: if i.triangles: for j in i.triangles: for k in i.incidentElements: if k: position = k.position break DMatrix = materialMatrix[materialMeshList[position[0]][ position[1]]] coord = AMORE.coordCurvedTriangle( j, i.incidentElements, coordinates) X, Y, _, _, Z, _, _ = plotResults.getGraphDataOFE( coord, coordinates, i.incidentElements, j, displacement, DMatrix, nSampling) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) else: for k in i.incidentElements: if k: position = k.position break DMatrix = materialMatrix[materialMeshList[position[0]][ position[1]]] numbering = plotResults.getNumbering(i.incidentElements) coord = AMORE.getCoord(coordinates, numbering) X, Y, _, _, Z, _, _ = plotResults.getGraphDataFE( coord, numbering, displacement, DMatrix, nSampling, solver) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) elif component == 'Sxy': for i in range(len(meshes)): for j in range(len(meshes[i])): if meshes[i][j]: DMatrix = materialMatrix[materialMeshList[i][j]] coord = AMORE.getCoord(coordinates, meshes[i][j]) X, Y, _, _, _, _, Z = plotResults.getGraphDataFE( coord, meshes[i][j], displacement, DMatrix, nSampling, solver) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) if polygons: for i in polygons: if i.triangles: for j in i.triangles: for k in i.incidentElements: if k: position = k.position break DMatrix = materialMatrix[materialMeshList[position[0]][ position[1]]] coord = AMORE.coordCurvedTriangle( j, i.incidentElements, coordinates) X, Y, _, _, _, _, Z = plotResults.getGraphDataOFE( coord, coordinates, i.incidentElements, j, displacement, DMatrix, nSampling) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) else: for k in i.incidentElements: if k: position = k.position break DMatrix = materialMatrix[materialMeshList[position[0]][ position[1]]] numbering = plotResults.getNumbering(i.incidentElements) coord = AMORE.getCoord(coordinates, numbering) X, Y, _, _, _, _, Z = plotResults.getGraphDataFE( coord, numbering, displacement, DMatrix, nSampling, solver) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) elif component == 'Syy': for i in range(len(meshes)): for j in range(len(meshes[i])): if meshes[i][j]: DMatrix = materialMatrix[materialMeshList[i][j]] coord = AMORE.getCoord(coordinates, meshes[i][j]) X, Y, _, _, _, Z, _ = plotResults.getGraphDataFE( coord, meshes[i][j], displacement, DMatrix, nSampling, solver) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) if polygons: for i in polygons: if i.triangles: for j in i.triangles: for k in i.incidentElements: if k: position = k.position break DMatrix = materialMatrix[materialMeshList[position[0]][ position[1]]] coord = AMORE.coordCurvedTriangle( j, i.incidentElements, coordinates) X, Y, _, _, _, Z, _ = plotResults.getGraphDataOFE( coord, coordinates, i.incidentElements, j, displacement, DMatrix, nSampling) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) else: for k in i.incidentElements: if k: position = k.position break DMatrix = materialMatrix[materialMeshList[position[0]][ position[1]]] numbering = plotResults.getNumbering(i.incidentElements) coord = AMORE.getCoord(coordinates, numbering) X, Y, _, _, _, Z, _ = plotResults.getGraphDataFE( coord, numbering, displacement, DMatrix, nSampling, solver) writeAndUpdate(limit, minCoord, maxCoord, X, Y, Z, nSampling, file) elif component == 'All': limitU = [math.inf, -math.inf] minCoordU = [0.0, 0.0] maxCoordU = [0.0, 0.0] limitV = [math.inf, -math.inf] minCoordV = [0.0, 0.0] maxCoordV = [0.0, 0.0] limitSxx = [math.inf, -math.inf] minCoordSxx = [0.0, 0.0] maxCoordSxx = [0.0, 0.0] limitSyy = [math.inf, -math.inf] minCoordSyy = [0.0, 0.0] maxCoordSyy = [0.0, 0.0] limitSxy = [math.inf, -math.inf] minCoordSxy = [0.0, 0.0] maxCoordSxy = [0.0, 0.0] limitMises = [math.inf, -math.inf] minCoordMises = [0.0, 0.0] maxCoordMises = [0.0, 0.0] for i in range(len(meshes)): for j in range(len(meshes[i])): if meshes[i][j]: DMatrix = materialMatrix[materialMeshList[i][j]] coord = AMORE.getCoord(coordinates, meshes[i][j]) X, Y, U, V, Sxx, Syy, Sxy = plotResults.getGraphDataFE( coord, meshes[i][j], displacement, DMatrix, nSampling, solver) writeAndUpdate(limitU, minCoordU, maxCoordU, X, Y, U, nSampling, file) writeAndUpdate(limitV, minCoordV, maxCoordV, X, Y, V, nSampling, file) writeAndUpdate(limitSxx, minCoordSxx, maxCoordSxx, X, Y, Sxx, nSampling, file) writeAndUpdate(limitSyy, minCoordSyy, maxCoordSyy, X, Y, Syy, nSampling, file) writeAndUpdate(limitSxy, minCoordSxy, maxCoordSxy, X, Y, Sxy, nSampling, file) Mises = np.zeros((nSampling, nSampling)) for ii in range(nSampling): for jj in range(nSampling): Mises[ii, jj] = math.sqrt(Sxx[ii, jj]**2 + Syy[ii, jj]**2 + 3 * Sxy[ii, jj]**2 - Sxx[ii, jj] * Syy[ii, jj]) writeAndUpdate(limitMises, minCoordMises, maxCoordMises, X, Y, Mises, nSampling, file) if polygons: for i in polygons: if i.triangles: for j in i.triangles: for k in i.incidentElements: if k: position = k.position break DMatrix = materialMatrix[materialMeshList[position[0]][ position[1]]] coord = AMORE.coordCurvedTriangle( j, i.incidentElements, coordinates) if abs(triArea(coord)) < 1e-6: continue # These small triangles may bring much error to the stress results. X, Y, U, V, Sxx, Syy, Sxy = plotResults.getGraphDataOFE( coord, coordinates, i.incidentElements, j, displacement, DMatrix, nSampling) writeAndUpdate(limitU, minCoordU, maxCoordU, X, Y, U, nSampling, file) writeAndUpdate(limitV, minCoordV, maxCoordV, X, Y, V, nSampling, file) writeAndUpdate(limitSxx, minCoordSxx, maxCoordSxx, X, Y, Sxx, nSampling, file) writeAndUpdate(limitSyy, minCoordSyy, maxCoordSyy, X, Y, Syy, nSampling, file) writeAndUpdate(limitSxy, minCoordSxy, maxCoordSxy, X, Y, Sxy, nSampling, file) Mises = np.zeros((nSampling, nSampling)) for ii in range(nSampling): for jj in range(nSampling): Mises[ii, jj] = math.sqrt(Sxx[ii, jj]**2 + Syy[ii, jj]**2 + 3 * Sxy[ii, jj]**2 - Sxx[ii, jj] * Syy[ii, jj]) writeAndUpdate(limitMises, minCoordMises, maxCoordMises, X, Y, Mises, nSampling, file) else: for k in i.incidentElements: if k: position = k.position break DMatrix = materialMatrix[materialMeshList[position[0]][ position[1]]] numbering = plotResults.getNumbering(i.incidentElements) coord = AMORE.getCoord(coordinates, numbering) X, Y, U, V, Sxx, Syy, Sxy = plotResults.getGraphDataFE( coord, numbering, displacement, DMatrix, nSampling, solver) writeAndUpdate(limitU, minCoordU, maxCoordU, X, Y, U, nSampling, file) writeAndUpdate(limitV, minCoordV, maxCoordV, X, Y, V, nSampling, file) writeAndUpdate(limitSxx, minCoordSxx, maxCoordSxx, X, Y, Sxx, nSampling, file) writeAndUpdate(limitSyy, minCoordSyy, maxCoordSyy, X, Y, Syy, nSampling, file) writeAndUpdate(limitSxy, minCoordSxy, maxCoordSxy, X, Y, Sxy, nSampling, file) Mises = np.zeros((nSampling, nSampling)) for ii in range(nSampling): for jj in range(nSampling): Mises[ii, jj] = math.sqrt(Sxx[ii, jj]**2 + Syy[ii, jj]**2 + 3 * Sxy[ii, jj]**2 - Sxx[ii, jj] * Syy[ii, jj]) writeAndUpdate(limitMises, minCoordMises, maxCoordMises, X, Y, Mises, nSampling, file) else: raise ValueError if component != 'All': print("The range of " + component + " is [%s,%s]." % (limit[0], limit[1])) print("Location of the minimum is [%s,%s]." % (minCoord[0], minCoord[1])) print("Location of the maximum is [%s,%s]." % (maxCoord[0], maxCoord[1])) else: print("The range of u is [%s,%s]." % (limitU[0], limitU[1])) print("Location of the minimum is [%s,%s]." % (minCoordU[0], minCoordU[1])) print("Location of the maximum is [%s,%s]." % (maxCoordU[0], maxCoordU[1])) print("The range of v is [%s,%s]." % (limitV[0], limitV[1])) print("Location of the minimum is [%s,%s]." % (minCoordV[0], minCoordV[1])) print("Location of the maximum is [%s,%s]." % (maxCoordV[0], maxCoordV[1])) print("The range of Sxx is [%s,%s]." % (limitSxx[0], limitSxx[1])) print("Location of the minimum is [%s,%s]." % (minCoordSxx[0], minCoordSxx[1])) print("Location of the maximum is [%s,%s]." % (maxCoordSxx[0], maxCoordSxx[1])) print("The range of Syy is [%s,%s]." % (limitSyy[0], limitSyy[1])) print("Location of the minimum is [%s,%s]." % (minCoordSyy[0], minCoordSyy[1])) print("Location of the maximum is [%s,%s]." % (maxCoordSyy[0], maxCoordSyy[1])) print("The range of Sxy is [%s,%s]." % (limitSxy[0], limitSxy[1])) print("Location of the minimum is [%s,%s]." % (minCoordSxy[0], minCoordSxy[1])) print("Location of the maximum is [%s,%s]." % (maxCoordSxy[0], maxCoordSxy[1])) print("The range of Mises stress is [%s,%s]." % (limitMises[0], limitMises[1])) print("Location of the minimum is [%s,%s]." % (minCoordMises[0], minCoordMises[1])) print("Location of the maximum is [%s,%s]." % (maxCoordMises[0], maxCoordMises[1])) file = open("nSampling.txt", "w") file.write(str(nSampling)) file.write("\n") if component != 'All': file.write(str(1)) else: file.write( str(6) ) # On Dec 11th, changed 5 to 6 since we want to output Mises stress as well.
def getGraphDataOFE(coord, coordinates, incidentElements, edge, displacement, DMatrix, nSampling): X = np.zeros((nSampling, nSampling)) Y = np.zeros((nSampling, nSampling)) U = np.zeros((nSampling, nSampling)) V = np.zeros((nSampling, nSampling)) Sxx = np.zeros((nSampling, nSampling)) Syy = np.zeros((nSampling, nSampling)) Sxy = np.zeros((nSampling, nSampling)) r = np.linspace(-1, 1, nSampling) s = np.linspace(-1, 1, nSampling) if len(coord) == 3: newCoord = np.zeros((4, 2)) newCoord[0:3, :] = coord newCoord[3, :] = coord[2, :] for i in range(nSampling): for j in range(nSampling): Nmat, _ = invShapeFunction.quadShapeFunction([r[i], s[j]]) xy = (Nmat @ newCoord).reshape(-1) X[i, j] = xy[0] Y[i, j] = xy[1] isoCoord = invShapeFunction.invTri(coord, xy) for k in range(len(incidentElements)): if incidentElements[k]: numbering = incidentElements[k].numbering fNumbering = getFullNumber(numbering) tempCoord = AMORE.getCoord(coordinates, numbering) rho = AMORE.getRho(edge, k) LCmat = stiffnessMatrix.getLC(coord, rho) rhoValue = isoCoord[0] * rho[0] + isoCoord[1] * rho[ 1] + (1.0 - isoCoord[0] - isoCoord[1]) * rho[2] if len(tempCoord) == 4: newIsoCoord = invShapeFunction.invQuad( tempCoord, xy) Nmat, Bmat, _ = shapeFunction.shapeQuadFE( tempCoord, newIsoCoord[0], newIsoCoord[1]) localDisp = rhoValue * Nmat @ displacement[ fNumbering] localStress = rhoValue * DMatrix @ Bmat @ displacement[ fNumbering] + DMatrix @ LCmat @ Nmat @ displacement[ fNumbering] U[i, j] += localDisp[0] V[i, j] += localDisp[1] Sxx[i, j] += localStress[0] Syy[i, j] += localStress[1] Sxy[i, j] += localStress[2] elif len(tempCoord) == 9: newIsoCoord = invShapeFunction.invQuadQuad( tempCoord, xy) Nmat, Bmat, _ = shapeFunction.shapeQuadQuadFE( tempCoord, newIsoCoord[0], newIsoCoord[1]) localDisp = rhoValue * Nmat @ displacement[ fNumbering] localStress = rhoValue * DMatrix @ Bmat @ displacement[ fNumbering] + DMatrix @ LCmat @ Nmat @ displacement[ fNumbering] U[i, j] += localDisp[0] V[i, j] += localDisp[1] Sxx[i, j] += localStress[0] Syy[i, j] += localStress[1] Sxy[i, j] += localStress[2] else: raise ValueError elif len(coord) == 6: newCoord = np.zeros((9, 2)) newCoord[0:3, :] = coord[0:3, :] newCoord[6, :] = newCoord[3, :] = coord[2, :] newCoord[4, :] = coord[3, :] newCoord[5, :] = coord[4, :] newCoord[7, :] = newCoord[8, :] = coord[5, :] for i in range(nSampling): for j in range(nSampling): Nmat, _ = invShapeFunction.quadQuadShapeFunction([r[i], s[j]]) xy = (Nmat @ newCoord).reshape(-1) X[i, j] = xy[0] Y[i, j] = xy[1] isoCoord = invShapeFunction.invTriQuad(coord, xy) triNmat, _ = invShapeFunction.triQuadShapeFunction(isoCoord) for k in range(len(incidentElements)): if incidentElements[k]: numbering = incidentElements[k].numbering fNumbering = getFullNumber(numbering) tempCoord = AMORE.getCoord(coordinates, numbering) rho = np.zeros(6) rho[0:3] = AMORE.getRho(edge, k) LCmat = stiffnessMatrix.getLC(coord, rho[0:3], isoCoord[0], isoCoord[1]) temp = [1, 2, 0] for l in range(3): rho[l + 3] = (rho[l] + rho[temp[l]]) / 2 rhoValue = (triNmat @ rho)[0] if len(tempCoord) == 4: newIsoCoord = invShapeFunction.invQuad( tempCoord, xy) Nmat, Bmat, _ = shapeFunction.shapeQuadFE( tempCoord, newIsoCoord[0], newIsoCoord[1]) localDisp = rhoValue * Nmat @ displacement[ fNumbering] localStress = rhoValue * DMatrix @ Bmat @ displacement[ fNumbering] + DMatrix @ LCmat @ Nmat @ displacement[ fNumbering] U[i, j] += localDisp[0] V[i, j] += localDisp[1] Sxx[i, j] += localStress[0] Syy[i, j] += localStress[1] Sxy[i, j] += localStress[2] elif len(tempCoord) == 9: newIsoCoord = invShapeFunction.invQuadQuad( tempCoord, xy) Nmat, Bmat, _ = shapeFunction.shapeQuadQuadFE( tempCoord, newIsoCoord[0], newIsoCoord[1]) localDisp = rhoValue * Nmat @ displacement[ fNumbering] localStress = rhoValue * DMatrix @ Bmat @ displacement[ fNumbering] + DMatrix @ LCmat @ Nmat @ displacement[ fNumbering] U[i, j] += localDisp[0] V[i, j] += localDisp[1] Sxx[i, j] += localStress[0] Syy[i, j] += localStress[1] Sxy[i, j] += localStress[2] else: raise ValueError else: raise ValueError return X, Y, U, V, Sxx, Syy, Sxy