<jupyter_start><jupyter_text>Capacitance matrix and LOM analysis PrerequisiteYou need to have a working local installation of Ansys.  1. Create the design in Metal<jupyter_code>%reload_ext autoreload
%autoreload 2
import qiskit_metal as metal
from qiskit_metal import designs, draw
from qiskit_metal import MetalGUI, Dict, Headings
design = designs.DesignPlanar()
gui = MetalGUI(design)

from qiskit_metal.qlibrary.qubits.transmon_pocket import TransmonPocket
from qiskit_metal.qlibrary.tlines.meandered import RouteMeander
design.variables['cpw_width'] = '15 um'
design.variables['cpw_gap'] = '9 um'<jupyter_output><empty_output><jupyter_text>In this example, the design consists of 4 qubits and 4 CPWs<jupyter_code># Allow running the same cell here multiple times to overwrite changes
design.overwrite_enabled = True

## Custom options for all the transmons
options = dict(
    # Some options we want to modify from the defaults
    # (see below for defaults)
    pad_width = '425 um', 
    pocket_height = '650um',
    # Adding 4 connectors (see below for defaults)
    connection_pads=dict(
        readout = dict(loc_W=+1,loc_H=-1, pad_width='200um'),
        bus1 = dict(loc_W=-1,loc_H=+1, pad_height='30um'),
        bus2 = dict(loc_W=-1,loc_H=-1, pad_height='50um')
    )
)

## Create 4 transmons

q1 = TransmonPocket(design, 'Q1', options = dict(
    pos_x='+2.42251mm', pos_y='+0.0mm', **options))
q2 = TransmonPocket(design, 'Q2', options = dict(
    pos_x='+0.0mm', pos_y='-0.95mm', orientation = '270', **options))
q3 = TransmonPocket(design, 'Q3', options = dict(
    pos_x='-2.42251mm', pos_y='+0.0mm', orientation = '180', **options))
q4 = TransmonPocket(design, 'Q4', options = dict(
    pos_x='+0.0mm', pos_y='+0.95mm', orientation = '90', **options))

RouteMeander.get_template_options(design)

options = Dict(
        lead=Dict(
            start_straight='0.2mm',
            end_straight='0.2mm'),
        trace_gap='9um',
        trace_width='15um')

def connect(component_name: str, component1: str, pin1: str, component2: str, pin2: str,
            length: str, asymmetry='0 um', flip=False, fillet='90um'):
    """Connect two pins with a CPW."""
    myoptions = Dict(
        fillet=fillet,
        hfss_wire_bonds = True,
        pin_inputs=Dict(
            start_pin=Dict(
                component=component1,
                pin=pin1),
            end_pin=Dict(
                component=component2,
                pin=pin2)),
        total_length=length)
    myoptions.update(options)
    myoptions.meander.asymmetry = asymmetry
    myoptions.meander.lead_direction_inverted = 'true' if flip else 'false'
    return RouteMeander(design, component_name, myoptions)

asym = 140
cpw1 = connect('cpw1', 'Q1', 'bus2', 'Q2', 'bus1', '6.0 mm', f'+{asym}um')
cpw2 = connect('cpw2', 'Q3', 'bus1', 'Q2', 'bus2', '6.1 mm', f'-{asym}um', flip=True)
cpw3 = connect('cpw3', 'Q3', 'bus2', 'Q4', 'bus1', '6.0 mm', f'+{asym}um')
cpw4 = connect('cpw4', 'Q1', 'bus1', 'Q4', 'bus2', '6.1 mm', f'-{asym}um', flip=True)

gui.rebuild()
gui.autoscale()<jupyter_output><empty_output><jupyter_text>2. Capacitance Analysis and LOM derivation using the analysis package - most users  Capacitance AnalysisSelect the analysis you intend to run from the `qiskit_metal.analyses` collection.Select the design to analyze and the tool to use for any external simulation<jupyter_code>from qiskit_metal.analyses.quantization import LOManalysis
c1 = LOManalysis(design, "q3d")<jupyter_output><empty_output><jupyter_text>(optional) You can review and update the Analysis default setup following the examples in the next two cells.<jupyter_code>c1.sim.setup
# example: update single setting
c1.sim.setup.max_passes = 6
# example: update multiple settings
c1.sim.setup_update(solution_order = 'Medium', auto_increase_solution_order = 'False')

c1.sim.setup<jupyter_output><empty_output><jupyter_text>Analyze a single qubit with 2 endcaps using the default (or edited) analysis setup. Then show the capacitance matrix (from the last pass).You can use the method `run()` instead of `sim.run()` in the following cell if you want to run both cap extraction and lom analysis in a single step. If so, make sure to also tweak the setup for the lom analysis. The input parameters are otherwise the same for the two methods.<jupyter_code>c1.sim.run(components=['Q1'], open_terminations=[('Q1', 'readout'), ('Q1', 'bus1'), ('Q1', 'bus2')])
c1.sim.capacitance_matrix<jupyter_output><empty_output><jupyter_text>(otional - case-dependent)If the previous cell was interrupted due to license limitations and for any reason you finally manually launched the simulation from the renderer GUI (outside qiskit-metal) you might be able to recover the simulation results by uncommenting and executing the following cell<jupyter_code>#c1.sim._get_results_from_renderer()
#c1.sim.capacitance_matrix<jupyter_output><empty_output><jupyter_text>The last variables you pass to the `run()` or `sim.run()` methods, will be stored in the `sim.setup` dictionary under the key `run`. You can recall the information passed by either accessing the dictionary directly, or by using the print handle below.<jupyter_code># c1.setup.run    <- direct access
c1.sim.print_run_args()<jupyter_output><empty_output><jupyter_text>You can re-run the analysis after varying the parameters.Not passing the parameter `components` to the `sim.run()` method, skips the rendering and tries to run the analysis on the latest design. If a design is not found, the full metal design is rendered.<jupyter_code>c1.sim.setup.freq_ghz = 4.8
c1.sim.run()
c1.sim.capacitance_matrix
type(c1.sim.capacitance_matrix)<jupyter_output><empty_output><jupyter_text>Lumped oscillator model (LOM)Using capacitance matrices obtained from each pass, save the many parameters of the Hamiltonian of the system. `get_lumped_oscillator()` operates on 4 setup parameters: Lj: float Cj: float fr: Union[list, float] fb: Union[list, float]<jupyter_code>c1.setup.junctions = Dict({'Lj': 12.31, 'Cj': 2})
c1.setup.freq_readout = 7.0
c1.setup.freq_bus = [6.0, 6.2]

c1.run_lom()
c1.lumped_oscillator_all
c1.plot_convergence();
c1.plot_convergence_chi()<jupyter_output><empty_output><jupyter_text>Once you are done with your analysis, please close it with `close()`. This will free up resources currently occupied by qiskit-metal to communiate with the tool.<jupyter_code>c1.sim.close()<jupyter_output><empty_output><jupyter_text>3. Directly access the renderer to modify other parameters<jupyter_code>c1.sim.start()
c1.sim.renderer<jupyter_output><empty_output><jupyter_text>Every renderer will have its own collection of methods. Below an example with q3d  Prepare and run a collection of predefined setupsThis is equivalent to going to the Project Manager panel in Ansys, right clicking on Analysis within the active Q3D design, selecting "Add Solution Setup...", and choosing/entering default values in the resulting popup window. You might want to do this to keep track of different solution setups, giving each of them a different/specific name.<jupyter_code>setup = c1.sim.renderer.new_ansys_setup(name = "Setup_demo", max_passes = 6)<jupyter_output><empty_output><jupyter_text>You can directly pass to `new_ansys_setup` all the setup parameters. Of course you will then need to run the individual setups by name as well.<jupyter_code>c1.sim.renderer.analyze_setup(setup.name)<jupyter_output><empty_output><jupyter_text>Get the capactiance matrix at a different passYou might want to use this if you intend to know what was the matrix at a different pass of the simulation.<jupyter_code># Using the analysis results, get its capacitance matrix as a dataframe.
c1.sim.renderer.get_capacitance_matrix(variation = '', solution_kind = 'AdaptivePass', pass_number = 5)<jupyter_output><empty_output><jupyter_text>Code to swap rows and columns in capacitance matrixfrom qiskit_metal.analyses.quantization.lumped_capacitive import df_reorder_matrix_basisdf_reorder_matrix_basis(fourq_q3d.get_capacitance_matrix(), 1, 2)  Close the renderer<jupyter_code>c1.sim.close()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10620451461699766, 'fraction_numerical': 0.02294313556186012, 'mean_word_length': 5.251349267540478, 'pattern_counts': {'":': 0, '<': 62, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '93177', 'license': 'Apache-2.0', 'n_tokens_mistral': 2747, 'n_tokens_neox': 2614, 'n_words': 794, 'path': 'tutorials/4 Analysis/A. Core - EM and quantization/4.01 Capacitance and LOM.ipynb', 'repo_name': 'camponogaraviera/qiskit-metal', 'size': '8107'}