Skip to content

Commit

Permalink
to_gmsh --> get_mesh (#150)
Browse files Browse the repository at this point in the history
Co-authored-by: Joaquin Matres <4514346+joamatab@users.noreply.github.com>
  • Loading branch information
simbilod and joamatab authored Sep 19, 2023
1 parent fc3b5b5 commit 515fa8f
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 32 deletions.
5 changes: 3 additions & 2 deletions docs/notebooks/femwell_02_heater.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from gdsfactory.technology import LayerStack
from skfem.io import from_meshio

from gplugins.gmsh.mesh import create_physical_mesh
from gplugins.gmsh.mesh import create_physical_mesh, get_mesh

gf.config.rich_output()
PDK = get_generic_pdk()
Expand Down Expand Up @@ -46,7 +46,8 @@ def mesh_with_physicals(mesh, filename):

# -

mesh = heater.to_gmsh(
mesh = get_mesh(
component=heater,
type="uz",
xsection_bounds=[(4, -4), (4, 4)],
layer_stack=filtered_layerstack,
Expand Down
9 changes: 7 additions & 2 deletions docs/notebooks/meshing_01_intro.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
from gdsfactory.technology import LayerStack
from skfem.io import from_meshio

from gplugins.gmsh.get_mesh import get_mesh
from gplugins.gmsh.mesh import create_physical_mesh

gf.config.rich_output()
Expand Down Expand Up @@ -95,8 +96,12 @@ def mesh_with_physicals(mesh, filename):

# The various processing and meshing functions are located under `gplugins.gmsh` and can be called from there, but a shortcut is implemented to mesh directly from a component:

mesh = waveguide.to_gmsh(
type="xy", z=0.09, layer_stack=filtered_layerstack, filename="mesh.msh"
mesh = get_mesh(
component=waveguide,
type="xy",
z=0.09,
layer_stack=filtered_layerstack,
filename="mesh.msh",
)

# This returns a gmsh `.msh` mesh, also saved in `filename` if provided, which can be processed:
Expand Down
33 changes: 25 additions & 8 deletions docs/notebooks/meshing_02_2D_xy_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from gdsfactory.technology import LayerStack
from skfem.io import from_meshio

from gplugins.gmsh.get_mesh import get_mesh
from gplugins.gmsh.mesh import create_physical_mesh

gf.config.rich_output()
Expand Down Expand Up @@ -45,26 +46,38 @@ def mesh_with_physicals(mesh, filename):
# At `z=0.09` um, according to the layer stack above we should see polygons from all three layers:

filename = "mesh"
mesh = waveguide.to_gmsh(
type="xy", z=0.09, layer_stack=filtered_layerstack, filename=f"{filename}.msh"
mesh = get_mesh(
component=waveguide,
type="xy",
z=0.09,
layer_stack=filtered_layerstack,
filename=f"{filename}.msh",
)
mesh = mesh_with_physicals(mesh, filename)
mesh = from_meshio(mesh)
mesh.draw().plot()

# At `z=0`, you can see only the core and slab:

mesh = waveguide.to_gmsh(
type="xy", z=0.0, layer_stack=filtered_layerstack, filename=f"{filename}.msh"
mesh = get_mesh(
component=waveguide,
type="xy",
z=0.0,
layer_stack=filtered_layerstack,
filename=f"{filename}.msh",
)
mesh = mesh_with_physicals(mesh, filename)
mesh = from_meshio(mesh)
mesh.draw().plot()

# At `z=1.0`, you can only see the vias appear:

mesh = waveguide.to_gmsh(
type="xy", z=1.0, layer_stack=filtered_layerstack, filename=f"{filename}.msh"
mesh = get_mesh(
component=waveguide,
type="xy",
z=1.0,
layer_stack=filtered_layerstack,
filename=f"{filename}.msh",
)
mesh = mesh_with_physicals(mesh, filename)
mesh = from_meshio(mesh)
Expand All @@ -86,8 +99,12 @@ def mesh_with_physicals(mesh, filename):
waveguide_trimmed
# -

mesh = waveguide_trimmed.to_gmsh(
type="xy", z=0.09, layer_stack=filtered_layerstack, filename=f"{filename}.msh"
mesh = get_mesh(
component=waveguide_trimmed,
type="xy",
z=0.09,
layer_stack=filtered_layerstack,
filename=f"{filename}.msh",
)
mesh = mesh_with_physicals(mesh, filename)
mesh = from_meshio(mesh)
Expand Down
7 changes: 5 additions & 2 deletions docs/notebooks/meshing_03_2D_uz_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from gdsfactory.technology import LayerStack
from skfem.io import from_meshio

from gplugins.gmsh.get_mesh import get_mesh
from gplugins.gmsh.mesh import create_physical_mesh

gf.config.rich_output()
Expand Down Expand Up @@ -52,7 +53,8 @@ def mesh_with_physicals(mesh, filename):

# Choosing the line going from `y=-4` to `y=4` at `x=4`, which crosses slab, via, and core:

mesh = waveguide_trimmed.to_gmsh(
mesh = get_mesh(
component=waveguide_trimmed,
type="uz",
xsection_bounds=[(4, -4), (4, 4)],
layer_stack=filtered_layerstack,
Expand All @@ -68,7 +70,8 @@ def mesh_with_physicals(mesh, filename):
#
# You can add a convenience argument to add a background mesh around the geometry (instead of defining a dummy polygon and layer in the layerstack with low mesh_order):

mesh = waveguide_trimmed.to_gmsh(
mesh = get_mesh(
component=waveguide_trimmed,
type="uz",
xsection_bounds=[(4, -4), (4, 4)],
layer_stack=filtered_layerstack,
Expand Down
19 changes: 13 additions & 6 deletions docs/notebooks/meshing_04_refinement.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from gdsfactory.technology import LayerStack
from skfem.io import from_meshio

from gplugins.gmsh.get_mesh import get_mesh
from gplugins.gmsh.mesh import create_physical_mesh

PDK = get_generic_pdk()
Expand Down Expand Up @@ -60,7 +61,8 @@ def mesh_with_physicals(mesh, filename):
# With `default_resolution_max` set to 1 um and `default_resolution_min` set to 100 nm:

# +
mesh = waveguide_trimmed.to_gmsh(
mesh = get_mesh(
component=waveguide_trimmed,
type="uz",
xsection_bounds=[(4, -4), (4, 4)],
layer_stack=filtered_layerstack,
Expand All @@ -78,7 +80,8 @@ def mesh_with_physicals(mesh, filename):

# With `default_resolution_max` set to 300 nm and `default_resolution_max` set to 50 nm:

mesh = waveguide_trimmed.to_gmsh(
mesh = get_mesh(
component=waveguide_trimmed,
type="uz",
xsection_bounds=[(4, -4), (4, 4)],
layer_stack=filtered_layerstack,
Expand All @@ -101,7 +104,8 @@ def mesh_with_physicals(mesh, filename):
# For example, to refine within the core only, one could use:

resolutions = {"core": {"resolution": 0.05, "distance": 0}}
mesh = waveguide_trimmed.to_gmsh(
mesh = get_mesh(
component=waveguide_trimmed,
type="uz",
xsection_bounds=[(4, -4), (4, 4)],
layer_stack=filtered_layerstack,
Expand All @@ -117,7 +121,8 @@ def mesh_with_physicals(mesh, filename):
# Adding a dropoff at the interface:

resolutions = {"core": {"resolution": 0.05, "distance": 5}}
mesh = waveguide_trimmed.to_gmsh(
mesh = get_mesh(
component=waveguide_trimmed,
type="uz",
xsection_bounds=[(4, -4), (4, 4)],
layer_stack=filtered_layerstack,
Expand All @@ -138,7 +143,8 @@ def mesh_with_physicals(mesh, filename):
"via_contact": {"resolution": 0.2, "distance": 0},
"oxide": {"resolution": 1, "distance": 0},
}
mesh = waveguide_trimmed.to_gmsh(
mesh = get_mesh(
component=waveguide_trimmed,
type="uz",
xsection_bounds=[(4, -4), (4, 4)],
layer_stack=filtered_layerstack,
Expand Down Expand Up @@ -178,7 +184,8 @@ def mesh_with_physicals(mesh, filename):

global_meshsize_array = np.array(global_meshsize_array)

mesh = waveguide_trimmed.to_gmsh(
mesh = get_mesh(
component=waveguide_trimmed,
type="uz",
xsection_bounds=[(4, -4), (4, 4)],
layer_stack=filtered_layerstack,
Expand Down
7 changes: 5 additions & 2 deletions docs/notebooks/meshing_05_3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from gdsfactory.technology import LayerStack
from skfem.io import from_meshio

from gplugins.gmsh.get_mesh import get_mesh
from gplugins.gmsh.mesh import create_physical_mesh

PDK = get_generic_pdk()
Expand Down Expand Up @@ -49,7 +50,8 @@ def mesh_with_physicals(mesh, filename):

# -

mesh = waveguide.to_gmsh(
mesh = get_mesh(
component=waveguide,
type="3D",
layer_stack=filtered_layerstack,
filename=f"{filename}.msh",
Expand Down Expand Up @@ -80,7 +82,8 @@ def mesh_with_physicals(mesh, filename):
print(waveguide.ports["top_e1"])
print(waveguide.ports["bot_e1"])

mesh = waveguide.to_gmsh(
mesh = get_mesh(
component=waveguide,
type="3D",
layer_stack=filtered_layerstack,
filename=f"{filename}.msh",
Expand Down
6 changes: 4 additions & 2 deletions gplugins/elmer/get_capacitance.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from numpy import isfinite
from pandas import read_csv


from gplugins.common.base_models.simulation import ElectrostaticResults
from gplugins.common.types import RFMaterialSpec
from gplugins.common.utils.async_helpers import (
Expand Down Expand Up @@ -190,7 +191,7 @@ def run_capacitive_simulation_elmer(
Default is a temporary directory.
simulator_params: Elmer-specific parameters. See template file for more details.
mesh_parameters:
Keyword arguments to provide to :func:`~Component.to_gmsh`.
Keyword arguments to provide to :func:`get_mesh`.
mesh_file: Path to a ready mesh to use. Useful for reusing one mesh file.
By default a mesh is generated according to ``mesh_parameters``.
Expand Down Expand Up @@ -223,7 +224,8 @@ def run_capacitive_simulation_elmer(
if mesh_file:
shutil.copyfile(str(mesh_file), str(simulation_folder / filename))
else:
component.to_gmsh(
get_mesh(
component=component,
type="3D",
filename=simulation_folder / filename,
layer_stack=layer_stack,
Expand Down
5 changes: 4 additions & 1 deletion gplugins/femwell/mode_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
Mesh,
)

from gplugins.gmsh.get_mesh import get_mesh

mesh_filename = "mesh.msh"


Expand Down Expand Up @@ -127,7 +129,8 @@ def compute_component_slice_modes(
"""

# Mesh
mesh = component.to_gmsh(
mesh = get_mesh(
component=component,
type="uz",
xsection_bounds=xsection_bounds,
layer_stack=layerstack,
Expand Down
6 changes: 5 additions & 1 deletion gplugins/femwell/solve_thermal.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ def get_thermal_conductivities(basis):
from gdsfactory.generic_tech import LAYER_STACK
from skfem import Mesh

from gplugins.gmsh.get_mesh import get_mesh

LAYER_STACK.layers["heater"].thickness = 0.13
LAYER_STACK.layers["heater"].zmin = 2.2
heater_len = 1 # 1 um, so normalized
Expand All @@ -83,7 +85,9 @@ def get_thermal_conductivities(basis):

# ====== MESH =====
filtered_layerstack = LAYER_STACK
filtered_layerstack.get_component_with_derived_layers(heater).to_gmsh(
heater_derived = filtered_layerstack.get_component_with_derived_layers(heater)
get_mesh(
component=heater_derived,
type="uz",
xsection_bounds=[(3, c.bbox[0, 1]), (3, c.bbox[1, 1])],
# xsection_bounds=[(3, -4), (3, 4)],
Expand Down
78 changes: 78 additions & 0 deletions gplugins/gmsh/get_mesh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import importlib.util

from gdsfactory import Component
from gdsfactory.typings import ComponentSpec, Layer, LayerStack

from gplugins.gmsh.uz_xsection_mesh import uz_xsection_mesh
from gplugins.gmsh.xy_xsection_mesh import xy_xsection_mesh
from gplugins.gmsh.xyz_mesh import xyz_mesh


def get_mesh(
component: ComponentSpec,
type: str,
layer_stack: LayerStack,
z: float | None = None,
xsection_bounds=None,
wafer_padding: float = 0.0,
wafer_layer: Layer = (99999, 0),
**kwargs,
):
"""Returns a gmsh mesh of the component for finite element simulation.
Arguments:
component: component
type: one of "xy", "uz", or "3D". Determines the type of mesh to return.
layer_stack: LayerStack object containing layer information.
z: used to define z-slice for xy meshing.
xsection_bounds: used to define in-plane line for uz meshing.
wafer_padding: padding beyond bbox to add to WAFER layers.
wafer_layer: layer to use for WAFER padding.
Keyword Args:
Arguments for the target meshing function in gplugins.gmsh
TODO! make compatible with new unified plugins interface
"""

# Add WAFER layer:
padded_component = Component()
padded_component << component
(xmin, ymin), (xmax, ymax) = component.bbox
points = [
[xmin - wafer_padding, ymin - wafer_padding],
[xmax + wafer_padding, ymin - wafer_padding],
[xmax + wafer_padding, ymax + wafer_padding],
[xmin - wafer_padding, ymax + wafer_padding],
]
padded_component.add_polygon(points, layer=wafer_layer)
padded_component.add_ports(component.get_ports_list())

if type == "xy":
if z is None:
raise ValueError(
'For xy-meshing, a z-value must be provided via the float argument "z".'
)

return xy_xsection_mesh(padded_component, z, layer_stack, **kwargs)
elif type == "uz":
if xsection_bounds is None:
raise ValueError(
"For uz-meshing, you must provide a line in the xy-plane "
"via the Tuple argument [[x1,y1], [x2,y2]] xsection_bounds."
)

return uz_xsection_mesh(
padded_component, xsection_bounds, layer_stack, **kwargs
)
elif type == "3D":
spec = importlib.util.find_spec("meshwell")
if spec is None:
print(
"3D meshing requires meshwell, see https://github.com/simbilod/meshwell or run pip install meshwell."
)

return xyz_mesh(padded_component, layer_stack, **kwargs)
else:
raise ValueError('Required argument "type" must be one of "xy", "uz", or "3D".')
6 changes: 4 additions & 2 deletions gplugins/gmsh/parse_gds.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ def tile_shapes(shapes_dict):
if __name__ == "__main__":
from gdsfactory.generic_tech import LAYER_STACK

from gplugins.gmsh.get_mesh import get_mesh

c = gf.components.straight_heater_doped_rib()
c.to_gmsh(type="xy", layer_stack=LAYER_STACK, z=0)
c.to_gmsh(type="xy", layer_stack=LAYER_STACK, z=0)
get_mesh(component=c, type="xy", layer_stack=LAYER_STACK, z=0)
get_mesh(component=c, type="xy", layer_stack=LAYER_STACK, z=0)
Loading

0 comments on commit 515fa8f

Please sign in to comment.