gdsfactory / gplugins

gdsfactory plugins
https://gdsfactory.github.io/gplugins/
MIT License
35 stars 30 forks source link

Fail to run Palace test files #325

Open ankagrwl opened 8 months ago

ankagrwl commented 8 months ago

Describe the bug It seems that the Palace config generator is running into an error while assigning Ports for the Interdigitated capacitor simulation

I installed Palace using Spack and it is added to the ./lib dir. There was another error in get_scattering.py line 365, added str to fix it filename=str(simulation_folder / filename),

The error is: image

To Reproduce

import os
from math import inf
from pathlib import Path

import gdsfactory as gf
import numpy as np
import pyvista as pv
import skrf
from gdsfactory.components.interdigital_capacitor_enclosed import (
    interdigital_capacitor_enclosed,
)
from gdsfactory.generic_tech import LAYER, get_generic_pdk
from gdsfactory.technology import LayerStack
from gdsfactory.technology.layer_stack import LayerLevel
from IPython.display import display
from matplotlib import pyplot as plt

from gplugins.common.types import RFMaterialSpec
from gplugins.palace import run_scattering_simulation_palace

gf.config.rich_output()
PDK = get_generic_pdk()
PDK.activate()

layer_stack = LayerStack(
    layers=dict(
        substrate=LayerLevel(
            layer=LAYER.WAFER,
            thickness=500,
            zmin=0,
            material="Si",
            mesh_order=2,
        ),
        bw=LayerLevel(
            layer=LAYER.WG,
            thickness=200e-3,
            zmin=500,
            material="Nb",
            mesh_order=2,
        ),
        bw_port=LayerLevel(
            layer=LAYER.PORT,
            thickness=200e-3,
            zmin=500,
            material="Nb",
            mesh_order=2,
        ),
    )
)
material_spec: RFMaterialSpec = {
    "Si": {"relative_permittivity": 11.45, "relative_permeability": 1},
    "Nb": {"relative_permittivity": np.inf, "relative_permeability": 1},
    "vacuum": {"relative_permittivity": 1, "relative_permeability": 1},
}

simulation_box = [[-200, -200], [200, 200]]
c = gf.Component("scattering_palace")
cap = c << interdigital_capacitor_enclosed(
    metal_layer=LAYER.WG, gap_layer=LAYER.DEEPTRENCH, enclosure_box=simulation_box
)
c.show()

# Add lumped port rectangles manually, see examples for https://awslabs.github.io/palace/stable/examples/cpw/
lumped_port_1_1 = gf.components.bbox(((-40, 11), (-46, 5)), layer=LAYER.PORT)
lumped_port_1_2 = gf.components.bbox(((-40, -11), (-46, -5)), layer=LAYER.PORT)
c << lumped_port_1_1
c << lumped_port_1_2
c.add_port("o1_1", lumped_port_1_1.center, layer=LAYER.PORT, width=1)
c.add_port("o1_2", lumped_port_1_2.center, layer=LAYER.PORT, width=1)

lumped_port_2_1 = gf.components.bbox(((40, 11), (46, 5)), layer=LAYER.PORT)
lumped_port_2_2 = gf.components.bbox(((40, -11), (46, -5)), layer=LAYER.PORT)
c << lumped_port_2_1
c << lumped_port_2_2
c.add_port("o2_1", lumped_port_2_1.center, layer=LAYER.PORT, width=1)
c.add_port("o2_2", lumped_port_2_2.center, layer=LAYER.PORT, width=1)

substrate = gf.components.bbox(bbox=simulation_box, layer=LAYER.WAFER)
c << substrate
c.show()

# help(run_scattering_simulation_palace)

results = run_scattering_simulation_palace(
    c,
    layer_stack=layer_stack,
    material_spec=material_spec,
    only_one_port=True,
    simulation_folder=Path(os.getcwd()) / "temporary",
    driven_settings={
        "MinFreq": 0.1,
        "MaxFreq": 5,
        "FreqStep": 5,
    },
    mesh_parameters=dict(
        background_tag="vacuum",
        background_padding=(0,) * 5 + (700,),
        port_names=c.ports,
        verbosity=1,
        default_characteristic_length=200,
        resolutions={
            "bw": {
                "resolution": 14,
            },
            "substrate": {
                "resolution": 50,
            },
            "vacuum": {
                "resolution": 120,
            },
            **{
                f"bw_port{port}_vacuum": {
                    "resolution": 8,
                    "DistMax": 30,
                    "DistMin": 10,
                    "SizeMax": 14,
                    "SizeMin": 3,
                }
                for port in c.ports
            },
        },
    ),
)
display(results)

What's the code to reproduce the behavior? What commands or code did you write to get the error? You can add screenshots to help explain your problem. Make sure you include the all code for others to reproduce your issue.

Expected behavior What would you like to happen?

Suggested fix How could we fix the bug?

Versions What version of gplugins and each gplugin are you using? Notice that we only may be able help you if you are using the latest version. You can find the version by running:

from gdsfactory.config import print_version_plugins

print_version_plugins()

And update to the latest version of all plugins by running:

pip install "gdsfactory[full]" --upgrade

Or only the specific plugin you are reporting:

pip install "gplugins[tidy3d]" --upgrade

Then copy paste the table so that we know which version of python and plugins you are using.

joamatab commented 8 months ago

Thank you for reporting the issue,

it would be great if someone could help fixing this

@nikosavola @sebastiangrimberg

CosimoMV commented 6 months ago

I get the same error of @ankagrwl (AttributeError: 'NoneType' object has no attribute 'group') when I try to run Palace Full-wave driven simulation example

sebastiangrimberg commented 6 months ago

Unfortunately I don't have any experience with the gdsfactory plugin for Palace, so can't be of much help here. This looks to be an error independent of Palace however, and points to a potential bug in the plugin Python code used to construct the JSON configuration file for Palace.

CosimoMV commented 6 months ago

Yes @sebastiangrimberg , I think this is related to the plugin for the construction of the JSON configuration file too. By the way, do you know an alternative to construct the JSON file?

sebastiangrimberg commented 6 months ago

Yes absolutely, my recommendation would be to write it by hand before generating it or modifying programmatically from a scripting language. You can base off of the examples here: https://awslabs.github.io/palace/dev/examples/examples/.

The only information you'll need from the gdsfactory plugin is the mesh (Palace reads the Gmsh format so that's fine) and the integer group numbers (these are referred to as "Attributes" in the Palace config) assigned to various domains and boundaries in order to prescribe material properties and boundary conditions. All of that info should be in the Gmsh model and mesh that gdsfactory constructs.