def homogen(h0, f, n): # First lets generate the uniform mesh for this mesh width mesh = msh.grid_square(1, h0) # Matrix of nodes p = mesh[0] # Matrix of triangles index t = mesh[1] # Now lets compute the stiffness matrix A = fem.stiffness(p, t) # Lets compute the load vector Load = fem.load(p, t, n, f) # Lets compute the vector m that analogous to the load vector # with f(x.y)=1 m = fem.load(p, t, n, lambda x, y: 1) # Lets create the matrix and vectors of the modified bigger system to # solve with lagrangian multipliers of size (size(A)+(1,1)) size = A.shape[0] B = sparse.lil_matrix(np.zeros([size + 1, size + 1])) B[0:size, 0:size] = A B[0:size, size] = m B[size, 0:size] = m.transpose() # We add a zero at the end of f Load = np.concatenate((Load, np.array([[0]]))) # Now lets get the solution of the linear system using spsolve function U = spla.spsolve(B, Load) #We extract the solution u and the multiplicer l u = U[0:size] l = U[size] # We return [p,t,u,l] return p, t, u, l
def homogen(h0,f,n): # First lets generate the uniform mesh for this mesh width mesh=msh.grid_square(1,h0) # Matrix of nodes p=mesh[0] # Matrix of triangles index t=mesh[1] # Now lets compute the stiffness matrix A=fem.stiffness(p,t) # Lets compute the load vector Load=fem.load(p,t,n,f) # Lets compute the vector m that analogous to the load vector # with f(x.y)=1 m=fem.load(p,t,n,lambda x,y:1) # Lets create the matrix and vectors of the modified bigger system to # solve with lagrangian multipliers of size (size(A)+(1,1)) size=A.shape[0] B=sparse.lil_matrix(np.zeros([size+1,size+1])) B[0:size,0:size]=A B[0:size,size]=m B[size,0:size]=m.transpose() # We add a zero at the end of f Load=np.concatenate((Load,np.array([[0]]))) # Now lets get the solution of the linear system using spsolve function U=spla.spsolve(B,Load) #We extract the solution u and the multiplicer l u=U[0:size] l=U[size] # We return [p,t,u,l] return p,t,u,l
def dirichlet_nonhomogeneous(h0, f, g, n): # First lets generate the uniform mesh for this mesh width mesh = msh.grid_square(1, h0) # Matrix of nodes p = mesh[0] # Matrix of triangles index t = mesh[1] # Matrix of border element index be = mesh[2] # Lets get the interior nodes in the mesh innod = fem.interiorNodes(p, t, be) # Rewrite the innod to match with indices beginning at 0 innod = [i - 1 for i in innod] # Now lets compute the stiffness matrix Stiff = fem.stiffness(p, t) # Now lets compute the mass matrix Mass = fem.mass(p, t) # Lets compute the load vector Load = fem.load(p, t, n, f) # The complete matrix for the bilinear form is given by the sum of # the stiffness and the mass B = Stiff + Mass # Lets define a vector with of the values of u_g in each node # that is zero in the innernodes and g everywhere else ug = np.array([g(p[i][0], p[i][1]) for i in range(len(p))]) ug[innod] = np.zeros(len(innod)) # Calculate the new load vector with the Dirichleft taken in account Load = Load - B.dot(ug).reshape(len(p), 1) # Now lets get the homogeneous problem solution as we did before # First lets initialize the array in zeros to respect the homogeneous # Dirichlet boundary conditions U = np.zeros(len(p)) # Lets take just the interior points in the matrix B and the Load vector Bint = B[innod][:, innod] Loadint = Load[innod] # Now lets get the solution of the linear system of the interior points # using spsolve function Uint = spla.spsolve(Bint, Loadint) # We put them in the correspondence interior points of the complete # solution U[innod] = Uint # Finally we sum up the two solutions to get the final solution u = U + ug # We return [p,t,U] return p, t, u
def dirichlet_nonhomogeneous(h0, f, g, n): # First lets generate the uniform mesh for this mesh width mesh = msh.grid_square(1, h0) # Matrix of nodes p = mesh[0] # Matrix of triangles index t = mesh[1] # Matrix of border element index be = mesh[2] #Lets get the interior nodes in the mesh innod = fem.interiorNodes(p, t, be) # Rewrite the innod to match with indices beginning at 0 innod = [i - 1 for i in innod] # Now lets compute the stiffness matrix Stiff = fem.stiffness(p, t) # Now lets compute the mass matrix Mass = fem.mass(p, t) # Lets compute the load vector Load = fem.load(p, t, n, f) # The complete matrix for the bilinear form is given by the sum of #the stiffness and the mass B = Stiff + Mass # Lets define a vector with of the values of u_g in each node # that is zero in the innernodes and g everywhere else ug = np.array([g(p[i][0], p[i][1]) for i in range(len(p))]) ug[innod] = np.zeros(len(innod)) #Calculate the new load vector with the Dirichleft taken in account Load = Load - B.dot(ug).reshape(len(p), 1) #Now lets get the homogeneous problem solution as we did before # First lets initialize the array in zeros to respect the homogeneous # Dirichlet boundary conditions U = np.zeros(len(p)) # Lets take just the interior points in the matrix B and the Load vector Bint = B[innod][:, innod] Loadint = Load[innod] # Now lets get the solution of the linear system of the interior points # using spsolve function Uint = spla.spsolve(Bint, Loadint) # We put them in the correspondence interior points of the complete # solution U[innod] = Uint # Finally we sum up the two solutions to get the final solution u = U + ug # We return [p,t,U] return p, t, u
def neumann(h0, f, n): # First lets generate the uniform mesh for this mesh width mesh = msh.grid_square(1, h0) # Matrix of nodes p = mesh[0] # Matrix of triangles index t = mesh[1] # Now lets compute the stiffness matrix Stiff = fem.stiffness(p, t) # Now lets compute the mass matrix Mass = fem.mass(p, t) # Lets compute the load vector Load = fem.load(p, t, n, f) # The complete matrix for the bilinear form is given by the sum of #the stiffness and the mass B = Stiff + Mass # Now lets get the solution of the linear system using spsolve function U = spla.spsolve(B, Load) # We return [p,t,U] return p, t, U
def neumann(h0,f,n): # First lets generate the uniform mesh for this mesh width mesh=msh.grid_square(1,h0) # Matrix of nodes p=mesh[0] # Matrix of triangles index t=mesh[1] # Now lets compute the stiffness matrix Stiff=fem.stiffness(p,t) # Now lets compute the mass matrix Mass=fem.mass(p,t) # Lets compute the load vector Load=fem.load(p,t,n,f) # The complete matrix for the bilinear form is given by the sum of #the stiffness and the mass B=Stiff+Mass # Now lets get the solution of the linear system using spsolve function U=spla.spsolve(B,Load) # We return [p,t,U] return p,t,U
def main(h0, n): p, t, be = mesh.grid_square(2, h0) # shift mesh to origin# h = mesh.max_mesh_width(p, t) IN = fem.interiorNodes(p, t, be) S = fem.stiffness(p, t) M = fem.mass(p, t) L = fem.load(p, t, n, lambda x, y: 1) S = S.tocsr() M = M.tocsr() L = L.tocsr() # neumannnodes N = np.zeros(len(p)) j = 0 for i in range(0, len(p)): if p[i, 0] == 0 or p[i, 0] == 2: if 2 > p[i, 1] and p[i, 1] >= 1: N[j] = i j = j + 1 if p[i, 1] == 2: N[j] = i j = j + 1 j = j - 1 # number of neumannnodes print(N) Sr = sp.csr_matrix((len(IN) + j, len(IN) + j)) Mr = sp.csr_matrix((len(IN) + j, len(IN) + j)) Lr = sp.csr_matrix((len(IN) + j, 1)) A = sp.csr_matrix((len(IN) + j, len(p))) for i in range(0, len(IN)): A[i, IN[i]] = 1 for i in range(0, j): A[i + len(IN), N[i]] = 1 Sr = A * S * A.transpose() Mr = A * M * A.transpose() Lr = A * L un = spla.spsolve(Sr + Mr, Lr) u1 = A.transpose() * un fem.plot(p, t, u1)
def dirichlet_homogeneous(h0,f,n): # First lets generate the uniform mesh for this mesh width mesh=msh.grid_square(1,h0) # Matrix of nodes p=mesh[0] # Matrix of triangles index t=mesh[1] # Matrix of border element index be=mesh[2] #Lets get the interior nodes in the mesh innod=fem.interiorNodes(p,t,be) # Rewrite the innod to match with indices beginning at 0 innod=[i-1 for i in innod] # Now lets compute the stiffness matrix Stiff=fem.stiffness(p,t) # Now lets compute the mass matrix Mass=fem.mass(p,t) # Lets compute the load vector Load=fem.load(p,t,n,f) # The complete matrix for the bilinear form is given by the sum of #the stiffness and the mass B=Stiff+Mass # Now lets initialize the array in zeros to respect the homogeneous # Dirichlet boundary conditions U=np.zeros(len(p)) # Lets take just the interior points in the matrix B and the Load vector Bint=B[innod][:,innod] Loadint=Load[innod] # Now lets get the solution of the linear system of the interior points # using spsolve function Uint=spla.spsolve(Bint,Loadint) # Finally we put them in the correspondence interior points of the complete # solution U[innod]=Uint # We return [p,t,U] return p,t,U
def dirichlet_homogeneous(h0, f, n): # First lets generate the uniform mesh for this mesh width mesh = msh.grid_square(1, h0) # Matrix of nodes p = mesh[0] # Matrix of triangles index t = mesh[1] # Matrix of border element index be = mesh[2] #Lets get the interior nodes in the mesh innod = fem.interiorNodes(p, t, be) # Rewrite the innod to match with indices beginning at 0 innod = [i - 1 for i in innod] # Now lets compute the stiffness matrix Stiff = fem.stiffness(p, t) # Now lets compute the mass matrix Mass = fem.mass(p, t) # Lets compute the load vector Load = fem.load(p, t, n, f) # The complete matrix for the bilinear form is given by the sum of #the stiffness and the mass B = Stiff + Mass # Now lets initialize the array in zeros to respect the homogeneous # Dirichlet boundary conditions U = np.zeros(len(p)) # Lets take just the interior points in the matrix B and the Load vector Bint = B[innod][:, innod] Loadint = Load[innod] # Now lets get the solution of the linear system of the interior points # using spsolve function Uint = spla.spsolve(Bint, Loadint) # Finally we put them in the correspondence interior points of the complete # solution U[innod] = Uint # We return [p,t,U] return p, t, U
# a) #Define the triangle with its nodes coordinates p=np.array([[1.,1.], [1.,2.], [2.,1.]]) # c) Lets define the source function by a lambda funcion f = lambda x1,x2: x1*x2 # 2 Assembling the elements # We gonna use the functions generated in the last homework to generate # the meshes to study as benchmark import meshes as msh a=1 h0=np.sqrt(2)/14 mesh=msh.grid_square(a,h0) p=mesh[0] t=mesh[1] be=mesh[2] K=0 nodes=np.array([p[i-1] for i in t[K]]) (T(t,K).transpose().dot(elemStiffness(nodes))).dot(T(t,K).toarray())
import FEM as fem import meshes as msh import numpy as np import scipy as sp import scipy.sparse as sparse import scipy.sparse.linalg as spla #We create the mesh h0 = np.sqrt(2) / 5 mesh = msh.grid_square(1, h0) # Matrix of nodes pi = mesh[0] # Matrix of triangles index t = mesh[1] # Matrix of boudary elements vertices be = mesh[2] # Lets get the coordinates of a triangle K = 0 p = np.array([pi[i - 1] for i in t[K]]) #Lets define first the function f f = lambda x1, x2: (8 * (np.pi**2) + 1) * np.cos(2 * np.pi * x1) * np.cos( 2 * np.pi * x2) # The closest value of h0 to 1 to be able to generate a regular h0 = np.sqrt(2) / 14 n = 3 # Lets get another time the mesh h0 = np.sqrt(2) / 10 mesh = msh.grid_square(1, h0)
import scipy as sp import scipy.sparse as sparse import scipy.sparse.linalg as spla # To get a solution u(x,y)=cos(pi x)*cos(pi y) the source function must # be f(x,y)=(2 pi^2)cos(pi x)*cos(pi y) #lets define the source function f= lambda x1,x2: (2*np.pi**2)*np.cos(np.pi*x1)*np.cos(np.pi*x2) # The order of the quadrature will be 3 n=3 # The closest value of h0 to 0.1 to be able to generate a regular h0=np.sqrt(2)/10 # We create the mesh mesh=msh.grid_square(1,h0) # Matrix of nodes pi=mesh[0] # Matrix of triangles index t=mesh[1] # Matrix of boudary elements vertices be=mesh[2] index=be[39] p=pi[index-1] g= lambda x1,x2: np.cos(np.pi*x1)*np.cos(np.pi*x2) sum(map(lambda K:(TB(be,p,K).transpose() .dot(elemLoadNeumann(np.array([p[i-1] for i in be[K]]),n,g))),range(0,len(be))))
import meshes import FEM import time import scipy.sparse.linalg as spla meshwidth = 0.05 processes = 8 p,t=meshes.grid_square(1,meshwidth) timer=time.time() seqM=FEM.mass(p,t) seqTime=time.time()-timer timer=time.time() parM,processes=FEM.massParallel(p,t,processes) parTime=time.time()-timer print "difference of matrices: ", spla.onenormest(seqM-parM) print "time for sequential assembling:", seqTime print "time for parallel assembling: ", parTime print "speed-up: ", seqTime/parTime print "efficiency:", (seqTime/parTime)/processes
file = 'square_mesh.msh' mesh1 = msh.read_gmsh(file) p1 = mesh1[0] t1 = mesh1[1] #Name of the file of the output plot file = 'unstructured.png' title = 'Unstructured mesh' msh.show(p1, t1, file, title) # Get the p and t arrays for the regular mesh of the square of side 1 # For structured meshes the value of h0 is not arbitrary, as it has to fit # a integer number of 1-dimensional elements in each border, the closest # h0 to 0.01 that fullfill that is h0=np.sqrt(2)/14=0.10101.... a = 1 h0 = np.sqrt(2) / 14 mesh2 = msh.grid_square(a, h0) p2 = mesh2[0] t2 = mesh2[1] #Name of the file of the output plot file = 'regular.png' title = 'Regular mesh' msh.show(p2, t2, file, title) # Lets plot the number of nodes depending on maximal mesh width for the # unstructured mesh generated by gmsh, all of them are meshes for a square of side length a=1, and # the value of maximal width will be varied in gmsh in 6 different values: # Lets put in an array yu the number of nodes for each h0 # and xu for the actual mesh width calculated with max_mesh_width xu = []