Example #1
0
    def PI_1(self, fun):
        
        # Compute quadrature grid for integration of right-hand-side
        if self.bc == True:
            if self.p%2 != 0:

                grid = self.breakpoints
                pts, wts = bsp.quadrature_grid(grid, self.pts_loc, self.wts_loc)

            else:

                grid = np.append(self.greville, self.greville[-1] + (self.greville[-1] - self.greville[-2])) 
                pts, wts = bsp.quadrature_grid(grid, self.pts_loc, self.wts_loc)%self.breakpoints[-1]

        else:

            pts, wts = bsp.quadrature_grid(self.greville, self.pts_loc, self.wts_loc)
            
        # Assemble vector of histopolation problem at greville points
        rhs = integrate_1d(pts, wts, fun)
        
        # Solve histopolation problem
        vec = np.linalg.solve(self.histopolation_V1, rhs)
        
        return vec   
Example #2
0
def mass_V0_B(T, p, bc, Bz0):
    
    el_b             = bsp.breakpoints(T, p)
    Nel              = len(el_b) - 1
    NbaseN           = Nel + p - bc*p
    
    pts_loc, wts_loc = np.polynomial.legendre.leggauss(p + 1)
    pts,     wts     = bsp.quadrature_grid(el_b, pts_loc, wts_loc)

    basisN           = bsp.basis_ders_on_quad_grid(T, p, pts, 0)

    M                = np.zeros((NbaseN, 2*p + 1))

    for ie in range(Nel):

        for il in range(p + 1):
            for jl in range(p + 1):

                value = 0.

                for q in range(p + 1):
                    value += wts[ie, q] * basisN[ie, il, 0, q] * basisN[ie, jl, 0, q] * Bz0(pts[ie, q])

                M[(ie + il)%NbaseN, p + jl - il] += value
                
    indices = np.indices((NbaseN, 2*p + 1))
    shift   = np.arange(NbaseN) - p
    
    row     = indices[0].flatten()
    col     = (indices[1] + shift[:, None])%NbaseN
    
    M       = spa.csr_matrix((M.flatten(), (row, col.flatten())), shape=(NbaseN, NbaseN))
    M.eliminate_zeros()
                
    return M    
Example #3
0
def L2_prod_V1(T, p, bc, fun):
    
    t                = T[1:-1]
    
    el_b             = bsp.breakpoints(T, p)
    Nel              = len(el_b) - 1
    NbaseN           = Nel + p - bc*p
    NbaseD           = NbaseN - (1 - bc)
    
    pts_loc, wts_loc = np.polynomial.legendre.leggauss(p + 1)
    pts,     wts     = bsp.quadrature_grid(el_b, pts_loc, wts_loc)

    basisD           = bsp.basis_ders_on_quad_grid(t, p - 1, pts, 0, normalize=True)
    
    f_int            = np.zeros(NbaseD)
    
    for ie in range(Nel):
        for il in range(p):
            
            value = 0.
            for q in range(p + 1):
                value += wts[ie, q]*fun(pts[ie, q])*basisD[ie, il, 0, q]
                
            f_int[(ie + il)%NbaseD] += value
            
    return f_int
Example #4
0
def create_space(ne, p, order=None, xmin=0., xmax=1.):
    grid  = np.linspace(xmin, xmax, ne+1)
    knots = make_knots(grid, p, periodic=False)
    spans = elements_spans(knots, p)

    # In[6]:
    nelements = len(grid) - 1
    nbasis    = len(knots) - p - 1

    # we need the value a B-Spline and its first derivative
    nderiv = 1

    # create the gauss-legendre rule, on [-1, 1]
    if order is None:
        order = p
    u, w = gauss_legendre( order )

    # for each element on the grid, we create a local quadrature grid
    points, weights = quadrature_grid( grid, u, w )

    # for each element and a quadrature points,
    # we compute the non-vanishing B-Splines
    basis = basis_ders_on_quad_grid( knots, p, points, nderiv )

    return SplineSpace(knots=knots,
                       degree=p,
                       nelements=nelements,
                       nbasis=nbasis,
                       points=points,
                       weights=weights,
                       spans=spans,
                       basis=basis)
Example #5
0
def matrixAssembly_V1(p, Nbase, T, bc):
    """
    Computes the 1d mass matrix in the space V1.
    
    Parameters
    ----------
    p : int
        spline degree
    
    Nbase : int
        number of spline functions
        
    T : np.array
        knot vector
        
    bc : boolean
        boundary conditions (True = periodic, False = homogeneous Dirichlet, None = no boundary conditions)
        
    Returns
    -------
    M : 2d np.array
        mass matrix in V1
    """

    t = T[1:-1]

    el_b = bsp.breakpoints(T, p)
    ne = len(el_b) - 1

    pts_loc, wts_loc = np.polynomial.legendre.leggauss(p + 1)
    pts, wts = bsp.quadrature_grid(el_b, pts_loc, wts_loc)

    d = 0
    basis = bsp.basis_ders_on_quad_grid(t, p - 1, pts, d, normalize=True)

    M = np.zeros((Nbase - 1, Nbase - 1))

    for ie in range(ne):
        for il in range(p):
            for jl in range(p):
                i = ie + il
                j = ie + jl

                value_m = 0.

                for g in range(p + 1):
                    value_m += wts[ie, g] * basis[ie, il, 0, g] * basis[ie, jl,
                                                                        0, g]

                M[i, j] += value_m

    if bc == True:
        M[:p - 1, :] += M[-p + 1:, :]
        M[:, :p - 1] += M[:, -p + 1:]
        M = M[:M.shape[0] - p + 1, :M.shape[1] - p + 1]

    return M
Example #6
0
def L2_prod_V1(fun, p, Nbase, T):
    """
    Computes the L2 scalar product of the function 'fun' with the B-splines of the space V1
    using a quadrature rule of order p + 1.
    
    Parameters
    ----------
    fun : callable
        function for scalar product
    
    p : int
        spline degree
    
    Nbase : int
        number of spline functions
        
    T : np.array
        knot vector
        
    Returns
    -------
    f_int : np.array
        the result of the integration with each basis function
    """

    t = T[1:-1]

    el_b = bsp.breakpoints(T, p)
    ne = len(el_b) - 1

    pts_loc, wts_loc = np.polynomial.legendre.leggauss(p + 1)
    pts, wts = bsp.quadrature_grid(el_b, pts_loc, wts_loc)

    d = 0
    basis = bsp.basis_ders_on_quad_grid(t, p - 1, pts, d, normalize=True)

    f_int = np.zeros(Nbase - 1)

    for ie in range(ne):
        for il in range(p):
            i = ie + il

            value = 0.
            for g in range(p + 1):
                value += wts[ie, g] * fun(pts[ie, g]) * basis[ie, il, 0, g]

            f_int[i] += value

    return f_int
Example #7
0
def mass_V1(T, p, bc):
    
    t                = T[1:-1]
    
    el_b             = bsp.breakpoints(T, p)
    Nel              = len(el_b) - 1
    NbaseN           = Nel + p - bc*p
    NbaseD           = NbaseN - (1 - bc)
    
    pts_loc, wts_loc = np.polynomial.legendre.leggauss(p + 1)
    pts,     wts     = bsp.quadrature_grid(el_b, pts_loc, wts_loc)

    basisD           = bsp.basis_ders_on_quad_grid(t, p - 1, pts, 0, normalize=True)
    
    M                = np.zeros((NbaseD, 2*p + 1))

    for ie in range(Nel):

        for il in range(p):
            for jl in range(p):

                value = 0.

                for q in range(p + 1):
                    value += wts[ie, q] * basisD[ie, il, 0, q] * basisD[ie, jl, 0, q]

                M[(ie + il)%NbaseD, p + jl - il] += value
                
    
    indices = np.indices((NbaseD, 2*p + 1))
    shift   = np.arange(NbaseD) - p

    row     = indices[0].flatten()
    col     = (indices[1] + shift[:, None])%NbaseD
    
    M       = spa.csr_matrix((M.flatten(), (row, col.flatten())), shape=(NbaseD, NbaseD))
    M.eliminate_zeros()
                
    return M
Example #8
0
def L2_prod_V0(T, p, bc, fun):
    
    el_b             = bsp.breakpoints(T, p)
    Nel              = len(el_b) - 1
    NbaseN           = Nel + p - bc*p
    
    pts_loc, wts_loc = np.polynomial.legendre.leggauss(p + 1)
    pts,     wts     = bsp.quadrature_grid(el_b, pts_loc, wts_loc)

    basisN           = bsp.basis_ders_on_quad_grid(T, p, pts, 0)
    
    f_int            = np.zeros(NbaseN)
    
    for ie in range(Nel):
        for il in range(p + 1):
            
            value = 0.
            for q in range(p + 1):
                value += wts[ie, q] * fun(pts[ie, q]) * basisN[ie, il, 0, q]
                
            f_int[(ie + il)%NbaseN] += value
            
    return f_int
Example #9
0
def histo(T, p, bc, grev):
    
    el_b = bsp.breakpoints(T, p)
    Nel = len(el_b) - 1
    t = T[1:-1]
    Nbase = Nel + p - bc*p
    
    if bc == True:
        
        pts_loc, wts_loc = np.polynomial.legendre.leggauss(p - 1)
        
        ne = Nbase
        D = np.zeros((ne, ne))
        
        if p%2 != 0:
            
            grid = el_b
            
            pts, wts = bsp.quadrature_grid(grid, pts_loc, wts_loc)
            col_quad = bsp.collocation_matrix(t, p - 1, pts.flatten(), bc, normalize=True)
            
            for ie in range(Nel):
                for il in range(p):
                    
                    i = (ie + il)%ne
                    
                    for k in range(p - 1):
                        D[ie, i] += wts[ie, k]*col_quad[ie*(p - 1) + k, i]

            return D
        
        else:
            
            grid = np.linspace(0., el_b[-1], 2*Nel + 1)
            
            pts, wts = bsp.quadrature_grid(grid, pts_loc, wts_loc)
            col_quad = bsp.collocation_matrix(t, p - 1, pts.flatten(), bc, normalize=True)
            
            for iee in range(2*Nel):
                for il in range(p):
                    
                    ie = int(iee/2)
                    ie_grev = int(np.ceil(iee/2) - 1)
                    
                    i = (ie + il)%ne
                    
                    for k in range(p - 1):
                        D[ie_grev, i] += wts[iee, k]*col_quad[iee*(p - 1) + k, i]

            return D
        
    else:
        
        ng = len(grev)
        
        col_quad = bsp.collocation_matrix(T, p, grev, bc)
        
        D = np.zeros((ng - 1, Nbase - 1))
        
        for i in range(ng - 1):
            for j in range(max(i - p + 1, 1), min(i + p + 3, Nbase)):
                s = 0.
                for k in range(j):
                    s += col_quad[i, k] - col_quad[i + 1, k]
                    
                D[i, j - 1] = s
                
        return D
Example #10
0
def matrixAssembly_V0(p, Nbase, T, bc):
    """
    Computes the 1d mass and advection matrix in the space V0.
    
    Parameters
    ----------
    p : int
        spline degree
    
    Nbase : int
        number of spline functions
        
    T : np.array
        knot vector
        
    bc : boolean
        boundary conditions (True = periodic, False = homogeneous Dirichlet, None = no boundary conditions)
        
    Returns
    -------
    M : 2d np.array
        mass matrix in V0
        
    D : 2d np.array
        advection matrix in V0
    """

    el_b = bsp.breakpoints(T, p)
    ne = len(el_b) - 1

    pts_loc, wts_loc = np.polynomial.legendre.leggauss(p + 1)
    pts, wts = bsp.quadrature_grid(el_b, pts_loc, wts_loc)

    d = 1
    basis = bsp.basis_ders_on_quad_grid(T, p, pts, d)

    M = np.zeros((Nbase, Nbase))
    C = np.zeros((Nbase, Nbase))

    for ie in range(ne):
        for il in range(p + 1):
            for jl in range(p + 1):
                i = ie + il
                j = ie + jl

                value_m = 0.
                value_c = 0.

                for g in range(p + 1):
                    value_m += wts[ie, g] * basis[ie, il, 0, g] * basis[ie, jl,
                                                                        0, g]
                    value_c += wts[ie, g] * basis[ie, il, 0, g] * basis[ie, jl,
                                                                        1, g]

                M[i, j] += value_m
                C[i, j] += value_c

    if bc == True:
        M[:p, :] += M[-p:, :]
        M[:, :p] += M[:, -p:]
        M = M[:M.shape[0] - p, :M.shape[1] - p]

        C[:p, :] += C[-p:, :]
        C[:, :p] += C[:, -p:]
        C = C[:C.shape[0] - p, :C.shape[1] - p]

    elif bc == False:
        M = M[1:-1, 1:-1]
        C = C[1:-1, 1:-1]

    return M, C
Example #11
0
def histopolation_matrix_1d(p, Nbase, T, grev, bc):
    """
    Computest the 1d histopolation matrix.
    
    Parameters
    ----------
    p : int
        spline degree
        
    Nbase : int
        number of spline functions
    
    T : np.array 
        knot vector
    
    grev : np.array
        greville points
        
    bc : boolean
        boundary conditions (True = periodic, False = homogeneous Dirichlet, None = no boundary conditions)
        
    Returns
    -------
    D : 2d np.array
        histopolation matrix
    """

    el_b = bsp.breakpoints(T, p)
    Nel = len(el_b) - 1
    t = T[1:-1]

    if bc == True:

        pts_loc, wts_loc = np.polynomial.legendre.leggauss(p - 1)

        ne = Nbase - p
        D = np.zeros((ne, ne))

        if p % 2 != 0:

            grid = el_b

            pts, wts = bsp.quadrature_grid(grid, pts_loc, wts_loc)
            col_quad = bsp.collocation_matrix(t,
                                              p - 1,
                                              pts.flatten(),
                                              bc,
                                              normalize=True)

            for ie in range(Nel):
                for il in range(p):

                    i = (ie + il) % ne

                    for k in range(p - 1):
                        D[ie, i] += wts[ie, k] * col_quad[ie * (p - 1) + k, i]

            return D

        else:

            grid = np.linspace(0., el_b[-1], 2 * Nel + 1)

            pts, wts = bsp.quadrature_grid(grid, pts_loc, wts_loc)
            col_quad = bsp.collocation_matrix(t,
                                              p - 1,
                                              pts.flatten(),
                                              bc,
                                              normalize=True)

            for iee in range(2 * Nel):
                for il in range(p):

                    ie = int(iee / 2)
                    ie_grev = int(np.ceil(iee / 2) - 1)

                    i = (ie + il) % ne

                    for k in range(p - 1):
                        D[ie_grev,
                          i] += wts[iee, k] * col_quad[iee * (p - 1) + k, i]

            return D

    else:

        ng = len(grev)

        col_quad = bsp.collocation_matrix(T, p, grev, bc)

        D = np.zeros((ng - 1, Nbase - 1))

        for i in range(ng - 1):
            for j in range(max(i - p + 1, 1), min(i + p + 3, Nbase)):
                s = 0.
                for k in range(j):
                    s += col_quad[i, k] - col_quad[i + 1, k]

                D[i, j - 1] = s

        return D
Example #12
0
def matrixAssembly_backgroundField(p, Nbase, T, bc, B_background_z):
    """
    Computes the 1d mass matrix weighted with some background field in the space V0.
    
    Parameters
    ----------
    p : int
        spline degree
    
    Nbase : int
        number of spline functions
        
    T : np.array
        knot vector
        
    bc : boolean
        boundary conditions (True = periodic, False = homogeneous Dirichlet, None = no boundary conditions)
        
    B_background_z : callable
        the variation of the background magnetic field in z-direction
        
    Returns
    -------
    D : 2d np.array
        mass matrix in V0
    """

    el_b = bsp.breakpoints(T, p)
    ne = len(el_b) - 1

    pts_loc, wts_loc = np.polynomial.legendre.leggauss(p + 1)
    pts, wts = bsp.quadrature_grid(el_b, pts_loc, wts_loc)

    d = 0
    basis = bsp.basis_ders_on_quad_grid(T, p, pts, d)

    D = np.zeros((Nbase, Nbase))

    for ie in range(ne):
        for il in range(p + 1):
            for jl in range(p + 1):
                i = ie + il
                j = ie + jl

                value_d = 0.

                for g in range(p + 1):
                    value_d += wts[ie, g] * basis[ie, il, 0, g] * basis[
                        ie, jl, 0, g] * B_background_z(pts[ie, g])

                D[i, j] += value_d

    if bc == True:
        D[:p, :] += D[-p:, :]
        D[:, :p] += D[:, -p:]
        D = D[:D.shape[0] - p, :D.shape[1] - p]

    elif bc == False:
        D = D[1:-1, 1:-1]

    return D