def compute_resonances(elt=None, K0=None, K1=None, K2=None, neigs=0): """ Compute resonances via a generalized linear eigenvalue problem. Input: elt K0 K1 K2 neigs -- Number of poles desired (default: 0 --> compute all) Output: l V """ if elt is not None: (N, nnz) = problem_size(elt) issparse = (neigs != 0) and (nnz < 0.2 * N ** 2) and (N > 100) (K0, K1, K2) = form_operators(elt, issparse) N = len(K0) # TODO: Adding sparsity Z = np.zeros((N, N)) I = np.eye(N) A = np.vstack((np.hstack((K0, Z)), np.hstack((Z, I)))) B = np.vstack((np.hstack((-K1, -K2)), np.hstack((I, Z)))) ll = eig(a=A, b=B, left=False, right=False) ll_sorted = (np.unique(ll.round(decimals=4)))[np.argsort(np.abs(np.unique(ll.round(decimals=4))))] ll_sorted = ll_sorted[np.abs(ll_sorted) < 1e308] return ll_sorted * 1.0j
def checked_resonances2(elt, neigs=0, tol=1e-6): """ Compute resonances with two densities in order to check convergence. If the same answer occurs to within tol, accept the pole as converged. Inputs: elt - coarse mesh neigs - number of poles desired? (default: 0 -> compute all) tol - absolute estimated error tolerance (default: 1e-6) Use tol = 0 to return everything """ (l, V) = compute_resonances(elt, neigs) if neigs == 0: neigs = len(l) N = problem_size(elt) dl = np.zeros((neigs,1)) V = V[0:N,:] for k in range(0,neigs): dl[k] = errest_resonance(elt, l[k], V[:,k]) if tol > 0: # Filter eigenvalues is_good = np.abs(dl) < tol l = l[is_good] dl = dl[is_good] V = V[:,is_good]
def plot_potential(elt): nelt = len(elt) (N, _) = problem_size(elt) N += (len(elt) - 1) u = np.zeros((N,)) x_tot = np.zeros((N,)) base = 0 for el in elt: order = el['order'] x = np.cos(np.pi * np.arange(order,-1,-1) / order) xelt = el['a'] * (1-x)/2 + el['b'] * (1+x)/2 x_tot[base:base+order+1] = xelt[:]; u[base:base+order+1] = eval_potential(el, xelt) base = base+order+1 return (x_tot, u)
def plot_fields(elt, u): (N, _) = problem_size(elt) x_tot = None if len(u) > N: x_tot = np.zeros((N+len(elt)-1,)) else: x_tot = np.zeros((N,)) base = 0 for el in elt: order = el['order'] x = np.cos(np.pi * np.arange(order,-1,-1) / order) xelt = el['a'] * (1-x)/2 + el['b'] * (1+x)/2 x_tot[base:base+order+1] = xelt if len(u) > N: base = base+order+1 else: base = base+order return x_tot
def plane_forcing (elt, l): """ Compute a forcing vector corresponding to the influence of an incident wave of the form exp(l*x) """ z = l/1.0j (N, _) = problem_size(elt) F = np.zeros((N,), dtype='complex_') base = 0 for el in elt: order = el['order'] x = np.cos(np.pi * np.arange(order,-1,-1) / order) xelt = el['a'] * (1-x)/2.0 + el['b'] * (1+x)/2.0 F[base:base+order+1] = -eval_potential(el, xelt) * np.exp(z*xelt) F[base] = 0 F[base+order] = 0 base = base+order return F