def DD_preconditioner(grid, ghost_vector_table, vector_table, r_index, p_index): r = [] i = 0 for node in node_iterator(grid): node_id = node.get_node_id() #print (node_id._id_no,'number') if not node.get_slave(): #print(node.get_coord()) vector = vector_table[str(node_id)] #print(node_id._id_no, vector[r_index], 'vv') r.append(vector[r_index]) #print('first loop:',i) i += 1 #matrix = spsolve(DD_init(grid),r) matrix = DD_init(grid).solve(np.array(r)) #vector[p_index] = vector[r_index] #vector_table[str(node_id)] = vector j = 0 for node in node_iterator(grid): node_id = node.get_node_id() if not node.get_slave(): vector = vector_table[str(node_id)] vector[p_index] = matrix[j] vector_table[str(node_id)] = vector #print('second loop:',j) j += 1
def Stencil_L(grid, Nl): Lmatrix = lil_matrix((len(Nl), len(Nl))) for node in node_iterator(grid): # Ignore slave (or boundary) nodes if not node.get_slave(): # Which row corresponds to the current node? idi = int(node.get_value()) for endpt1 in connect_iterator(grid, node.get_node_id()): # Which column corresponds to the current node? idj = int(grid.get_value(endpt1)) # We must not include slave nodes in the matrix columns if not grid.get_slave(endpt1): if idi - idj == 0: Lmatrix[idi, idj] = 4 elif abs(idi - idj) == 1: Lmatrix[idi, idj] = -1 elif abs(idi - idj) == int(np.sqrt(len(Nl))): Lmatrix[idi, idj] = -1 return Lmatrix
def triangle_iterator(grid): """Iterate over the triangles in a grid""" # Get the ghost node table ghost_table = grid.reference_ghost_table() # Loop over the nodes in the grid for node in node_iterator(grid): # Loop over the edges joined to the node for endpt1 in endpt_iterator(grid, node.get_node_id()): # Get the node sitting to the endpoint (which may be a # ghost node) if grid.is_in(endpt1): node1 = grid.get_node(endpt1) else: node1 = ghost_table.get_node(endpt1) #Loop over another set of edges joined to the node for endpt2 in endpt_iterator(grid, node.get_node_id()): # If the endpoints are joined by an additional edge if grid.is_edge(endpt1, endpt2): # Get the node sitting to the endpoint (which may be a # ghost node) if grid.is_in(endpt2): node2 = grid.get_node(endpt2) else: node2 = ghost_table.get_node(endpt2) # Then return the triangle yield [node, node1, node2]
def matrix_mult(grid, ghost_vector_table, vector_table, d_index, q_index): """ Evaluate q = Ad""" # Loop over the full nodes for node in node_iterator(grid): node_id = node.get_node_id() # Do not change the slave nodes if not node.get_slave(): # Find sum A_{ij} d_j sum = 0.0 # Loop over the end points connect to node i for endpt in connect_iterator(grid, node_id): # Find (A)_{ij} stiffness = grid.get_matrix_value(node_id, endpt) # Find d_j, which may be a full or ghost node if grid.is_in(endpt): d = vector_table[str(endpt)][d_index] else: d = ghost_vector_table[str(endpt)][d_index] # Update the sum sum = sum + stiffness * d # Store the result vector_table[str(node_id)][q_index] = sum
def Amatrix(grid, Coord, Nl, h): Amatrix = lil_matrix((len(Nl), len(Nl))) for node in node_iterator(grid): if not node.get_slave(): idi = int(node.get_value()) #print idi, node.get_coord() #print node.get_value(), node.get_node_id()._id_no for endpt in connect_iterator(grid, node.get_node_id()): idj = int(grid.get_value(endpt)) #print idj, grid.get_coord(endpt) #print endpt._id_no, grid.get_value(endpt) aentry = grid.get_matrix_value(node.get_node_id(), endpt)[1] #print aentry if not grid.get_slave(endpt): Amatrix[idi, idj] = aentry print len(Coord) return Amatrix / float(len(Coord))
def G2(grid, Nl): G2 = lil_matrix((len(Nl), len(Nl))) for node in node_iterator(grid): # Ignore slave (or boundary) nodes if not node.get_slave(): # Which row corresponds to the current node? i = int(node.get_value()) for endpt1 in connect_iterator(grid, node.get_node_id()): # Which column corresponds to the current node? j = int(grid.get_value(endpt1)) # What is the corresponding matrix value (in the FEM grid) g2 = grid.get_matrix_value(node.get_node_id(), endpt1)[3] # We must not include slave nodes in the matrix columns if not grid.get_slave(endpt1): G2[i, j] = g2 return G2
def plot_fem_solution(grid): from grid.Grid import Grid from grid.NodeTable import node_iterator from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm from matplotlib.ticker import LinearLocator, FormatStrFormatter from matplotlib.pyplot import show, figure from scipy.interpolate import griddata from numpy import mgrid, array # # The connection values are set separately with respect to the location, #grid=Grid() # #Find the position of the nodes and the values node_x = [] node_y = [] node_v = [] for node in node_iterator(grid): coord = node.get_coord() node_x.append(coord[0]) node_y.append(coord[1]) node_v.append(node.get_value()) # Store the results in an array node_x = array(node_x) node_y = array(node_y) node_v = array(node_v) #print('node_x',node_x) #print('node_value', node_v) # Initialise the figure fig = figure() ax = fig.gca(projection='3d') ax = fig.gca() # Interpolate the nodes onto a structured mesh X, Y = mgrid[node_x.min():node_x.max():10j, node_y.min():node_y.max():10j] Z = griddata((node_x, node_y), node_v, (X, Y), method='cubic') # Make a surface plot ax.plot_surface(X, Y, Z, cmap='viridis', linewidth=0) # Set the z axis limits ax.set_zlim(node_v.min(), node_v.max()) # Make the ticks looks pretty ax.zaxis.set_major_locator(LinearLocator(10)) ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f')) # Include a colour bar #fig.colorbar(surf, shrink=0.5, aspect=5) # Show the plot show()
def build_equation_linear_2D(grid, tri_integrate, rhs_function): """Define the stiffness matrix and load vector""" # Set the values for the slave nodes and initialise the load value # to 0 for node in node_iterator(grid): node.set_load(0.0) if (node.get_slave()): set_slave_value(grid, node) # Add the matrix connections for linear basis functions and # initialise to zero for node in node_iterator(grid): node_id = node.get_node_id() if not grid.is_connection(node_id, node_id): grid.add_connection(node_id, node_id) grid.set_matrix_value(node_id, node_id, np.array([0.0, 0.0, 0.0, 0.0])) for endpt1 in endpt_iterator(grid, node.get_node_id()): if not grid.is_connection(node_id, endpt1): grid.add_connection(node_id, endpt1) grid.set_matrix_value(node_id, endpt1, np.array([0.0, 0.0, 0.0, 0.0])) # Evalue that A matrix and rhs vector # Loop over the triangles for tri in triangle_iterator(grid): #print(tri[0].get_node_id()._id_no) if tri[1].get_node_id() < tri[2].get_node_id(): # Find the local stiffness entries stiff1, stiff2, stiff3 \ = local_stiffness_linear_2D(tri[0], tri[1], tri[2], tri_integrate) # Find the local load entries local_load = local_load_linear_2D(tri[0], tri[1], tri[2], rhs_function) # Add in the contributions from the current triangle sum_load(tri[0], local_load) sum_stiffness(grid, tri[0], tri[0], stiff1) sum_stiffness(grid, tri[0], tri[1], stiff2) sum_stiffness(grid, tri[0], tri[2], stiff3)
def plot_fem_grid(grid): from grid.NodeTable import node_iterator from grid.EdgeTable import endpt_iterator from grid.Edge import DomainSet from matplotlib.pyplot import plot, show #This prints out the list of triangles for node in node_iterator(grid): #node_i=node.get_node_id() node_i = [node.get_node_id()._id_no] #print(node_i) for endpt_1 in endpt_iterator(grid, node.get_node_id()): node_j = [endpt_1._id_no] #print(node_j) for endpt_2 in endpt_iterator(grid, node.get_node_id()): node_k = [endpt_2._id_no] #print(node_k) #if grid.is_edge(endpt_1,endpt_2) == True: # print(node_i+node_j+node_k) # This plot the grid out from build_packman_grid for node in node_iterator(grid): for endpt in endpt_iterator(grid, node.get_node_id()): x = [ node.get_coord()[0], grid.get_node(endpt._id_no).get_coord()[0] ] y = [ node.get_coord()[1], grid.get_node(endpt._id_no).get_coord()[1] ] plot(x, y) x1 = np.linspace(0 + 1 / float(12), 1.0 - 1 / float(12), 12) y1 = np.linspace(0 + 1 / float(12), 1.0 - 1.0 / float(10), 12) X, Y = np.meshgrid(x1, y1) #fig, ax = plt.subplots() #fig,ax = plt.subplots(1,1,figsize=(10,10)) plt.scatter(X, Y, s=1) show()
def FD_G1(grid, Nl, h): G1 = lil_matrix((len(Nl), len(Nl))) # for node in Nl: # # node.set_value(Nl.index(node)) for node in node_iterator(grid): if not node.get_slave(): i = int(node.get_value()) for endpt1 in connect_iterator(grid, node.get_node_id()): j = int(grid.get_value(endpt1)) if not grid.get_slave(endpt1): if i - j == 0: G1[i, j] = 1 * -h elif i - j == np.sqrt(len(Nl)): G1[i, j] = 0 * -h elif i - j == -np.sqrt(len(Nl)): G1[i, j] = h # elif i-j == 1: # # # G1[i,j] = -h # # elif i-j == -1: # # # G1[i,j] = -h # # elif i-j == np.sqrt(len(Nl))+1: # # G1[i,j] =-h # # elif i-j == -np.sqrt(len(Nl))+1: # # G1[i,j] = h return G1
def get_grid(self, processor_no): """ Get a grid from the given processor no This applies to the global group """ # Get the grid from the neighbouring processor grid = self._comm.recv(source=self._tids[processor_no], tag=self._tag) # When python pickles the grid it does not appear to handle the # static variables correctly. In particular, the counter in NodeTable # used to determine the local ID is not set correctly. The # We must make sure that counter is greater than the maximum # local ID value so that if a new node is added it will be given # the correct local ID # Find the maximum counter in the full nodes max_counter = 0 for node in node_iterator(grid): node_id = node.get_node_id() if (node_id.get_no() > max_counter): max_counter = node_id.get_no() # Find the maximum counter in the full and ghost nodes ghost_table = grid.reference_ghost_table() for node in node_iterator(ghost_table): node_id = node.get_node_id() if (node_id.get_no() > max_counter): max_counter = node_id.get_no() # Adjust the static variable in the NodeTable accordingly if max_counter > NodeTable._counter: NodeTable._counter = max_counter+1 # Return the grid return grid
def plot_fem_grid(c, grid): from grid.NodeTable import node_iterator from grid.NghNodes import ngh_iterator from grid.EdgeTable import endpt_iterator from grid.Edge import DomainSet from matplotlib.pyplot import plot, show import matplotlib.pyplot as plt #for ngh in grid.reference_ghost_table(): #print(ngh.get_coord(),'ghost') for node in node_iterator(grid): print(node.get_coord(),'full nodes') #print (node.get_global_id()._id_no, node.get_coord()) #print(node) #plot(node._coord) for endpt in endpt_iterator(grid,node.get_node_id()): #print(endpt, grid.get_coord(endpt)) if grid.is_in(endpt): #print(grid.get_coord(endpt), 'm') x = [node.get_coord()[0], grid.get_coord(endpt)[0]] y = [node.get_coord()[1], grid.get_coord(endpt)[1]] #plot(x,y) if grid.reference_ghost_table().is_in(endpt): print(grid.reference_ghost_table().get_coord(endpt),'ghost') x = [node.get_coord()[0], grid.reference_ghost_table().get_coord(endpt)[0]] #print(ngh[1][i]._id_no) #print(grid.get_coord(ngh[1][i]._id_no)) y = [node.get_coord()[1], grid.reference_ghost_table().get_coord(endpt)[1]] plot(x,y) #print(endpt._id_no,"connected") #plot(node._coord,grid.get_node(endpt._id_no).get_coord()) for ghost in ngh_iterator(grid.reference_ghost_commun()): #print(ghost[1]) for node in ghost[1]: #print(grid.reference_ghost_table().get_coord(node),'coord') for endpt in endpt_iterator(grid, node): #print(endpt) if grid.reference_ghost_table().is_in(endpt): x = [grid.reference_ghost_table().get_coord(node)[0], grid.reference_ghost_table().get_coord(endpt)[0]] y = [grid.reference_ghost_table().get_coord(node)[1], grid.reference_ghost_table().get_coord(endpt)[1]] plot(x,y) #for endpt in endpt_iterator() plt.title('subgrid'+str(c)) show ()
def Amatrix(grid): # node.set_value(Nl.index(node)) # Nl = [] for node in (not_slave_node(grid)): Nl.append([node, node.get_node_id()]) Nl = sorted(Nl, key=itemgetter(1)) Nl = [node[0] for node in Nl] for node in Nl: node.set_value(Nl.index(node)) Amatrix = csr_matrix((len(Nl), len(Nl))) for node in node_iterator(grid): if not node.get_slave(): idi = int(node.get_value()) #print idi, node.get_coord() #print node.get_value(), node.get_node_id()._id_no for endpt in connect_iterator(grid, node.get_node_id()): idj = int(grid.get_value(endpt)) #print idj, grid.get_coord(endpt) #print endpt._id_no, grid.get_value(endpt) aentry = grid.get_matrix_value(node.get_node_id(), endpt)[1] #print aentry if not grid.get_slave(endpt): Amatrix[idi, idj] = aentry return Amatrix / float(len(Coord))
def G2(grid): #build_matrix_fem_2D(grid, Poisson_tri_integrate, TPS_tri_intergrateX, TPS_tri_intergrateY, X, Y) Nl=[] for node in (not_slave_node(grid)): Nl.append([node,node.get_node_id()]) Nl=sorted(Nl, key = itemgetter(1)) Nl=[node[0] for node in Nl] for node in Nl: node.set_value(Nl.index(node)) G2 = csr_matrix((len(Nl), len(Nl))) for node in node_iterator(grid): # Ignore slave (or boundary) nodes if not node.get_slave(): # Which row corresponds to the current node? i = int(node.get_value()) for endpt1 in connect_iterator(grid, node.get_node_id()): # Which column corresponds to the current node? j = int(grid.get_value(endpt1)) # What is the corresponding matrix value (in the FEM grid) g2 = grid.get_matrix_value(node.get_node_id(), endpt1)[3] # We must not include slave nodes in the matrix columns if not grid.get_slave(endpt1): G2[i, j] = g2 return G2
def calculate_residual(grid, ghost_vector_table, vector_table, x_index, b_index, r_index): """ Evaluate r = b-Ax""" # Find Ax matrix_mult(grid, ghost_vector_table, vector_table, x_index, r_index) # Find r = b - Ax # Loop over the full nodes for node in node_iterator(grid): node_id = node.get_node_id() # Ignore slave nodes if not node.get_slave(): # Find r_i = b_i - (Ax)_i vector = vector_table[str(node_id)] vector[r_index] = vector[b_index] - vector[r_index] vector_table[str(node_id)] = vector
def identity_preconditioner(grid, ghost_vector_table, vector_table, r_index, p_index): """ p =I *r""" # Loop through the list of full nodes for node in node_iterator(grid): node_id = node.get_node_id() # Ignore the slace nodes if not node.get_slave(): # Get the array of values assigned to the current node vector = vector_table[str(node_id)] # Copy across the entries indexed by r_index into those # indexed by p_index vector[p_index] = vector[r_index] # Update the array of values assignmed to the current node vector_table[str(node_id)] = vector
def Lmatrix(grid): Nl = [] for node in (not_slave_node(grid)): Nl.append([node, node.get_node_id()]) Nl = sorted(Nl, key=itemgetter(1)) Nl = [node[0] for node in Nl] for node in Nl: node.set_value(Nl.index(node)) # Lmatrix = lil_matrix((len(Nl), len(Nl))) for node in node_iterator(grid): # Ignore slave (or boundary) nodes if not node.get_slave(): # Which row corresponds to the current node? i = int(node.get_value()) for endpt1 in connect_iterator(grid, node.get_node_id()): # Which column corresponds to the current node? j = int(grid.get_value(endpt1)) # What is the corresponding matrix value (in the FEM grid) lentry = grid.get_matrix_value(node.get_node_id(), endpt1)[0] # We must not include slave nodes in the matrix columns if not grid.get_slave(endpt1): Lmatrix[i, j] = lentry return Lmatrix
def generate_XGmatrix(): build_equation_linear_2D(grid, TPS_tri_intergrateX, zero) Nl = [] for node in (not_slave_node(grid)): #print(i) Nl.append([node, node.get_node_id()]) Nl = sorted(Nl, key=itemgetter(1)) Nl = [node[0] for node in Nl] for node in Nl: node.set_value(Nl.index(node)) XGmatrix = zeros([len(Nl), len(Nl)]) for node in node_iterator(grid): # Ignore slave (or boundary) nodes if not node.get_slave(): # Which row corresponds to the current node? i = int(node.get_value()) for endpt1 in connect_iterator(grid, node.get_node_id()): # Which column corresponds to the current node? j = int(grid.get_value(endpt1)) # What is the corresponding matrix value (in the FEM grid) stiffness = grid.get_matrix_value(node.get_node_id(), endpt1)[0] # We must not include slave nodes in the matrix columns if not grid.get_slave(endpt1): XGmatrix[i, j] = stiffness return XGmatrix
def Stencil_A(grid, Nl, h): Amatrix = lil_matrix((len(Nl), len(Nl))) for node in node_iterator(grid): if not node.get_slave(): idi = int(node.get_value()) # Loop over the matrix entries in the current row for endpt in connect_iterator(grid, node.get_node_id()): # Which column corresponds to the current node? idj = int(grid.get_value(endpt)) # We must not include slave nodes in the matrix columns if not grid.get_slave(endpt): if idi - idj == 0: Amatrix[idi, idj] = h**2 / 2 elif abs(idi - idj) == 1: Amatrix[idi, idj] = h**2 / 12 elif abs(idi - idj) == int(np.sqrt(len(Nl))): Amatrix[idi, idj] = h**2 / 12 elif abs(idi - idj) == int(np.sqrt(len(Nl))) + 1: Amatrix[idi, idj] = h**2 / 12 return Amatrix
def conjugate_gradient(commun, grid, preconditioner, tolerance=1.0E-12, max_no_loops=5000): """Preconditioned conjugate gradient method""" # These are indices into temporary storage areas needed by the routine residual_index = 0 direction_index = 1 tmp_index = 2 precond_index = 3 x_index = 4 b_index = 5 # Initialise the scaling terms used by CG resid_norm2 = 0.0 alpha_new = 0.0 alpha_old = 0.0 beta = 0.0 gamma = 0.0 # Explicitly recalculate the residual after this number of steps residual_recalc = 50 # How many loops did the CG method take to solve the problem? no_loops = max_no_loops # With each full node in the grid, store an array containing all of the # information needed by the CG method # We use a dictionary to store the information vector_table = dict() # Loop of the full nodes for node in node_iterator(grid): # 6 pieces of information must be stored with each node vector = [0.0] * 6 # Find the initial guess vector[x_index] = node.get_value() # Find the right hand side vector[b_index] = node.get_load() # Store the array vector_table[str(node.get_node_id())] = vector # With each ghost node in the grid, store an array containing all of the # information needed by the CG method ghost_table = grid.reference_ghost_table() # We use a dictionary to store the information ghost_vector_table = dict() # Loop over the ghost nodes for node in node_iterator(ghost_table): # 6 pieces of information must be stored with each node vector = [0.0] * 6 # Store the array ghost_vector_table[str(node.get_node_id())] = vector # Update the ghost nodes commun.update_vector_table(grid, vector_table, ghost_vector_table) # Find the initial residual calculate_residual(grid, ghost_vector_table, vector_table, x_index, b_index, residual_index) # Residual norm^2 = <r, r> resid_norm2 = inner_product(vector_table, residual_index, residual_index) resid_norm2 = commun.global_sum(resid_norm2) # Apply the preconditioner (s = M^{-1}r) preconditioner(grid, ghost_vector_table, vector_table, residual_index, precond_index) # Initialise the direction vector (d = s) for key, value in vector_table.iteritems(): value[direction_index] = value[precond_index] # Find alpha_new = < r, s> alpha_new = inner_product(vector_table, residual_index, precond_index) alpha_new = commun.global_sum(alpha_new) # Start the CG iterations for loop in range(max_no_loops): # Temporarily store A*direction_vector (q = A*d) commun.update_vector_table(grid, vector_table, ghost_vector_table) matrix_mult(grid, ghost_vector_table, vector_table, direction_index, tmp_index) # Beta = alpha_new/<d, q> dq = inner_product(vector_table, direction_index, tmp_index) dq = commun.global_sum(dq) beta = alpha_new / dq # Update the current solution in the given direction (x = x + beta*d) for key, value in vector_table.iteritems(): value[x_index] = value[x_index] + beta * value[direction_index] # Find the current residual # Every residual_recalc iterations recalculate the residual explicitly # (r = b-A*x) if loop % residual_recalc == 0: commun.update_vector_table(grid, vector_table, ghost_vector_table) calculate_residual(grid, ghost_vector_table, vector_table, x_index, b_index, residual_index) else: # Otherwise use quick formula to update the residual (r = r-beta*q) for key, value in vector_table.iteritems(): value[residual_index] = value[residual_index] \ - beta*value[tmp_index] # Residual norm^2 = <r, r> resid_norm2 = inner_product(vector_table, residual_index, residual_index) resid_norm2 = commun.global_sum(resid_norm2) # If the residual is small, then exit if (sqrt(resid_norm2) < tolerance): no_loops = loop break # alpha_old = alpha_new alpha_old = alpha_new # Apply the preconditioner (s = M^{-1}r) commun.update_vector_table(grid, vector_table, ghost_vector_table) preconditioner(grid, ghost_vector_table, vector_table, residual_index, precond_index) # Find alpha_new = < r, s> alpha_new = inner_product(vector_table, residual_index, precond_index) alpha_new = commun.global_sum(alpha_new) # Gamma = alpha_new/alpha_old gamma = alpha_new / alpha_old # Update the direction vector (d = r + gamma d) for key, value in vector_table.iteritems(): value[direction_index] = value[precond_index] \ + gamma*value[direction_index] # Transfer the results from the temporary data structure into the grid # data structure for node in node_iterator(grid): node.set_value(vector_table[str(node.get_node_id())][x_index]) # Return the number of CG iterations as well as the residual return no_loops, sqrt(resid_norm2)
def build_matrix_fem_2D(grid, tri_integrate1, tri_integrate2, tri_integrate3, X, Y): coordx = X.flatten() coordy = Y.flatten() Coord = zip(coordx, coordy) """ This routine builds the A matrix G1 and G2 matrix and stiffness, and store it on grid. """ print 'START' # Add the matrix connections for linear basis functions and # initialise to zero for node in node_iterator(grid): node_id = node.get_node_id() if not grid.is_connection(node_id, node_id): grid.add_connection(node_id, node_id) grid.set_matrix_value(node_id, node_id, np.array([0.0, 0.0, 0.0, 0.0])) for endpt1 in endpt_iterator(grid, node.get_node_id()): if not grid.is_connection(node_id, endpt1): grid.add_connection(node_id, endpt1) grid.set_matrix_value(node_id, endpt1, np.array([0.0, 0.0, 0.0, 0.0])) # Evalue that matrix and rhs vector # Loop over the triangles for tri in triangle_iterator(grid): #print(tri[0].get_node_id()._id_no) if tri[1].get_node_id() < tri[2].get_node_id(): # Find the local stiffness entries stiff1, stiff2, stiff3 \ = local_stiffness_linear_2D(tri[0], tri[1], tri[2], tri_integrate1) # Add in the contributions from the current triangle #sum_load(tri[0], local_load) sum_stiffness(grid, tri[0], tri[0], stiff1) sum_stiffness(grid, tri[0], tri[1], stiff2) sum_stiffness(grid, tri[0], tri[2], stiff3) XG1, XG2, XG3 \ = local_stiffness_linear_2D(tri[0], tri[1], tri[2], tri_integrate2) sum_G1(grid, tri[0], tri[0], XG1) sum_G1(grid, tri[0], tri[1], XG2) sum_G1(grid, tri[0], tri[2], XG3) YG1, YG2, YG3 \ = local_stiffness_linear_2D(tri[0], tri[1], tri[2], tri_integrate3) sum_G2(grid, tri[0], tri[0], YG1) sum_G2(grid, tri[0], tri[1], YG2) sum_G2(grid, tri[0], tri[2], YG3) print 'FINISH' ############################################################################### ############################################################################### #Store A matrix for whole grid nodes for tri in triangle_iterator(grid): if (tri[1].get_node_id() < tri[2].get_node_id()): # print type(tri[0].get_node_id()), tri[1].get_node_id(),tri[2].get_node_id(),'dasd' basis1 = set_polynomial_linear_2D(tri[0], tri[1], tri[2]) basis2 = set_polynomial_linear_2D(tri[1], tri[0], tri[2]) basis3 = set_polynomial_linear_2D(tri[2], tri[1], tri[0]) for i in Coord: if In_triangle(tri[0], tri[1], tri[2], i): #print i, 'coord of data' ii = basis1.eval(i[0], i[1]) * basis1.eval(i[0], i[1]) #print ii, 'eva at the data' sum_Aentry(grid, tri[0], tri[0], ii) ij = basis1.eval(i[0], i[1]) * basis2.eval(i[0], i[1]) sum_Aentry(grid, tri[0], tri[1], ij) ik = basis1.eval(i[0], i[1]) * basis3.eval(i[0], i[1]) sum_Aentry(grid, tri[0], tri[2], ik)
# Build a 5*5 grid i = 6 n = 2**i # Specify the boundary conditions and the rhs true_soln = exp_soln rhs = exp_rhs # Create a square FEM grid of size n*n build_square_grid_matrix(n, grid, true_soln) # Loop through the grid and find all of the node in the interior of the # domain. At the same time make a record of which row in the matrix # corresponds to which node count = 0 for node in node_iterator(grid): if not node.get_slave(): #print node.get_node_id() node.set_value(count) count = count + 1 # Initialise the A matrix fem_matrix = eye(count) # Initialise the load vector load_vector = zeros([count, 1]) # Define the A matrix and load vector for node in node_iterator(grid): # Ignore slave (or boundary) nodes
def not_slave_node(grid): for node in node_iterator(grid): if not node.get_slave(): yield node
Endpt.append(endpt) Endpt.sort() for endpt2 in (Endpt): stiffness = grid.get_matrix_value(node,endpt2) #print(node._id_no,endpt2._id_no,stiffness) fem_matrix[node._id_no,endpt2._id_no]=stiffness matrixfem =np.matrix(fem_matrix) reduced_matrix=matrixfem[~(matrixfem==0).all(1).A1] transfem=np.transpose(reduced_matrix) redumatrix=transfem[~(transfem==0).all(1).A1] B=np.array(redumatrix) BoundaryNode = [] for i, node in enumerate(node_iterator(grid)): if node.get_slave(): BoundaryNode.append([node,node.get_node_id()]) BoundaryNodeLoad_ID = sorted(BoundaryNode,key = itemgetter(1)) BoundaryNodeLoad_Ordered=[node[0] for node in BoundaryNodeLoad_ID] boundary_value=[] for node in (BoundaryNodeLoad_Ordered): boundary_value.append(true_soln(node.get_coord())) #print(load_vector) # #
def DD_init(grid): count = 0 for node in node_iterator(grid): if not node.get_slave(): #print(node.get_coord()) node.set_value(count) count = count + 1 #print count, 'count' #print(count,'count') # Initialise the A matrix #fem_matrix = csr_matrix((count, count), dtype=float) fem_matrix = eye(count) # Initialise the load vector #load_vector = zeros([count, 1]) # Define the A matrix and load vector for node in node_iterator(grid): # Ignore slave (or boundary) nodes if not node.get_slave(): # Which row corresponds to the current node? i = int(node.get_value()) # Add in the entry to the load vector #coord = node.get_coord() #load_vector[i] = load_vector[i]+rhs(coord) # Loop over the matrix entries in the current row for endpt1 in connect_iterator(grid, node.get_node_id()): if grid.is_in(endpt1): j = int(grid.get_value(endpt1)) stiffness = grid.get_matrix_value(node.get_node_id(), endpt1) if not grid.get_slave(endpt1): fem_matrix[i, j] = stiffness # if grid.reference_ghost_table().is_in(endpt1): # # j = int(grid.reference_ghost_table().get_value(endpt1)) # # #stiffness = grid.get_matrix_value(node.get_node_id(), endpt1) # # if not grid.reference_ghost_table().get_slave(endpt1): # # fem_matrix[i, j] = 0 #if not grid.is_in(endpt1): #print "not in grid" # Which column corresponds to the current node? # What is the corresponding matrix value (in the FEM grid) #stiffness = grid.get_matrix_value(node.get_node_id(), endpt1) # We must not include slave nodes in the matrix columns #if not grid.get_slave(endpt1): #fem_matrix[i, j] = stiffness #print(fem_matrix) # Update the load vector to take non-zero boundary conditions # into account #else: #coord = grid.get_coord(endpt1) #load_vector[i] = load_vector[i]-stiffness*true_soln(coord) #print fem_matrix # fem= splu(fem_matrix) # fem = LinearOperator(fem.shape,matvec=fem.solve) return splu(fem_matrix)
def generate_Amatrix(): Nl = [] for node in (not_slave_node(grid)): Nl.append([node, node.get_node_id()]) Nl = sorted(Nl, key=itemgetter(1)) Nl = [node[0] for node in Nl] for node in Nl: node.set_value(Nl.index(node)) Amatrix = zeros([len(Nl), len(Nl)]) #plot_fem_grid(grid) for node in node_iterator(grid): if not node.get_slave(): print node.get_node_id()._id_no, node.get_value() for tri in Interior_triangle_iterator(grid): if (tri[1].get_node_id() < tri[2].get_node_id()): #print tri[0].get_node_id()._id_no, tri[1].get_node_id()._id_no, tri[2].get_node_id()._id_no basis1 = set_polynomial_linear_2D(tri[0], tri[2], tri[1]) basis2 = set_polynomial_linear_2D(tri[1], tri[2], tri[0]) basis3 = set_polynomial_linear_2D(tri[2], tri[1], tri[0]) for i in Coord: if NIn_triangle(tri[0], tri[1], tri[2], i): #print In_triangle(tri[0] , tri[1], tri[2], i) #print tri[0].get_node_id()._id_no, tri[1].get_node_id()._id_no, tri[2].get_node_id()._id_no, i,\ #tri[0].get_coord(), tri[1].get_coord(), tri[2].get_coord() Idi = int(tri[0].get_value()) Amatrix[Idi, Idi] += basis1.eval(i[0], i[1]) * basis1.eval( i[0], i[1]) if not tri[1].get_slave(): #print tri[1].get_node_id()._id_no, tri[1].get_value() #print tri[1].get_value() Idj = int(tri[1].get_value()) Amatrix[Idi, Idj] += basis1.eval(i[0], i[1]) * basis2.eval( i[0], i[1]) if not tri[2].get_slave(): #print tri[2].get_node_id()._id_no Idk = int(tri[2].get_value()) Amatrix[Idi, Idk] += basis1.eval(i[0], i[1]) * basis3.eval( i[0], i[1]) # Remove the data once it's been used #Coord.remove(i) # return Amatrix / float(len(Coord))