Beispiel #1
0
def computeError(df, df2, mesh, vm, basis):
    from dgfs1D.quadratures import nodal_basis_at, zwglj
    f, f2 = map(lambda v: v.get().reshape(basis.Nq, -1, vm.vsize()), (df, df2))
    Nq, Ne2, nvars = f2.shape
    r, w = zwglj(Nq, 0., 0.)
    r2 = r * 0.5 + 0.5
    r2 = np.array([*(-np.flip(r2)), *(r2)])
    im = nodal_basis_at(Nq, r, r2)

    fr = np.einsum('rm,mjk->rjk', im, f)
    fr = fr.swapaxes(0, 2).reshape((-1, Ne2, Nq)).swapaxes(0, 2)
    f2r = f2
    order = 2  # integer norm order
    diff = np.abs(fr - f2r)**order
    L1e = np.einsum('q,qjk,j->jk', w, diff, mesh.jac.ravel())

    res = np.sum(L1e, axis=(0, 1))
    res = np.array([res, 0.])
    comm, rank, root = get_comm_rank_root()
    if rank != root:
        comm.Reduce(res, None, op=get_mpi('sum'), root=root)
        return None
    else:
        comm.Reduce(get_mpi('in_place'), res, op=get_mpi('sum'), root=root)
        return (res[0]**(1. / order)) / ((mesh.xhi - mesh.xlo) * 2 * vm.L())
Beispiel #2
0
def computeError2(df, df2, mesh, vm, basis):
    from dgfs1D.quadratures import nodal_basis_at, zwglj
    f, f2 = map(lambda v: v.get().reshape(basis.Nq, -1, vm.vsize()), (df, df2))
    Nq, Ne2, nvars = f2.shape
    r, w = zwglj(Nq, 0., 0.)
    r2, w2 = zwglj(Nq, 0., 0.)
    #r2 = r*0.5 + 0.5;
    #r2 = np.array([*(-np.flip(r2)), *(r2)]);
    im = nodal_basis_at(Nq, r, r2)

    fr = np.einsum('rm,mjk->rjk', im, f)
    f2r = np.einsum('rm,mjk->rjk', im, f2)

    xmesh, jac = mesh.xmesh, mesh.jac
    xsol = np.array(
        [0.5 * (xmesh[j] + xmesh[j + 1]) + jac[j] * r2 for j in range(Ne2)]).T
    time = 0.2
    u = np.sin(2 * np.pi * (xsol - time))
    #fr = np.stack([u]*nvars,2)
    #fr.set(np.stack([u]*Nv,2).ravel())
    #fr = fr.reshape

    #fr = fr.swapaxes(0,2).reshape((-1, Ne2, Nq)).swapaxes(0,2);
    #fr = f
    #f2r = f2;
    order = 2  # integer norm order
    #diff = np.abs(fr - f2r)**order;
    diff = np.abs(fr - f2r)**order
    L1e = np.einsum('q,qjk,j->jk', w2, diff, mesh.jac.ravel())

    res = np.sum(L1e, axis=(0, 1))
    #res = np.max(diff)
    #res = np.max(np.abs(df - df2))

    res = np.array([res, 0.])
    comm, rank, root = get_comm_rank_root()
    if rank != root:
        comm.Reduce(res, None, op=get_mpi('sum'), root=root)
        return None
    else:
        comm.Reduce(get_mpi('in_place'), res, op=get_mpi('sum'), root=root)
        return (res[0]**(1. / order)) / ((mesh.xhi - mesh.xlo) * 2 * vm.L())
Beispiel #3
0
    def glj(self):
        xlo = self.cfg.lookupfloat(msect, 'xlo')
        xhi = self.cfg.lookupfloat(msect, 'xhi')
        assert xlo < xhi, "xlo must be less than xhi"

        alpha = self.cfg.lookupordefault(msect, 'alpha', 0.0)
        beta = self.cfg.lookupordefault(msect, 'beta', 0.0)
        assert alpha > -1., 'Requirement of gauss quadratures'
        assert beta > -1., 'Requirement of gauss quadratures'

        Ne = self.cfg.lookupint(msect, 'Ne')
        assert Ne > 0, "Need atleast one element to define a mesh"

        # quadrature in interval [-1, 1]
        z, _ = zwglj(Ne + 1, alpha, beta)
        z = z.astype(self.cfg.dtype)

        # scale to interval [xlo, xhi]
        z = 0.5 * (xhi + xlo) + 0.5 * (xhi - xlo) * z

        return z
Beispiel #4
0
    def __init__(self, cfg, **kwargs):
        super().__init__(cfg, **kwargs)

        # number of quadrature points inside each element
        self._Nq = self._K

        # the Gauss-Lobatto quadrature on standard interval
        self._z, self._w = zwglj(self._Nq, 0., 0.)

        # define the lagrange nodal basis
        self._B = nodal_basis_at(self._K, self._z, self._z).T

        # define the mass matrix
        # since the basis is identity, this just have weights on diagonal
        self._M = np.einsum("mq,q,lq->ml", self._B, self._w, self._B)
        self._invM = np.linalg.inv(self._M)

        # Forward transform operator
        self._fwdTransMat = self._B  # identity

        # interpolation operator
        Nqr = self.cfg.lookupint(basissect, 'Nqr')
        #zr = np.linspace(-1., 1., Nqr) # the reconstruction points
        zr, _ = zwglj(Nqr, 0., 0.)  # the reconstruction points
        Br = nodal_basis_at(self._K, self._z, zr).T  # at "recons" points
        #self._interpMat = np.einsum('kr,kq->rq', Br, self._fwdTransMat)
        self._interpMat = Br

        # the H tensor (see J. Comput. Phys. 378, 178-208, 2019)
        H = np.einsum("mq,aq,bq,q->mab", self._B, self._B, self._B, self._w)
        invM_H = np.einsum("ml,mab->lab", self._invM, H)
        invM_H = H

        # svd decomposition
        # defines the U, V matrices, and identifies the significant modes
        U, V, sigModes = [0] * self._K, [0] * self._K, [0] * self._K
        for m in range(self._K):
            u, s, v = np.linalg.svd(invM_H[m, :, :])
            U[m], V[m] = u, np.dot(np.diag(s), v)
            U[m], V[m] = map(filter_tol, (U[m], V[m]))
            nnzUm = np.where(np.sum(U[m], axis=0) != 0)[0]
            nnzVm = np.where(np.sum(V[m], axis=1) != 0)[0]
            sigModes[m] = np.intersect1d(nnzUm, nnzVm)

        self._U, self._V, self._sigModes = U, V, sigModes

        # define the {K-1} order derivative matrix
        D = jac_nodal_basis_at(self._K, self._z, self._z)[0]
        self._Sx = np.matmul(self._M, D.T).T
        self._derivMat = self._Sx.T

        # define the operator for reconstructing solution at faces
        self._Nqf = 2  # number of points used in reconstruction at faces
        zqf, _ = zwglj(self._Nqf, 0., 0.)
        self._Bqf = nodal_basis_at(self._K, self._z, zqf).T

        # define the correction functions at the left and right boundaries
        self._gLD = self._Bqf[:, 0]  #/self._w[0]
        self._gRD = self._Bqf[:, -1]  #/self._w[-1]
        #gLD, gRD = invM[0,:], invM[-1,:]

        # prepare kernels
        # since B is identity, (fwdTrans, bwdTrans) just copy data
        self._fwdTransKern = get_mm_kernel(self._fwdTransMat)
        self._bwdTransKern = get_mm_kernel(self._B.T)
        self._bwdTransFaceKern = get_mm_kernel(self._Bqf.T)
        self._derivKern = get_mm_kernel(self._Sx.T)
        self._invMKern = get_mm_kernel(self._invM.T)

        # U, V operator kernels
        for m in range(self._K):
            self._uTransKerns[m] = get_mm_kernel(self._U[m].T)
            self._vTransKerns[m] = get_mm_kernel(self._V[m])

        # operators for limiting
        V = ortho_basis_at(self._K, self._z).T
        invV = np.linalg.inv(V)

        computeCellAvgOp = V.copy()
        computeCellAvgOp[:, 1:] = 0
        computeCellAvgOp = np.matmul(computeCellAvgOp, invV)

        extractLinOp = V.copy()
        extractLinOp[:, 2:] = 0
        extractLinOp = np.matmul(extractLinOp, invV)
        extractDrLinOp = np.matmul(D.T, extractLinOp)

        self.computeCellAvgKern, self.extractDrLinKern = map(
            get_mm_kernel, (computeCellAvgOp, extractDrLinOp))
Beispiel #5
0
    def __init__(self, cfg, **kwargs):
        super().__init__(cfg, **kwargs)

        # number of quadrature points inside each element
        self._Nq = self.cfg.lookupordefault(basissect, 'Nq',
                                            np.int(np.ceil(1.5 * self._K)))

        # define the orthonormal basis
        # the Gauss quadrature on standard interval
        self._z, self._w = zwgrjm(self._Nq, 0., 0.)

        # define the modified basis (see Karniadakis, page 64)
        self._B = self.modified_basis_at(self._K, self._z)

        # define the mass matrix
        self._M = np.einsum("mq,q,lq->ml", self._B, self._w, self._B)
        self._invM = np.linalg.inv(self._M)

        # Forward transform operator
        self._fwdTransMat = np.einsum("ml,lq,q->mq", self._invM, self._B,
                                      self._w)

        # interpolation operator
        Nqr = self.cfg.lookupint(basissect, 'Nqr')
        zr = np.linspace(-1, 1, Nqr)  # the reconstruction points
        Br = self.modified_basis_at(self._K, zr)  # basis at reconst points
        self._interpMat = Br

        # the H tensor (see J. Comput. Phys. 378, 178-208, 2019)
        H = np.einsum("mq,aq,bq,q->mab", self._B, self._B, self._B, self._w)
        invM_H = np.einsum("ml,mab->lab", self._invM, H)

        # svd decomposition
        # defines the U, V matrices, and identifies the significant modes
        U, V, sigModes = [0] * self._K, [0] * self._K, [0] * self._K
        for m in range(self._K):
            u, s, v = np.linalg.svd(H[m, :, :])
            U[m], V[m] = u, np.dot(np.diag(s), v)
            U[m], V[m] = map(filter_tol, (U[m], V[m]))
            nnzUm = np.where(np.sum(U[m], axis=0) != 0)[0]
            nnzVm = np.where(np.sum(V[m], axis=1) != 0)[0]
            sigModes[m] = np.intersect1d(nnzUm, nnzVm)

        self._U, self._V, self._sigModes = U, V, sigModes

        # define the {K-1} order derivative matrix
        D = self.jac_modified_basis_at(self._K, self._z)
        self._Sx = np.einsum("lq,q,mq->ml", self._B, self._w, D)
        #self._Sx = np.einsum("ml,mn->ln", self._invM, self._Sx)
        #self._Sx = np.einsum("lm,mn->ln", self._invM, self._Sx)

        # define the operator for reconstructing solution at faces
        self._Nqf = 2  # number of points used in reconstruction at faces
        zqf, _ = zwglj(self._Nqf, 0., 0.)
        self._Bqf = self.modified_basis_at(self._K, zqf)
        #self._gBqf = np.einsum("ml,mn->ln", self._invM, self._Bqf)

        # define the correction functions at the left and right boundaries
        #self._gLD, self._gRD = self._gBqf[:,0], self._gBqf[:,-1]
        self._gLD, self._gRD = self._Bqf[:, 0], self._Bqf[:, -1]

        # prepare kernels
        self._fwdTransKern = get_mm_kernel(self._fwdTransMat)
        self._bwdTransKern = get_mm_kernel(self._B.T)
        self._bwdTransFaceKern = get_mm_kernel(self._Bqf.T)
        self._derivKern = get_mm_kernel(self._Sx.T)
        self._invMKern = get_mm_kernel(self._invM.T)

        # U, V operator kernels
        for m in range(self._K):
            self._uTransKerns[m] = get_mm_kernel(self._U[m].T)
            self._vTransKerns[m] = get_mm_kernel(self._V[m])
Beispiel #6
0
def computeError_3D(df, df2, mesh, vm, basis, dx, dx2):
    from dgfs1D.quadratures import nodal_basis_at, zwglj
    f, f2 = map(lambda v: v.get().reshape(basis.Nq, -1, vm.vsize()), (df, df2))
    Nq, Ne2, nvars = f2.shape
    _, Ne, _ = f.shape
    x, x2 = map(lambda v: v[:, :, 0].reshape(basis.Nq, -1), (dx, dx2))
    y, y2 = map(lambda v: v[:, :, 1].reshape(basis.Nq, -1), (dx, dx2))

    w = np.array(basis.w[0])

    # interpolation operator
    dim = mesh.cfg.dim
    Nq1 = int(Nq**(1. / dim))
    Ne1 = int(Ne2**(1. / dim))

    print(f.shape, f2.shape, Ne1)

    r, _ = zwglj(Nq1, 0., 0.)
    r2 = r * 0.5 + 0.5
    r2 = np.array([*(-np.flip(r2)), *(r2)])
    Br = nodal_basis_at(basis._K1, r, r2).T  # at "recons" points
    from dgfs1D.util import ndkron
    im = ndkron(*[Br] * dim).T
    print(im.shape)

    fr = np.einsum('rm,mjk->rjk', im, f)
    # fr = (q1*q2, e1*e2, v)
    #
    #fr = fr.swapaxes(0,2).reshape((-1, Ne2, Nq)).swapaxes(0,2);
    f2r = f2

    xr, yr = map(lambda v: np.einsum('rm,mj->rj', im, v), (x, y))
    #func = lambda v: v.reshape(Ne2, Nq).T
    #func = lambda v: v.reshape(Nq1,Nq1,Ne1,Ne1).swapaxes(1,2).reshape(Nq, Ne2)
    func = lambda v: v.T.reshape(Nq1, Nq1, Ne1, Ne1).swapaxes(1, 2).reshape(
        Nq, Ne2)
    func = lambda v: v.reshape(Nq1, Nq1, Ne1, Ne1).swapaxes(1, 2).reshape(
        Nq1 * Ne1, Nq1 * Ne1).swapaxes(0, 1).ravel().reshape(Nq, Ne2)

    func = lambda v: v.reshape(Nq1, Nq1, Ne1, Ne1).swapaxes(1, 2).reshape(
        Nq, Ne2)
    xr, yr = map(func, (xr, yr))

    np.set_printoptions(suppress=True)
    print(x2.T)
    print(xr.T)

    print(x2.shape, xr.shape)
    import matplotlib.pyplot as plt
    plt.scatter(xr, yr, marker='o', s=20, facecolors='none', edgecolors='r')
    plt.scatter(x2, y2, c='k', marker='.', s=.1)
    plt.savefig('plot.pdf')
    print(np.linalg.norm(x2 - xr), np.linalg.norm(y2 - yr))
    exit(-1)

    jac = mesh.jac
    from dgfs1D.util import ndgrid
    jac = np.array(ndgrid(*jac)[0])

    order = 2  # integer norm order
    diff = np.abs(fr - f2r)**order
    L1e = np.einsum('q,qjk,j->jk', w.ravel(), diff, jac.ravel())

    res = np.sum(L1e, axis=(0, 1))
    res = np.array([res, 0.])
    comm, rank, root = get_comm_rank_root()
    if rank != root:
        comm.Reduce(res, None, op=get_mpi('sum'), root=root)
        return None
    else:
        comm.Reduce(get_mpi('in_place'), res, op=get_mpi('sum'), root=root)

        dim = mesh.cfg.dim
        fac = 0
        for i in range(dim):
            fac += (mesh.xhi[i] - mesh.xlo[i])
        fac *= (2 * vm.L())**3

        return (res[0]**(1. / order)) / fac