Note
Go to the end to download the full example code.
2D Extractor: CPWG analysis#
This example shows how you can use PyAEDT to create a CPWG (coplanar waveguide with ground) design in 2D Extractor and run a simulation.
Perform required imports#
Perform required imports.
import os
import ansys.aedt.core
Set AEDT version#
Set AEDT version.
aedt_version = "2024.2"
Set non-graphical mode#
Set non-graphical mode.
You can set non_graphical
either to True
or False
.
non_graphical = False
Launch AEDT and 2D Extractor#
Launch AEDT 2023 R2 in graphical mode and launch 2D Extractor. This example uses SI units.
q = ansys.aedt.core.Q2d(version=aedt_version,
non_graphical=non_graphical,
new_desktop=True,
project=ansys.aedt.core.generate_unique_name("pyaedt_q2d_example"),
design="coplanar_waveguide")
C:\actions-runner\_work\_tool\Python\3.10.9\x64\lib\subprocess.py:1072: ResourceWarning: subprocess 8228 is still running
_warn("subprocess %s is still running" % self.pid,
C:\actions-runner\_work\pyaedt\pyaedt\.venv\lib\site-packages\ansys\aedt\core\generic\settings.py:231: ResourceWarning: unclosed file <_io.TextIOWrapper name='D:\\Temp\\pyaedt_ansys_0bf9f20b-53ab-4ce4-97b2-0987472c9727.log' mode='a' encoding='cp1252'>
self.__logger = val
Define variables#
Define variables.
e_factor = "e_factor"
sig_bot_w = "sig_bot_w"
co_gnd_w = "gnd_w"
clearance = "clearance"
cond_h = "cond_h"
d_h = "d_h"
sm_h = "sm_h"
for var_name, var_value in {
"sig_bot_w": "150um",
"e_factor": "2",
"gnd_w": "500um",
"clearance": "150um",
"cond_h": "50um",
"d_h": "150um",
"sm_h": "20um",
}.items():
q[var_name] = var_value
delta_w_half = "({0}/{1})".format(cond_h, e_factor)
sig_top_w = "({1}-{0}*2)".format(delta_w_half, sig_bot_w)
co_gnd_top_w = "({1}-{0}*2)".format(delta_w_half, co_gnd_w)
model_w = "{}*2+{}*2+{}".format(co_gnd_w, clearance, sig_bot_w)
Create primitives#
Create primitives and define the layer heights.
layer_1_lh = 0
layer_1_uh = cond_h
layer_2_lh = layer_1_uh + "+" + d_h
layer_2_uh = layer_2_lh + "+" + cond_h
Create signal#
Create a signal.
base_line_obj = q.modeler.create_polyline(points=[[0, layer_2_lh, 0], [sig_bot_w, layer_2_lh, 0]], name="signal")
top_line_obj = q.modeler.create_polyline(points=[[0, layer_2_uh, 0], [sig_top_w, layer_2_uh, 0]])
q.modeler.move(assignment=[top_line_obj], vector=[delta_w_half, 0, 0])
q.modeler.connect([base_line_obj, top_line_obj])
q.modeler.move(assignment=[base_line_obj], vector=["{}+{}".format(co_gnd_w, clearance), 0, 0])
True
Create coplanar ground#
Create a coplanar ground.
base_line_obj = q.modeler.create_polyline(points=[[0, layer_2_lh, 0], [co_gnd_w, layer_2_lh, 0]], name="co_gnd_left")
top_line_obj = q.modeler.create_polyline(points=[[0, layer_2_uh, 0], [co_gnd_top_w, layer_2_uh, 0]])
q.modeler.move(assignment=[top_line_obj], vector=[delta_w_half, 0, 0])
q.modeler.connect([base_line_obj, top_line_obj])
base_line_obj = q.modeler.create_polyline(points=[[0, layer_2_lh, 0], [co_gnd_w, layer_2_lh, 0]], name="co_gnd_right")
top_line_obj = q.modeler.create_polyline(points=[[0, layer_2_uh, 0], [co_gnd_top_w, layer_2_uh, 0]])
q.modeler.move(assignment=[top_line_obj], vector=[delta_w_half, 0, 0])
q.modeler.connect([base_line_obj, top_line_obj])
q.modeler.move(assignment=[base_line_obj], vector=["{}+{}*2+{}".format(co_gnd_w, clearance, sig_bot_w), 0, 0])
True
Create reference ground plane#
Create a reference ground plane.
q.modeler.create_rectangle(origin=[0, layer_1_lh, 0], sizes=[model_w, cond_h], name="ref_gnd")
<ansys.aedt.core.modeler.cad.object_3d.Object3d object at 0x0000020CDB3A65F0>
Create dielectric#
Create a dielectric.
q.modeler.create_rectangle(
origin=[0, layer_1_uh, 0], sizes=[model_w, d_h], name="Dielectric", material="FR4_epoxy"
)
<ansys.aedt.core.modeler.cad.object_3d.Object3d object at 0x0000020CDB3A72B0>
Create conformal coating#
Create a conformal coating.
sm_obj_list = []
ids = [1, 2, 3]
if aedt_version >= "2023.1":
ids = [0, 1, 2]
for obj_name in ["signal", "co_gnd_left", "co_gnd_right"]:
obj = q.modeler.get_object_from_name(obj_name)
e_obj_list = []
for i in ids:
e_obj = q.modeler.create_object_from_edge(obj.edges[i])
e_obj_list.append(e_obj)
e_obj_1 = e_obj_list[0]
q.modeler.unite(e_obj_list)
new_obj = q.modeler.sweep_along_vector(e_obj_1.id, [0, sm_h, 0])
sm_obj_list.append(e_obj_1)
new_obj = q.modeler.create_rectangle(origin=[co_gnd_w, layer_2_lh, 0], sizes=[clearance, sm_h])
sm_obj_list.append(new_obj)
new_obj = q.modeler.create_rectangle(origin=[co_gnd_w, layer_2_lh, 0], sizes=[clearance, sm_h])
q.modeler.move([new_obj], [sig_bot_w + "+" + clearance, 0, 0])
sm_obj_list.append(new_obj)
sm_obj = sm_obj_list[0]
q.modeler.unite(sm_obj_list)
sm_obj.material_name = "SolderMask"
sm_obj.color = (0, 150, 100)
sm_obj.name = "solder_mask"
Assign conductor#
Assign a conductor to the signal.
obj = q.modeler.get_object_from_name("signal")
q.assign_single_conductor(assignment=[obj], name=obj.name, conductor_type="SignalLine", solve_option="SolveOnBoundary",
units="mm")
<ansys.aedt.core.modules.boundary.BoundaryObject object at 0x0000020CDB32BB20>
Create reference ground#
Create a reference ground.
obj = [q.modeler.get_object_from_name(i) for i in ["co_gnd_left", "co_gnd_right", "ref_gnd"]]
q.assign_single_conductor(assignment=obj, name="gnd", conductor_type="ReferenceGround", solve_option="SolveOnBoundary",
units="mm")
<ansys.aedt.core.modules.boundary.BoundaryObject object at 0x0000020CDB329510>
Assign Huray model on signal#
Assign the Huray model on the signal.
obj = q.modeler.get_object_from_name("signal")
q.assign_huray_finitecond_to_edges(obj.edges, radius="0.5um", ratio=3, name="b_" + obj.name)
<ansys.aedt.core.modules.boundary.BoundaryObject object at 0x0000020CDB32B2B0>
Create setup, analyze, and plot#
Create the setup, analyze it, and plot solution data.
setup = q.create_setup(name="new_setup")
sweep = setup.add_sweep(name="sweep1", sweep_type="Discrete")
sweep.props["RangeType"] = "LinearStep"
sweep.props["RangeStart"] = "1GHz"
sweep.props["RangeStep"] = "100MHz"
sweep.props["RangeEnd"] = "5GHz"
sweep.props["SaveFields"] = False
sweep.props["SaveRadFields"] = False
sweep.props["Type"] = "Interpolating"
sweep.update()
q.analyze()
a = q.post.get_solution_data(expressions="Z0(signal,signal)", context="Original")
a.plot()
<Figure size 2000x1000 with 1 Axes>
Save project and close AEDT#
Save the project and close AEDT.
home = os.path.expanduser("~")
q.save_project(os.path.join(home, "Downloads", "pyaedt_example", q.project_name + ".aedt"))
q.release_desktop()
True
Total running time of the script: (1 minutes 13.521 seconds)