Skip to content

Latest commit

 

History

History

Readme.md

Tutorial

Basics

... To be written

Drawing Coplanar Waveguides

... To be written

Meandering resonators can be drawn via the CPW_Meander_Resonator function. Note that the class is a valid CPW object and can thus, be strung together with other CPW objects or linked via the function CPW2CPW. The meanders are configured such that the inner and outer path lengths are equal. The number of meanders depends on the specified turn-radius and maximal width parameters.

Drawing Capacitors

Basic capacitors can be drawn via the classes Capacitor_Interdigitated (interdigitated capacitors) and Capacitor_GapCPW (a basic gap in a CPW line). Both classes have a cpw_params attribute that can be passed onto CPW2CPW. Thus, the capacitors can act like CPW objects and be strung in series with other CPW lines. To see the basic configurations of interdigitated capacitors that can be drawn, consider the following unit-tests (to be run on configuring a layer_photo in the usual Klayout code):

#Testing the configurations
cap = Capacitor_Interdigitated(DPoint(600e3,1240e3),
                                 3.3e3, #Finger width
                                 3.3e3, #Capacitor Finger Space
                                 100e3, #Finger length
                                 3.3e3, #Capacitor gap
                                 10e3, #Padding width
                                 5e3, #Side gap
                                 5, 'same_N_right',
                                 trans_in = klayout.db.Trans(0, False, 0, 0))
cap.place( cell, layer_photo )
cap = Capacitor_Interdigitated(DPoint(800e3,1240e3),
                                 3.3e3, #Finger width
                                 3.3e3, #Capacitor Finger Space
                                 100e3, #Finger length
                                 10e3, #Capacitor gap
                                 20e3, #Padding width
                                 5e3, #Side gap
                                 5, 'same_N_left',
                                 trans_in = klayout.db.Trans(0, False, 0, 0))
cap.place( cell, layer_photo )
cap = Capacitor_Interdigitated(DPoint(1000e3,1240e3),
                                 3.3e3, #Finger width
                                 10e3, #Capacitor Finger Space
                                 100e3, #Finger length
                                 10e3, #Capacitor gap
                                 10e3, #Padding width
                                 15e3, #Side gap
                                 5, 'diff_N_start',
                                 trans_in = klayout.db.Trans(0, False, 0, 0))
cap.place( cell, layer_photo )
cap = Capacitor_Interdigitated(DPoint(1200e3,1240e3),
                                 10e3, #Finger width
                                 3.3e3, #Capacitor Finger Space
                                 100e3, #Finger length
                                 20e3, #Capacitor gap
                                 10e3, #Padding width
                                 5e3, #Side gap
                                 5, 'diff_N_end',
                                 trans_in = klayout.db.Trans(0, False, 0, 0))
cap.place( cell, layer_photo )

Merging metallic elements

Now there is a handy utility function to help merge contiguous metallic elements in a layer:

Utilities.merge_all_metallic_elements(cell, layer_photo)

COMSOL

Setup

Klayout designs can be ported into fresh COMSOL simulations after installing COMSOL and MPh (https://mph.readthedocs.io/en/latest/installation.html):

pip install mph

NOTE: THERE IS AN APPARENT BUG IN THE MPH LIBRARY IN WHICH THE CLIENT IS NOT INITIALISED ON SOME COMPUTERS. The symptom is that COMSOL_Model won't initialise due to an error originating from client.py in the mph library. A temporary fix is to comment the following lines in mph/client.py:

    #Lines 129-132 in mph/client.py
    java.setPreference('tempfiles.saving.warnifoverwriteolder', 'off')
    java.setPreference('tempfiles.recovery.autosave', 'off')
    java.setPreference('tempfiles.recovery.checkforrecoveries', 'off')
    java.setPreference('tempfiles.saving.optimize', 'filesize')

Typical usage

The MPh library takes care of the Java interface to talk to COMSOL. It could perhaps be bypassed as most of the model-building functionality just uses the JPype library to run the Java raw commands (see COMSOL.py). Here is some boilerplate code from the tutorial ExampleCOMSOL.ipynb:

###SEE ExampleCOMSOL.ipynb for more details###

from ClassLib.COMSOL import COMSOL_Model
import matplotlib.pyplot as plt

chip_len = CHIP.dx
chip_wid = CHIP.dy
chip_thickness = 0.5e-3

#Start up the COMSOL engine
COMSOL_Model.init_engine(num_cores = 32)
#Reset the engine (only required if re-rerunning the cell)
COMSOL_Model.close_all_models()

mainComsol = COMSOL_Model('supercond')

#Initialise with s-parameter and capacitance-matrix simulations
sim_sParams = COMSOL_Simulation_RFsParameters(mainComsol)
sim_capMats = COMSOL_Simulation_CapMats(mainComsol)
mainComsol.initialize_model(chip_len, chip_wid, chip_thickness, [sim_sParams, sim_capMats])

#Add the Klayout components and initialise the inlet and outlet RF ports
mainComsol.add_metallic_Klayout(layout, layer_photo)
sim_sParams.create_port_on_CPW(pad_L,True)
sim_sParams.create_port_on_CPW(pad_R,False)

#Register the resonator line as fine-structure when meshing
mainComsol.register_fine_structure(res_mean.start*1e-9 + DPoint(1e-6,0), 1.2e-6, 10e-6)

#Build and run the simulations
mainComsol.build_geom_mater_elec_mesh()

#Display the index mapping for the conductors in the capacitance matrix
mainComsol.display_conductor_indices()
#Calculate capacitance matrix
capMat = sim_capMats.run()

#Set frequency range and run s-parameter simulation
sim_sParams.set_freq_range(7.210e9,7.214e9,30)
sim_sParams.set_freq_range(7.210e9,7.214e9,3)
sim_sParams.run()

#Save the model and results to an MPH file
mainComsol.save("TestResonator.mph")

#Plot the s-parameters
s_param_vals = sim_sParams.run(False)
plt.plot(s_param_vals[0]/1e9, s_param_vals[1],'bo-',label='S11')
plt.plot(s_param_vals[0]/1e9, s_param_vals[2],'ro-',label='S21')
plt.grid(True, which="both")
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))
plt.xlabel('f(GHz)')
plt.ylabel('S-parameters')
plt.show()

The class COMSOL_Model wraps functionality given in MPh to create a silicon chip with metallic structures on its top surface. Currently the code just supports a simple s-parameter frequency sweep (although the mph file will store the E-field data for inspection via the COMSOL GUI).