def solve(self, b, u=None): if len(self.naxes) == 0: d = self.scale with np.errstate(divide='ignore'): d = 1. / self.scale d = np.where(np.isfinite(d), d, 0) if u is not None: u[:] = b * d return u return b * d elif len(self.naxes) == 1: axis = self.naxes[0] u = self.pmat.solve(b, u=u, axis=axis) with np.errstate(divide='ignore'): u /= self.scale u[:] = np.where(np.isfinite(u), u, 0) return u elif len(self.naxes) == 2: from shenfun.la import SolverGeneric2NP H = SolverGeneric2NP([self]) u = H(b, u) return u
v = TestFunction(T) # Get f on quad points fj = Array(T, buffer=fl(*X)) # Compute right hand side of biharmonic equation f_hat = inner(v, fj) # Get left hand side of biharmonic equation if family == 'chebyshev': # No integration by parts due to weights matrices = inner(v, div(grad(div(grad(u))))) else: # Use form with integration by parts. matrices = inner(div(grad(v)), div(grad(u))) # Create linear algebra solver H = SolverGeneric2NP(matrices) # Solve and transform to real space u_hat = Function(T) # Solution spectral space u_hat = H(f_hat, u_hat) # Solve uq = u_hat.backward() # Compare with analytical solution uj = ul(*X) print(abs(uj - uq).max()) assert np.allclose(uj, uq) points = np.array([[0.2, 0.3], [0.1, 0.5]]) p = T.eval(points, u_hat, method=2) assert np.allclose(p, ul(*points))
# Compute the right hand side on the quadrature mesh gj = Array(T, buffer=g) # Take scalar product g_hat = Function(T) g_hat = inner(v, gj, output_array=g_hat) if by_parts: mats = inner(div(grad(v)), div(grad(u))) else: mats = inner(v, div(grad(div(grad(u))))) # Solve u_hat = Function(T) Sol1 = SolverGeneric2NP(mats) u_hat = Sol1(g_hat, u_hat) # Transform back to real space. uj = u_hat.backward() uq = Array(T, buffer=ue) X = T.local_mesh(True) print('Error =', np.linalg.norm(uj - uq)) theta0, r0 = X[0], X[1] x0, y0 = r0 * np.cos(theta0), r0 * np.sin(theta0) plt.contourf(x0, y0, uq) plt.colorbar() # Postprocess # Refine for a nicer plot. Refine simply pads Functions with zeros, which