Example #1
0
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
Example #2
0
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
Example #3
0
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]
Example #4
0
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
Example #5
0
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))
Example #6
0
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
Example #7
0
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()
Example #8
0
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)
Example #9
0
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()
Example #10
0
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
Example #11
0
    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
Example #12
0
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 ()
Example #13
0
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))
Example #14
0
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
Example #15
0
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
Example #16
0
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
Example #17
0
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
Example #18
0
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
Example #19
0
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
Example #20
0
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)
Example #21
0
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)
Example #22
0
# 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
Example #23
0
def not_slave_node(grid):
    for node in node_iterator(grid):
        if not node.get_slave():
            yield node
Example #24
0
            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)
#   
#
Example #25
0
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)
Example #26
0
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))