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
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
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
def process_analysis(an_list, circ, outfile, verbose, cli_tran_method=None, guess=True, disable_step_control=False): """ Processes an analysis vector: an_list: the list of analysis to be performed, as returned by netlist_parser circ: the circuit instance, returned by netlist_parser outfile: a filename. Results will be written to it. If set to stdout, prints to stdout verbose: verbosity level cli_tran_method: force the specified method in each tran analysis (see transient.py) guess: use the builtin method get_dc_guess to guess x0 Returns: None """ x0_op = None x0_ic_dict = {} results = {} for directive in [x for x in an_list if x["type"] == "ic"]: x0_ic_dict.update({ directive["name"]:\ dc_analysis.build_x0_from_user_supplied_ic(circ, voltages_dict=directive["vdict"], currents_dict=directive["cdict"]) }) for an in an_list: if outfile != 'stdout': data_filename = outfile + "." + an["type"] else: data_filename = outfile if an["type"] == "ic": continue if an["type"] == "op": if not an.has_key('guess_label') or an["guess_label"] is None: x0_op = dc_analysis.op_analysis(circ, guess=guess, data_filename=data_filename, verbose=verbose) else: if not an["guess_label"] in x0_ic_dict: printing.print_warning( "op: guess is set but no matching .ic directive was found." ) printing.print_warning( "op: using built-in guess method: " + str(guess)) x0_op = dc_analysis.op_analysis(circ, guess=guess, verbose=verbose) else: x0_op = dc_analysis.op_analysis( circ, guess=False, x0=x0_ic_dict[an["guess_label"]], verbose=verbose) sol = x0_op elif an["type"] == "dc": if an["source_name"][0].lower() == "v": elem_type = "vsource" elif an["source_name"][0].lower() == "i": elem_type = "isource" else: printing.print_general_error( "Type of sweep source is unknown: " + an[1][0]) sys.exit(1) sol = dc_analysis.dc_analysis( circ, start=an["start"], stop=an["stop"], step=an["step"], \ type_descr=(elem_type, an["source_name"][1:]), xguess=x0_op, data_filename=data_filename, guess=guess, stype=an['stype'], verbose=verbose) #{"type":"tran", "tstart":tstart, "tstop":tstop, "tstep":tstep, "uic":uic, "method":method, "ic_label":ic_label} elif an["type"] == "tran": if cli_tran_method is not None: tran_method = cli_tran_method.upper() elif an["method"] is not None: tran_method = an["method"].upper() else: tran_method = options.default_tran_method # setup the initial condition (t=0) according to uic # uic = 0 -> all node voltages and currents are zero # uic = 1 -> node voltages and currents are those computed in the last OP analysis # uic = 2 -> node voltages and currents are those computed in the last OP analysis # combined with the ic=XX directive found in capacitors and inductors # uic = 3 -> use a .ic directive defined by the user uic = an["uic"] if uic == 0: x0 = None elif uic == 1: if x0_op is None: printing.print_general_error( "uic is set to 1, but no op has been calculated yet.") sys.exit(51) x0 = x0_op elif uic == 2: if x0_op is None: printing.print_general_error( "uic is set to 2, but no op has been calculated yet.") sys.exit(51) x0 = dc_analysis.modify_x0_for_ic(circ, x0_op) elif uic == 3: if an["ic_label"] is None: printing.print_general_error( "uic is set to 3, but param ic=<ic_label> was not defined." ) sys.exit(53) elif not an["ic_label"] in x0_ic_dict: printing.print_general_error("uic is set to 3, but no .ic directive named %s was found." \ %(str(an["ic_label"]),)) sys.exit(54) x0 = x0_ic_dict[an["ic_label"]] sol = transient.transient_analysis(circ, \ tstart=an["tstart"], tstep=an["tstep"], tstop=an["tstop"], \ x0=x0, mna=None, N=None, verbose=verbose, data_filename=data_filename, \ use_step_control=(not disable_step_control), method=tran_method) elif an["type"] == "shooting": if an["method"] == "brute-force": sol = bfpss.bfpss(circ, period=an["period"], step=an["step"], mna=None, Tf=None, \ D=None, points=an["points"], autonomous=an["autonomous"], x0=x0_op, \ data_filename=data_filename, verbose=verbose) elif an["method"] == "shooting": sol = shooting.shooting(circ, period=an["period"], step=an["step"], mna=None, \ Tf=None, D=None, points=an["points"], autonomous=an["autonomous"], \ data_filename=data_filename, verbose=verbose) elif an["type"] == "symbolic": if not 'subs' in an.keys(): an.update({'subs': None}) sol = symbolic.solve(circ, an['source'], opts={'ac': an['ac']}, subs=an['subs'], verbose=verbose) elif an["type"] == "ac": sol = ac.ac_analysis(circ=circ, start=an['start'], nsteps=an['nsteps'], \ stop=an['stop'], step_type='LOG', xop=x0_op, mna=None,\ data_filename=data_filename, verbose=verbose) elif an["type"] == "temp": constants.T = utilities.Celsius2Kelvin(an['temp']) results.update({an["type"]: sol}) return results
def process_analysis(an_list, circ, outfile, verbose, cli_tran_method=None, guess=True, disable_step_control=False): """ Processes an analysis vector: an_list: the list of analysis to be performed, as returned by netlist_parser circ: the circuit instance, returned by netlist_parser outfile: a filename. Results will be written to it. If set to stdout, prints to stdout verbose: verbosity level cli_tran_method: force the specified method in each tran analysis (see transient.py) guess: use the builtin method get_dc_guess to guess x0 Returns: None """ x0_op = None x0_ic_dict = {} results = {} for directive in [ x for x in an_list if x["type"] == "ic" ]: x0_ic_dict.update({ directive["name"]:\ dc_analysis.build_x0_from_user_supplied_ic(circ, voltages_dict=directive["vdict"], currents_dict=directive["cdict"]) }) for an in an_list: if outfile != 'stdout': data_filename = outfile + "." + an["type"] else: data_filename = outfile if an["type"] == "ic": continue if an["type"] == "op": if not an.has_key('guess_label') or an["guess_label"] is None: x0_op = dc_analysis.op_analysis(circ, guess=guess, data_filename=data_filename, verbose=verbose) else: if not an["guess_label"] in x0_ic_dict: printing.print_warning("op: guess is set but no matching .ic directive was found.") printing.print_warning("op: using built-in guess method: "+str(guess)) x0_op = dc_analysis.op_analysis(circ, guess=guess, verbose=verbose) else: x0_op = dc_analysis.op_analysis(circ, guess=False, x0=x0_ic_dict[an["guess_label"]], verbose=verbose) sol = x0_op elif an["type"] == "dc": if an["source_name"][0].lower() == "v": elem_type = "vsource" elif an["source_name"][0].lower() == "i": elem_type = "isource" else: printing.print_general_error("Type of sweep source is unknown: " + an[1][0]) sys.exit(1) sol = dc_analysis.dc_analysis( circ, start=an["start"], stop=an["stop"], step=an["step"], \ type_descr=(elem_type, an["source_name"][1:]), xguess=x0_op, data_filename=data_filename, guess=guess, stype=an['stype'], verbose=verbose) #{"type":"tran", "tstart":tstart, "tstop":tstop, "tstep":tstep, "uic":uic, "method":method, "ic_label":ic_label} elif an["type"] == "tran": if cli_tran_method is not None: tran_method = cli_tran_method.upper() elif an["method"] is not None: tran_method = an["method"].upper() else: tran_method = options.default_tran_method # setup the initial condition (t=0) according to uic # uic = 0 -> all node voltages and currents are zero # uic = 1 -> node voltages and currents are those computed in the last OP analysis # uic = 2 -> node voltages and currents are those computed in the last OP analysis # combined with the ic=XX directive found in capacitors and inductors # uic = 3 -> use a .ic directive defined by the user uic = an["uic"] if uic == 0: x0 = None elif uic == 1: if x0_op is None: printing.print_general_error("uic is set to 1, but no op has been calculated yet.") sys.exit(51) x0 = x0_op elif uic == 2: if x0_op is None: printing.print_general_error("uic is set to 2, but no op has been calculated yet.") sys.exit(51) x0 = dc_analysis.modify_x0_for_ic(circ, x0_op) elif uic == 3: if an["ic_label"] is None: printing.print_general_error("uic is set to 3, but param ic=<ic_label> was not defined.") sys.exit(53) elif not an["ic_label"] in x0_ic_dict: printing.print_general_error("uic is set to 3, but no .ic directive named %s was found." \ %(str(an["ic_label"]),)) sys.exit(54) x0 = x0_ic_dict[an["ic_label"]] sol = transient.transient_analysis(circ, \ tstart=an["tstart"], tstep=an["tstep"], tstop=an["tstop"], \ x0=x0, mna=None, N=None, verbose=verbose, data_filename=data_filename, \ use_step_control=(not disable_step_control), method=tran_method) elif an["type"] == "shooting": if an["method"]=="brute-force": sol = bfpss.bfpss(circ, period=an["period"], step=an["step"], mna=None, Tf=None, \ D=None, points=an["points"], autonomous=an["autonomous"], x0=x0_op, \ data_filename=data_filename, verbose=verbose) elif an["method"]=="shooting": sol = shooting.shooting(circ, period=an["period"], step=an["step"], mna=None, \ Tf=None, D=None, points=an["points"], autonomous=an["autonomous"], \ data_filename=data_filename, verbose=verbose) elif an["type"] == "symbolic": if not 'subs' in an.keys(): an.update({'subs':None}) sol = symbolic.solve(circ, an['source'], opts={'ac':an['ac']}, subs=an['subs'], verbose=verbose) elif an["type"] == "ac": sol = ac.ac_analysis(circ=circ, start=an['start'], nsteps=an['nsteps'], \ stop=an['stop'], step_type='LOG', xop=x0_op, mna=None,\ data_filename=data_filename, verbose=verbose) elif an["type"] == "temp": constants.T = utilities.Celsius2Kelvin(an['temp']) results.update({an["type"]:sol}) return results