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]
Esempio n. 3
0
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)
Esempio n. 4
0
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
Esempio n. 5
0
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