Vivaldi antenna#
Full parametric Vivaldi antenna mesh using gmsh/OpenCASCADE.
The exponential taper profile follows: $\(y = \pm\frac{w_s}{2} \cdot e^{C(x - x_0)}\)\( where \)C\( is the opening rate (25 here) and \)x_0$ is the taper start.
Coordinate convention (matches the diagram, x is the long axis):
Ground plane centred at origin in XY plane
Aperture opens toward +x
Cavity is on the −x side
Z is vertical (substrate thickness)
import gmsh
import math
import numpy as np
from palacetoolkit.mesh import (
Entity,
run_meshing_pipeline,
generate_3d_mesh,
refine_near_surfaces
)
from palacetoolkit.viz import run_with_scrollable_output, view_mesh
Antenna parameters#
taper_length: float = 0.243
aperture_width: float = 0.105
opening_rate: float = 25.0
slot_width: float = 5e-4
cavity_diameter: float = 0.024
cavity_to_taper: float = 0.023
ground_plane_length: float = 0.300
ground_plane_width: float = 0.125
h_sub: float = 0.015
air_height: float = 0.05
air_margin: float = 0.05
freq_ghz = 4.5
c0 = 3e8
wavelength = c0 / (freq_ghz * 1e9)
mesh_file = "vivaldi.msh"
# Derived coordinates
Lx = ground_plane_length
Ly = ground_plane_width
# Left edge of the ground plane.
x0 = -Lx/2
# Right edge of the ground plane.
x1 = Lx/2
# x_taper_start: where the exponential section begins
x_taper_start = x1 - taper_length
# x_slot_left: start of parallel section = end of cavity = x_taper_start - s
x_slot_left = x_taper_start - cavity_to_taper
# cavity centre
x_cav = x_slot_left - cavity_diameter / 2
print(f"Ground plane: [{x0:.4f}, {x1:.4f}]")
print(f"Taper starts at: x = {x_taper_start:.4f}")
print(f"Parallel section: x = [{x_slot_left:.4f}, {x_taper_start:.4f}] "
f"length = {cavity_to_taper*1e3:.1f} mm (= cavity_to_taper)")
print(f"Cavity centre at: x = {x_cav:.4f}")
print(f"Cavity right edge: x = {x_slot_left:.4f} (= x_taper_start - s)")
Ground plane: [-0.1500, 0.1500]
Taper starts at: x = -0.0930
Parallel section: x = [-0.1160, -0.0930] length = 23.0 mm (= cavity_to_taper)
Cavity centre at: x = -0.1280
Cavity right edge: x = -0.1160 (= x_taper_start - s)
Exponential taper mathematics#
The upper edge of the Vivaldi slot follows: $\(y_{\text{upper}}(x) = \frac{w_s}{2} \cdot e^{C(x - x_{\text{ts}})}\)\( scaled so that \)y_{\text{upper}}(x_1) = w_a/2$.
We solve for the normalisation constant \(A\): $\(A = \frac{w_a/2}{e^{C(x_1 - x_{\text{ts}})}}\)\( which gives: \)\(y_{\text{upper}}(x) = A \cdot e^{C(x - x_{\text{ts}})}\)$
The lower edge is the mirror: \(y_{\text{lower}} = -y_{\text{upper}}\).
def taper_y(x: float, sign: float = 1.0) -> float:
# Normalisation: amplitude A chosen so y(x1) = aperture_width/2
A = (aperture_width / 2) / math.exp(opening_rate * (x1 - x_taper_start))
return sign * A * math.exp(opening_rate * (x - x_taper_start))
# Quick sanity checks
print(f"y at taper start : {taper_y(x_taper_start):+.5f} (expected ≈ {slot_width/2:+.5f})")
print(f"y at aperture : {taper_y(x1):+.5f} (expected ≈ {aperture_width/2:+.5f})")
y at taper start : +0.00012 (expected ≈ +0.00025)
y at aperture : +0.05250 (expected ≈ +0.05250)
Initialise gmsh#
gmsh.initialize()
gmsh.model.add("vivaldi_antenna")
kernel = gmsh.model.occ
Build the 3-D volumes (substrate + air sphere)#
# Bounding box extents
total_xmin = x0 - air_margin
total_xmax = x1 + air_margin
total_ymin = -Ly/2 - air_margin
total_ymax = Ly/2 + air_margin
total_zmax = h_sub + air_height
# Substrate
substrate = kernel.addBox(
x0, -Ly/2, 0,
Lx, Ly, h_sub
)
# Air sphere (replace air box, consistent with patch_antenna workflow)
airsphere_radius = max(abs(total_xmin), abs(total_xmax), abs(total_ymin), abs(total_ymax), total_zmax)
air_sphere = kernel.addSphere(0.0, 0.0, 0.0, airsphere_radius)
print("Substrate tag:", substrate)
print("Air sphere tag:", air_sphere)
Substrate tag: 1
Air sphere tag: 2
Build the copper patch (ground plane + taper slot + cavity)#
Strategy:
Start with a full rectangular ground-plane surface.
Subtract the exponential slot (built from a spline boundary).
Subtract the circular cavity.
The result is the physical copper surface at z = h_sub.
# Top rectangle. We´ll cut the slot and cavity out of this.
top_rect = kernel.addRectangle(x0, -Ly/2, h_sub, Lx, Ly)
# Parallel section geometry.
p_ul = kernel.addPoint(x_slot_left, +slot_width/2, h_sub)
p_ur = kernel.addPoint(x_taper_start, +slot_width/2, h_sub)
p_lr = kernel.addPoint(x_taper_start, -slot_width/2, h_sub)
p_ll = kernel.addPoint(x_slot_left, -slot_width/2, h_sub)
# Straight lines
line_top_par = kernel.addLine(p_ul, p_ur) # upper parallel edge
line_bot_par = kernel.addLine(p_lr, p_ll) # lower parallel edge (reversed for CCW)
line_left = kernel.addLine(p_ll, p_ul) # left closing line (at x_slot_left)
# Interpolate points along the exponential taper curve from x_taper_start to x1.
N_pts = 100
xs = np.linspace(x_taper_start, x1, N_pts)
# Upper spline
upper_inner = [kernel.addPoint(float(x), taper_y(float(x), +1.0), h_sub)
for x in xs[1:]]
upper_spline = kernel.addSpline([p_ur] + upper_inner)
# Lower spline: starts at p_lr, reversed direction for CCW loop.
lower_inner = [kernel.addPoint(float(x), taper_y(float(x), -1.0), h_sub)
for x in xs[1:]]
# In the loop we traverse lower in reverse (aperture → taper_start),
# so we list points aperture-end first.
lower_spline = kernel.addSpline(lower_inner[::-1] + [p_lr])
# Aperture closing line (right edge, x = x1)
p_apt = upper_inner[-1] # top-right aperture point
p_apb = lower_inner[-1] # bottom-right aperture point
line_aperture = kernel.addLine(p_apt, p_apb)
slot_loop = kernel.addCurveLoop([
line_left, # up the left edge (x_slot_left, bot→top)
line_top_par, # rightward along upper parallel
upper_spline, # upper exponential curve to aperture
line_aperture, # down the aperture edge
lower_spline, # lower exponential back to x_taper_start (reversed)
line_bot_par, # leftward along lower parallel back to start
])
slot_surf = kernel.addPlaneSurface([slot_loop])
# Circular cavity
cav_r = cavity_diameter / 2
cav_cx = x_cav
cav_cy = 0.0
cav_circle = kernel.addCircle(cav_cx, cav_cy, h_sub, cav_r)
cav_loop = kernel.addCurveLoop([cav_circle])
cav_surf = kernel.addPlaneSurface([cav_loop])
print(f"Parallel section: x=[{x_slot_left:.4f}, {x_taper_start:.4f}] y=±{slot_width/2:.5f}")
print(f"Exponential section: x=[{x_taper_start:.4f}, {x1:.4f}]")
print(f"Aperture width at x1: {2*taper_y(x1,1)*1e3:.2f} mm (target {aperture_width*1e3:.2f} mm)")
print("Top rectangle tag: ", top_rect)
print("Slot surface tag: ", slot_surf)
print("Cavity surface tag: ", cav_surf)
Parallel section: x=[-0.1160, -0.0930] y=±0.00025
Exponential section: x=[-0.0930, 0.1500]
Aperture width at x1: 105.00 mm (target 105.00 mm)
Top rectangle tag: 8
Slot surface tag: 9
Cavity surface tag: 10
Feed port#
From the inset diagram, the feed port is a square face in the YZ plane
at the left edge of the ground plane (x = x0). It is centred on the slot
(y = 0) and spans the substrate thickness in z.
feed_offsetis the x-axis offset that positions where along the slot the port is referenced — here it locates the port atx = x0 + feed_offsetinside the ground plane, but the excitation face itself sits flush atx = x0(the left wall of the computational domain).The port is square: width = height =
slot_widthin the YZ cross-section.It is centred at
y = 0, z = h_sub / 2(mid-height of the substrate).
port_size = slot_width # square side length [m]
port_x_ctr = x_taper_start - port_size / 2 # port centre along x
port_x0 = port_x_ctr - port_size / 2 # left x of port
port_y0 = -port_size / 2 # bottom y (centred on slot)
# Flat XY-plane rectangle at z = h_sub — no rotation needed.
feed_port_surf = kernel.addRectangle(
port_x0, # x start
port_y0, # y start (centred: -w_s/2 .. +w_s/2)
h_sub, # z = top of substrate
port_size, # dx = slot_width (square in x)
port_size, # dy = slot_width (square in y, touches both copper edges)
)
print(f"Feed port surface tag: {feed_port_surf}")
print(f"Port centre: x={port_x_ctr:.4f} y=0 z={h_sub:.5f} (top of substrate)")
print(f"Port x range: [{port_x0:.4f}, {port_x0+port_size:.4f}]")
print(f"Port y range: [{port_y0:.5f}, {-port_y0:.5f}]")
print(f"Port size: {port_size*1e3:.2f} mm × {port_size*1e3:.2f} mm (square)")
print(f"Sanity: port_x_ctr ({port_x_ctr:.4f}) should be between "
f"cavity right edge ({x_cav + cavity_diameter/2:.4f}) "
f"and taper start ({x_taper_start:.4f})")
Feed port surface tag: 11
Port centre: x=-0.0932 y=0 z=0.01500 (top of substrate)
Port x range: [-0.0935, -0.0930]
Port y range: [-0.00025, 0.00025]
Port size: 0.50 mm × 0.50 mm (square)
Sanity: port_x_ctr (-0.0932) should be between cavity right edge (-0.1160) and taper start (-0.0930)
Boolean operations — assemble the copper patch#
Cut the slot and cavity out of the ground-plane rectangle. The feed strip is kept separate (it is a distinct conductor patch).
kernel.synchronize()
# Cut slot + cavity from ground-plane rectangle
# BooleanCut returns (result_dimtags, map)
copper_patch, _ = kernel.cut(
[(2, top_rect)], # object: full rectangle
[(2, slot_surf), (2, cav_surf)], # tools: slot + cavity
removeObject=True, removeTool=True
)
kernel.synchronize()
print("Copper patch surfaces after boolean cut:")
for dim, tag in copper_patch:
print(f" dim={dim}, tag={tag}")
Copper patch surfaces after boolean cut:
dim=2, tag=8
Entity definition.#
In order to get a good mesh we need to fragment it and restore it, run_meshing_pipeline does this and also defines the physical groups.
entities = [
Entity("copper_patch", dim=2, btype="pec", mesh_order=1, tags=[copper_patch[0][1]]),
Entity("substrate", dim=3, btype="dielectric", mesh_order=1, tags=[substrate], loss_tan=0.0009, eps_r=2.2, mu_r=1.0),
Entity("air_sphere", dim=3, btype="dielectric", mesh_order=2, tags=[air_sphere], loss_tan=0.0, eps_r=1.0, mu_r=1.0),
Entity("feed_port", dim=2, btype="waveport", mesh_order=0, tags=[feed_port_surf]),
]
pg_map = run_meshing_pipeline(entities)
refine_near_surfaces(entities[0].dimtags + entities[-1].dimtags,
wavelength,
ppw_near=300,
ppw_far=5,
transition_distance=wavelength/4,
set_as_background=True)
generate_3d_mesh(entities, mesh_file, optimize=True)
gmsh.option.setNumber("Mesh.MshFileVersion", 2.2)
gmsh.write(mesh_file)
gmsh.finalize()
Physical group 'substrate' (dim=3): pg=1, tags=[1]
Physical group 'air_sphere' (dim=3): pg=2, tags=[2]
Physical group 'copper_patch' (dim=2): pg=3, tags=[8]
Physical group 'feed_port' (dim=2): pg=4, tags=[11]
Physical group 'air_sphere__substrate' (dim=2): pg=5, tags=[12, 13, 14, 15, 5, 16, 17, 18]
Physical group 'air_sphere__None' (dim=2): pg=6, tags=[19]
ppw_near=300 ppw_far=5
SizeMax=0.0133 transition=0.0167
global: 16 curves, SizeMin=0.0002
Info : Meshing 1D...
Info : [ 0%] Meshing curve 4 (Line)
Info : [ 10%] Meshing curve 8 (Line)
Info : [ 10%] Meshing curve 9 (Line)
Info : [ 20%] Meshing curve 11 (Line)
Info : [ 20%] Meshing curve 12 (Line)
Info : [ 20%] Meshing curve 13 (Line)
Info : [ 30%] Meshing curve 14 (Line)
Info : [ 30%] Meshing curve 15 (Line)
Info : [ 30%] Meshing curve 16 (Line)
Info : [ 40%] Meshing curve 17 (Line)
Info : [ 40%] Meshing curve 18 (Line)
Info : [ 40%] Meshing curve 19 (Line)
Info : [ 50%] Meshing curve 20 (Line)
Info : [ 50%] Meshing curve 21 (Line)
Info : [ 60%] Meshing curve 22 (Circle)
Info : [ 60%] Meshing curve 23 (BSpline)
Info : [ 60%] Meshing curve 24 (Line)
Info : [ 70%] Meshing curve 25 (BSpline)
Info : [ 70%] Meshing curve 26 (Line)
Info : [ 70%] Meshing curve 27 (Line)
Info : [ 80%] Meshing curve 28 (Line)
Info : [ 80%] Meshing curve 29 (Line)
Info : [ 80%] Meshing curve 30 (Line)
Info : [ 90%] Meshing curve 32 (Circle)
Info : [100%] Meshing curve 34 (Line)
Info : [100%] Meshing curve 35 (Line)
Info : Done meshing 1D (Wall 1.88283s, CPU 1.81569s)
Info : Meshing 2D...
Info : [ 0%] Meshing surface 5 (Plane, MeshAdapt)
Info : [ 10%] Meshing surface 8 (Plane, MeshAdapt)
Info : [ 20%] Meshing surface 11 (Plane, MeshAdapt)
Info : [ 30%] Meshing surface 12 (Plane, MeshAdapt)
Info : [ 40%] Meshing surface 13 (Plane, MeshAdapt)
Info : [ 50%] Meshing surface 14 (Plane, MeshAdapt)
Info : [ 60%] Meshing surface 15 (Plane, MeshAdapt)
Info : [ 70%] Meshing surface 16 (Plane, MeshAdapt)
Info : [ 80%] Meshing surface 17 (Plane, MeshAdapt)
Info : [ 90%] Meshing surface 18 (Plane, MeshAdapt)
Info : [100%] Meshing surface 19 (Sphere, MeshAdapt)
Info : Done meshing 2D (Wall 5.92237s, CPU 5.90935s)
Info : Meshing 3D...
Info : 3D Meshing 2 volumes with 1 connected component
Info : Tetrahedrizing 18829 nodes...
Info : Done tetrahedrizing 18837 nodes (Wall 0.295651s, CPU 0.290184s)
Info : Reconstructing mesh...
Info : - Creating surface mesh
Info : - Identifying boundary edges
Info : - Recovering boundary
Info : Done reconstructing mesh (Wall 0.580503s, CPU 0.575125s)
Info : Found volume 2
Info : Found volume 1
Info : It. 0 - 0 nodes created - worst tet radius 34.952 (nodes removed 0 0)
Info : It. 500 - 496 nodes created - worst tet radius 3.19998 (nodes removed 0 4)
Info : It. 1000 - 992 nodes created - worst tet radius 3.29385 (nodes removed 0 8)
Info : It. 1500 - 1488 nodes created - worst tet radius 2.98787 (nodes removed 0 12)
Info : It. 2000 - 1980 nodes created - worst tet radius 2.21376 (nodes removed 0 20)
Info : It. 2500 - 2480 nodes created - worst tet radius 2.03058 (nodes removed 0 20)
Info : It. 3000 - 2980 nodes created - worst tet radius 1.97895 (nodes removed 0 20)
Info : It. 3500 - 3476 nodes created - worst tet radius 1.8197 (nodes removed 0 24)
Info : It. 4000 - 3972 nodes created - worst tet radius 1.74223 (nodes removed 0 28)
Info : It. 4500 - 4469 nodes created - worst tet radius 1.67595 (nodes removed 0 31)
Info : It. 5000 - 4968 nodes created - worst tet radius 1.61457 (nodes removed 0 32)
Info : It. 5500 - 5467 nodes created - worst tet radius 1.86937 (nodes removed 0 33)
Info : It. 6000 - 5967 nodes created - worst tet radius 1.51066 (nodes removed 0 33)
Info : It. 6500 - 6467 nodes created - worst tet radius 1.46905 (nodes removed 0 33)
Info : It. 7000 - 6967 nodes created - worst tet radius 1.43197 (nodes removed 0 33)
Info : It. 7500 - 7461 nodes created - worst tet radius 1.39799 (nodes removed 0 39)
Info : It. 8000 - 7961 nodes created - worst tet radius 1.36684 (nodes removed 0 39)
Info : It. 8500 - 8455 nodes created - worst tet radius 1.33936 (nodes removed 0 45)
Info : It. 9000 - 8955 nodes created - worst tet radius 1.31112 (nodes removed 0 45)
Info : It. 9500 - 9452 nodes created - worst tet radius 1.28486 (nodes removed 0 48)
Info : It. 10000 - 9952 nodes created - worst tet radius 1.26075 (nodes removed 0 48)
Info : It. 10500 - 10452 nodes created - worst tet radius 1.2391 (nodes removed 0 48)
Info : It. 11000 - 10950 nodes created - worst tet radius 1.21802 (nodes removed 0 50)
Info : It. 11500 - 11450 nodes created - worst tet radius 1.19886 (nodes removed 0 50)
Info : It. 12000 - 11950 nodes created - worst tet radius 1.1814 (nodes removed 0 50)
Info : It. 12500 - 12450 nodes created - worst tet radius 1.16408 (nodes removed 0 50)
Info : It. 13000 - 12950 nodes created - worst tet radius 1.14617 (nodes removed 0 50)
Info : It. 13500 - 13450 nodes created - worst tet radius 1.13022 (nodes removed 0 50)
Info : It. 14000 - 13950 nodes created - worst tet radius 1.11679 (nodes removed 0 50)
Info : It. 14500 - 14450 nodes created - worst tet radius 1.10362 (nodes removed 0 50)
Info : It. 15000 - 14950 nodes created - worst tet radius 1.1308 (nodes removed 0 50)
Info : It. 15500 - 15448 nodes created - worst tet radius 1.07942 (nodes removed 0 52)
Info : It. 16000 - 15948 nodes created - worst tet radius 1.06716 (nodes removed 0 52)
Info : It. 16500 - 16448 nodes created - worst tet radius 1.0563 (nodes removed 0 52)
Info : It. 17000 - 16948 nodes created - worst tet radius 1.04573 (nodes removed 0 52)
Info : It. 17500 - 17448 nodes created - worst tet radius 1.03526 (nodes removed 0 52)
Info : It. 18000 - 17948 nodes created - worst tet radius 1.02558 (nodes removed 0 52)
Info : It. 18500 - 18448 nodes created - worst tet radius 1.01597 (nodes removed 0 52)
Info : It. 19000 - 18948 nodes created - worst tet radius 1.00774 (nodes removed 0 52)
Info : 3D refinement terminated (38264 nodes total):
Info : - 26 Delaunay cavities modified for star shapeness
Info : - 52 nodes could not be inserted
Info : - 216865 tetrahedra created in 2.73033 sec. (79428 tets/s)
Info : 4 node relocations
Info : Done meshing 3D (Wall 4.25849s, CPU 4.26071s)
Info : Optimizing mesh...
Info : Optimizing volume 1
Info : Optimization starts (volume = 0.0005625) with worst = 0.000289261 / average = 0.592864:
Info : 0.00 < quality < 0.10 : 297 elements
Info : 0.10 < quality < 0.20 : 801 elements
Info : 0.20 < quality < 0.30 : 1681 elements
Info : 0.30 < quality < 0.40 : 5167 elements
Info : 0.40 < quality < 0.50 : 8958 elements
Info : 0.50 < quality < 0.60 : 11495 elements
Info : 0.60 < quality < 0.70 : 11119 elements
Info : 0.70 < quality < 0.80 : 9732 elements
Info : 0.80 < quality < 0.90 : 5468 elements
Info : 0.90 < quality < 1.00 : 1491 elements
Info : 2287 edge swaps, 100 node relocations (volume = 0.0005625): worst = 0.000309648 / average = 0.608497 (Wall 0.0431121s, CPU 0.043229s)
Info : 2423 edge swaps, 115 node relocations (volume = 0.0005625): worst = 0.000329345 / average = 0.6088 (Wall 0.0576463s, CPU 0.057853s)
Info : 2441 edge swaps, 120 node relocations (volume = 0.0005625): worst = 0.000329345 / average = 0.608884 (Wall 0.0702314s, CPU 0.070517s)
Info : 0.00 < quality < 0.10 : 6 elements
Info : 0.10 < quality < 0.20 : 1 elements
Info : 0.20 < quality < 0.30 : 375 elements
Info : 0.30 < quality < 0.40 : 5510 elements
Info : 0.40 < quality < 0.50 : 9027 elements
Info : 0.50 < quality < 0.60 : 11469 elements
Info : 0.60 < quality < 0.70 : 11237 elements
Info : 0.70 < quality < 0.80 : 9789 elements
Info : 0.80 < quality < 0.90 : 5513 elements
Info : 0.90 < quality < 1.00 : 1489 elements
Info : Optimizing volume 2
Warning : 2 ill-shaped tets are still in the mesh
Info : Optimization starts (volume = 0.0328953) with worst = 0.000224913 / average = 0.678141:
Info : 0.00 < quality < 0.10 : 589 elements
Info : 0.10 < quality < 0.20 : 1579 elements
Info : 0.20 < quality < 0.30 : 3071 elements
Info : 0.30 < quality < 0.40 : 7814 elements
Info : 0.40 < quality < 0.50 : 15648 elements
Info : 0.50 < quality < 0.60 : 23015 elements
Info : 0.60 < quality < 0.70 : 27328 elements
Info : 0.70 < quality < 0.80 : 31555 elements
Info : 0.80 < quality < 0.90 : 34975 elements
Info : 0.90 < quality < 1.00 : 15082 elements
Info : 4755 edge swaps, 225 node relocations (volume = 0.0328953): worst = 0.000316063 / average = 0.692736 (Wall 0.126227s, CPU 0.125273s)
Info : 4882 edge swaps, 254 node relocations (volume = 0.0328953): worst = 0.000316063 / average = 0.692877 (Wall 0.162867s, CPU 0.161823s)
Info : 0.00 < quality < 0.10 : 8 elements
Info : 0.10 < quality < 0.20 : 0 elements
Info : 0.20 < quality < 0.30 : 240 elements
Info : 0.30 < quality < 0.40 : 7963 elements
Info : 0.40 < quality < 0.50 : 15629 elements
Info : 0.50 < quality < 0.60 : 23060 elements
Info : 0.60 < quality < 0.70 : 27511 elements
Info : 0.70 < quality < 0.80 : 31853 elements
Info : 0.80 < quality < 0.90 : 35235 elements
Info : 0.90 < quality < 1.00 : 14954 elements
Info : Done optimizing mesh (Wall 0.5531s, CPU 0.529983s)
Info : 38460 nodes 253619 elements
Warning : 2 ill-shaped tets are still in the mesh
Warning : ------------------------------
Warning : Mesh generation error summary
Warning : 2 warnings
Warning : 0 errors
Warning : Check the full log for details
Warning : ------------------------------
Info : Optimizing mesh (Netgen)...
Info : Optimizing volume 1
Info : CalcLocalH: 17912 Points 54439 Elements 30154 Surface Elements
Info : Remove Illegal Elements
Info : 5520 illegal tets
Info : SplitImprove
Info : badmax = 313633
Info : 751 splits performed
Info : SwapImprove
Info : 456 swaps performed
Info : SwapImprove2
Info : 7 swaps performed
Info : 4151 illegal tets
Info : SplitImprove
Info : badmax = 73860.9
Info : 772 splits performed
Info : SwapImprove
Info : 154 swaps performed
Info : SwapImprove2
Info : 141 swaps performed
Info : 2307 illegal tets
Info : SplitImprove
Info : badmax = 9194.41
Info : 566 splits performed
Info : SwapImprove
Info : 82 swaps performed
Info : SwapImprove2
Info : 66 swaps performed
Info : 680 illegal tets
Info : SplitImprove
Info : badmax = 9194.41
Info : 199 splits performed
Info : SwapImprove
Info : 15 swaps performed
Info : SwapImprove2
Info : 12 swaps performed
Info : 52 illegal tets
Info : SplitImprove
Info : badmax = 9194.41
Info : 16 splits performed
Info : SwapImprove
Info : 2 swaps performed
Info : SwapImprove2
Info : 1 swaps performed
Info : 3 illegal tets
Info : SplitImprove
Info : badmax = 9194.41
Info : 1 splits performed
Info : SwapImprove
Info : 0 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : 0 illegal tets
Info : Volume Optimization
Info : CombineImprove
Info : 737 elements combined
Info : ImproveMesh
Info : Total badness = 144887
Info : Total badness = 132150
Info : SplitImprove
Info : badmax = 8364.09
Info : 1 splits performed
Info : ImproveMesh
Info : Total badness = 132174
Info : Total badness = 131064
Info : SwapImprove
Info : 3859 swaps performed
Info : SwapImprove2
Info : 3 swaps performed
Info : ImproveMesh
Info : Total badness = 122719
Info : Total badness = 117831
Info : CombineImprove
Info : 129 elements combined
Info : ImproveMesh
Info : Total badness = 116163
Info : Total badness = 115773
Info : SplitImprove
Info : badmax = 7026.46
Info : 0 splits performed
Info : ImproveMesh
Info : Total badness = 115773
Info : Total badness = 115745
Info : SwapImprove
Info : 1511 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : ImproveMesh
Info : Total badness = 113432
Info : Total badness = 111438
Info : CombineImprove
Info : 33 elements combined
Info : ImproveMesh
Info : Total badness = 111069
Info : Total badness = 110950
Info : SplitImprove
Info : badmax = 7006.38
Info : 0 splits performed
Info : ImproveMesh
Info : Total badness = 110950
Info : Total badness = 110944
Info : SwapImprove
Info : 732 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : ImproveMesh
Info : Total badness = 110077
Info : Total badness = 109160
Info : Optimizing volume 2
Info : CalcLocalH: 35431 Points 156676 Elements 37650 Surface Elements
Info : Remove Illegal Elements
Info : 0 illegal tets
Info : Volume Optimization
Info : CombineImprove
Info : 644 elements combined
Info : ImproveMesh
Info : Total badness = 263887
Info : Total badness = 237532
Info : SplitImprove
Info : badmax = 20417.9
Info : 1 splits performed
Info : ImproveMesh
Info : Total badness = 237611
Info : Total badness = 234276
Info : SwapImprove
Info : 8283 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : ImproveMesh
Info : Total badness = 219376
Info : Total badness = 214404
Info : CombineImprove
Info : 135 elements combined
Info : ImproveMesh
Info : Total badness = 213139
Info : Total badness = 212597
Info : SplitImprove
Info : badmax = 7390.53
Info : 0 splits performed
Info : ImproveMesh
Info : Total badness = 212597
Info : Total badness = 212495
Info : SwapImprove
Info : 1586 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : ImproveMesh
Info : Total badness = 211012
Info : Total badness = 209983
Info : CombineImprove
Info : 32 elements combined
Info : ImproveMesh
Info : Total badness = 209706
Info : Total badness = 209607
Info : SplitImprove
Info : badmax = 7234.06
Info : 0 splits performed
Info : ImproveMesh
Info : Total badness = 209607
Info : Total badness = 209588
Info : SwapImprove
Info : 574 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : ImproveMesh
Info : Total badness = 209152
Info : Total badness = 208774
Info : Done optimizing mesh (Wall 12.149s, CPU 12.1483s)
Info : Writing 'vivaldi.msh'...
Mesh saved to vivaldi.mshInfo : Done writing 'vivaldi.msh'
Nodes: 39057
Elements: 250451
Info : Writing 'vivaldi.msh'...
Info : Done writing 'vivaldi.msh'
Mesh generation#
view_mesh(mesh_file, transparent_groups="air_sphere__None", transparent_alpha=0)
Loading mesh file: vivaldi.msh
Groups to render transparent: air_sphere__None
Mesh loaded successfully with 2 cell blocks
Found 37650 triangles total
Physical group tags in mesh: {3: 'copper_patch', 4: 'feed_port', 5: 'air_sphere__substrate', 6: 'air_sphere__None'}