Skip to content

Commit

Permalink
docs
Browse files Browse the repository at this point in the history
  • Loading branch information
simbilod committed Nov 25, 2024
1 parent b0d9ea4 commit 54ef84e
Show file tree
Hide file tree
Showing 8 changed files with 1,001 additions and 0 deletions.
41 changes: 41 additions & 0 deletions docs/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Book settings
# Learn more at https://jupyterbook.org/customize/config.html

title: My sample book
author: The Jupyter Book Community
logo: logo.png

# Force re-execution of notebooks on each build.
# See https://jupyterbook.org/content/execute.html
execute:
execute_notebooks: force
exclude_patterns:
- 'gdsfactory_interface'

# Define the name of the latex output file for PDF builds
latex:
latex_documents:
targetname: book.tex

# Add a bibtex file so that we can create citations
bibtex_bibfiles:
- references.bib

# Information about where the book exists on the web
repository:
url: https://github.com/executablebooks/jupyter-book # Online location of your book
path_to_book: docs # Optional path to your book, relative to the repository root
branch: master # Which branch of the repository should be used when creating links (optional)

# Add GitHub buttons to your book
# See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository
html:
use_issues_button: true
use_repository_button: true

sphinx:
config:
html_js_files:
- https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js
mime_types:
application/vnd.plotly.v1+json: plotly
12 changes: 12 additions & 0 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Table of contents
# Learn more at https://jupyterbook.org/customize/toc.html

format: jb-book
root: intro
chapters:
- file: intro_gmsh
- file: polysurfaces
- file: prisms
- file: models
- file: resolution
- file: gdsfactory_interface
87 changes: 87 additions & 0 deletions docs/gdsfactory_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# %% [markdown]
# # GDSFactory integration
# GDSFactory has an interface to meshwell (v1.0.7)

# %% [markdown]
# > **Warning**
# > The GDSFactory plugin for meshwell/gmsh has not been updated since meshwell version 1.0.7! Some features may be missing, and some more bugs might be present.
#
# %%[markdown]
# GDSFactory has the concept of a "LayerStack", which contains the information about the final fabricated layers:

# %%
import gmsh
import gdsfactory as gf
from gplugins.gmsh.get_mesh import get_mesh
from gdsfactory.generic_tech.layer_stack import get_layer_stack

PDK = gf.generic_tech.get_generic_pdk()
PDK.bend_points_distance = 0.5

LAYER_STACK = get_layer_stack()
LAYER_STACK.pprint()


# %%

c = gf.components.spiral_heater.spiral_racetrack_heater_metal(num=3)
c.plot()

# %% [markdown]
# In meshwell 1.0.7, only a ThresholdField as a distance from the surfaces/volumes was supported. From the GDSFactory plugin, this is entered as a dict for the LayerLevels:
# %%
resolutions = {}
resolutions["core"] = {"resolution": 0.1, "distance": 5}
resolutions["heater"] = {"resolution": 0.2, "distance": 10}
# %% [markdown]
# the "type" argument in get_mesh can be "xy", "uz", or "3D", depending on if a 2D in-plane, 2D out-of-plane cross-section, or 3D mesh si desired:

# %%
xbound = (c.dxmin + c.dxmax) / 2
ymax = c.dymin
ymin = (c.dymin + c.dymax) / 2

mesh = get_mesh(
c,
type="uz",
xsection_bounds=[[xbound, ymin], [xbound, ymax]],
layer_stack=LAYER_STACK,
filename="heater_uz.msh",
resolutions=resolutions,
default_characteristic_length=10,
wafer_padding=50,
interface_delimiter="___",
)

# %%
try:
gmsh.initialize()
gmsh.open("heater_uz.msh")
gmsh.fltk.run()
except: # noqa: E722
print("Skipping CAD GUI visualization - only available when running locally")

# %%
resolutions = {}
resolutions["core"] = {"resolution": 0.5, "distance": 10}
resolutions["heater"] = {"resolution": 5, "distance": 10}

mesh = get_mesh(
c,
type="3D",
layer_stack=LAYER_STACK,
filename="heater_3D.msh",
resolutions=resolutions,
default_characteristic_length=20,
wafer_padding=50,
interface_delimiter="___",
)

# %%
try:
gmsh.initialize()
gmsh.open("heater_3D.msh")
gmsh.fltk.run()
except: # noqa: E722
print("Skipping CAD GUI visualization - only available when running locally")
# %%
169 changes: 169 additions & 0 deletions docs/intro_gmsh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# %% [markdown]
# # GMSH
# Since meshwell is a wrapper around GMSH, we will first review GMSH Python API. For a more thorough explanation of the below, see the GMSH documentation (https://gmsh.info/doc/texinfo/gmsh.html), tutorials (https://gitlab.onelab.info/gmsh/gmsh/-/tree/master/tutorials/python) and API (https://gitlab.onelab.info/gmsh/gmsh/-/blob/master/api/gmsh.py?ref_type=heads).

# %%
import gmsh
import meshio
from meshwell.visualization import plot2D

# %% [markdown]
# ## Bottom-up construction of CAD entities
# The most general way to create CAD entities in GMSH is "bottom-up", going from points --> lines --> closed loops --> surfaces --> closed shells --> volumes

# %%
# Initialize GMSH
gmsh.initialize()
model = gmsh.model
model.add("bottom_up")

# Create points
p1 = model.occ.addPoint(0, 0, 0)
p2 = model.occ.addPoint(2, 0, 0)
p3 = model.occ.addPoint(2, 1, 0)
p4 = model.occ.addPoint(1, 1, 0)
p5 = model.occ.addPoint(1, 2, 0)
p6 = model.occ.addPoint(0, 2, 0)

# Create lines
l1 = model.occ.addLine(p1, p2)
l2 = model.occ.addLine(p2, p3)
l3 = model.occ.addLine(p3, p4)
l4 = model.occ.addLine(p4, p5)
l5 = model.occ.addLine(p5, p6)
l6 = model.occ.addLine(p6, p1)

# Create curve loop
cl = model.occ.addCurveLoop([l1, l2, l3, l4, l5, l6])

# Create surface
s1 = model.occ.addPlaneSurface([cl])

# Create the mesh
model.occ.synchronize()
model.mesh.generate(2)

gmsh.write("bottom_up.xao")
gmsh.write("bottom_up.msh")
gmsh.finalize()

# Read the mesh
mesh = meshio.read("bottom_up.msh")

# %%
try:
gmsh.initialize()
gmsh.open("bottom_up.xao")
gmsh.fltk.run()
except: # noqa: E722
print("Skipping CAD GUI visualization - only available when running locally")

# %%
try:
gmsh.initialize()
gmsh.open("bottom_up.msh")
gmsh.fltk.run()
except: # noqa: E722
print("Skipping mesh GUI visualization - only available when running locally")

# %%
plot2D(mesh, wireframe=True)

# %% [markdown]
# ## Construction of CAD entities from primitives
# A limited set of primitives (rectangles, circles, arcs, spheres, boxes, etc.) are also already implemented in GMSH:
# %%
gmsh.initialize()
model = gmsh.model
model.add("bottom_up")

# Create rectangle
box = model.occ.addRectangle(0, 0, 0, 1, 1)

# Create circle
circle = model.occ.addDisk(3, 0, 0, 0.5, 0.5)

# Create the mesh
model.occ.synchronize()
model.mesh.generate(2)
gmsh.write("primitives.msh")
gmsh.finalize()

# %%
mesh = meshio.read("primitives.msh")
plot2D(mesh, wireframe=True)

# %% [markdown]
# ## Constructive geometry operations
# More complex elementary entities can also be created from constructive geometry operations (cut, fuse, intersect):

# %%
gmsh.initialize()
model = gmsh.model
model.add("bottom_up")

# Create rectangle
box = model.occ.addRectangle(-1, -1, 0, 2, 2)

# Create circle
circle = model.occ.addDisk(0, 0, 0, 0.5, 0.5)

# Keep difference, delete originals
difference = model.occ.cut(
[(2, box)], [(2, circle)], removeObject=True, removeTool=True
)

# Create the mesh
model.occ.synchronize()
model.mesh.generate(2)
gmsh.write("booleans.msh")
gmsh.finalize()

# %%
mesh = meshio.read("booleans.msh")
plot2D(mesh, wireframe=True)

# %% [markdown]
# ## Physical entities
# It is almost always extremely useful to be able to refer to all of the mesh nodes within a set of elementary entities. In GMSH, this is achieved by assigning a "physical" group to a set of elementary entities:

# %%
gmsh.initialize()
model = gmsh.model
model.add("physicals")

# Create rectangle
box1 = model.occ.addRectangle(0, 0, 0, 1, 1)
box2 = model.occ.addRectangle(-2, -2, 0, 1, 1)

# Create circle
circle1 = model.occ.addDisk(3, 0, 0, 0.5, 0.5)
circle2 = model.occ.addDisk(2, -2, 0, 0.5, 0.5)

model.occ.synchronize()

# Create physical groups
model.addPhysicalGroup(2, [box1, box2], tag=1, name="boxes")
model.addPhysicalGroup(2, [circle1, circle2], tag=2, name="circles")

# Create the mesh
model.occ.synchronize()
model.mesh.generate(2)
gmsh.write("physicals.msh")
gmsh.finalize()

# %%
mesh = meshio.read("physicals.msh")
plot2D(mesh)

# %% [markdown]
# ## The sharp bits
#
# ### Conflicting entities
# When adding elementary entities, overlaps and interfaces are not "merged" by default: the entities will overlap and will be meshed separately. The resulting sub-meshes will not be connected.
#
#

# %% [markdown]
# ### Keeping track of integers
# Whenever entities are created / transformed (e.g. when healing interfaces), there can be reassignment of the integer tags used to label them. In the official tutorials, entity tags are re-identified based on some characteristic like bounding extent to later assign to physical groups.
Loading

0 comments on commit 54ef84e

Please sign in to comment.