(levels, strength, CF, keep)
Extend the multigrid hierarchy.
Extend the multigrid hierarchy.
Extend the multigrid hierarchy .
def _extend_hierarchy(levels, strength, CF, keep):
    """Extend the multigrid hierarchy."""
    def unpack_arg(v):
        if isinstance(v, tuple):
            return v[0], v[1]
        return v, {}

    A = levels[-1].A

    # Compute the strength-of-connection matrix C, where larger
    # C[i,j] denote stronger couplings between i and j.
    fn, kwargs = unpack_arg(strength)
    if fn == 'symmetric':
        C = symmetric_strength_of_connection(A, **kwargs)
    elif fn == 'classical':
        C = classical_strength_of_connection(A, **kwargs)
    elif fn == 'distance':
        C = distance_strength_of_connection(A, **kwargs)
    elif fn in ('ode', 'evolution'):
        C = evolution_strength_of_connection(A, **kwargs)
    elif fn == 'energy_based':
        C = energy_based_strength_of_connection(A, **kwargs)
    elif fn == 'algebraic_distance':
        C = algebraic_distance(A, **kwargs)
    elif fn == 'affinity':
        C = affinity_distance(A, **kwargs)
    elif fn is None:
        C = A
    else:
        raise ValueError(f'Unrecognized strength of connection method: {fn}')

    # Generate the C/F splitting
    fn, kwargs = unpack_arg(CF)
    if fn == 'RS':
        splitting = split.RS(C, **kwargs)
    elif fn == 'PMIS':
        splitting = split.PMIS(C, **kwargs)
    elif fn == 'PMISc':
        splitting = split.PMISc(C, **kwargs)
    elif fn == 'CLJP':
        splitting = split.CLJP(C, **kwargs)
    elif fn == 'CLJPc':
        splitting = split.CLJPc(C, **kwargs)
    elif fn == 'CR':
        splitting = CR(C, **kwargs)
    else:
        raise ValueError(f'Unknown C/F splitting method {CF}')

    # Generate the interpolation matrix that maps from the coarse-grid to the
    # fine-grid
    P = direct_interpolation(A, C, splitting)

    # Generate the restriction matrix that maps from the fine-grid to the
    # coarse-grid
    R = P.T.tocsr()

    # Store relevant information for this level
    if keep:
        levels[-1].C = C                  # strength of connection matrix
        levels[-1].splitting = splitting  # C/F splitting

    levels[-1].P = P                  # prolongation operator
    levels[-1].R = R                  # restriction operator

    levels.append(MultilevelSolver.Level())

    # Form next level through Galerkin product
    A = R * A * P
    levels[-1].A = A
def _extend_hierarchy ( levels , strength , CF , keep ) : def unpack_arg ( v ) : if isinstance ( v , tuple ) : return v [ 0 ] , v [ 1 ] return v , { } A = levels [ - 1 ] . A # Compute the strength-of-connection matrix C, where larger # C[i,j] denote stronger couplings between i and j. fn , kwargs = unpack_arg ( strength ) if fn == 'symmetric' : C = symmetric_strength_of_connection ( A , * * kwargs ) elif fn == 'classical' : C = classical_strength_of_connection ( A , * * kwargs ) elif fn == 'distance' : C = distance_strength_of_connection ( A , * * kwargs ) elif fn in ( 'ode' , 'evolution' ) : C = evolution_strength_of_connection ( A , * * kwargs ) elif fn == 'energy_based' : C = energy_based_strength_of_connection ( A , * * kwargs ) elif fn == 'algebraic_distance' : C = algebraic_distance ( A , * * kwargs ) elif fn == 'affinity' : C = affinity_distance ( A , * * kwargs ) elif fn is None : C = A else : raise ValueError ( f'Unrecognized strength of connection method: {fn}' ) # Generate the C/F splitting fn , kwargs = unpack_arg ( CF ) if fn == 'RS' : splitting = split . RS ( C , * * kwargs ) elif fn == 'PMIS' : splitting = split . PMIS ( C , * * kwargs ) elif fn == 'PMISc' : splitting = split . PMISc ( C , * * kwargs ) elif fn == 'CLJP' : splitting = split . CLJP ( C , * * kwargs ) elif fn == 'CLJPc' : splitting = split . CLJPc ( C , * * kwargs ) elif fn == 'CR' : splitting = CR ( C , * * kwargs ) else : raise ValueError ( f'Unknown C/F splitting method {CF}' ) # Generate the interpolation matrix that maps from the coarse-grid to the # fine-grid P = direct_interpolation ( A , C , splitting ) # Generate the restriction matrix that maps from the fine-grid to the # coarse-grid R = P . T . tocsr ( ) # Store relevant information for this level if keep : levels [ - 1 ] . C = C # strength of connection matrix levels [ - 1 ] . splitting = splitting # C/F splitting levels [ - 1 ] . P = P # prolongation operator levels [ - 1 ] . R = R # restriction operator levels . append ( MultilevelSolver . Level ( ) ) # Form next level through Galerkin product A = R * A * P levels [ - 1 ] . A = A