def interp(self, y, eigval=1, same_mesh=False, verbose=False): """Interpolate solution eigenvector and it's derivative onto y """ N = self.N nx, eigval = self.get_eigval(eigval, verbose) phi_hat = np.zeros(N, np.complex) phi_hat[:-4] = np.squeeze(self.eigvectors[:, nx]) if same_mesh: phi = np.zeros_like(phi_hat) dphidy = np.zeros_like(phi_hat) if self.SB is None: self.SB = ShenBiharmonicBasis(N, quad=self.quad, plan=True) self.SD = ShenDirichletBasis(N, quad=self.quad, plan=True) self.CDB = inner_product((self.SD, 0), (self.SB, 1)) phi = self.SB.ifst(phi_hat, phi) dphidy_hat = self.CDB.matvec(phi_hat) dphidy_hat = self.SD.apply_inverse_mass(dphidy_hat) dphidy = self.SD.backward(dphidy_hat, dphidy) else: # Recompute interpolation matrices if necessary if not len(self.P4) == len(y): SB = ShenBiharmonicBasis(N, quad=self.quad) V = self.V = SB.vandermonde(y) P4 = self.P4 = SB.get_vandermonde_basis(V) T4x = self.T4x = SB.get_vandermonde_basis_derivative(V, 1) phi = np.dot(self.P4, phi_hat) dphidy = np.dot(self.T4x, phi_hat) return phi, dphidy
def interp(self, y, eigvals, eigvectors, eigval=1, same_mesh=False, verbose=False): """Interpolate solution eigenvector and it's derivative onto y args: y Interpolation points eigvals All computed eigenvalues eigvectors All computed eigenvectors kwargs: eigval The chosen eigenvalue, ranked with descending imaginary part. The largest imaginary part is 1, the second largest is 2, etc. same_mesh Boolean. Whether or not to interpolate to the same quadrature points as used for computing the eigenvectors verbose Boolean. Print information or not """ N = self.N nx, eigval = self.get_eigval(eigval, eigvals, verbose) phi_hat = np.zeros(N, np.complex) phi_hat[:-4] = np.squeeze(eigvectors[:, nx]) if same_mesh: phi = np.zeros_like(phi_hat) dphidy = np.zeros_like(phi_hat) if self.SB is None: self.SB = ShenBiharmonicBasis(N, quad=self.quad, plan=True) self.SD = ShenDirichletBasis(N, quad=self.quad, plan=True) self.CDB = inner_product((self.SD, 0), (self.SB, 1)) phi = self.SB.ifst(phi_hat, phi) dphidy_hat = self.CDB.matvec(phi_hat) dphidy_hat = self.SD.apply_inverse_mass(dphidy_hat) dphidy = self.SD.backward(dphidy_hat, dphidy) else: # Recompute interpolation matrices if necessary if not len(self.P4) == len(y): SB = ShenBiharmonicBasis(N, quad=self.quad) V = SB.vandermonde(y) self.P4 = SB.get_vandermonde_basis(V) self.T4x = SB.get_vandermonde_basis_derivative(V, 1) phi = np.dot(self.P4, phi_hat) dphidy = np.dot(self.T4x, phi_hat) return eigval, phi, dphidy
def assemble(self): N = self.N SB = ShenBiharmonicBasis(N, quad=self.quad) SB.plan((N, N), 0, np.float, {}) x, w = self.x, self.w = SB.points_and_weights(N) V = SB.vandermonde(x) # Trial function P4 = SB.get_vandermonde_basis(V) # Second derivatives T2x = SB.get_vandermonde_basis_derivative(V, 2) # (u'', v) K = np.zeros((N, N)) K[:-4, :-4] = inner_product((SB, 0), (SB, 2)).diags().toarray() # ((1-x**2)u, v) xx = np.broadcast_to((1 - x**2)[:, np.newaxis], (N, N)) #K1 = np.dot(w*P4.T, xx*P4) # Alternative: K1 = np.dot(w*P4.T, ((1-x**2)*P4.T).T) K1 = np.zeros((N, N)) K1 = SB.scalar_product(xx * P4, K1) K1 = extract_diagonal_matrix( K1).diags().toarray() # For improved roundoff # ((1-x**2)u'', v) K2 = np.zeros((N, N)) K2 = SB.scalar_product(xx * T2x, K2) K2 = extract_diagonal_matrix( K2).diags().toarray() # For improved roundoff # (u'''', v) Q = np.zeros((self.N, self.N)) Q[:-4, :-4] = inner_product((SB, 0), (SB, 4)).diags().toarray() # (u, v) M = np.zeros((self.N, self.N)) M[:-4, :-4] = inner_product((SB, 0), (SB, 0)).diags().toarray() Re = self.Re a = self.alfa B = -Re * a * 1j * (K - a**2 * M) A = Q - 2 * a**2 * K + a**4 * M - 2 * a * Re * 1j * M - 1j * a * Re * ( K2 - a**2 * K1) return A, B