.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples\05-Q3D\Q3D_DC_IR.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_05-Q3D_Q3D_DC_IR.py: Q3D Extractor: PCB DCIR analysis -------------------------------- This example shows how you can use PyAEDT to create a design in Q3D Extractor and run a DC IR Drop simulation starting from an EDB Project. .. GENERATED FROM PYTHON SOURCE LINES 8-11 Perform required imports ~~~~~~~~~~~~~~~~~~~~~~~~ Perform required imports. .. GENERATED FROM PYTHON SOURCE LINES 11-15 .. code-block:: Python import os import pyaedt .. GENERATED FROM PYTHON SOURCE LINES 16-19 Set AEDT version ~~~~~~~~~~~~~~~~ Set AEDT version. .. GENERATED FROM PYTHON SOURCE LINES 19-22 .. code-block:: Python aedt_version = "2024.1" .. GENERATED FROM PYTHON SOURCE LINES 23-26 Set up project files and path ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Download needed project file and set up temporary project directory. .. GENERATED FROM PYTHON SOURCE LINES 26-35 .. code-block:: Python project_dir = pyaedt.generate_unique_folder_name() aedb_project = pyaedt.downloads.download_file('edb/ANSYS-HSD_V1.aedb', destination=project_dir) coil = pyaedt.downloads.download_file('inductance_3d_component', 'air_coil.a3dcomp') res = pyaedt.downloads.download_file('resistors', 'Res_0402.a3dcomp') project_name = pyaedt.generate_unique_name("HSD") output_edb = os.path.join(project_dir, project_name + '.aedb') output_q3d = os.path.join(project_dir, project_name + '_q3d.aedt') .. GENERATED FROM PYTHON SOURCE LINES 36-40 Open EDB ~~~~~~~~ Open the EDB project and create a cutout on the selected nets before exporting to Q3D. .. GENERATED FROM PYTHON SOURCE LINES 40-48 .. code-block:: Python edb = pyaedt.Edb(aedb_project, edbversion=aedt_version) edb.cutout(["1.2V_AVDLL_PLL", "1.2V_AVDDL", "1.2V_DVDDL", "NetR106_1"], ["GND"], output_aedb_path=output_edb, use_pyaedt_extent_computing=True, ) .. rst-class:: sphx-glr-script-out .. code-block:: none C:\actions-runner\_work\pyaedt\pyaedt\testenv\lib\site-packages\pyedb\dotnet\edb_core\components.py:185: DeprecationWarning: Use new property :func:`instances` instead. warnings.warn("Use new property :func:`instances` instead.", DeprecationWarning) [[0.022903601428309994, 0.0687375259513446], [0.02304646506556407, 0.06810090632382818], [0.02308056292432885, 0.06798321402755685], [0.025721400460243713, 0.06059405990094516], [0.025832015076226816, 0.06037420643241395], [0.02599290332692254, 0.06013342014927757], [0.026117566301186005, 0.059981517875627256], [0.02651910015861637, 0.059579984018196905], [0.026586056930005972, 0.059518838114455644], [0.02693453943571554, 0.05922843602636434], [0.0269622469688975, 0.05920616873058622], [0.031134053159860956, 0.05597380121231693], [0.031190979485084647, 0.05593280581169422], [0.03137428040859384, 0.0558103280502945], [0.031582858614209536, 0.05570382969879277], [0.03834973057875869, 0.053194377967395214], [0.03869758475453261, 0.05313149807897392], [0.039227070108729535, 0.05313014999960498], [0.03973452671388853, 0.05326427792228474], [0.04026859112194551, 0.05356960588571382], [0.040641624759074686, 0.05393885974328623], [0.04095237573431778, 0.05446978703453285], [0.04109166457619173, 0.054975851382507775], [0.041094466634292184, 0.05534269997333201], [0.04109428367028657, 0.0553709355606793], [0.04104908615549033, 0.0575649272409746], [0.041046981671272235, 0.05761236166846335], [0.04066600191016067, 0.06320005881026784], [0.04064908611307354, 0.06332725593241376], [0.04058481891644457, 0.06365034894807488], [0.040434054803263786, 0.06401432571483504], [0.040278535856694386, 0.0642470762664744], [0.04026188810298574, 0.06427121750045746], [0.03523275742407547, 0.07134000863384793], [0.03512485342105291, 0.07146762763124666], [0.03481552767976474, 0.07177695337253483], [0.03435947005023539, 0.0720402583677096], [0.033891016883249823, 0.07216578001549522], [0.03363108596563051, 0.07220000056999999], [0.029642428636052272, 0.07220000056999999], [0.029627277942905955, 0.07219988579330847], [0.027927438942503855, 0.07217412946752286], [0.027843048529560797, 0.07216927931781611], [0.027220284389757213, 0.07210700322019893], [0.027060706534908142, 0.07207784392640419], [0.026879686158052363, 0.07202933966261212], [0.026800302236482394, 0.07200448861783905], [0.02420720288895093, 0.07107268711201903], [0.024045048376626268, 0.07099747710317793], [0.023683583814363553, 0.07078878544085301], [0.023311214319146782, 0.07041641594563619], [0.023015557008038968, 0.06990432246116815], [0.022879260313195288, 0.06939565627110772], [0.022879260313195333, 0.06895715817774653]] .. GENERATED FROM PYTHON SOURCE LINES 49-53 Identify pin positions ~~~~~~~~~~~~~~~~~~~~~~ Identify [x,y] pin locations on the components to define where to assign sources and sinks for Q3D. .. GENERATED FROM PYTHON SOURCE LINES 53-59 .. code-block:: Python pin_u11_scl = [i for i in edb.components["U11"].pins.values() if i.net_name == "1.2V_AVDLL_PLL"] pin_u9_1 = [i for i in edb.components["U9"].pins.values() if i.net_name == "1.2V_AVDDL"] pin_u9_2 = [i for i in edb.components["U9"].pins.values() if i.net_name == "1.2V_DVDDL"] pin_u11_r106 = [i for i in edb.components["U11"].pins.values() if i.net_name == "NetR106_1"] .. GENERATED FROM PYTHON SOURCE LINES 60-63 Append Z Positions ~~~~~~~~~~~~~~~~~~ Compute Q3D 3D position. The factor 1000 converts from "meters" to "mm". .. GENERATED FROM PYTHON SOURCE LINES 63-76 .. code-block:: Python location_u11_scl = [i * 1000 for i in pin_u11_scl[0].position] location_u11_scl.append(edb.components["U11"].upper_elevation * 1000) location_u9_1_scl = [i * 1000 for i in pin_u9_1[0].position] location_u9_1_scl.append(edb.components["U9"].upper_elevation * 1000) location_u9_2_scl = [i * 1000 for i in pin_u9_2[0].position] location_u9_2_scl.append(edb.components["U9"].upper_elevation * 1000) location_u11_r106 = [i * 1000 for i in pin_u11_r106[0].position] location_u11_r106.append(edb.components["U11"].upper_elevation * 1000) .. GENERATED FROM PYTHON SOURCE LINES 77-80 Identify pin positions for 3D components ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Identify the pin positions where 3D components of passives are to be added. .. GENERATED FROM PYTHON SOURCE LINES 80-89 .. code-block:: Python location_l2_1 = [i * 1000 for i in edb.components["L2"].pins["1"].position] location_l2_1.append(edb.components["L2"].upper_elevation * 1000) location_l4_1 = [i * 1000 for i in edb.components["L4"].pins["1"].position] location_l4_1.append(edb.components["L4"].upper_elevation * 1000) location_r106_1 = [i * 1000 for i in edb.components["R106"].pins["1"].position] location_r106_1.append(edb.components["R106"].upper_elevation * 1000) .. GENERATED FROM PYTHON SOURCE LINES 90-93 Save and close EDB ~~~~~~~~~~~~~~~~~~ Save and close EDB. Then, open EDT in HFSS 3D Layout to generate the 3D model. .. GENERATED FROM PYTHON SOURCE LINES 93-99 .. code-block:: Python edb.save_edb() edb.close_edb() h3d = pyaedt.Hfss3dLayout(output_edb, specified_version=aedt_version, non_graphical=False, new_desktop_session=True) .. rst-class:: sphx-glr-script-out .. code-block:: none C:\actions-runner\_work\_tool\Python\3.10.9\x64\lib\subprocess.py:1072: ResourceWarning: subprocess 9308 is still running _warn("subprocess %s is still running" % self.pid, C:\actions-runner\_work\pyaedt\pyaedt\testenv\lib\site-packages\pyaedt\generic\settings.py:383: ResourceWarning: unclosed file <_io.TextIOWrapper name='D:\\Temp\\pyaedt_ansys.log' mode='a' encoding='cp1252'> self._logger = val .. GENERATED FROM PYTHON SOURCE LINES 100-104 Export to Q3D ~~~~~~~~~~~~~ Create a dummy setup and export the layout in Q3D. The ``keep_net_name`` parameter reassigns Q3D net names from HFSS 3D Layout. .. GENERATED FROM PYTHON SOURCE LINES 104-108 .. code-block:: Python setup = h3d.create_setup() setup.export_to_q3d(output_q3d, keep_net_name=True) h3d.close_project() .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 109-112 Open Q3D ~~~~~~~~ Launch the newly created q3d project. .. GENERATED FROM PYTHON SOURCE LINES 112-117 .. code-block:: Python q3d = pyaedt.Q3d(output_q3d) q3d.modeler.delete("GND") q3d.delete_all_nets() .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 118-121 Insert inductors ~~~~~~~~~~~~~~~~ Create new coordinate systems and place 3D component inductors. .. GENERATED FROM PYTHON SOURCE LINES 121-142 .. code-block:: Python q3d.modeler.create_coordinate_system(location_l2_1, name="L2") comp = q3d.modeler.insert_3d_component(coil, coordinate_system="L2") comp.rotate(q3d.AXIS.Z, -90) comp.parameters["n_turns"] = "3" comp.parameters["d_wire"] = "100um" q3d.modeler.set_working_coordinate_system("Global") q3d.modeler.create_coordinate_system(location_l4_1, name="L4") comp2 = q3d.modeler.insert_3d_component(coil, coordinate_system="L4") comp2.rotate(q3d.AXIS.Z, -90) comp2.parameters["n_turns"] = "3" comp2.parameters["d_wire"] = "100um" q3d.modeler.set_working_coordinate_system("Global") q3d.modeler.set_working_coordinate_system("Global") q3d.modeler.create_coordinate_system(location_r106_1, name="R106") comp3 = q3d.modeler.insert_3d_component(res, geometry_parameters={'$Resistance': 2000}, coordinate_system="R106") comp3.rotate(q3d.AXIS.Z, -90) q3d.modeler.set_working_coordinate_system("Global") .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 143-146 Delete dielectrics ~~~~~~~~~~~~~~~~~~ Delete all dielectric objects since not needed in DC analysis. .. GENERATED FROM PYTHON SOURCE LINES 146-157 .. code-block:: Python q3d.modeler.delete(q3d.modeler.get_objects_by_material("Megtron4")) q3d.modeler.delete(q3d.modeler.get_objects_by_material("Megtron4_2")) q3d.modeler.delete(q3d.modeler.get_objects_by_material("Megtron4_3")) q3d.modeler.delete(q3d.modeler.get_objects_by_material("Solder Resist")) objs_copper = q3d.modeler.get_objects_by_material("copper") objs_copper_names = [i.name for i in objs_copper] q3d.plot(show=False,objects=objs_copper_names, plot_as_separate_objects=False, export_path=os.path.join(q3d.working_directory, "Q3D.jpg"), plot_air_objects=False) .. image-sg:: /examples/05-Q3D/images/sphx_glr_Q3D_DC_IR_001.png :alt: Q3D DC IR :srcset: /examples/05-Q3D/images/sphx_glr_Q3D_DC_IR_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 158-163 Assign source and sink ~~~~~~~~~~~~~~~~~~~~~~ Use previously calculated positions to identify faces, select the net "1_Top" and assign sources and sinks on nets. .. GENERATED FROM PYTHON SOURCE LINES 163-185 .. code-block:: Python sink_f = q3d.modeler.create_circle(q3d.PLANE.XY, location_u11_scl, 0.1) source_f1 = q3d.modeler.create_circle(q3d.PLANE.XY, location_u9_1_scl, 0.1) source_f2 = q3d.modeler.create_circle(q3d.PLANE.XY, location_u9_2_scl, 0.1) source_f3= q3d.modeler.create_circle(q3d.PLANE.XY, location_u11_r106, 0.1) sources_objs = [source_f1, source_f2, source_f3] q3d.auto_identify_nets() identified_net = q3d.nets[0] q3d.sink(sink_f, net_name=identified_net) source1 = q3d.source(source_f1, net_name=identified_net) source2 = q3d.source(source_f2, net_name=identified_net) source3 = q3d.source(source_f3, net_name=identified_net) sources_bounds = [source1, source2, source3] q3d.edit_sources(dcrl={"{}:{}".format(source1.props["Net"], source1.name): "-1.0A", "{}:{}".format(source2.props["Net"], source2.name): "-1.0A", "{}:{}".format(source2.props["Net"], source3.name): "-1.0A"}) .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 186-190 Create setup ~~~~~~~~~~~~ Create a setup and a frequency sweep from DC to 2GHz. Analyze project. .. GENERATED FROM PYTHON SOURCE LINES 190-199 .. code-block:: Python setup = q3d.create_setup() setup.dc_enabled = True setup.capacitance_enabled = False setup.ac_rl_enabled = False setup.props["SaveFields"] = True setup.props["DC"]["Cond"]["MaxPass"]=3 setup.analyze() .. GENERATED FROM PYTHON SOURCE LINES 200-203 Field Calculator ~~~~~~~~~~~~~~~~ We will create a named expression using field calculator. .. GENERATED FROM PYTHON SOURCE LINES 203-212 .. code-block:: Python drop_name = "Vdrop3_3" fields = q3d.ofieldsreporter q3d.ofieldsreporter.CalcStack("clear") q3d.ofieldsreporter.EnterQty("Phidc") q3d.ofieldsreporter.EnterScalar(3.3) q3d.ofieldsreporter.CalcOp("+") q3d.ofieldsreporter.AddNamedExpression(drop_name, "DC R/L Fields") .. GENERATED FROM PYTHON SOURCE LINES 213-216 Phi plot ~~~~~~~~ Compute ACL solutions and plot them. .. GENERATED FROM PYTHON SOURCE LINES 216-222 .. code-block:: Python plot1 = q3d.post.create_fieldplot_surface(q3d.modeler.get_objects_by_material("copper"), quantity=drop_name) q3d.post.plot_field_from_fieldplot(plot1.name, project_path=q3d.working_directory, mesh_plot=False, image_format="jpg", view="isometric", show=False, plot_cad_objs=False, log_scale=False) .. image-sg:: /examples/05-Q3D/images/sphx_glr_Q3D_DC_IR_002.png :alt: Q3D DC IR :srcset: /examples/05-Q3D/images/sphx_glr_Q3D_DC_IR_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 223-227 Computing Voltage on Source Circles ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Using Field Calculator we can compute the voltage on source circles and get the value using get_solution_data method. .. GENERATED FROM PYTHON SOURCE LINES 227-250 .. code-block:: Python curves = [] for source_circle, source_bound in zip(sources_objs, sources_bounds): source_sheet_name = source_circle.name curves.append("V{}".format(source_bound.name)) q3d.ofieldsreporter.CalcStack("clear") q3d.ofieldsreporter.CopyNamedExprToStack(drop_name) q3d.ofieldsreporter.EnterSurf(source_sheet_name) q3d.ofieldsreporter.CalcOp("Maximum") q3d.ofieldsreporter.AddNamedExpression("V{}".format(source_bound.name), "DC R/L Fields") data = q3d.post.get_solution_data( curves, q3d.nominal_adaptive, variations={"Freq": "1GHz"}, report_category="DC R/L Fields", ) for curve in curves: print(data.data_real(curve)) .. rst-class:: sphx-glr-script-out .. code-block:: none [3.260417875446388] [3.2218341951839946] [3.2863685179632416] .. GENERATED FROM PYTHON SOURCE LINES 251-255 Close AEDT ~~~~~~~~~~ After the simulation completes, you can close AEDT or release it using the ``release_desktop`` method. All methods provide for saving projects before closing. .. GENERATED FROM PYTHON SOURCE LINES 255-258 .. code-block:: Python q3d.save_project() q3d.release_desktop() .. rst-class:: sphx-glr-script-out .. code-block:: none True .. rst-class:: sphx-glr-timing **Total running time of the script:** (7 minutes 55.226 seconds) .. _sphx_glr_download_examples_05-Q3D_Q3D_DC_IR.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: Q3D_DC_IR.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: Q3D_DC_IR.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_