Example #1
0
def dc_analysis(circ,
                start,
                stop,
                step,
                source,
                sweep_type='LINEAR',
                guess=True,
                x0=None,
                outfile="stdout",
                verbose=3):
    """Performs a sweep of the value of V or I of a independent source from start
    value to stop value using the provided step.
    For every circuit generated, computes the op and prints it out.
    This function relays on dc_analysis.op_analysis to actually solve each circuit.

    circ: the circuit instance to be simulated
    start: start value of the sweep source
    stop: stop value of the sweep source
    step: the step size in the sweep
    source: string, the name of the source to be swept
    sweep_type: either options.dc_lin_step (default) or options.dc_log_step
    guess: op_analysis will guess to start the first NR iteration for the first point,
           the previsious dc is used from then on
    outfile: string, filename of the output file. If set to 'stdout', prints to screen.
    verbose: verbosity level

    Returns:
    * A results.dc_solution instance, if a solution was found for at least one sweep value.
    * None, if an error occurred (eg invalid start/stop/step values) or there was no solution
      for any sweep value.
    """
    if outfile == 'stdout':
        verbose = 0
    printing.print_info_line(("Starting DC analysis:", 2), verbose)
    elem_type, elem_descr = source[0].lower(), source.lower()  # eg. 'v', 'v34'
    sweep_label = elem_type[0].upper() + elem_descr[1:]

    if sweep_type == options.dc_log_step and stop - start < 0:
        printing.print_general_error(
            "DC analysis has log sweeping and negative stepping.")
        sys.exit(1)
    if (stop - start) * step < 0:
        raise ValueError, "Unbonded stepping in DC analysis."

    points = (stop - start) / step + 1
    sweep_type = sweep_type.upper()[:3]

    if sweep_type == options.dc_log_step:
        dc_iter = utilities.log_axis_iterator(stop, start, nsteps=points)
    elif sweep_type == options.dc_lin_step:
        dc_iter = utilities.lin_axis_iterator(stop, start, nsteps=points)
    else:
        printing.print_general_error("Unknown sweep type: %s" % (sweep_type, ))
        sys.exit(1)

    if elem_type != 'v' and elem_type != 'i':
        printing.print_general_error(
            "Sweeping is possible only with voltage and current sources. (" +
            str(elem_type) + ")")
        sys.exit(1)

    source_elem = None
    for index in xrange(len(circ)):
        if circ[index].part_id.lower() == elem_descr:
            if elem_type == 'v':
                if isinstance(circ[index], devices.VSource):
                    source_elem = circ[index]
                    break
            if elem_type == 'i':
                if isinstance(circ[index], devices.ISource):
                    source_elem = circ[index]
                    break
    if not source_elem:
        printing.print_general_error("%s was not found." % source[0].part_id)
        sys.exit(1)

    if isinstance(source_elem, devices.VSource):
        initial_value = source_elem.dc_value
    else:
        initial_value = source_elem.dc_value

    # If the initial value is set to None, op_analysis will attempt a smart guess (if guess),
    # Then for each iteration, the last result is used as x0, since op_analysis will not
    # attempt to guess the op if x0 is not None.
    x = x0

    sol = results.dc_solution(circ,
                              start,
                              stop,
                              sweepvar=sweep_label,
                              stype=sweep_type,
                              outfile=outfile)

    printing.print_info_line(("Solving... ", 3), verbose, print_nl=False)
    tick = ticker.ticker(1)
    tick.display(verbose > 2)

    # sweep setup

    # tarocca il generatore di tensione, avvia DC silenziosa, ritarocca etc
    index = 0
    for sweep_value in dc_iter:
        index = index + 1
        if isinstance(source_elem, devices.VSource):
            source_elem.dc_value = sweep_value
        else:
            source_elem.dc_value = sweep_value
        # silently calculate the op
        x = op_analysis(circ, x0=x, guess=guess, verbose=0)
        if x is None:
            tick.hide(verbose > 2)
            if not options.dc_sweep_skip_allowed:
                print "Could't solve the circuit for sweep value:", start + index * step
                solved = False
                break
            else:
                print "Skipping sweep value:", start + index * step
                continue
        solved = True
        sol.add_op(sweep_value, x)

        tick.step(verbose > 2)

    tick.hide(verbose > 2)
    if solved:
        printing.print_info_line(("done", 3), verbose)

    # clean up
    if isinstance(source_elem, devices.VSource):
        source_elem.dc_value = initial_value
    else:
        source_elem.dc_value = initial_value

    return sol if solved else None
Example #2
0
def ac_analysis(circ, start, nsteps, stop, step_type, xop=None, mna=None,\
 AC=None, Nac=None, J=None, data_filename="stdout", verbose=3):
    """Performs an AC analysis of the circuit (described by circ).
	"""

    if data_filename == 'stdout':
        verbose = 0

    #check step/start/stop parameters
    if start == 0:
        printing.print_general_error("AC analysis has start frequency = 0")
        sys.exit(5)
    if start > stop:
        printing.print_general_error("AC analysis has start > stop")
        sys.exit(1)
    if nsteps < 1:
        printing.print_general_error("AC analysis has number of steps <= 1")
        sys.exit(1)
    if step_type == options.ac_log_step:
        omega_iter = utilities.log_axis_iterator(stop, start, nsteps)
    elif step_type == options.ac_lin_step:
        omega_iter = utilities.lin_axis_iterator(stop, start, nsteps)
    else:
        printing.print_general_error("Unknown sweep type.")
        sys.exit(1)

    tmpstr = "Vea =", options.vea, "Ver =", options.ver, "Iea =", options.iea, "Ier =", \
    options.ier, "max_ac_nr_iter =", options.ac_max_nr_iter
    printing.print_info_line((tmpstr, 5), verbose)
    del tmpstr

    printing.print_info_line(("Starting AC analysis: ", 1), verbose)
    tmpstr = "w: start = %g Hz, stop = %g Hz, %d steps" % (start, stop, nsteps)
    printing.print_info_line((tmpstr, 3), verbose)
    del tmpstr

    #It's a good idea to call AC with prebuilt MNA matrix if the circuit is big
    if mna is None:
        (mna, N) = dc_analysis.generate_mna_and_N(circ)
        del N
        mna = utilities.remove_row_and_col(mna)
    if Nac is None:
        Nac = generate_Nac(circ)
        Nac = utilities.remove_row(Nac, rrow=0)
    if AC is None:
        AC = generate_AC(circ, [mna.shape[0], mna.shape[0]])
        AC = utilities.remove_row_and_col(AC)

    if circ.is_nonlinear():
        if J is not None:
            pass
            # we used the supplied linearization matrix
        else:
            if xop is None:
                printing.print_info_line(
                    ("Starting OP analysis to get a linearization point...",
                     3),
                    verbose,
                    print_nl=False)
                #silent OP
                xop = dc_analysis.op_analysis(circ, verbose=0)
                if xop is None:  #still! Then op_analysis has failed!
                    printing.print_info_line(("failed.", 3), verbose)
                    printing.print_general_error(
                        "OP analysis failed, no linearization point available. Quitting."
                    )
                    sys.exit(3)
                else:
                    printing.print_info_line(("done.", 3), verbose)
            printing.print_info_line(("Linearization point (xop):", 5),
                                     verbose)
            if verbose > 4: xop.print_short()
            printing.print_info_line(("Linearizing the circuit...", 5),
                                     verbose,
                                     print_nl=False)
            J = generate_J(xop=xop.asmatrix(),
                           circ=circ,
                           mna=mna,
                           Nac=Nac,
                           data_filename=data_filename,
                           verbose=verbose)
            printing.print_info_line((" done.", 5), verbose)
            # we have J, continue
    else:  #not circ.is_nonlinear()
        # no J matrix is required.
        J = 0

    printing.print_info_line(("MNA (reduced):", 5), verbose)
    printing.print_info_line((str(mna), 5), verbose)
    printing.print_info_line(("AC (reduced):", 5), verbose)
    printing.print_info_line((str(AC), 5), verbose)
    printing.print_info_line(("J (reduced):", 5), verbose)
    printing.print_info_line((str(J), 5), verbose)
    printing.print_info_line(("Nac (reduced):", 5), verbose)
    printing.print_info_line((str(Nac), 5), verbose)

    sol = results.ac_solution(circ,
                              ostart=start,
                              ostop=stop,
                              opoints=nsteps,
                              stype=step_type,
                              op=xop,
                              outfile=data_filename)

    # setup the initial values to start the iteration:
    nv = len(circ.nodes_dict)
    j = numpy.complex('j')

    Gmin_matrix = dc_analysis.build_gmin_matrix(circ, options.gmin,
                                                mna.shape[0], verbose)

    iter_n = 0  # contatore d'iterazione
    #printing.print_results_header(circ, fdata, print_int_nodes=options.print_int_nodes, print_omega=True)
    printing.print_info_line(("Solving... ", 3), verbose, print_nl=False)
    tick = ticker.ticker(increments_for_step=1)
    tick.display(verbose > 1)

    x = xop
    for omega in omega_iter:
        (x, error, solved, n_iter) = dc_analysis.dc_solve(mna=(mna + numpy.multiply(j*omega, AC) + J), \
        Ndc=Nac,  Ntran=0, circ=circuit.circuit(title="Dummy circuit for AC", filename=None), Gmin=Gmin_matrix, x0=x, \
        time=None, locked_nodes=None, MAXIT=options.ac_max_nr_iter, skip_Tt=True, verbose=0)
        if solved:
            tick.step(verbose > 1)
            iter_n = iter_n + 1
            # hooray!
            sol.add_line(omega, x)
        else:
            break

    tick.hide(verbose > 1)

    if solved:
        printing.print_info_line(("done.", 1), verbose)
        ret_value = sol
    else:
        printing.print_info_line(("failed.", 1), verbose)
        ret_value = None

    return ret_value
Example #3
0
def ac_analysis(circ, start, points, stop, sweep_type, x0=None,
                mna=None, AC=None, Nac=None, J=None,
                outfile="stdout", verbose=3):
    """Performs an AC analysis of the circuit described by circ.

    Parameters:
    start (float): the start angular frequency for the AC analysis
    stop (float): stop angular frequency
    points (float): the number of points to be use the discretize the
                    [start, stop] interval.
    sweep_type (string): Either 'LOG' or 'LINEAR', defaults to 'LOG'.
    outfile (string): the filename of the output file where the results will be written.
                      '.ac' is automatically added at the end to prevent different
                      analyses from overwriting each-other's results.
                      If unset or set to None, defaults to stdout.
    verbose (int): the verbosity level, from 0 (silent) to 6 (debug).

    Returns: an AC results object
        """

    if outfile == 'stdout':
        verbose = 0

    # check step/start/stop parameters
    nsteps = points - 1
    if start == 0:
        printing.print_general_error("AC analysis has start frequency = 0")
        sys.exit(5)
    if start > stop:
        printing.print_general_error("AC analysis has start > stop")
        sys.exit(1)
    if nsteps < 1:
        printing.print_general_error("AC analysis has number of steps <= 1")
        sys.exit(1)
    if sweep_type == options.ac_log_step:
        omega_iter = utilities.log_axis_iterator(stop, start, nsteps)
    elif sweep_type == options.ac_lin_step:
        omega_iter = utilities.lin_axis_iterator(stop, start, nsteps)
    else:
        printing.print_general_error("Unknown sweep type.")
        sys.exit(1)

    tmpstr = "Vea =", options.vea, "Ver =", options.ver, "Iea =", options.iea, "Ier =", \
        options.ier, "max_ac_nr_iter =", options.ac_max_nr_iter
    printing.print_info_line((tmpstr, 5), verbose)
    del tmpstr

    printing.print_info_line(("Starting AC analysis: ", 1), verbose)
    tmpstr = "w: start = %g Hz, stop = %g Hz, %d steps" % (start, stop, nsteps)
    printing.print_info_line((tmpstr, 3), verbose)
    del tmpstr

    # It's a good idea to call AC with prebuilt MNA matrix if the circuit is
    # big
    if mna is None:
        (mna, N) = dc_analysis.generate_mna_and_N(circ, verbose=verbose)
        del N
        mna = utilities.remove_row_and_col(mna)
    if Nac is None:
        Nac = generate_Nac(circ)
        Nac = utilities.remove_row(Nac, rrow=0)
    if AC is None:
        AC = generate_AC(circ, [mna.shape[0], mna.shape[0]])
        AC = utilities.remove_row_and_col(AC)

    if circ.is_nonlinear():
        if J is not None:
            pass
            # we used the supplied linearization matrix
        else:
            if x0 is None:
                printing.print_info_line(
                    ("Starting OP analysis to get a linearization point...", 3), verbose, print_nl=False)
                # silent OP
                x0 = dc_analysis.op_analysis(circ, verbose=0)
                if x0 is None:  # still! Then op_analysis has failed!
                    printing.print_info_line(("failed.", 3), verbose)
                    printing.print_general_error(
                        "OP analysis failed, no linearization point available. Quitting.")
                    sys.exit(3)
                else:
                    printing.print_info_line(("done.", 3), verbose)
            printing.print_info_line(
                ("Linearization point (xop):", 5), verbose)
            if verbose > 4:
                x0.print_short()
            printing.print_info_line(
                ("Linearizing the circuit...", 5), verbose, print_nl=False)
            J = generate_J(xop=x0.asmatrix(), circ=circ, mna=mna,
                           Nac=Nac, data_filename=outfile, verbose=verbose)
            printing.print_info_line((" done.", 5), verbose)
            # we have J, continue
    else:  # not circ.is_nonlinear()
        # no J matrix is required.
        J = 0

    printing.print_info_line(("MNA (reduced):", 5), verbose)
    printing.print_info_line((str(mna), 5), verbose)
    printing.print_info_line(("AC (reduced):", 5), verbose)
    printing.print_info_line((str(AC), 5), verbose)
    printing.print_info_line(("J (reduced):", 5), verbose)
    printing.print_info_line((str(J), 5), verbose)
    printing.print_info_line(("Nac (reduced):", 5), verbose)
    printing.print_info_line((str(Nac), 5), verbose)

    sol = results.ac_solution(circ, ostart=start, ostop=stop,
                              opoints=nsteps, stype=sweep_type, op=x0, outfile=outfile)

    # setup the initial values to start the iteration:
    nv = len(circ.nodes_dict)
    j = numpy.complex('j')

    Gmin_matrix = dc_analysis.build_gmin_matrix(
        circ, options.gmin, mna.shape[0], verbose)

    iter_n = 0  # contatore d'iterazione
    printing.print_info_line(("Solving... ", 3), verbose, print_nl=False)
    tick = ticker.ticker(increments_for_step=1)
    tick.display(verbose > 1)

    x = x0
    for omega in omega_iter:
        (x, error, solved, n_iter) = dc_analysis.dc_solve(
            mna=(mna + numpy.multiply(j * omega, AC) + J),
            Ndc = Nac,
            Ntran = 0,
            circ = circuit.Circuit(
                title="Dummy circuit for AC", filename=None),
            Gmin = Gmin_matrix,
            x0 = x,
            time = None,
            locked_nodes = None,
            MAXIT = options.ac_max_nr_iter,
            skip_Tt = True,
            verbose = 0)
        if solved:
            tick.step(verbose > 1)
            iter_n = iter_n + 1
            # hooray!
            sol.add_line(omega, x)
        else:
            break

    tick.hide(verbose > 1)

    if solved:
        printing.print_info_line(("done.", 1), verbose)
        ret_value = sol
    else:
        printing.print_info_line(("failed.", 1), verbose)
        ret_value = None

    return ret_value
Example #4
0
def dc_analysis(
    circ,
    start,
    stop,
    step,
    type_descr,
    xguess=None,
    data_filename="stdout",
    print_int_nodes=True,
    guess=True,
    stype="LINEAR",
    verbose=2,
):
    """Performs a sweep of the value of V or I of a independent source from start 
	value to stop value using the provided step. 
	For every circuit generated, computes the op and prints it out.
	This function relays on dc_analysis.op_analysis to actually solve each circuit.
	
	circ: the circuit instance to be simulated
	start: start value of the sweep source
	stop: stop value of the sweep source
	step: step value of the sweep source
	elem_type: string, may be 'vsource' or 'isource'
	elem_descr: the description of the element, used to recognize it in circ (i.e v<desc>)
	data_filename: string, filename of the output file. If set to stdout, prints to screen
	print_int_nodes: do it
	guess: op_analysis will guess to start the first NR iteration for the first point, the previsious dc is used from then on
	verbose: verbosity level
	
	Returns:
	A results.dc_solution instance, if a solution was found for at least one sweep value.
	None, if an error occurred (eg invalid start/stop/step values) or there was no solution
	for any sweep value.
	"""
    if data_filename == "stdout":
        verbose = 0
    printing.print_info_line(("Starting DC analysis:", 2), verbose)
    (elem_type, elem_descr) = type_descr
    sweep_label = elem_type[0].upper() + elem_descr

    # check step/start/stop parameters
    if step == 0:
        printing.print_general_error("Can't sweep with step=0 !")
        sys.exit(1)
    if start > stop:
        printing.print_general_error("DC analysis has start > stop")
        sys.exit(1)
    if (stop - start) / step < 1:
        printing.print_general_error("DC analysis has number of steps < 1")
        sys.exit(1)
    if stype == options.dc_log_step:
        dc_iter = utilities.log_axis_iterator(stop, start, nsteps=int(stop - start) / step)
    elif stype == options.dc_lin_step:
        dc_iter = utilities.lin_axis_iterator(stop, start, nsteps=int(stop - start) / step)
    else:
        printing.print_general_error("Unknown sweep type: %s" % (stype,))
        sys.exit(1)

    if elem_type != "vsource" and elem_type != "isource":
        printing.print_general_error(
            "Sweeping is possible only with voltage and current sources. (" + str(elem_type) + ")"
        )
        sys.exit(1)

    source_elem = None
    for index in xrange(len(circ.elements)):
        if circ.elements[index].descr == elem_descr:
            if elem_type == "vsource":
                if isinstance(circ.elements[index], devices.vsource):
                    source_elem = circ.elements[index]
                    break
            if elem_type == "isource":
                if isinstance(circ.elements[index], devices.isource):
                    source_elem = circ.elements[index]
                    break
    if not source_elem:
        printing.print_general_error(elem_type + " element with descr. " + elem_descr + " was not found.")
        sys.exit(1)

    if isinstance(source_elem, devices.vsource):
        initial_value = source_elem.vdc
    else:
        initial_value = source_elem.idc

        # The initial value is set to None and this IS CORRECT.
        # op_analysis will attempt to do a smart guess, if called with x0 = None and guess=True
        # For each iteration over the source voltage (current) value, the last result is used as x0.
        # op_analysis will not attempt to guess the op if x0 is not None
    x = None

    sol = results.dc_solution(circ, start, stop, sweepvar=sweep_label, stype=stype, outfile=data_filename)

    printing.print_info_line(("Solving... ", 3), verbose, print_nl=False)
    tick = ticker.ticker(1)
    tick.display(verbose > 2)

    # sweep setup

    # tarocca il generatore di tensione, avvia DC silenziosa, ritarocca etc
    index = 0
    for sweep_value in dc_iter:
        index = index + 1
        if isinstance(source_elem, devices.vsource):
            source_elem.vdc = sweep_value
        else:
            source_elem.idc = sweep_value
            # silently calculate the op
        op = op_analysis(circ, x0=x, guess=guess, verbose=0)
        if op is None:
            tick.hide(verbose > 2)
            if not options.dc_sweep_skip_allowed:
                print "Could't solve the circuit for sweep value:", start + index * step
                solved = False
                break
            else:
                print "Skipping sweep value:", start + index * step
                continue
        solved = True
        sol.add_op(sweep_value, op)

        if guess:
            guess = False

        tick.step(verbose > 2)

    tick.hide(verbose > 2)
    if solved:
        printing.print_info_line(("done", 3), verbose)

        # clean up
    if isinstance(source_elem, devices.vsource):
        source_elem.vdc = initial_value
    else:
        source_elem.idc = initial_value

    return sol if solved else None
Example #5
0
File: ac.py Project: vovkd/ahkab
def ac_analysis(circ, start, nsteps, stop, step_type, xop=None, mna=None,\
	AC=None, Nac=None, J=None, data_filename="stdout", verbose=3):
	"""Performs an AC analysis of the circuit (described by circ).
	"""
	
	if data_filename == 'stdout':
		verbose = 0

	#check step/start/stop parameters
	if start == 0:
		printing.print_general_error("AC analysis has start frequency = 0")
                sys.exit(5)
	if start > stop:
		printing.print_general_error("AC analysis has start > stop")
		sys.exit(1)
	if nsteps < 1:
		printing.print_general_error("AC analysis has number of steps <= 1")
		sys.exit(1)
	if step_type == options.ac_log_step:
		omega_iter = utilities.log_axis_iterator(stop, start, nsteps)
	elif step_type == options.ac_lin_step:
		omega_iter = utilities.lin_axis_iterator(stop, start, nsteps)
	else:
		printing.print_general_error("Unknown sweep type.") 
		sys.exit(1)
	
	tmpstr = "Vea =", options.vea, "Ver =", options.ver, "Iea =", options.iea, "Ier =", \
	options.ier, "max_ac_nr_iter =", options.ac_max_nr_iter
	printing.print_info_line((tmpstr, 5), verbose)
	del tmpstr
	
	printing.print_info_line(("Starting AC analysis: ", 1), verbose)
	tmpstr = "w: start = %g Hz, stop = %g Hz, %d steps" % (start, stop, nsteps)
	printing.print_info_line((tmpstr, 3), verbose)
	del tmpstr

	#It's a good idea to call AC with prebuilt MNA matrix if the circuit is big
	if mna is None:
		(mna, N) = dc_analysis.generate_mna_and_N(circ)
		del N
		mna = utilities.remove_row_and_col(mna)
	if Nac is None:
		Nac = generate_Nac(circ)
		Nac = utilities.remove_row(Nac, rrow=0)
	if AC is None:
		AC = generate_AC(circ, [mna.shape[0], mna.shape[0]])
		AC = utilities.remove_row_and_col(AC)

	
	if circ.is_nonlinear():
		if J is not None:
			pass
			# we used the supplied linearization matrix
		else:
			if xop is None:
				printing.print_info_line(("Starting OP analysis to get a linearization point...", 3), verbose, print_nl=False)
				#silent OP
				xop = dc_analysis.op_analysis(circ, verbose=0)
				if xop is None: #still! Then op_analysis has failed!
					printing.print_info_line(("failed.", 3), verbose)
					printing.print_general_error("OP analysis failed, no linearization point available. Quitting.") 
					sys.exit(3)
				else:
					printing.print_info_line(("done.", 3), verbose)
			printing.print_info_line(("Linearization point (xop):", 5), verbose)
			if verbose > 4: xop.print_short()
			printing.print_info_line(("Linearizing the circuit...", 5), verbose, print_nl=False)
			J = generate_J(xop=xop.asmatrix(), circ=circ, mna=mna, Nac=Nac, data_filename=data_filename, verbose=verbose)
			printing.print_info_line((" done.", 5), verbose)
			# we have J, continue
	else: #not circ.is_nonlinear()
		# no J matrix is required.
		J = 0
	
	printing.print_info_line(("MNA (reduced):", 5), verbose)
	printing.print_info_line((str(mna), 5), verbose)
	printing.print_info_line(("AC (reduced):", 5), verbose)
	printing.print_info_line((str(AC), 5), verbose)
	printing.print_info_line(("J (reduced):", 5), verbose)
	printing.print_info_line((str(J), 5), verbose)
	printing.print_info_line(("Nac (reduced):", 5), verbose)
	printing.print_info_line((str(Nac), 5), verbose)
	
	sol = results.ac_solution(circ, ostart=start, ostop=stop, opoints=nsteps, stype=step_type, op=xop, outfile=data_filename)

	# setup the initial values to start the iteration:
	nv = len(circ.nodes_dict)
	j = numpy.complex('j')

	Gmin_matrix = dc_analysis.build_gmin_matrix(circ, options.gmin, mna.shape[0], verbose)

	iter_n = 0  # contatore d'iterazione
	#printing.print_results_header(circ, fdata, print_int_nodes=options.print_int_nodes, print_omega=True)
	printing.print_info_line(("Solving... ", 3), verbose, print_nl=False)
	tick = ticker.ticker(increments_for_step=1)
	tick.display(verbose > 1)

	x = xop
	for omega in omega_iter:
		(x, error, solved, n_iter) = dc_analysis.dc_solve(mna=(mna + numpy.multiply(j*omega, AC) + J), \
		Ndc=Nac,  Ntran=0, circ=circuit.circuit(title="Dummy circuit for AC", filename=None), Gmin=Gmin_matrix, x0=x, \
		time=None, locked_nodes=None, MAXIT=options.ac_max_nr_iter, skip_Tt=True, verbose=0)
		if solved:
			tick.step(verbose > 1)
			iter_n = iter_n + 1
			# hooray!
			sol.add_line(omega, x)
		else:
			break
	
	tick.hide(verbose > 1)
	
	if solved:
		printing.print_info_line(("done.", 1), verbose)
		ret_value = sol
	else:
		printing.print_info_line(("failed.", 1), verbose)
		ret_value =  None
	
	return ret_value
Example #6
0
def dc_analysis(circ, start, stop, step, type_descr, xguess=None, data_filename="stdout", print_int_nodes=True, guess=True, stype="LINEAR", verbose=2):
	"""Performs a sweep of the value of V or I of a independent source from start 
	value to stop value using the provided step. 
	For every circuit generated, computes the op and prints it out.
	This function relays on dc_analysis.op_analysis to actually solve each circuit.
	
	circ: the circuit instance to be simulated
	start: start value of the sweep source
	stop: stop value of the sweep source
	step: step value of the sweep source
	elem_type: string, may be 'vsource' or 'isource'
	elem_descr: the description of the element, used to recognize it in circ (i.e v<desc>)
	data_filename: string, filename of the output file. If set to stdout, prints to screen
	print_int_nodes: do it
	guess: op_analysis will guess to start the first NR iteration for the first point, the previsious dc is used from then on
	verbose: verbosity level
	
	Returns:
	A results.dc_solution instance, if a solution was found for at least one sweep value.
	None, if an error occurred (eg invalid start/stop/step values) or there was no solution
	for any sweep value.
	"""
	if data_filename == 'stdout':
		verbose = 0
	printing.print_info_line(("Starting DC analysis:", 2), verbose)
	(elem_type, elem_descr) = type_descr
	sweep_label = elem_type[0].upper()+elem_descr

	#check step/start/stop parameters
	if step == 0:
		printing.print_general_error("Can't sweep with step=0 !")
		sys.exit(1)
	if start > stop:
		printing.print_general_error("DC analysis has start > stop")
		sys.exit(1)
	if (stop-start)/step < 1:
		printing.print_general_error("DC analysis has number of steps < 1")
		sys.exit(1)
	if stype == options.dc_log_step:
		dc_iter = utilities.log_axis_iterator(stop, start, nsteps=int(stop-start)/step)
	elif stype == options.dc_lin_step:
		dc_iter = utilities.lin_axis_iterator(stop, start, nsteps=int(stop-start)/step)
	else:
		printing.print_general_error("Unknown sweep type: %s" % (stype,)) 
		sys.exit(1)

	if elem_type != 'vsource' and elem_type != 'isource':
		printing.print_general_error("Sweeping is possible only with voltage and current sources. (" +str(elem_type)+ ")")
		sys.exit(1)

	source_elem = None
	for index in xrange(len(circ.elements)):
		if circ.elements[index].descr == elem_descr:
			if elem_type == 'vsource': 
				if isinstance(circ.elements[index], devices.vsource):
					source_elem = circ.elements[index]
					break
			if elem_type == 'isource':
				if isinstance(circ.elements[index], devices.isource):
					source_elem = circ.elements[index]
					break
	if not source_elem:
		printing.print_general_error(elem_type + " element with descr. "+ elem_descr +" was not found.")
		sys.exit(1)
	
	if isinstance(source_elem, devices.vsource):
		initial_value = source_elem.vdc
	else:
		initial_value = source_elem.idc

	# The initial value is set to None and this IS CORRECT. 
	# op_analysis will attempt to do a smart guess, if called with x0 = None and guess=True
	# For each iteration over the source voltage (current) value, the last result is used as x0.
	# op_analysis will not attempt to guess the op if x0 is not None
	x = None
	
	sol = results.dc_solution(circ, start, stop, sweepvar=sweep_label, stype=stype, outfile=data_filename)
	
	printing.print_info_line(("Solving... ", 3), verbose, print_nl=False)
	tick = ticker.ticker(1)
	tick.display(verbose>2)

	#sweep setup
	
	#tarocca il generatore di tensione, avvia DC silenziosa, ritarocca etc
	index = 0
	for sweep_value in dc_iter:
		index = index + 1
		if isinstance(source_elem, devices.vsource):
			source_elem.vdc = sweep_value
		else:
			source_elem.idc = sweep_value
		#silently calculate the op
		op = op_analysis(circ, x0=x, guess=guess, verbose=0)
		if op is None:
			tick.hide(verbose>2)
			if not options.dc_sweep_skip_allowed:
				print "Could't solve the circuit for sweep value:", start + index*step
				solved = False
				break
			else:
				print "Skipping sweep value:", start + index*step
				continue
		solved = True
		sol.add_op(sweep_value, op)
		
		if guess:
			guess = False

		tick.step(verbose>2)
	
	tick.hide(verbose>2)
	if solved:
		printing.print_info_line(("done", 3), verbose)
	
	# clean up
	if isinstance(source_elem, devices.vsource):
		source_elem.vdc = initial_value
	else:
		source_elem.idc = initial_value

	return sol if solved else None