qiskit-community / qiskit-metal

Quantum Hardware Design. Open-source project for engineers and scientists to design superconducting quantum devices with ease.
https://qiskit-community.github.io/qiskit-metal/
Apache License 2.0
272 stars 201 forks source link

Gmsh Renderer does not support overlapping geometries #871

Open diemilio opened 1 year ago

diemilio commented 1 year ago

Information

What is the current behavior?

Gmsh Renderer does not currently support overlapping geometries like shown below:

image

When working with only one layer, Gmsh Renderer will correctly generate and mesh the geometry, but this becomes problematic later on when surfaces need to be used to define boundary conditions because there will be faces inside the overlap that will be incorrectly assigned. Furthermore, when working with more than one layer, the render_design method in QElmerRenderer will throw the following error if there is such an overlapping structure and the next layer has a geometry that sits on top of this region: Intersection operation cannot be performed

Steps to reproduce the problem

Create design with overlapping geometries (with 'subtract' set to False), create a QGmshRenderer object, and run render_design.

The following code reproduces this error:

from qiskit_metal import designs
from qiskit_metal.qlibrary.sample_shapes.rectangle import Rectangle
from qiskit_metal.qlibrary.sample_shapes.circle_raster import CircleRaster
from qiskit_metal.renderers.renderer_gmsh.gmsh_renderer import QGmshRenderer

via_rad = 10
via_base_rad = via_rad+5
stub_width = 10
stub_length = 250
stub_subs_margin = 6

design = designs.MultiPlanar({}, overwrite_enabled=True, layer_stack_filename="via_layer_stack.txt")

stub1_met_ops = { 'width': str(stub_length-via_base_rad)+'um',
                  'height': str(stub_width)+'um',
                  'pos_x': str(-stub_length/2-stub_length/2-via_base_rad/2)+'um',
                  'pos_y': '0',
                  'orientation': '0',
                  'subtract': 'False',
                  'helper': 'False',
                  'chip': 'main',
                  'layer': '1' }

stub1_subs_ops = { 'width': str(stub_length-via_base_rad)+'um',
                  'height': str(stub_width+stub_subs_margin)+'um',
                  'pos_x': str(-stub_length/2-stub_length/2-via_base_rad/2)+'um',
                  'pos_y': '0',
                  'orientation': '0',
                  'subtract': 'True',
                  'helper': 'False',
                  'chip': 'main',
                  'layer': '1' }

via_bot_met_ops = { 'radius': str(via_base_rad)+'um',
                    'resolution': '16',
                    'pos_x': str(-stub_length/2-via_base_rad/2)+'um',
                    'pos_y': '0',
                    'subtract': 'False',
                    'helper': 'False',
                    'chip': 'main',
                    'layer': '1' }

via_bot_subs_ops = { 'radius': str(via_base_rad+stub_subs_margin)+'um',
                    'resolution': '16',
                    'pos_x': str(-stub_length/2-via_base_rad/2)+'um',
                    'pos_y': '0',
                    'subtract': 'True',
                    'helper': 'False',
                    'chip': 'main',
                    'layer': '1' }

via_met_ops = { 'radius': str(via_rad)+'um',
                'resolution': '16',
                'pos_x': str(-stub_length/2-via_base_rad/2)+'um',
                'pos_y': '0',
                'subtract': 'False',
                'helper': 'False',
                'chip': 'main',
                'layer': '2' }

Rectangle(design, 'stub1_met', stub1_met_ops)
Rectangle(design, 'stub1_subs', stub1_subs_ops)
CircleRaster(design, 'via_bot_met', via_bot_met_ops)
CircleRaster(design, 'via_bot_subs', via_bot_subs_ops)
CircleRaster(design, 'via_met', via_met_ops)

gmsh = QGmshRenderer(design, layer_types=dict(metal=[1,2,3], dielectric=[4]))
gmsh.options.mesh.min_size = '5um'
gmsh.options.mesh.max_size = '50um'

gmsh.render_design(mesh_geoms=False, skip_junctions=True)

For this code to run, text file "via_layer_stack.txt" with the content below needs to be added in the same folder where the code is executed:

chip_name,layer,datatype,material,thickness,z_coord,fill
'main',1,0,'pec','5um','0um','True'
'main',2,0,'pec','10um','5um','True'
'main',3,0,'pec','5um','15um','True'
'main',4,0,'silicon','-200um','0um','True'

What is the expected behavior?

the overlapping region should be subtracted so there are no internal volume or surfaces. This is already correctly done for geometries with their 'subtract' option set to False.

Suggested solutions