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:

  1. Start with a full rectangular ground-plane surface.

  2. Subtract the exponential slot (built from a spline boundary).

  3. Subtract the circular cavity.

  4. 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_offset is the x-axis offset that positions where along the slot the port is referenced — here it locates the port at x = x0 + feed_offset inside the ground plane, but the excitation face itself sits flush at x = x0 (the left wall of the computational domain).

  • The port is square: width = height = slot_width in 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'}