Exemple #1
0
from spicepy.netsolve import net_solve
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
plt.close('all')

# =============================================================================
# Changing dt to see the impact on fit
# Conclusion: it's second order accurate space derivatives (see pdf also)
# =============================================================================

analytic_I = lambda t: 25.64102564 * np.exp(-5000. * t) * (39. * np.cos(
    31224.98999 * t) - 6.244997998 * np.sin(31224.98999 * t))
mse = lambda x, y: np.mean(np.power(x - y, 2))
netm = ntl.Network('RLC10u.net')
net_solve(netm)
simulated_Im = netm.get_current('R1')
new_tm = netm.t[1:]
dtm = netm.t[2] - netm.t[1]
new_tm -= dtm / 2
mse_m = mse(simulated_Im[1:], analytic_I(new_tm))

netu = ntl.Network('RLCu.net')
net_solve(netu)
simulated_Iu = netu.get_current('R1')
new_tu = netu.t[1:]
dtu = netu.t[2] - netu.t[1]
new_tu -= dtu / 2
mse_u = mse(simulated_Iu[1:], analytic_I(new_tu))

netn = ntl.Network('RLC100n.net')
Exemple #2
0

# check rms
def check(rms, toll):
    if rms < toll:
        print('OK')
    else:
        print('*FAILED*')


print('Start benchmark:')

# DC network
print(' * Testing DC network ...', end=' ', flush=True)
net = ntl.Network('../demo/dc_network.net')
net_solve(net)
ref = np.loadtxt('./dc_network/solution.txt')
rms = np.sqrt(np.sum((ref - net.x)**2)) / ref.size
check(rms, 1e-10)

# OP network
print(' * Testing OP network ...', end=' ', flush=True)
net = ntl.Network('../demo/op_network.net')
net_solve(net)
ref = np.loadtxt('./op_network/solution.txt')
rms = np.sqrt(np.sum((ref - net.x)**2)) / ref.size
check(rms, 1e-5)

# AC network (single frequency)
print(' * Testing AC network (single frequency) ...', end=' ', flush=True)
net = ntl.Network('../demo/ac_single_frequency.net')
Exemple #3
0
def get_solution(fname, update, context):
    """
    'get_solution' computes the solution of a network using SpicePy

    :param fname: filename with the netlist
    :param update: bot update
    :param context: CallbackContext
    :return:
        * mex:  solution formatted in a string
    """
    try:
        # create network and solve it
        net = ntl.Network(fname)

        # check if number of nodes exceeds the limit
        NMAX = 40
        if net.node_num > NMAX:
            mex = "Your netlist includes more than {:d} nodes.\n".format(
                net.node_num)
            mex += "*The maximum allowed number on this bot is {:d}.*\n".format(
                NMAX)
            mex += "Please reduce the number of nodes or take a look to the computational core of this bot "
            mex += "that does not have this limitation:\n"
            mex += "[SpicePy project](https://github.com/giaccone/SpicePy)"

        else:

            # limit sample for .tran to 2000 (max)
            if net.analysis[0].lower() == '.tran':
                Nsamples = float(net.convert_unit(net.analysis[2])) / float(
                    net.convert_unit(net.analysis[1]))
                if Nsamples > 2000:
                    step = float(net.convert_unit(net.analysis[2])) / 1999
                    net.analysis[1] = '{:.3e}'.format(step)

                    mex = "Your netlits defines a '.tran' analysis with *{:d}* samples\n".format(
                        int(Nsamples))
                    mex += "Since this bot runs on a limited hardware shared by many users\n"
                    mex += "The analysis has been limited to *2000* samples:\n"
                    mex += "`.tran " + net.analysis[1] + " " + net.analysis[
                        -1] + "`"

                    context.bot.send_message(
                        chat_id=update.message.chat_id,
                        text=mex,
                        parse_mode=telegram.ParseMode.MARKDOWN)

            # limit sample for .ac to 2000 (max)
            elif net.analysis[0].lower() == '.ac':
                # get frequencies
                net.frequency_span()

                if not np.isscalar(net.f):
                    # get Nsamples
                    Nsamples = len(net.f)
                    # limit di 2000 max
                    if Nsamples > 2000:
                        scale = 2000 / Nsamples
                        old_analysys = "`" + " ".join(net.analysis) + "`"
                        net.analysis[2] = str(
                            int(
                                np.ceil(
                                    scale *
                                    float(net.convert_unit(net.analysis[2])))))
                        new_analysys = "`" + " ".join(net.analysis) + "`"

                        mex = "Your netlits defines a '.tran' analysis with *{:d}* samples\n".format(
                            int(Nsamples))
                        mex += "Since this bot runs on a limited hardware shared by many users\n"
                        mex += "The analysis has been limited to *2000* samples:\n"
                        mex += "original analysis: " + old_analysys + "\n"
                        mex += "ner analysis: " + new_analysys + "\n"

                        context.bot.send_message(
                            chat_id=update.message.chat_id,
                            text=mex,
                            parse_mode=telegram.ParseMode.MARKDOWN)

            # get configurations
            fname = './users/' + str(update.message.chat_id) + '.cnf'
            fid = open(fname, 'r')
            flag = fid.readline()[:-1]  # read nodal_pot conf
            nodal_pot = flag == 'True'
            flag = fid.readline()[:-1]  # read polar conf
            polar = flag == 'True'
            flag = fid.readline()  # read dB conf
            dB = flag == 'True'

            if net.analysis[0] == '.op':
                # forcepolar to False for .op problems
                polar = False

            # solve the network
            net_solve(net)

            # .op and .ac (single-frequency): prepare mex to be printed
            if (net.analysis[0].lower() == '.op') | (
                (net.analysis[0].lower() == '.ac') & (np.isscalar(net.f))):
                # get branch quantities
                net.branch_voltage()
                net.branch_current()
                net.branch_power()

                # prepare message
                mex = net.print(polar=polar, message=True)
                mex = mex.replace(
                    '==============================================\n'
                    '               branch quantities'
                    '\n==============================================\n',
                    '*branch quantities*\n`')
                mex = mex.replace(
                    '----------------------------------------------', '')
                mex += '`'

                # if the user wants node potentials add it to mex
                if nodal_pot:
                    # create local dictionary node-number 2 node-label
                    num2node_label = {
                        num: name
                        for name, num in net.node_label2num.items()
                        if name != '0'
                    }

                    # compute the node potentials
                    mex0 = '*node potentials*\n`'
                    for num in num2node_label:
                        voltage = net.get_voltage('(' + num2node_label[num] +
                                                  ')')[0]
                        if polar:
                            mex0 += 'v(' + num2node_label[
                                num] + ') = {:10.4f} V < {:10.4f}°\n'.format(
                                    np.abs(voltage),
                                    np.angle(voltage) * 180 / np.pi)
                        else:
                            mex0 += 'v(' + num2node_label[
                                num] + ') = {:10.4f} V\n'.format(voltage)

                    # add newline
                    mex0 += '`\n\n'

                    # add node potentials before branch quantities
                    mex = mex0 + mex

            elif net.analysis[0].lower() == '.tran':
                hf = net.plot(to_file=True,
                              filename='./users/tran_plot_' +
                              str(update.message.chat_id) + '.png',
                              dpi_value=150)
                mex = None
                plt.close(hf)

            elif net.analysis[0].lower() == '.ac':
                hf = net.bode(to_file=True,
                              decibel=dB,
                              filename='./users/bode_plot_' +
                              str(update.message.chat_id) + '.png',
                              dpi_value=150)
                mex = None
                if isinstance(hf, list):
                    for fig in hf:
                        plt.close(fig)
                else:
                    plt.close(hf)

            # Log every time a network is solved
            # To make stat it is saved the type of network and the UserID
            StatLog.info('Analysis: ' + net.analysis[0] + ' - UserID: ' +
                         str(update.effective_user.id))

        return net, mex

    except:
        # set network to None
        net = None
        # read network with issues
        wrong_net = ''
        with open(fname) as f:
            for line in f:
                wrong_net += line
        wrong_net = wrong_net.replace('\n', '  /  ')

        # log error
        SolverLog.error('UserID: ' + str(update.effective_user.id) +
                        ' - Netlist error: ' + wrong_net)
        return net, "*Something went wrong with your netlist*.\nPlease check the netlist format."