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())
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())
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
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))
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])
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