Coax to waveguide#
This notebook outlines the design and simulation workflow for a horn antenna fed by a standard WR-90 waveguide operating at a target frequency of 10 GHz (λ≈30mm)
Design Parameters#
The antenna geometry and probe feed are defined based on the following physical constraints:
Waveguide (WR-90):
22.86 mm (width)
10.16 mm (height)
40 mm (length)
Probe Feed:
Probe Length: 5.89 mm (≈λ/5) to ensure optimal impedance matching.
Coaxial Geometry: 3.6 mm (outer diameter) and 1.28 mm (inner diameter).
These parameters serve as the foundation for our geometric construction and subsequent discretization, ensuring the antenna is tuned for its intended frequency of operation.
import gmsh
import math
import os
import json
from palacetoolkit.viz import run_with_scrollable_output, view_mesh
from palacetoolkit.geometry import extract_tag, xmin, xmax, ymin, ymax, zmin, zmax
from palacetoolkit.mesh import refine_near_surfaces
from palacetoolkit.viz import view_mesh
from palacetoolkit.mesh import (
refine_near_surfaces
)
Parameters:#
inner_diameter_mm: Inner diameter of the coaxial cable in millimeters.
outer_diameter_mm: Outer diameter of the coaxial cable in millimeters.
probe_length_mm : Length of the probe in milimiters.
length_mm: Length of the coaxial cable section in millimeters.
wg_height: Height of the rectangular waveguide in millimeters.
wg_length: Length of the rectangular waveguide in millimeters.
wg_width: Width of the rectangular waveguide in millimeters.
freq_ghz: Frequency of the wave in gigahertz.
verbose: Verbosity level for Gmsh output
filename: Name of the output mesh file.
inner_diameter_mm: float = 1.28
outer_diameter_mm: float = 3.6
probe_length_mm = 5.89
length_mm: float = 5
wg_height: float = 10.16
wg_length: float = 40
wg_width: float = 22.86
freq_ghz: float = 10.0
verbose: int = 2
filename: str = "coax_to_waveguide.msh"
mesh_order = 1
gui = False
order = 1
Initializing the Modeling Environment#
gmsh.initialize()
gmsh.option.setNumber("General.Verbosity", 5)
gmsh.model.add("coax_to_waveguide")
kernel = gmsh.model.occ
Design Parameter Calculation#
We calculate the operating wavelength (λ) and derive the critical dimensions for the coaxial probe and backshort position. By basing these values on the 10 GHz design frequency, we ensure the geometry is physically optimized for efficient power transfer within the waveguide structure.
c = 3e8
lamda = (c / (freq_ghz * 1e9)) * 1e3
inner_radius = inner_diameter_mm / 2
outer_radius = outer_diameter_mm / 2
# y_top is the y-coordinate of the center of the coax probe,
# which is typically placed at the center of the waveguide height
y_top = wg_height / 2
coax_y_max = y_top + length_mm
# backshort_z is the distance from the probe tip to the backshort plane,
# which is typically around λ/5 for good impedance matching
backshort_z = lamda / 5
print(f"Wavelength: {lamda:.2f} mm")
print(f"Probe length: {probe_length_mm:.2f} mm")
print(f"Backshort Z position: {backshort_z:.2f} mm")
Wavelength: 30.00 mm
Probe length: 5.89 mm
Backshort Z position: 6.00 mm
Geometry Construction and Boolean Operations#
In this step, we construct the CAD model by defining the waveguide box and the coaxial feed components. We use Boolean cut operations to integrate the probe into the waveguide and define the dielectric region. Finally, we perform a global fragment operation to ensure all geometric volumes are properly connected, forming a unified topology ready for discretization.
# Waveguide box
waveguide = kernel.addBox(
-wg_width/2, -wg_height/2, 0,
wg_width, wg_height, wg_length
)
# Outer coax cylinder
outer_cyl = kernel.addCylinder(0, y_top, backshort_z,
0, length_mm, 0, outer_radius)
# Inner conductor
inner_cyl = kernel.addCylinder(0, coax_y_max, backshort_z,
0, -(length_mm + probe_length_mm), 0, inner_radius)
kernel.synchronize()
coax_dielectric, _ = kernel.cut([(3, outer_cyl)], [(3, inner_cyl)],
removeObject=True, removeTool=False)
waveguide_cut, _ = kernel.cut([(3, waveguide)], [(3, inner_cyl)],
removeObject=True, removeTool= True)
kernel.synchronize()
all_volumes = gmsh.model.getEntities(3)
kernel.fragment(all_volumes, [])
kernel.synchronize()
Geometric Entity Classification#
Here, we categorize the fragmented CAD entities into functional groups based on their spatial coordinates. We define logical filters to isolate the waveguide walls, coaxial conductors, waveports, and internal volumes. This classification step is essential for mapping the geometry to the specific physical boundary conditions required by the Palace solver
all_2d_entities = gmsh.model.getEntities(2)
all_3d_entities = gmsh.model.getEntities(3)
def is_interface(x):
return (math.isclose(ymin(x), y_top, abs_tol=1e-4) and
math.isclose(ymax(x), y_top, abs_tol=1e-4) and
math.isclose(xmax(x), outer_radius, abs_tol=1e-4))
def is_coax_port(x):
return (math.isclose(ymin(x), coax_y_max, abs_tol=1e-4) and
math.isclose(ymax(x), coax_y_max, abs_tol=1e-4) and
math.isclose(xmax(x), outer_radius, abs_tol=1e-4))
def is_inner_conductor(x):
return (math.isclose(xmax(x), inner_radius, abs_tol=1e-4) and
not is_interface(x))
def is_outer_conductor(x):
return (math.isclose(xmax(x), outer_radius, abs_tol=1e-4) and
ymin(x) >= y_top - 1e-4 and
not is_coax_port(x) and
not is_interface(x))
def is_waveport(x):
return( math.isclose(zmax(x), wg_length, abs_tol=1e-4) and
math.isclose(zmin(x), wg_length, abs_tol=1e-4))
def is_waveguide_wall(x):
return (not is_coax_port(x) and
not is_inner_conductor(x) and
not is_outer_conductor(x) and
not is_waveport(x) and
not is_interface(x))
def is_coax_volume(x):
return ymin(x) >= y_top - 1e-4
def is_waveguide_volume(x):
return ymax(x) <= y_top + 1e-4
coax_port_surfs = [x for x in all_2d_entities if is_coax_port(x)]
inner_cond_surfs = [x for x in all_2d_entities if is_inner_conductor(x)]
outer_cond_surfs = [x for x in all_2d_entities if is_outer_conductor(x)]
waveguide_wall_surfs = [x for x in all_2d_entities if is_waveguide_wall(x)]
waveport_surfs = [x for x in all_2d_entities if is_waveport(x)]
coax_vols = [x for x in all_3d_entities if is_coax_volume(x)]
waveguide_vols = [x for x in all_3d_entities if is_waveguide_volume(x)]
Physical Group Assignment#
In this block, we map the classified geometric entities to Physical Groups. Assigning these unique identifiers allows the Palace solver to distinguish between different materials and boundary conditions, such as the waveguide walls (PEC), the coaxial probe, and the internal air and dielectric volumes. Finally, we store these identifiers in a pg_map dictionary for streamlined reference during the simulation configuration.
pg_coax_port = gmsh.model.addPhysicalGroup(2, [x[1] for x in coax_port_surfs], -1, "coax_port")
pg_probe = gmsh.model.addPhysicalGroup(2, [x[1] for x in inner_cond_surfs], -1, "inner_conductor")
pg_outer_cyl = gmsh.model.addPhysicalGroup(2, [x[1] for x in outer_cond_surfs], -1, "outer_conductor")
pg_waveguide = gmsh.model.addPhysicalGroup(2, [x[1] for x in waveguide_wall_surfs], -1, "waveguide_walls")
pg_waveport = gmsh.model.addPhysicalGroup(2, [x[1] for x in waveport_surfs], -1, "waveport")
pg_dieletric = gmsh.model.addPhysicalGroup(3, [x[1] for x in coax_vols], -1, "coax_volume")
pg_air = gmsh.model.addPhysicalGroup(3, [x[1] for x in waveguide_vols], -1, "waveguide_volume")
pg_map = {
"coax_port": pg_coax_port,
"waveport": pg_waveport,
"waveguide_surface": pg_waveguide,
"waveguide_volume": pg_air,
"probe": pg_probe,
"outer_cyl": pg_outer_cyl,
"dielectric": pg_dieletric
}
Mesh Generation, Refinement, and Export#
We conclude the workflow by applying a graded mesh refinement strategy, concentrating element density near the coaxial feed and waveport to accurately resolve the high-frequency electromagnetic field gradients.
def _generate_coax_to_waveguide_mesh():
refine_near_surfaces([(2, extract_tag(x)) for x in inner_cond_surfs + outer_cond_surfs + waveport_surfs + coax_port_surfs],
wavelength= lamda,
ppw_near = 50,
ppw_far = 20,
transition_distance= lamda / 8,
)
gmsh.model.mesh.generate(3)
gmsh.model.mesh.setOrder(order)
gmsh.model.mesh.optimize("Netgen")
gmsh.option.setNumber("Mesh.MshFileVersion", 2.2)
gmsh.option.setNumber("Mesh.Binary", 0)
script_dir = os.getcwd()
output_path = os.path.join(script_dir, filename)
gmsh.write(output_path)
run_with_scrollable_output(_generate_coax_to_waveguide_mesh, title="Coax-to-waveguide mesh generation", max_lines=10)
if gui:
gmsh.fltk.run()
gmsh.finalize()
Info : Meshing 1D...
Info : [ 0%] Meshing curve 1 (Line)
Info : [ 10%] Meshing curve 2 (Line)
Info : [ 20%] Meshing curve 3 (Line)
Info : [ 20%] Meshing curve 4 (Line)
Info : [ 30%] Meshing curve 5 (Line)
Info : [ 30%] Meshing curve 6 (Line)
Info : [ 40%] Meshing curve 7 (Line)
Info : [ 40%] Meshing curve 8 (Line)
Info : [ 50%] Meshing curve 9 (Line)
Info : [ 50%] Meshing curve 10 (Line)
Info : [ 60%] Meshing curve 11 (Line)
Info : [ 60%] Meshing curve 12 (Circle)
Info : [ 70%] Meshing curve 13 (Circle)
Info : [ 70%] Meshing curve 14 (Line)
Info : [ 80%] Meshing curve 15 (Line)
Info : [ 80%] Meshing curve 16 (Circle)
Info : [ 90%] Meshing curve 17 (Circle)
Info : [ 90%] Meshing curve 18 (Line)
Info : [100%] Meshing curve 19 (Circle)
Info : [100%] Meshing curve 20 (Line)
Info : Done meshing 1D (Wall 0.0688756s, CPU 0.070071s)
Info : Meshing 2D...
Info : [ 0%] Meshing surface 1 (Plane, MeshAdapt)
Info : [ 10%] Meshing surface 2 (Plane, MeshAdapt)
Info : [ 20%] Meshing surface 3 (Plane, MeshAdapt)
Info : [ 30%] Meshing surface 4 (Plane, MeshAdapt)
Info : [ 40%] Meshing surface 5 (Plane, MeshAdapt)
Info : [ 50%] Meshing surface 6 (Plane, MeshAdapt)
Info : [ 60%] Meshing surface 7 (Plane, MeshAdapt)
Info : [ 60%] Meshing surface 8 (Cylinder, MeshAdapt)
Info : [ 70%] Meshing surface 9 (Plane, MeshAdapt)
Info : [ 80%] Meshing surface 10 (Cylinder, MeshAdapt)
Info : [ 90%] Meshing surface 11 (Plane, MeshAdapt)
Info : [100%] Meshing surface 12 (Cylinder, MeshAdapt)
Info : Done meshing 2D (Wall 0.128015s, CPU 0.118216s)
Info : Meshing 3D...
Info : 3D Meshing 2 volumes with 1 connected component
Info : Tetrahedrizing 2478 nodes...
Info : Done tetrahedrizing 2486 nodes (Wall 0.019306s, CPU 0.018991s)
Info : Reconstructing mesh...
Info : - Creating surface mesh
Info : - Identifying boundary edges
Info : - Recovering boundary
Info : Done reconstructing mesh (Wall 0.0447786s, CPU 0.040989s)
Info : Found volume 1
Info : Found volume 2
Info : It. 0 - 0 nodes created - worst tet radius 5.10984 (nodes removed 0 0)
Info : It. 500 - 500 nodes created - worst tet radius 1.38331 (nodes removed 0 0)
Info : It. 1000 - 1000 nodes created - worst tet radius 1.14555 (nodes removed 0 0)
Info : It. 1500 - 1500 nodes created - worst tet radius 1.01555 (nodes removed 0 0)
Info : 3D refinement terminated (4074 nodes total):
Info : - 1 Delaunay cavities modified for star shapeness
Info : - 0 nodes could not be inserted
Info : - 17595 tetrahedra created in 0.0557985 sec. (315331 tets/s)
Info : 0 node relocations
Info : Done meshing 3D (Wall 0.135981s, CPU 0.131193s)
Info : Optimizing mesh...
Info : Optimizing volume 1
Info : Optimization starts (volume = 9283.88) with worst = 0.0112082 / average = 0.7543:
Info : 0.00 < quality < 0.10 : 46 elements
Info : 0.10 < quality < 0.20 : 131 elements
Info : 0.20 < quality < 0.30 : 227 elements
Info : 0.30 < quality < 0.40 : 324 elements
Info : 0.40 < quality < 0.50 : 526 elements
Info : 0.50 < quality < 0.60 : 1048 elements
Info : 0.60 < quality < 0.70 : 2411 elements
Info : 0.70 < quality < 0.80 : 4363 elements
Info : 0.80 < quality < 0.90 : 5466 elements
Info : 0.90 < quality < 1.00 : 2448 elements
Info : 398 edge swaps, 2 node relocations (volume = 9283.88): worst = 0.230379 / average = 0.768879 (Wall 0.00519735s, CPU 0.005208s)
Info : 399 edge swaps, 2 node relocations (volume = 9283.88): worst = 0.3 / average = 0.768906 (Wall 0.00605874s, CPU 0.006103s)
Info : No ill-shaped tets in the mesh :-)
Info : 0.00 < quality < 0.10 : 0 elements
Info : 0.10 < quality < 0.20 : 0 elements
Info : 0.20 < quality < 0.30 : 0 elements
Info : 0.30 < quality < 0.40 : 310 elements
Info : 0.40 < quality < 0.50 : 510 elements
Info : 0.50 < quality < 0.60 : 1039 elements
Info : 0.60 < quality < 0.70 : 2404 elements
Info : 0.70 < quality < 0.80 : 4404 elements
Info : 0.80 < quality < 0.90 : 5508 elements
Info : 0.90 < quality < 1.00 : 2448 elements
Info : Optimizing volume 2
Info : Optimization starts (volume = 44.3679) with worst = 0.0689716 / average = 0.695575:
Info : 0.00 < quality < 0.10 : 1 elements
Info : 0.10 < quality < 0.20 : 5 elements
Info : 0.20 < quality < 0.30 : 10 elements
Info : 0.30 < quality < 0.40 : 5 elements
Info : 0.40 < quality < 0.50 : 28 elements
Info : 0.50 < quality < 0.60 : 57 elements
Info : 0.60 < quality < 0.70 : 157 elements
Info : 0.70 < quality < 0.80 : 228 elements
Info : 0.80 < quality < 0.90 : 103 elements
Info : 0.90 < quality < 1.00 : 11 elements
Info : 16 edge swaps, 0 node relocations (volume = 44.3679): worst = 0.277905 / average = 0.707631 (Wall 0.000170567s, CPU 0.000196s)
Info : 18 edge swaps, 0 node relocations (volume = 44.3679): worst = 0.322615 / average = 0.709237 (Wall 0.000224197s, CPU 0.000261s)
Info : No ill-shaped tets in the mesh :-)
Info : 0.00 < quality < 0.10 : 0 elements
Info : 0.10 < quality < 0.20 : 0 elements
Info : 0.20 < quality < 0.30 : 0 elements
Info : 0.30 < quality < 0.40 : 4 elements
Info : 0.40 < quality < 0.50 : 24 elements
Info : 0.50 < quality < 0.60 : 60 elements
Info : 0.60 < quality < 0.70 : 160 elements
Info : 0.70 < quality < 0.80 : 232 elements
Info : 0.80 < quality < 0.90 : 100 elements
Info : 0.90 < quality < 1.00 : 11 elements
Info : Done optimizing mesh (Wall 0.0186066s, CPU 0.018026s)
Info : 4074 nodes 22560 elements
Info : Optimizing mesh (Netgen)...
Info : Optimizing volume 1
Info : CalcLocalH: 3894 Points 16623 Elements 4592 Surface Elements
Info : Remove Illegal Elements
Info : 849 illegal tets
Info : SplitImprove
Info : badmax = 19.2097
Info : 132 splits performed
Info : SwapImprove
Info : 162 swaps performed
Info : SwapImprove2
Info : 6 swaps performed
Info : 533 illegal tets
Info : SplitImprove
Info : badmax = 1512.76
Info : 129 splits performed
Info : SwapImprove
Info : 64 swaps performed
Info : SwapImprove2
Info : 8 swaps performed
Info : 184 illegal tets
Info : SplitImprove
Info : badmax = 643.824
Info : 53 splits performed
Info : SwapImprove
Info : 6 swaps performed
Info : SwapImprove2
Info : 3 swaps performed
Info : 47 illegal tets
Info : SplitImprove
Info : badmax = 4612.07
Info : 15 splits performed
Info : SwapImprove
Info : 1 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : 7 illegal tets
Info : SplitImprove
Info : badmax = 643.824
Info : 1 splits performed
Info : SwapImprove
Info : 0 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : 5 illegal tets
Info : SplitImprove
Info : badmax = 643.824
Info : 1 splits performed
Info : SwapImprove
Info : 0 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : 2 illegal tets
Info : SplitImprove
Info : badmax = 643.824
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 : 187 elements combined
Info : ImproveMesh
Info : Total badness = 25994.5
Info : Total badness = 24658.1
Info : SplitImprove
Info : badmax = 26.2601
Info : 1 splits performed
Info : ImproveMesh
Info : Total badness = 24663.8
Info : Total badness = 24480.3
Info : SwapImprove
Info : 1068 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : ImproveMesh
Info : Total badness = 22625.6
Info : Total badness = 22076.3
Info : CombineImprove
Info : 18 elements combined
Info : ImproveMesh
Info : Total badness = 21913.7
Info : Total badness = 21864.4
Info : SplitImprove
Info : badmax = 16.4601
Info : 0 splits performed
Info : ImproveMesh
Info : Total badness = 21864.4
Info : Total badness = 21858.7
Info : SwapImprove
Info : 239 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : ImproveMesh
Info : Total badness = 21657.3
Info : Total badness = 21509.1
Info : CombineImprove
Info : 13 elements combined
Info : ImproveMesh
Info : Total badness = 21376.5
Info : Total badness = 21357.7
Info : SplitImprove
Info : badmax = 11.0073
Info : 0 splits performed
Info : ImproveMesh
Info : Total badness = 21357.7
Info : Total badness = 21356.2
Info : SwapImprove
Info : 107 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : ImproveMesh
Info : Total badness = 21304
Info : Total badness = 21240.1
Info : Optimizing volume 2
Info : CalcLocalH: 218 Points 591 Elements 436 Surface Elements
Info : Remove Illegal Elements
Info : 170 illegal tets
Info : SplitImprove
Info : badmax = 15.5651
Info : 18 splits performed
Info : SwapImprove
Info : 18 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : 128 illegal tets
Info : SplitImprove
Info : badmax = 15.5651
Info : 16 splits performed
Info : SwapImprove
Info : 6 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : 90 illegal tets
Info : SplitImprove
Info : badmax = 18.1167
Info : 12 splits performed
Info : SwapImprove
Info : 6 swaps performed
Info : SwapImprove2
Info : 2 swaps performed
Info : 62 illegal tets
Info : SplitImprove
Info : badmax = 196.553
Info : 11 splits performed
Info : SwapImprove
Info : 6 swaps performed
Info : SwapImprove2
Info : 1 swaps performed
Info : 33 illegal tets
Info : SplitImprove
Info : badmax = 196.553
Info : 8 splits performed
Info : SwapImprove
Info : 4 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : 7 illegal tets
Info : SplitImprove
Info : badmax = 196.553
Info : 2 splits performed
Info : SwapImprove
Info : 0 swaps performed
Info : SwapImprove2
Info : 1 swaps performed
Info : 0 illegal tets
Info : Volume Optimization
Info : CombineImprove
Info : 23 elements combined
Info : ImproveMesh
Info : Total badness = 1527.24
Info : Total badness = 1486.36
Info : SplitImprove
Info : badmax = 19.2346
Info : 0 splits performed
Info : ImproveMesh
Info : Total badness = 1486.36
Info : Total badness = 1485.72
Info : SwapImprove
Info : 36 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : ImproveMesh
Info : Total badness = 1438.64
Info : Total badness = 1419.21
Info : CombineImprove
Info : 2 elements combined
Info : ImproveMesh
Info : Total badness = 1400.97
Info : Total badness = 1399.34
Info : SplitImprove
Info : badmax = 19.8755
Info : 1 splits performed
Info : ImproveMesh
Info : Total badness = 1403.89
Info : Total badness = 1401.13
Info : SwapImprove
Info : 17 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : ImproveMesh
Info : Total badness = 1381.54
Info : Total badness = 1367.13
Info : CombineImprove
Info : 4 elements combined
Info : ImproveMesh
Info : Total badness = 1323.25
Info : Total badness = 1320.26
Info : SplitImprove
Info : badmax = 14.5745
Info : 0 splits performed
Info : ImproveMesh
Info : Total badness = 1320.26
Info : Total badness = 1320.18
Info : SwapImprove
Info : 7 swaps performed
Info : SwapImprove2
Info : 0 swaps performed
Info : ImproveMesh
Info : Total badness = 1311.37
Info : Total badness = 1308.24
Info : Done optimizing mesh (Wall 0.739781s, CPU 0.740042s)
Info : Writing '/home/martin/Desktop/PalaceToolkit/docs/examples/coax_to_waveguide.msh'...
Info : Done writing '/home/martin/Desktop/PalaceToolkit/docs/examples/coax_to_waveguide.msh'
Coax-to-waveguide mesh generation
ppw_near=50 ppw_far=20 SizeMax=1.5000 transition=3.7500 global: 12 curves, SizeMin=0.6000
view_mesh(filename, transparent_groups= "air_sphere__None")
Loading mesh file: coax_to_waveguide.msh
Groups to render transparent: air_sphere__None
Mesh loaded successfully with 2 cell blocks
Found 4928 triangles total
Physical group tags in mesh: {1: 'coax_port', 2: 'inner_conductor', 3: 'outer_conductor', 4: 'waveguide_walls', 5: 'waveport'}
Generating the Palace Configuration File#
Finally, we assemble the simulation parameters into a JSON configuration file. This file serves as the definitive input for Palace.
palace_config = {
"Problem": {
"Type": "Driven",
"Verbose": 2,
"Output": "/work/postpro/coax2waveguide"
},
"Model": {
"Mesh": f"/work/coax_to_waveguide.msh",
"L0": 1e-3,
"Refinement": {}
},
"Domains": {
"Materials": [
{
"Attributes": [pg_map["waveguide_volume"]],
"Permittivity": 1.0,
"Permeability": 1.0
},
{
"Attributes": [pg_map["dielectric"]],
"Permittivity": 2.2,
"Permeability": 1.0
}
]
},
"Boundaries": {
"PEC": {
"Attributes": [pg_map["waveguide_surface"]] + [pg_map["outer_cyl"]] + [pg_map["probe"]]
},
"WavePort": [
{
"Index": 2,
"Attributes": [pg_map["waveport"]],
"Mode": 1,
"Offset": 0.0
},
{
"Index": 1,
"Attributes": [pg_map["coax_port"]],
"Mode": 1,
"Offset": 0.0,
"Excitation": True
}
]
},
"Solver": {
"Order": 2,
"Device": "CPU",
"Driven": {
"MinFreq": 6.0,
"MaxFreq": 12.0,
"FreqStep": 0.1,
"SaveStep": 2,
"AdaptiveTol": 0.001
},
"Linear": {
"Type": "Default",
"KSPType": "GMRES",
"Tol": 1e-08,
"MaxIts": 200,
"ComplexCoarseSolve": True
}
}
}
with open("coax_to_waveguide.json", 'w') as json_file:
json.dump(palace_config, json_file, indent=4)
print(f"Palace config successfully generated: coax_to_waveguide.json")
Palace config successfully generated: coax_to_waveguide.json