예제 #1
0
def resonance_dominant_bond_orders(rgr):
    """ resonance-dominant bond orders, by bond
    """
    bnd_keys = list(_bond_keys(rgr))
    bnd_ords_by_res = [
        dict_.values_by_key(_bond_orders(dom_rgr), bnd_keys)
        for dom_rgr in dominant_resonances(rgr)]
    bnd_ords_lst = list(map(frozenset, zip(*bnd_ords_by_res)))
    bnd_dom_res_ords_dct = dict(zip(bnd_keys, bnd_ords_lst))
    return bnd_dom_res_ords_dct
예제 #2
0
def _bond_capacities(rgr):
    """ the number of electron pairs available for further pi-bonding, by bond
    """
    atm_unsat_vlc_dct = _atom_unsaturated_valences(rgr)

    def _pi_capacities(bnd_key):
        return min(map(atm_unsat_vlc_dct.__getitem__, bnd_key))

    bnd_keys = list(_bond_keys(rgr))
    bnd_caps = tuple(map(_pi_capacities, bnd_keys))
    bnd_cap_dct = dict(zip(bnd_keys, bnd_caps))
    return bnd_cap_dct
예제 #3
0
def resonance_avg_bond_orders(rgr):
    """ resonance-dominant bond orders, by bond
    """
    bnd_keys = list(_bond_keys(rgr))
    bnd_ords_by_res = [
        dict_.values_by_key(_bond_orders(dom_rgr), bnd_keys)
        for dom_rgr in dominant_resonances(rgr)]
    nres = len(bnd_ords_by_res)
    bnd_ords_lst = zip(*bnd_ords_by_res)
    avg_bnd_ord_lst = [sum(bnd_ords)/nres for bnd_ords in bnd_ords_lst]
    avg_bnd_ord_dct = dict(zip(bnd_keys, avg_bnd_ord_lst))
    return avg_bnd_ord_dct
예제 #4
0
def _add_pi_bonds(rgr, bnd_ord_inc_dct):
    """ add pi bonds to this graph
    """
    bnd_keys = _bond_keys(rgr)
    assert set(bnd_ord_inc_dct.keys()) <= bnd_keys

    bnd_keys = list(bnd_keys)
    bnd_ords = dict_.values_by_key(_bond_orders(rgr), bnd_keys)
    bnd_ord_incs = dict_.values_by_key(bnd_ord_inc_dct, bnd_keys, fill_val=0)
    new_bnd_ords = numpy.add(bnd_ords, bnd_ord_incs)
    bnd_ord_dct = dict(zip(bnd_keys, new_bnd_ords))
    rgr = _set_bond_orders(rgr, bnd_ord_dct)
    return rgr
예제 #5
0
def subresonances(rgr):
    """ this connected graph and its lower-spin (more pi-bonded) resonances
    """
    def _inc_range(bnd_cap):
        return tuple(range(0, bnd_cap+1))

    add_pi_bonds_ = functools.partial(_add_pi_bonds, rgr)

    atm_keys = list(_atom_keys(rgr))
    bnd_keys = list(_bond_keys(rgr))
    atm_unsat_vlcs = dict_.values_by_key(
        _atom_unsaturated_valences(rgr), atm_keys)
    atm_bnd_keys_lst = dict_.values_by_key(_atom_bond_keys(rgr), atm_keys)
    bnd_caps = dict_.values_by_key(_bond_capacities(rgr), bnd_keys)
    bnd_ord_dct = _bond_orders(rgr)

    def _is_valid(bnd_ord_inc_dct):
        # check if pi bonds exceed unsaturated valences
        def __tally(atm_bnd_keys):
            return sum(dict_.values_by_key(bnd_ord_inc_dct, atm_bnd_keys))
        atm_unsat_vlc_decs = tuple(map(__tally, atm_bnd_keys_lst))
        enough_elecs = numpy.all(
            numpy.less_equal(atm_unsat_vlc_decs, atm_unsat_vlcs))
        # check if all bond orders are less than 4 (should only affect C2)
        bnd_inc_keys = bnd_ord_inc_dct.keys()
        bnd_incs = dict_.values_by_key(bnd_ord_inc_dct, bnd_inc_keys)
        bnd_ords = dict_.values_by_key(bnd_ord_dct, bnd_inc_keys)
        new_bnd_ords = numpy.add(bnd_ords, bnd_incs)
        not_too_many = numpy.all(numpy.less(new_bnd_ords, 4))
        return enough_elecs and not_too_many

    def _bond_value_dictionary(bnd_vals):
        return dict(zip(bnd_keys, bnd_vals))

    bnd_ord_incs_itr = itertools.product(*map(_inc_range, bnd_caps))
    bnd_ord_inc_dct_itr = map(_bond_value_dictionary, bnd_ord_incs_itr)
    bnd_ord_inc_dct_itr = filter(_is_valid, bnd_ord_inc_dct_itr)
    rgrs = tuple(sorted(map(add_pi_bonds_, bnd_ord_inc_dct_itr), key=_frozen))
    return rgrs