Пример #1
0
def func(x, ivc):
    """
    This function calculate scores for parameters of swarms and need curve
    :param x: population of swarms
    :return: array of score
    """
    # global c
    # c += 1
    global time_func_0, time_func_1
    # time_func_0 = time.clock()
    result = []
    for i in range(len(x)):
        # ivc_1 = get_ivc("3_win")
        time_func_0 = time.clock()
        create_cir('test', x[i])
        logger = Logging.setup_logging()
        circuit = spice.LoadFile('test.cir')
        input_data = spice.Init_Data(1000, 0.3)
        analysis = spice.CreateCVC(circuit, input_data, 100)
        # spice.SaveFile(analysis, "test.csv")
        # plot(i+c)
        ivc_2 = [analysis.input_dummy, analysis.VCurrent]
        result.append(compare_ivc(ivc, ivc_2))
        time_func_1 = time.clock()

    return result
Пример #2
0
def init():
    logger = Logging.setup_logging()
    # libraries_path = find_libraries()
    libraries_path = '/home/anurag/Workspace/DTU/CourseProj/AE/website/DTU-VLAB/dtuvlab/lab/simulations/libraries'
    print(libraries_path)
    spice_library = SpiceLibrary(libraries_path)
    print(spice_library)
    circuit = Circuit('Diode Characteristic Curve')
    circuit.include(spice_library['1N4148'])
    print(spice_library['1N4148'])
    return circuit
    def __init__(self, scl_file, scl_schema_file, logger=None):
        if logger == None:
            logger = Logging.setup_logging(logging_level=20)
        self.logger = logger

        logger.info("init simulation")

        self._dont_add_commands = False  #semaphore for commands during simulation
        self._command_que = []  # list for commands during simulation

        self.scl_schema_file = scl_schema_file
        self.scd_schema = None
        self.scl_file = scl_file
        self.scl = None

        self.measurantsA = {}
        self.measurantsV = {}
        self.actuators = {}
        self.circuit = ""
        self.simulation_nodes = {}

        self.arrA = {}  # list of simulated amperes during simulation
        self.arrV = {}  # list of simulated voltages during simulation
        self.nextStep_dict = {
        }  #list of IED's that need a nextstep signal during simulation

        if os.path.exists('static/plot.png'):
            os.remove('static/plot.png')
        #general simulation options, these should not be altered during simulation
        self.title = ".title substation model"
        self.options = "#.options interp  ; strongly reduces memory requirements"
        self.save = ".save none       ; ensure only last step is kept each iteration"
        #values: 19 us, 25 us, 250us
        self.tran = ".tran 19us 3600s uic; run for an hour max, with 100 samples per cycle (201u stepsize does not distort, 200 does...)"

        self.ngspice_shared = None

        self.init_simulator()
def func_x(x, y=None,  ivc=None):
    """
    This function calculate scores for parameters of swarms and need curve
    :param x: population of swarms
    :return: array of score
    """
    global time_func_0, time_func_1, _x, _y
    _x = x
    # time_func_0 = time.clock()
    result = []
    for i in range(len(x)):
        time_func_0 = time.clock()

        create_cir('test', x[i][:]*y[i][:])
        logger = Logging.setup_logging()
        circuit = spice.LoadFile('test.cir')
        input_data = spice.Init_Data(1000, 0.3)
        analysis = spice.CreateCVC(circuit, input_data, 100)
        ivc_2 = [analysis.input_dummy, analysis.VCurrent]
        result.append(compare_ivc(ivc, ivc_2))
        time_func_1 = time.clock()

    return result
#!#
#!# Simulation
#!# ----------

####################################################################################################

import os

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

####################################################################################################

import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging()

####################################################################################################

from PySpice.Spice.Netlist import Circuit
from PySpice.Spice.Library import SpiceLibrary
from PySpice.Unit import *
from PySpice.Physics.SemiConductor import ShockleyDiode

####################################################################################################

libraries_path = os.path.join(os.environ['PySpice_examples_path'], 'libraries')
spice_library = SpiceLibrary(libraries_path)

####################################################################################################
Пример #6
0
#r# ================

#r# This example show a CEM simulation.

# Fixme: retrieve PDF reference and complete

####################################################################################################

import os

import matplotlib.pyplot as plt

####################################################################################################

import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging()

####################################################################################################

from PySpice.Doc.ExampleTools import find_libraries
from PySpice.Probe.Plot import plot
from PySpice.Spice.Library import SpiceLibrary
from PySpice.Spice.Netlist import Circuit
from PySpice.Unit import *

####################################################################################################

libraries_path = find_libraries()
spice_library = SpiceLibrary(libraries_path)

####################################################################################################
Пример #7
0
* example substation description
*xIFL            v_220_4/3  v_220_5/1/2  v_220_6  IFL vss=220000
*xCTR1           v_220_4/3  v_220_5/1/2  v_220_6  v_220_7  v_220_8  v_220_9  CTR
*xPTR            v_220_7  v_220_8  v_220_9  v_132_1  v_132_2  v_132_3  PTR
*xCBR            v_132_1  v_132_2  v_132_3  v_132_4  v_132_5  v_132_6  CBR
*xVTR2           v_132_4, v_132_5, v_132_6                             VTR
*xCTR2           v_132_4  v_132_5  v_132_6  v_132_7  v_132_8  v_132_9  CTR
*xDIS            v_132_7  v_132_8  v_132_9  v_132_10 v_132_11 v_132_12 DIS
*xload           v_132_10 v_132_11 v_132_12 load rload=5500
*
xload           S12/E1/W1/BB1_a S12/E1/W1/BB1_b S12/E1/W1/BB1_c load rload=5500
"""

PORT = 65000

logger = Logging.setup_logging(logging_level=0)

measurantsV = {}
measurantsA = {}
actuators = {}

scd_schema = xmlschema.XMLSchema("../schema/SCL.xsd")
scl = scd_schema.to_dict("../simpleIO_inputs.cid")

#pprint.pprint(scl)
#exit(0)


# process LNode in substation section, attach relevant LD/LN data, and initiate a tcp connection to the ied
# lnode can be attached at each level of the substation
def LNode(item, levelRef, SubEquipment):
Пример #8
0
#!/usr/bin/env python3
#coding=utf-8

import sys
import os

import numpy, random, math

import traceback
import time, datetime

## Spice logger is disabled
import PySpice.Logging.Logging as Logging

logger = Logging.setup_logging(config_file="logging.yml")

from PySpice.Spice.Netlist import Circuit
from PySpice.Unit.Units import *

import matplotlib.pyplot as plt
try:
    import networkx
except:
    print("Networkx library not installed. No graph will be produced")

from PySpice.Spice.Library import SpiceLibrary
from PySpice.Plot.BodeDiagram import bode_diagram
from PySpice.Spice.Netlist import Circuit

import deap
from deap import base, tools, creator
Пример #9
0
import numpy as np
import pandas as pd
import os
from matplotlib import pyplot as plt
from sympy import Symbol
from PySpice.Spice.Netlist import Circuit, SubCircuitFactory
from PySpice.Spice.Library import SpiceLibrary
from PySpice.Plot.BodeDiagram import bode_diagram
from scipy import signal, optimize
import shutil
import tempfile
import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging(logging_level='DEBUG')

# Janky monkeypatch hack
from PySpice.Spice.NgSpice.Shared import NgSpiceShared


def exec_command(self, command, join_lines=True):
    """ Execute a command and return the output. """

    if len(command) > self.__MAX_COMMAND_LENGTH__:
        raise ValueError('Command must not exceed {} characters'.format(
            self.__MAX_COMMAND_LENGTH__))

    self._logger.debug('Execute command: {}'.format(command))
    self.clear_output()
    rc = self._ngspice_shared.ngSpice_Command(command.encode('ascii'))
    if rc:
        raise NameError("ngSpice_Command '{}' returned {}".format(command, rc))
    if join_lines:
Пример #10
0
    def check_installation(self):
        """Tool to check PySpice is correctly installed.

        """

        import ctypes.util

        print('OS:', sys.platform)
        print()

        print('Environments:')
        for _ in (
                'PATH',
                'LD_LIBRARY_PATH',
                'PYTHONPATH',
                'NGSPICE_LIBRARY_PATH',
                'SPICE_LIB_DIR',
                'SPICE_EXEC_DIR',
                'SPICE_ASCIIRAWFILE',
                'SPICE_SCRIPTS',
                'NGSPICE_MEAS_PRECISION',
                'SPICE_NO_DATASEG_CHECK',
                'NGSPICE_INPUT_DIR',
        ):
            print(_, os.environ.get(_, 'undefined'))
        print()

        if 'VIRTUAL_ENV' in os.environ:
            print('On Virtual Environment:')
            for _ in ('VIRTUAL_ENV', ):
                print(_, os.environ.get(_, 'undefined'))
            print()

        if 'CONDA_PREFIX' in os.environ:
            print('On Anaconda:')
            for _ in (
                    # not specific
                    'CONDA_EXE',
                    'CONDA_PYTHON_EXE',
                    # 'CONDA_SHLVL', # shell level, 1 in conda else 0
                    # '_CE_CONDA', # empty
                    # specific
                    'CONDA_DEFAULT_ENV',
                    'CONDA_PREFIX',
                    # 'CONDA_PROMPT_MODIFIER',
            ):
                print(_, os.environ.get(_, 'undefined'))
            print()

        try:
            print('Load PySpice module')
            import PySpice
            print('loaded {} version {}'.format(PySpice.__file__,
                                                PySpice.__version__))
            print()
        except ModuleNotFoundError:
            print('PySpice module not found')
            return

        import PySpice.Logging.Logging as Logging
        logger = Logging.setup_logging(logging_level='INFO')

        from PySpice.Config import ConfigInstall
        from PySpice.Spice import NgSpice
        from PySpice.Spice.NgSpice import NGSPICE_SUPPORTED_VERSION
        from PySpice.Spice.NgSpice.Shared import NgSpiceShared

        print('ngspice supported version:', NGSPICE_SUPPORTED_VERSION)
        print()

        ##############################################

        message = os.linesep.join((
            'NgSpiceShared configuration is',
            '  NgSpiceShared.NGSPICE_PATH = {0.NGSPICE_PATH}',
            '  NgSpiceShared.LIBRARY_PATH = {0.LIBRARY_PATH}',
        ))
        print(message.format(NgSpiceShared))
        print()

        ##############################################

        cwd = Path(os.curdir).resolve()
        print('Working directory:', cwd)
        print()

        locale_ngspice = cwd.joinpath(
            'ngspice-{}'.format(NGSPICE_SUPPORTED_VERSION))
        if locale_ngspice.exists() and locale_ngspice.is_dir():
            print('Found local ngspice:')
            for root, _, filenames in os.walk(locale_ngspice,
                                              followlinks=True):
                for filename in filenames:
                    print(root, filename)
            print()

        ngspice_module_path = Path(NgSpice.__file__).parent
        print('NgSpice:', ngspice_module_path)
        for root, _, filenames in os.walk(ngspice_module_path):
            for filename in filenames:
                print(root, filename)
        print()

        ##############################################

        if ConfigInstall.OS.on_windows:
            print('OS is Windows')
            library = NgSpiceShared.LIBRARY_PATH
        elif ConfigInstall.OS.on_osx:
            print('OS is OSX')
            library = 'ngspice'
        elif ConfigInstall.OS.on_linux:
            print('OS is Linux')
            library = 'ngspice'
        else:
            raise NotImplementedError

        library_path = ctypes.util.find_library(library)
        print('Found in library search path: {}'.format(library_path))

        ##############################################

        print('\nLoad NgSpiceShared')
        ngspice = NgSpiceShared.new_instance(verbose=True)

        if ConfigInstall.OS.on_linux:
            # For Linux see DLOPEN(3)
            # Apparently there is no simple way to get the path of the loaded library ...
            # But we can look in the process maps
            pid = os.getpid()
            maps_path = '/proc/{}/maps'.format(pid)
            with open(maps_path) as fh:
                for line in fh:
                    if '.so' in line and 'ngspice' in line:
                        parts = [x for x in line.split() if x]
                        path = parts[-1]
                        print('loaded {}'.format(path))
                        break
        print()

        if ngspice.spinit_not_found:
            print('WARNING: spinit was not found')
            print()

        message = os.linesep.join((
            'Ngspice version is {0.ngspice_version}',
            '  has xspice: {0.has_xspice}',
            '  has cider {0.has_cider}',
        ))
        print(message.format(ngspice))
        print()

        command = 'version -f'
        print('> ' + command)
        print(ngspice.exec_command(command))
        print()

        circuit_test = CircuitTest()
        circuit_test.test_spinit()

        print('PySpice should work as expected')
Пример #11
0
#!/usr/bin/env python3
#coding=utf-8

import sys
import os

import numpy, random, math

import  traceback
import time, datetime


## Spice logger is disabled
import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging(config_file="logging.yml")

from PySpice.Spice.Netlist import Circuit
from PySpice.Unit.Units import *

import matplotlib.pyplot as plt
try:
    import networkx
except:
    print("Networkx library not installed. No graph will be produced")

from PySpice.Spice.Library import SpiceLibrary
from PySpice.Plot.BodeDiagram import bode_diagram
from PySpice.Spice.Netlist import Circuit

import deap
from deap import base, tools, creator
Пример #12
0
    def check_installation(self):
        """Tool to check PySpice is correctly installed.

        """

        import ctypes.util

        try:
            print('Load PySpice module')
            import PySpice
            print('loaded {} version {}'.format(PySpice.__file__,
                                                PySpice.__version__))
        except ModuleNotFoundError:
            print('PySpice module not found')
            return

        import PySpice.Logging.Logging as Logging
        logger = Logging.setup_logging(logging_level='INFO')

        from PySpice.Config import ConfigInstall
        from PySpice.Spice.NgSpice.Shared import NgSpiceShared

        ##############################################

        message = '''
        NgSpiceShared configuration is
          NgSpiceShared.NGSPICE_PATH = {0.NGSPICE_PATH}
          NgSpiceShared.LIBRARY_PATH = {0.LIBRARY_PATH}
        '''
        print(message.format(NgSpiceShared))

        ##############################################

        if ConfigInstall.OS.on_windows:
            print('OS is Windows')
            library = NgSpiceShared.LIBRARY_PATH
        elif ConfigInstall.OS.on_osx:
            print('OS is OSX')
            library = 'ngspice'
        elif ConfigInstall.OS.on_linux:
            print('OS is Linux')
            library = 'ngspice'
        else:
            raise NotImplementedError

        library_path = ctypes.util.find_library(library)
        print('Found in library search path: {}'.format(library_path))

        ##############################################

        print('\nLoad NgSpiceShared')
        ngspice = NgSpiceShared(verbose=True)

        if ConfigInstall.OS.on_linux:
            # For Linux see DLOPEN(3)
            # Apparently there is no simple way to get the path of the loaded library ...
            # But we can look in the process maps
            pid = os.getpid()
            maps_path = '/proc/{}/maps'.format(pid)
            with open(maps_path) as fh:
                for line in fh:
                    if '.so' in line and 'ngspice' in line:
                        parts = [x for x in line.split() if x]
                        path = parts[-1]
                        print('loaded {}'.format(path))
                        break

        message = '''
        Ngspice version is {0.ngspice_version}
          has xspice: {0.has_xspice}
          has cider {0.has_cider}
        '''
        print(message.format(ngspice))

        command = 'version -f'
        print('> ' + command)
        print(ngspice.exec_command(command))

        print()
        print('PySpice should work as expected')
Пример #13
0
def script():
    logger = Logging.setup_logging()
    libraries_path = find_libraries()
    print(libraries_path)
    spice_library = SpiceLibrary(libraries_path)
    print(spice_library)
    circuit = Circuit('Diode Characteristic Curve')
    circuit.include(spice_library['1N4148'])
    print(spice_library['1N4148'])

    # def defaultCircuitParams():
    circuit.V('input', 'in', circuit.gnd, 10 @ u_V)
    circuit.R(1, 'in', 'out', 1 @ u_Ω)  # not required for simulation
    circuit.X('D1', '1N4148', 'out', circuit.gnd)

    # Voltage and Resistance in 10e-06, X is diode type
    # def setCircuitParams(V, R, X):
    #     circuit.V('input', 'in', circuit.gnd, V@u_V)
    #     circuit.R(1, 'in', 'out', R@u_Ω) # not required for simulation
    #     circuit.X('D1', X, 'out', circuit.gnd)

    #r# We simulate the circuit at these temperatures: 0, 25 and 100 °C.

    # Fixme: Xyce ???
    temperatures = [0, 25, 100] @ u_Degree
    analyses = {}

    # def simulateTemp():
    for temperature in temperatures:
        simulator = circuit.simulator(temperature=temperature,
                                      nominal_temperature=temperature)
        analysis = simulator.dc(Vinput=slice(-2, 5, .01))
        analyses[float(temperature)] = analysis

    ####################################################################################################

    #r# We plot the characteristic curve and compare it to the Shockley diode model:
    #r#
    #r# .. math::
    #r#
    #r#     I_d = I_s \left( e^{\frac{V_d}{n V_T}} - 1 \right)
    #r#
    #r# where :math:`V_T = \frac{k T}{q}`
    #r#
    #r# In order to scale the reverse biased region, we have to do some hack with Matplotlib.
    #r#
    silicon_forward_voltage_threshold = .7

    shockley_diode = ShockleyDiode(Is=4e-9, degree=25)

    def two_scales_tick_formatter(value, position):
        if value >= 0:
            return '{} mA'.format(value)
        else:
            return '{} nA'.format(value / 100)

    formatter = ticker.FuncFormatter(two_scales_tick_formatter)

    figure, (ax1, ax2) = plt.subplots(2, figsize=(20, 10))

    ax1.set_title('1N4148 Characteristic Curve ')
    ax1.set_xlabel('Voltage [V]')
    ax1.set_ylabel('Current')
    ax1.grid()
    ax1.set_xlim(-2, 2)
    ax1.axvspan(-2, 0, facecolor='green', alpha=.2)
    ax1.axvspan(0,
                silicon_forward_voltage_threshold,
                facecolor='blue',
                alpha=.1)
    ax1.axvspan(silicon_forward_voltage_threshold,
                2,
                facecolor='blue',
                alpha=.2)
    ax1.set_ylim(-500, 750)  # Fixme: round
    ax1.yaxis.set_major_formatter(formatter)
    Vd = analyses[25].out
    # compute scale for reverse and forward region
    forward_region = Vd >= 0 @ u_V
    reverse_region = np.invert(forward_region)
    scale = reverse_region * 1e11 + forward_region * 1e3
    #?# check temperature
    for temperature in temperatures:
        analysis = analyses[float(temperature)]
        ax1.plot(Vd, -analysis.Vinput * scale)
    ax1.plot(Vd, shockley_diode.I(Vd) * scale, 'black')
    ax1.legend(['@ {} °C'.format(temperature)
                for temperature in temperatures] +
               ['Shockley Diode Model Is = 4 nA'],
               loc=(.02, .8))
    ax1.axvline(x=0, color='black')
    ax1.axhline(y=0, color='black')
    ax1.axvline(x=silicon_forward_voltage_threshold, color='red')
    ax1.text(-1, -100, 'Reverse Biased Region', ha='center', va='center')
    ax1.text(1, -100, 'Forward Biased Region', ha='center', va='center')

    #r# Now we compute and plot the static and dynamic resistance.
    #r#
    #r# .. math::
    #r#
    #r#   \frac{d I_d}{d V_d} = \frac{1}{n V_T}(I_d + I_s)
    #r#
    #r# .. math::
    #r#
    #r#   r_d = \frac{d V_d}{d I_d} \approx \frac{n V_T}{I_d}

    ax2.set_title('Resistance @ 25 °C')
    ax2.grid()
    ax2.set_xlim(-2, 3)
    ax2.axvspan(-2, 0, facecolor='green', alpha=.2)
    ax2.axvspan(0,
                silicon_forward_voltage_threshold,
                facecolor='blue',
                alpha=.1)
    ax2.axvspan(silicon_forward_voltage_threshold,
                3,
                facecolor='blue',
                alpha=.2)
    analysis = analyses[25]
    static_resistance = -analysis.out / analysis.Vinput
    dynamic_resistance = np.diff(-analysis.out) / np.diff(analysis.Vinput)
    ax2.semilogy(analysis.out, static_resistance, basey=10)
    ax2.semilogy(analysis.out[10:-1], dynamic_resistance[10:], basey=10)
    ax2.axvline(x=0, color='black')
    ax2.axvline(x=silicon_forward_voltage_threshold, color='red')
    ax2.axhline(y=1, color='red')
    ax2.text(-1.5, 1.1, 'R limitation = 1 Ω', color='red')
    ax2.legend(['{} Resistance'.format(x) for x in ('Static', 'Dynamic')],
               loc=(.05, .2))
    ax2.set_xlabel('Voltage [V]')
    ax2.set_ylabel('Resistance [Ω]')

    plt.tight_layout()
    plt.show()
Пример #14
0
    def define_circuit(self):
        logger = Logging.setup_logging()
        circuit_lab = self.circuit
        circuit = Circuit(circuit_lab["name"])

        # for complex circuit elements that requires SPICE library
        # libraries_path = find_libraries()

        python_file = os.path.abspath(sys.argv[0])
        examples_root = parent_directory_of(python_file)
        libraries_path = os.path.join(examples_root, 'libraries')

        spice_library = SpiceLibrary(libraries_path)

        # return message
        message = ""

        # add all elements to the PySpice circuit
        for element in circuit_lab:
            if element == "V":
                for dc_voltage_source in circuit_lab["V"]:
                    circuit.V(
                        dc_voltage_source["id"],
                        circuit.gnd if dc_voltage_source["node1"] == "gnd" else
                        dc_voltage_source["node1"],
                        circuit.gnd if dc_voltage_source["node2"] == "gnd" else
                        dc_voltage_source["node2"],
                        dc_voltage_source["value"] @ u_V)

            elif element == "VA":
                for ac_voltage_source in circuit_lab["VA"]:
                    circuit.SinusoidalVoltageSource(
                        ac_voltage_source["id"],
                        circuit.gnd if ac_voltage_source["node1"] == "gnd" else
                        ac_voltage_source["node1"],
                        circuit.gnd if ac_voltage_source["node2"] == "gnd" else
                        ac_voltage_source["node2"],
                        amplitude=ac_voltage_source["amplitude"] @ u_V,
                        frequency=ac_voltage_source["frequency"] @ u_Hz,
                        offset=ac_voltage_source["offset"] @ u_V)

            elif element == "I":
                for dc_current_source in circuit_lab["I"]:
                    circuit.I(
                        dc_current_source["id"],
                        circuit.gnd if dc_current_source["node1"] == "gnd" else
                        dc_current_source["node1"],
                        circuit.gnd if dc_current_source["node2"] == "gnd" else
                        dc_current_source["node2"],
                        dc_current_source["value"] @ u_A)

            elif element == "IA":
                for ac_current_source in circuit_lab["IA"]:
                    circuit.SinusoidalCurrentSource(
                        ac_current_source["id"],
                        circuit.gnd if ac_current_source["node1"] == "gnd" else
                        ac_current_source["node1"],
                        circuit.gnd if ac_current_source["node2"] == "gnd" else
                        ac_current_source["node2"],
                        amplitude=ac_current_source["amplitude"] @ u_A,
                        frequency=ac_current_source["frequency"] @ u_Hz,
                        offset=ac_current_source["offset"] @ u_A)

            elif element == "R":
                for resistor in circuit_lab["R"]:
                    circuit.R(
                        resistor["id"], circuit.gnd if resistor["node1"]
                        == "gnd" else resistor["node1"], circuit.gnd
                        if resistor["node2"] == "gnd" else resistor["node2"],
                        resistor["value"] @ u_Ω)

            elif element == "L":
                for inductor in circuit_lab["L"]:
                    circuit.L(
                        inductor["id"], circuit.gnd if inductor["node1"]
                        == "gnd" else inductor["node1"], circuit.gnd
                        if inductor["node2"] == "gnd" else inductor["node2"],
                        inductor["value"] @ u_H)

            elif element == "C":
                for capacitor in circuit_lab["C"]:
                    circuit.C(
                        capacitor["id"], circuit.gnd if capacitor["node1"]
                        == "gnd" else capacitor["node1"], circuit.gnd
                        if capacitor["node2"] == "gnd" else capacitor["node2"],
                        capacitor["value"] @ u_F)

            elif element == "D":
                for diode in circuit_lab["D"]:
                    try:
                        circuit.include(spice_library[diode["modelType"]])
                        circuit.X(
                            diode["id"], diode["modelType"], circuit.gnd
                            if diode["node1"] == "gnd" else diode["node1"],
                            circuit.gnd
                            if diode["node2"] == "gnd" else diode["node2"])
                    except KeyError as e:
                        message += " " + str(e)

            elif element == "nBJT":
                for nBJT in circuit_lab["nBJT"]:
                    try:
                        circuit.include(spice_library[nBJT["modelType"]])
                        circuit.BJT(nBJT["id"],
                                    circuit.gnd if nBJT["node1"] == "gnd" else
                                    nBJT["node1"],
                                    circuit.gnd if nBJT["node2"] == "gnd" else
                                    nBJT["node2"],
                                    circuit.gnd if nBJT["node3"] == "gnd" else
                                    nBJT["node3"],
                                    model=nBJT["modelType"])
                    except KeyError as e:
                        message += " " + str(e)

            elif element == "pBJT":
                for pBJT in circuit_lab["pBJT"]:
                    try:
                        circuit.include(spice_library[pBJT["modelType"]])
                        circuit.BJT(pBJT["id"],
                                    circuit.gnd if pBJT["node3"] == "gnd" else
                                    pBJT["node3"],
                                    circuit.gnd if pBJT["node2"] == "gnd" else
                                    pBJT["node2"],
                                    circuit.gnd if pBJT["node1"] == "gnd" else
                                    pBJT["node1"],
                                    model=pBJT["modelType"])
                    except KeyError as e:
                        message += " " + str(e)

            elif element == "NMOS":
                for NMOS in circuit_lab["NMOS"]:
                    try:
                        circuit.include(spice_library[NMOS["modelType"]])
                        # nodes are: drain, gate, source, bulk
                        circuit.MOSFET(NMOS["id"],
                                       circuit.gnd if NMOS["node4"] == "gnd"
                                       else NMOS["node4"],
                                       circuit.gnd if NMOS["node2"] == "gnd"
                                       else NMOS["node2"],
                                       circuit.gnd if NMOS["node3"] == "gnd"
                                       else NMOS["node3"],
                                       circuit.gnd if NMOS["node1"] == "gnd"
                                       else NMOS["node1"],
                                       model=NMOS["modelType"])
                    except KeyError as e:
                        message += " " + str(e)

            elif element == "PMOS":
                for PMOS in circuit_lab["PMOS"]:
                    try:
                        circuit.include(spice_library[PMOS["modelType"]])
                        # nodes are: source, gate, drain, bulk
                        circuit.MOSFET(PMOS["id"],
                                       circuit.gnd if PMOS["node1"] == "gnd"
                                       else PMOS["node1"],
                                       circuit.gnd if PMOS["node2"] == "gnd"
                                       else PMOS["node2"],
                                       circuit.gnd if PMOS["node3"] == "gnd"
                                       else PMOS["node3"],
                                       circuit.gnd if PMOS["node4"] == "gnd"
                                       else PMOS["node4"],
                                       model=PMOS["modelType"])
                    except KeyError as e:
                        message += " " + str(e)

            # add ammeter as a 0 volt voltage source
            elif element == "AM":
                for ammeter in circuit_lab["AM"]:
                    circuit.V(
                        ammeter["id"], circuit.gnd if ammeter["node1"] == "gnd"
                        else ammeter["node1"], circuit.gnd if ammeter["node2"]
                        == "gnd" else ammeter["node2"], ammeter["value"] @ u_V)

        if not message:
            self.spice = circuit
            return message
        return "Undefined model type:" + message