def solve(self): """Solve problem""" self.updateGeometry() self.updateMesh() self.ep = [self.ptype, self.t] self.D = cfc.hooke(self.ptype, self.E, self.v) cfu.info("Assembling system matrix...") nDofs = np.size(self.dofs) ex, ey = cfc.coordxtr(self.edof, self.coords, self.dofs) K = np.zeros([nDofs, nDofs]) for eltopo, elx, ely in zip(self.edof, ex, ey): Ke = cfc.planqe(elx, ely, self.ep, self.D) cfc.assem(eltopo, K, Ke) cfu.info("Solving equation system...") f = np.zeros([nDofs, 1]) bc = np.array([], 'i') bcVal = np.array([], 'i') bc, bcVal = cfu.applybc(self.bdofs, bc, bcVal, 5, 0.0, 0) cfu.applyforce(self.bdofs, f, 7, 10e5, 1) self.a, self.r = cfc.solveq(K, f, bc, bcVal) cfu.info("Computing element forces...") ed = cfc.extractEldisp(self.edof, self.a) self.vonMises = [] # For each element: for i in range(self.edof.shape[0]): # Determine element stresses and strains in the element. es, et = cfc.planqs(ex[i, :], ey[i, :], self.ep, self.D, ed[i, :]) # Calc and append effective stress to list. self.vonMises.append( sqrt( pow(es[0], 2) - es[0] * es[1] + pow(es[1], 2) + 3 * es[2]))
mesh.elType = 3 # Degrees of freedom per node. mesh.dofsPerNode = 2 # Factor that changes element sizes. mesh.elSizeFactor = 0.10 coords, edof, dofs, bdofs, elementmarkers = mesh.create() # ----- Solve problem nDofs = np.size(dofs) ex, ey = cfc.coordxtr(edof, coords, dofs) K = np.zeros([nDofs, nDofs]) for eltopo, elx, ely in zip(edof, ex, ey): Ke = cfc.planqe(elx, ely, ep, D) cfc.assem(eltopo, K, Ke) bc = np.array([], 'i') bcVal = np.array([], 'f') bc, bcVal = cfu.applybc(bdofs, bc, bcVal, left_support, 0.0, 0) bc, bcVal = cfu.applybc(bdofs, bc, bcVal, right_support, 0.0, 2) f = np.zeros([nDofs, 1]) cfu.applyforcetotal(bdofs, f, top_line, -10e5, 2) a, r = cfc.solveq(K, f, bc, bcVal) ed = cfc.extractEldisp(edof, a) vonMises = []
def executeFem(self): q = self.inputData.q B = self.inputData.B b = self.inputData.b hvec = self.inputData.hvec Mvec = self.inputData.Mvec kmat = self.inputData.kmat rhow = self.inputData.rhow hn = self.inputData.hn coords = self.outputData.coords edof = self.outputData.edof bdofs = self.outputData.bdofs elementmarkers = self.outputData.elementmarkers ex = self.outputData.ex ey = self.outputData.ey ndof=edof.max() # --- Definera randvillkor bc = np.array([],int) bcVal = np.array([],int) bc,bcVal = cfu.applybc(bdofs, bc, bcVal, 3, 0) bc,bcVal = cfu.applybc(bdofs, bc, bcVal, 2, 0) if self.inputData.perm == True: bc,bcVal = cfu.applybc(bdofs, bc, bcVal, (599+hn), 0) # --- Definiera materialmatris ep=[(1)] D=np.zeros([2,2]) # --- Skapa tom K-matris och f-vektor K = np.zeros([ndof,ndof]) C = np.zeros([ndof,ndof]) for eltopo, elx, ely, elMarker in zip(edof, ex, ey, elementmarkers): Dn = elMarker - 100 D[0,0] = kmat[Dn,0]*60*60*24*365.25 D[1,1] = kmat[Dn,1]*60*60*24*365.25 M = Mvec[Dn] Ke = cfc.flw2te(elx, ely, ep, D) Ce = tg.flwtec(elx,ely,rhow,M) cfc.assem(eltopo, K, Ke) cfc.assem(eltopo,C,Ce) a0 = tg.strdist(coords, ndof, q, B, b, hvec) a0 = np.asmatrix(a0) self.outputData.K = K self.outputData.C = C self.outputData.a0 = a0 self.outputData.bc = bc self.outputData.bcVal = bcVal
def solve(self): """Löser ett system av kontinuerliga balkar""" # Kontrollera att vi har materialegenskaper E = 2.1e9 A = 0.1 * 0.1 I = 0.1 * (0.1**3) / 12 if self.properties == None: self.properties = [] for i in enumerate(self.segments): self.properties.append([E, A, I]) # Beräkna antal element och frihetsgrader self.n_dofs = 0 self.n_elements = 0 for n in self.segments: self.n_dofs += n * 3 self.n_elements += n self.n_dofs += 3 # Global styvhetsmatris och lastvektor K = np.zeros((self.n_dofs, self.n_dofs), float) f = np.zeros((self.n_dofs, 1), float) # Elementtopologimatris. Varje rad representerar # ett element och dess frihetsgradskopplingar. edof = np.zeros((self.n_elements, 6), int) # Elementkoordinatsmatriser. Varje rad # anger koordinaterna för varje element ex = np.zeros((self.n_elements, 2), float) ey = np.zeros((self.n_elements, 2), float) # Elementegenskapsmatris. Anger elementegenskaperna # för varje element. ep = np.zeros((self.n_elements, 3), float) # Elementlastvektor. Anger elementlasten för varje # element. eq = np.zeros((self.n_elements, 2), float) # X-koordinat för varje beräkningspunkt. self.x = np.zeros((self.n_elements + 1), float) # Assemblera styvhetsmatrisen dof = 1 # Räknare för frihetsgrader el = 0 # Elementräknare self.support_dofs = [] # Randvillkor för varje upplag x = 0.0 # Aktuell x-koordinat för element for l, n, q, p in zip(self.lengths, self.segments, self.loads, self.properties): l_n = l / n self.support_dofs.append([dof, dof + 1, dof + 2]) for i in range(n): # Tilldela elementkoordinater ex[el, :] = [x, x + l_n] ey[el, :] = [0.0, 0.0] ep[el, :] = p eq[el, :] = [0.0, q] x += l_n # Beräkna element styvhet Ke, fe = cfc.beam2e(ex[el, :], ey[el, :], ep[el, :], eq[el, :]) # Tilldela elementtopologi etopo = np.array( [dof, dof + 1, dof + 2, dof + 3, dof + 4, dof + 5]) dof += 3 # Assemblera in element i global styvhetsmatris cfc.assem(etopo, K, Ke, f, fe) edof[el, :] = etopo el += 1 # Lägg till randvillkor för sista upplaget self.support_dofs.append([dof, dof + 1, dof + 2]) # Tillämpa randvillkor bc_prescr = [] bc_val = [] for dofs, support in zip(self.support_dofs, self.supports): if support == BeamModel.FIXED_Y: bc_prescr.append(dofs[1]) bc_val.append(0.0) elif support == BeamModel.FIXED_XY: bc_prescr.append(dofs[0]) bc_val.append(0.0) bc_prescr.append(dofs[1]) bc_val.append(0.0) elif support == BeamModel.FIXED_XYR: bc_prescr.append(dofs[0]) bc_val.append(0.0) bc_prescr.append(dofs[1]) bc_val.append(0.0) bc_prescr.append(dofs[2]) bc_val.append(0.0) # Lösning av ekvationssystem a, _ = cfc.solveq(K, f, np.asarray(bc_prescr), np.asarray(bc_val)) # Tilldela resultatvariabler self.y_displ = a[1::3] self.x_displ = a[0::3] self.rot = a[2::3] # Beräkna inre krafter och förskjutningar ed = cfc.extractEldisp(edof, a) # Skapa matris för de inre krafterna self.NVM = np.zeros((self.y_displ.shape[0], 3), float) # Beräkna elementkrafter i = 0 for el_displ, el_x, el_y, el_ep, el_eq in zip(ed, ex, ey, ep, eq): es = cfc.beam2s(el_x, el_y, el_ep, el_displ, el_eq) self.NVM[i, :] = es[0][0] self.x[i] = el_x[0] i += 1 # Sista positionen måste också tilldelas self.NVM[i, :] = es[0][1] self.x[i] = el_x[1]
elif numElementNodes == 9: K_el, f_el = quad.quad9e(ex[iel], ey[iel], Dmat, thickness, eq) else: if numElementNodes == 3: # core version of plante /tri3el K_el, f_el = cfc.plante(ex[iel], ey[iel], ep, Dmat, eq) # Transpose so correct dim for assem f_el = f_el.T elif numElementNodes == 4: # Number of intergration points. 1, 2 or 3 n = 2 ep = np.array([ep[0], ep[1], n]) K_el, f_el = cfc.plani4e(ex[iel], ey[iel], ep, Dmat, eq) f_el = f_el.T cfc.assem(eldofs[iel], K, K_el, R, f_el) r, R0 = cfc.solveq(K, R, bc) nodMiddle = numNodesY//2 + 1 # Mid nod on right edge xC = r[-(nodMiddle*2), 0] # 2 dofs per node, so this is the middle dof on end # 2 dofs per node, so this is the middle dof on end yC = r[-(nodMiddle*2)+1, 0] print("Element: ", numElementNodes) print( "Displacement center node right end, x:{:12.3e} y:{:12.3e}".format(xC, yC)) # Sum uf reaction forces R0Sum = np.zeros(2, 'f') for i in range(0, (numNodesY*2), 2): R0Sum[0] += R0[i, 0]
ex2 = np.array([6, 6]) ex3 = np.array([0, 6]) ey1 = np.array([4, 0]) ey2 = np.array([4, 0]) ey3 = np.array([4, 4]) eq1 = np.array([0, 0]) eq2 = np.array([0, 0]) eq3 = np.array([0, -10e+3]) Ke1 = cfc.beam2e(ex1, ey1, ep1) Ke2 = cfc.beam2e(ex2, ey2, ep1) Ke3, fe3 = cfc.beam2e(ex3, ey3, ep3, eq3) # ----- Assemble Ke into K --------------------------------------- cfc.assem(Edof[0, :], K, Ke1) cfc.assem(Edof[1, :], K, Ke2) cfc.assem(Edof[2, :], K, Ke3, f, fe3) # ----- Solve the system of equations and compute reactions ------ bc = np.array([1, 2, 3, 10, 11]) a, r = cfc.solveq(K, f, bc) print("a = ") print(a) print("r = ") print(r) # ----- Section forces -------------------------------------------
# ----- Element stiffness matrices ------------------------------ E = 2.1e11 A = 45.3e-4 I = 2510e-8 ep = np.array([E, A, I]) ex = np.array([0., 3.]) ey = np.array([0., 0.]) Ke = cfc.beam2e(ex, ey, ep) print(Ke) # ----- Assemble Ke into K --------------------------------------- K = cfc.assem(Edof, K, Ke) # ----- Solve the system of equations and compute support forces - bc = np.array([1, 2, 11]) (a, r) = cfc.solveq(K, f, bc) # ----- Section forces ------------------------------------------- Ed = cfc.extractEldisp(Edof, a) es1, ed1, ec1 = cfc.beam2s(ex, ey, ep, Ed[0, :], nep=10) es2, ed2, ec2 = cfc.beam2s(ex, ey, ep, Ed[1, :], nep=10) es3, ed3, ec3 = cfc.beam2s(ex, ey, ep, Ed[2, :], nep=10) # ----- Results --------------------------------------------------
[8, 9, 12, 11], [10, 11, 14, 13], [11, 12, 15, 14], ]) Ex, Ey = cfc.coordxtr(Edof, Coord, Dof) # ----- Generate FE-mesh ----- #clf; eldraw2(Ex,Ey,[1 3 0],Edof(:,1)); #disp('PRESS ENTER TO CONTINUE'); pause; clf; # ----- Create and assemble element matrices ----- for i in range(8): Ke = cfc.flw2qe(Ex[i], Ey[i], ep, D) K = cfc.assem(Edof[i], K, Ke) # ----- Solve equation system ----- bcPrescr = np.array([1, 2, 3, 4, 7, 10, 13, 14, 15]) bcVal = np.array([0, 0, 0, 0, 0, 0, 0.5e-3, 1e-3, 1e-3]) a, r = cfc.solveq(K, f, bcPrescr, bcVal) # ----- Compute element flux vector ----- Ed = cfc.extractEldisp(Edof, a) Es = np.zeros((8, 2)) for i in range(8): Es[i], Et = cfc.flw2qs(Ex[i], Ey[i], ep, D, Ed[i]) # ----- Draw flux vectors and contourlines -----
[2, 3] # element 3 between node 2 and 3 ]) # Stiffness matrix K and load vector f K = np.zeros((3, 3)) f = np.zeros((3, 1)) # Element stiffness matrices k = 1500. ep1 = k ep2 = 2. * k Ke1 = cfc.spring1e(ep1) Ke2 = cfc.spring1e(ep2) # Assemble Ke into K cfc.assem(Edof[0, :], K, Ke2) cfc.assem(Edof[1, :], K, Ke1) cfc.assem(Edof[2, :], K, Ke2) print("Stiffness matrix K:") print(K) # f[1] corresponds to edof 2 f[1] = 100 # Solve the system of equations bc = np.array([1, 3]) a, r = cfc.solveq(K, f, bc) print("Displacements a:") print(a)
# ---- Solve problem -------------------------------------------------------- nDofs = np.size(dofs) K = lil_matrix((nDofs,nDofs)) ex, ey = cfc.coordxtr(edof, coords, dofs) print("Assembling K... ("+str(nDofs)+")") for eltopo, elx, ely, elMarker in zip(edof, ex, ey, elementmarkers): if elType == 2: Ke = cfc.plante(elx, ely, elprop[elMarker][0], elprop[elMarker][1]) else: Ke = cfc.planqe(elx, ely, elprop[elMarker][0], elprop[elMarker][1]) cfc.assem(eltopo, K, Ke) print("Applying bc and loads...") bc = np.array([],'i') bcVal = np.array([],'i') bc, bcVal = cfu.applybc(bdofs, bc, bcVal, markFixed, 0.0) f = np.zeros([nDofs,1]) cfu.applyforcetotal(bdofs, f, markLoad, value = -10e5, dimension=2) print("Solving system...") a,r = cfc.spsolveq(K, f, bc, bcVal)
ep2 = 24.3 ep3 = 0.4 ep4 = 17.0 ep5 = 7.7 # ----- Element stiffness matrices ------------------------------ Ke1 = cfc.spring1e(ep1) Ke2 = cfc.spring1e(ep2) Ke3 = cfc.spring1e(ep3) Ke4 = cfc.spring1e(ep4) Ke5 = cfc.spring1e(ep5) # ---- Assemble Ke into K --------------------------------------- cfc.assem(Edof[0, :], K, Ke1) cfc.assem(Edof[1, :], K, Ke2) cfc.assem(Edof[2, :], K, Ke3) cfc.assem(Edof[3, :], K, Ke4) cfc.assem(Edof[4, :], K, Ke5) print("Stiffness matrix K:") print(K) # ----- Solve the system of equations ---------------------------- bc = np.array([1, 6]) bcVal = np.array([-17.0, 20.0]) a, r = cfc.solveq(K, f, bc, bcVal) print("Displacements a:")
def execute(self): # ------ Transfer model variables to local variables self.inputData.updateparams() version = self.inputData.version units = self.inputData.units v = self.inputData.v ep = self.inputData.ep E = self.inputData.E mp = self.inputData.mp fp = self.inputData.fp bp = self.inputData.bp ep[1] = ep[1] * U2SI[units][0] E = E * U2SI[units][2] for i in range(len(fp[0])): fp[1][i] = fp[1][i] * U2SI[units][1] for i in range(len(bp[0])): bp[1][i] = bp[1][i] * U2SI[units][0] # Get most updated dxf dimensions and import model geometry to calfem format self.inputData.dxf.readDXF(self.inputData.dxf_filename) for dim in self.inputData.d: ("Adjusting Dimension {0} with val {1}".format( dim[0], dim[1] * U2SI[units][0])) self.inputData.dxf.adjustDimension(dim[0], dim[1] * U2SI[units][0]) self.inputData.dxf.adjustDimension( self.inputData.c['aName'], self.inputData.c['a'] * U2SI[units][0]) self.inputData.dxf.adjustDimension( self.inputData.c['bName'], self.inputData.c['b'] * U2SI[units][0]) dxf = self.inputData.dxf if self.inputData.refineMesh: geometry, curve_dict = dxf.convertToGeometry(max_el_size=mp[2]) else: geometry, curve_dict = dxf.convertToGeometry() # Generate the mesh meshGen = cfm.GmshMeshGenerator(geometry) meshGen.elSizeFactor = mp[2] # Max Area for elements meshGen.elType = mp[0] meshGen.dofsPerNode = mp[1] meshGen.returnBoundaryElements = True coords, edof, dofs, bdofs, elementmarkers, boundaryElements = meshGen.create( ) # Add the force loads and boundary conditions bc = np.array([], int) bcVal = np.array([], int) nDofs = np.size(dofs) f = np.zeros([nDofs, 1]) for i in range(len(bp[0])): bc, bcVal = cfu.applybc(bdofs, bc, bcVal, dxf.markers[bp[0][i]], bp[1][i]) for i in range(len(fp[0])): xforce = fp[1][i] * np.cos(np.radians(fp[2][i])) yforce = fp[1][i] * np.sin(np.radians(fp[2][i])) cfu.applyforce(bdofs, f, dxf.markers[fp[0][i]], xforce, dimension=1) cfu.applyforce(bdofs, f, dxf.markers[fp[0][i]], yforce, dimension=2) # ------ Calculate the solution print("") print("Solving the equation system...") # Define the elements coordinates ex, ey = cfc.coordxtr(edof, coords, dofs) # Define the D and K matrices D = (E / (1 - v**2)) * np.matrix([[1, v, 0], [v, 1, 0], [0, 0, (1 - v) / 2]]) K = np.zeros([nDofs, nDofs]) # Extract element coordinates and topology for each element for eltopo, elx, ely in zip(edof, ex, ey): Ke = cfc.plante(elx, ely, ep, D) cfc.assem(eltopo, K, Ke) # Solve the system a, r = cfc.solveq(K, f, bc, bcVal) # ------ Determine stresses and displacements print("Computing the element forces") # Extract element displacements ed = cfc.extractEldisp(edof, a) # Determine max displacement max_disp = [[0, 0], 0] # [node idx, value] for idx, node in zip(range(len(ed)), ed): for i in range(3): disp = math.sqrt(node[2 * i]**2 + node[2 * i + 1]**2) if disp > max_disp[1]: max_disp = [[idx, 2 * i], disp] # Determine Von Mises stresses vonMises = [] max_vm = [0, 0] # [node idx, value] for i in range(edof.shape[0]): es, et = cfc.plants(ex[i, :], ey[i, :], ep, D, ed[i, :]) try: vonMises.append( math.sqrt( pow(es[0, 0], 2) - es[0, 0] * es[0, 1] + pow(es[0, 1], 2) + 3 * es[0, 2])) if vonMises[-1] > max_vm[1]: max_vm = [i, vonMises[-1]] except ValueError: vonMises.append(0) print("CAUGHT MATH EXCEPTION with es = {0}".format(es)) # Note: es = [sigx sigy tauxy] # ------ Store the solution in the output model variables self.outputData.disp = ed self.outputData.stress = vonMises self.outputData.geometry = geometry self.outputData.a = a self.outputData.coords = coords self.outputData.edof = edof self.outputData.mp = mp self.outputData.meshGen = meshGen self.outputData.statistics = [ max_vm, max_disp, curve_dict, self.inputData.dxf.anchor, self.inputData.dxf.wh ] if self.inputData.paramFilename is None: print("Solution completed.")
def assem(self): self.K = lil_matrix((self.n_dofs, self.n_dofs)) for eltopo, elx, ely in zip(self.mesh.edof, self.mesh.ex, self.mesh.ey): Ke = self.on_create_Ke(elx, ely, self.mesh.shape.element_type) cfc.assem(eltopo, self.K, Ke)
def execute(self): # --- Överför modell variabler till lokala referenser ep = self.inputData.ep E = self.inputData.E v = self.inputData.v Elementsize = self.inputData.Elementsize # --- Anropa InputData för en geomtetribeskrivning geometry = self.inputData.geometry() # --- Nätgenerering elType = 3 # <-- Fyrnodselement flw2i4e dofsPerNode = 2 meshGen = cfm.GmshMeshGenerator(geometry) meshGen.elSizeFactor = Elementsize # <-- Anger max area för element meshGen.elType = elType meshGen.dofsPerNode = dofsPerNode meshGen.returnBoundaryElements = True coords, edof, dof, bdofs, elementmarkers, boundaryElements = meshGen.create( ) self.outputData.topo = meshGen.topo #Solver bc = np.array([], 'i') bcVal = np.array([], 'i') D = cfc.hooke(1, E, v) nDofs = np.size(dof) ex, ey = cfc.coordxtr(edof, coords, dof) #Coordinates K = np.zeros([nDofs, nDofs]) #Append Boundary Conds f = np.zeros([nDofs, 1]) bc, bcVal = cfu.applybc(bdofs, bc, bcVal, 30, 0.0, 0) cfu.applyforce(bdofs, f, 20, 100e3, 1) qs_array = [] qt_array = [] for x, y, z in zip(ex, ey, edof): Ke = cfc.planqe(x, y, ep, D) cfc.assem(z, K, Ke) asolve, r = cfc.solveq(K, f, bc, bcVal) ed = cfc.extractEldisp(edof, asolve) for x, y, z in zip(ex, ey, ed): qs, qt = cfc.planqs(x, y, ep, D, z) qs_array.append(qs) qt_array.append(qt) vonMises = [] stresses1 = [] stresses2 = [] # For each element: for i in range(edof.shape[0]): # Determine element stresses and strains in the element. es, et = cfc.planqs(ex[i, :], ey[i, :], ep, D, ed[i, :]) # Calc and append effective stress to list. vonMises.append( np.sqrt( pow(es[0], 2) - es[0] * es[1] + pow(es[1], 2) + 3 * es[2])) ## es: [sigx sigy tauxy] # sigmaij = np.array([[es(i,1),es(i,3),0],[es(i,3),es(i,2),0],[0,0,0]]) sigmaij = np.array([[es[0], es[2], 0], [es[2], es[1], 0], [0, 0, 0]]) [v, w] = np.linalg.eig(sigmaij) stresses1.append(v[0] * w[0]) stresses2.append(v[1] * w[1]) # --- Överför modell variabler till lokala referenser self.outputData.vonMises = vonMises self.outputData.edof = edof self.outputData.coords = coords self.outputData.stresses1 = stresses1 self.outputData.stresses2 = stresses2 self.outputData.geometry = geometry self.outputData.asolve = asolve self.outputData.r = r self.outputData.ed = ed self.outputData.qs = qs_array self.outputData.qt = qt_array self.outputData.dofsPerNode = dofsPerNode self.outputData.elType = elType self.outputData.calcDone = True