예제 #1
0
def loop_analysis(g, ctrl_src, tree, types={}):
    """Loop analysis respect to the tree of the network graph g"""
    eqs = []
    vars = []

    # loop equations of the cobranch voltages
    cobranches = g.branches() - tree.branches()
    for cobranch in cobranches:
        if btype(cobranch, types) not in 'IFG':
            lpos, lneg = g.loop(cobranch, tree, include_cobranch=True)
            lhs_pos = [Calculus(f_u(b, ctrl_src, types)) for b in lpos]
            lhs_neg = [Calculus(f_u(b, ctrl_src, types)) for b in lneg]
            lhs = Add(*lhs_pos) - Add(*lhs_neg)
            eqs.append(lhs)
            if btype(cobranch, types) not in 'U':
                vars.append(Calculus('I_' + cobranch))
            if btype(cobranch, types) in 'N':
                vars.append(Calculus('V_' + cobranch))

    # cut equations of the tree currents (for substitution or additional)
    tcur = {}
    for tb in tree.branches():
        bpos, bneg = g.cut(tb, tree, include_tree_branch=False)
        # moving (bpos, bneg) from lhs to rhs by negation
        rhs_pos = [Calculus(branch_current(b, ctrl_src, types)) for b in bneg]
        rhs_neg = [Calculus(branch_current(b, ctrl_src, types)) for b in bpos]
        rhs = Add(*rhs_pos) - Add(*rhs_neg)
        if btype(tb, types) not in 'IFGU':
            tcur[Calculus('I_' + tb)] = rhs.expand()
            if btype(tb, types) in 'N':
                vars.append(Calculus('V_' + tb))
        else:
            eqs.append(Calculus(f_i(tb, ctrl_src, types)) - rhs)
            if btype(tb, types) not in 'U':
                vars.append(Calculus('V_' + tb))

    # finally add variables and equations of controlled sources
    for src, ctrl in ctrl_src.items():
        if btype(src, types) in 'EG' and btype(ctrl, types) != 'V':
            v_ctrl = Calculus('V_' + ctrl)
            if v_ctrl not in vars:  # ctrl is no 'IFG' in tree
                # control voltage is unknown
                vars.append(v_ctrl)
                # try if control voltage can be substituted
                # then control branch is a (controlled) voltage source
                lhs = v_ctrl - f_u(ctrl, ctrl_src, types)
                if lhs == 0:
                    # ctrl is a current source
                    if ctrl in cobranches:
                        # add missing loop equation for v_ctrl which
                        # was omitted due to: btype(cobranch, types) not in 'IFG'
                        lpos, lneg = g.loop(ctrl, tree, include_cobranch=False)
                        lhs_pos = [
                            Calculus(f_u(b, ctrl_src, types)) for b in lpos
                        ]
                        lhs_neg = [
                            Calculus(f_u(b, ctrl_src, types)) for b in lneg
                        ]
                        lhs = v_ctrl + Add(*lhs_pos) - Add(*lhs_neg)
                    # if v_ctrl is in tree then var and cut equation are
                    # already added because ctrl is a current source
                eqs.append(lhs)
        elif btype(src, types) in 'F' and src in cobranches:
            if ctrl in tree.branches() and btype(ctrl, types) not in 'IFG':
                i_ctrl = Calculus('I_' + ctrl)
                # just a test avoiding duplication
                if i_ctrl not in vars:
                    # control current is unknown
                    vars.append(i_ctrl)
                    # remove cut equation for ctrl from tcur and add it to eqs
                    eqs.append(i_ctrl - tcur.pop(i_ctrl))

    # substitute tree currents by cobranch currents
    eqs = [e.subs(tcur).expand() for e in eqs]
    return eqs, vars
예제 #2
0
def cut_analysis(g, ctrl_src, tree, types={}):
    """Cut analysis respect to the tree of the network graph g"""
    eqs = []
    vars = []

    # cut equations of the tree currents
    for tb in tree.branches():
        if btype(tb, types) not in 'VEH':
            bpos, bneg = g.cut(tb, tree)
            lhs_pos = [Calculus(f_i(b, ctrl_src, types)) for b in bpos]
            lhs_neg = [Calculus(f_i(b, ctrl_src, types)) for b in bneg]
            lhs = Add(*lhs_pos) - Add(*lhs_neg)
            eqs.append(lhs)
            if btype(tb, types) not in 'U':
                vars.append(Calculus(branch_voltage(tb, ctrl_src, types)))
            if btype(tb, types) in 'N':
                vars.append(Calculus(branch_current(tb, ctrl_src, types)))

    # loop equations of the cobranch voltages
    cobranches = g.branches() - tree.branches()
    covolts = {}
    for cobranch in cobranches:
        lpos, lneg = g.loop(cobranch, tree)
        # moving (bpos, bneg) from lhs to rhs by negation
        rhs_pos = [Calculus(branch_voltage(b, ctrl_src, types)) for b in lneg]
        rhs_neg = [Calculus(branch_voltage(b, ctrl_src, types)) for b in lpos]
        rhs = Add(*rhs_pos) - Add(*rhs_neg)
        rhs = rhs.expand()
        if btype(cobranch, types) not in 'VEHU':
            covolts[Calculus(branch_voltage(cobranch, ctrl_src, types))] = rhs
            if btype(cobranch, types) in 'N':
                vars.append(Calculus('I_' + cobranch))
        else:
            eqs.append(Calculus(f_u(cobranch, ctrl_src, types)) - rhs)
            if btype(cobranch, types) not in 'U':
                vars.append(Calculus('I_' + cobranch))

    # finally add variables and equations of controlled sources
    for src, ctrl in ctrl_src.items():
        if btype(src, types) in 'FH' and btype(ctrl, types) != 'I':
            i_ctrl = Calculus('I_' + ctrl)
            if i_ctrl not in vars:  # ctrl is no 'VEH' in cotree
                # control current is unknown
                vars.append(i_ctrl)
                # try if control current can be substituted
                # then control branch is a (controlled) current source
                lhs = i_ctrl - Calculus(f_i(ctrl, ctrl_src, types))
                if lhs == 0:
                    # ctrl is a voltage source
                    if ctrl in tree.branches():
                        # add missing cut equation for i_ctrl which
                        # was omitted due to: btype(tb, types) not in 'VEH'
                        bpos, bneg = g.cut(ctrl,
                                           tree,
                                           include_tree_branch=False)
                        lhs_pos = [
                            Calculus(f_i(b, ctrl_src, types)) for b in bpos
                        ]
                        lhs_neg = [
                            Calculus(f_i(b, ctrl_src, types)) for b in bneg
                        ]
                        lhs = i_ctrl + Add(*lhs_pos) - Add(*lhs_neg)
                    # if i_ctrl is in cotree then var and loop equation are
                    # already added because ctrl is a voltage source
                eqs.append(lhs)
        elif btype(src, types) in 'E' and src in tree.branches():
            if ctrl in cobranches and btype(ctrl, types) not in 'VEH':
                v_ctrl = Calculus('V_' + ctrl)
                # just a test avoiding duplication
                if v_ctrl not in vars:
                    # control voltage is unknown
                    vars.append(v_ctrl)
                    # remove loop equation for ctrl from covolts and add to eqs
                    eqs.append(v_ctrl - covolts.pop(v_ctrl))

    # substitute cobranch voltages by tree voltages
    eqs = [e.subs(covolts).expand() for e in eqs]
    return eqs, vars