{"slug": "apec-2026-s10-python-for-power-electronics-from-zero-to-ai-flyback-magnetic", "title": "APEC 2026 S10: Python For Power Electronics: From Zero To AI . Flyback Magnetic Ansys  Automation", "summary": "A developer published a Python script that automates the construction of a flyback transformer model in Ansys Maxwell 3D using the PyAEDT library, covering core geometry, gapping, bobbin, and winding parameters. The script defines ferrite material properties with Steinmetz core-loss coefficients, builds the core and winding window via boolean subtraction, and configures an eddy-current solution for a 120 kHz design with 30 primary and 10 secondary turns. It is presented as a training lesson on scripting power-electronics magnetics simulation.", "body_md": "|  | import shutil | \n|  | import os | \n|  | import sys | \n|  | import time | \n|  | import pyaedt | \n|  | from pyaedt.modeler.cad.object3d import Object3d | \n|  | number_segments_arcs = 12 | \n|  | gap_length = 500e-6 | \n|  | resudial_gap_length = 0.000005 | \n|  | bobbin_thickness = 0.001 | \n|  | dim = {\"A\": 0.02850, \"B\": 0.01400, \"C\": 0.01140, \"D\": 0.00960, \"E\": 0.02170, \"F\": 0.00990} | \n|  | primary_wire_diameter = 0.0005 | \n|  | primary_wire_coating = 34e-6 | \n|  | secondary_wire_diameter = 0.00147 | \n|  | primary_number_turns = 30 | \n|  | secondary_number_turns = 10 | \n|  | secondary_strand_diameter = 50e-6 | \n|  | secondary_number_strands = 400 | \n|  | frequency = 120000 | \n|  | current_primary = 0.7 | \n|  | current_secondary = 2.1 | \n|  | voltage_secondary = 12 | \n|  | material = { | \n|  | \"name\": \"95\", | \n|  | \"initial_permeability\": 2980, | \n|  | \"resistivity\": 2, | \n|  | \"steinmetz_k\": 6.941832847, | \n|  | \"steinmetz_alpha\": 1.433728921, | \n|  | \"steinmetz_beta\": 2.494912103, | \n|  | } | \n|  | color_ferrite = [89, 94, 107] | \n|  | color_copper = [242, 140, 102] | \n|  | color_litz = [0xd3, 0xe1, 0xf5] | \n|  | color_teflon = [0x53, 0x97, 0x96] | \n|  | color_bobbin = [52, 52, 52] | \n|  | color_tape = [0xed, 0xbe, 0x1c] | \n|  | output_dir = \"C:/Users/alfonso/Magnetics training/outputs\" | \n|  | os.makedirs(output_dir, exist_ok=True) | \n|  | project = pyaedt.Maxwell3d( | \n|  | project=f\"{output_dir}/Lesson_27_{time.time()}\", | \n|  | solution_type=\"EddyCurrent\", | \n|  | non_graphical=False, | \n|  | new_desktop=False, | \n|  | close_on_exit=False | \n|  | ) | \n|  | project.modeler.model_units = \"meter\" | \n|  | aedt_material = project.materials.add_material(material[\"name\"]) | \n|  | aedt_material.permeability = material[\"initial_permeability\"] | \n|  | conductivity = 1.0 / material[\"resistivity\"] | \n|  | aedt_material.conductivity = conductivity | \n|  | aedt_material.set_power_ferrite_coreloss( | \n|  | cm=material[\"steinmetz_k\"], | \n|  | x=material[\"steinmetz_alpha\"], | \n|  | y=material[\"steinmetz_beta\"] | \n|  | ) | \n|  | core = project.modeler.create_box( | \n|  | origin=[-dim[\"C\"] / 2, -dim[\"A\"] / 2, -2 * dim[\"B\"] / 2], | \n|  | sizes=[dim[\"C\"], dim[\"A\"], 2 * dim[\"B\"]], | \n|  | name=\"core\", | \n|  | material=material[\"name\"] | \n|  | ) | \n|  | core.color = color_ferrite | \n|  | core.transparency = 0 | \n|  | project.modeler.fit_all() | \n|  | central_column = project.modeler.create_cylinder( | \n|  | orientation=pyaedt.constants.AXIS.Z, | \n|  | origin=[0, 0, -dim[\"D\"]], | \n|  | radius=dim[\"F\"] / 2, | \n|  | height=dim[\"D\"] * 2, | \n|  | num_sides=number_segments_arcs, | \n|  | name=\"central_column\", | \n|  | material=\"air\" | \n|  | ) | \n|  | winding_window = project.modeler.create_cylinder( | \n|  | orientation=pyaedt.constants.AXIS.Z, | \n|  | origin=[0, 0, -dim[\"D\"]], | \n|  | radius=dim[\"E\"] / 2, | \n|  | height=dim[\"D\"] * 2, | \n|  | num_sides=number_segments_arcs, | \n|  | name=\"winding_window\", | \n|  | material=\"air\" | \n|  | ) | \n|  | winding_window.subtract(central_column, True) | \n|  | core.subtract(winding_window, False) | \n|  | gap = project.modeler.create_box( | \n|  | origin=[-dim[\"F\"] / 2, -dim[\"F\"] / 2, -0], | \n|  | sizes=[dim[\"F\"], dim[\"F\"], gap_length], | \n|  | name=\"gap\", | \n|  | material=\"air\" | \n|  | ) | \n|  | core.subtract(gap, False) | \n|  | resudial_gap = project.modeler.create_box( | \n|  | origin=[-dim[\"A\"] / 2, -dim[\"A\"] / 2, -0], | \n|  | sizes=[dim[\"A\"], dim[\"A\"], resudial_gap_length], | \n|  | name=\"resudial_gap\", | \n|  | material=\"air\" | \n|  | ) | \n|  | core.subtract(resudial_gap, False) | \n|  | project.set_core_losses( | \n|  | assignment=[core.name], | \n|  | core_loss_on_field=True | \n|  | ) | \n|  | bobbin = project.modeler.create_cylinder( | \n|  | orientation=pyaedt.constants.AXIS.Z, | \n|  | origin=[0, 0, -dim[\"D\"]], | \n|  | radius=dim[\"E\"] / 2, | \n|  | height=dim[\"D\"] * 2, | \n|  | num_sides=number_segments_arcs, | \n|  | name=\"bobbin\", | \n|  | material=\"PVC plastic\" | \n|  | ) | \n|  | bobbin.color = color_bobbin | \n|  | bobbin.transparency = 0 | \n|  | bobbin_winding_window = project.modeler.create_cylinder( | \n|  | orientation=pyaedt.constants.AXIS.Z, | \n|  | origin=[0, 0, -dim[\"D\"] + bobbin_thickness], | \n|  | radius=dim[\"E\"] / 2, | \n|  | height=dim[\"D\"] * 2 - bobbin_thickness * 2, | \n|  | num_sides=number_segments_arcs, | \n|  | name=\"bobbin\", | \n|  | material=\"air\" | \n|  | ) | \n|  | bobbin_winding_window_hole = project.modeler.create_cylinder( | \n|  | orientation=pyaedt.constants.AXIS.Z, | \n|  | origin=[0, 0, -dim[\"D\"]], | \n|  | radius=dim[\"F\"] / 2 + bobbin_thickness, | \n|  | height=dim[\"D\"] * 2, | \n|  | num_sides=number_segments_arcs, | \n|  | name=\"central_column\", | \n|  | material=\"air\" | \n|  | ) | \n|  | bobbin_winding_window.subtract(bobbin_winding_window_hole, False) | \n|  | bobbin.subtract(central_column, False) | \n|  | bobbin.subtract(bobbin_winding_window, False) | \n|  | primary_terminals = [] | \n|  | current_turn_height = (primary_number_turns - 1) * (primary_wire_diameter + 2 * primary_wire_coating) / 2 | \n|  | for index in range(0, primary_number_turns): | \n|  | turn_section = project.modeler.create_circle( | \n|  | orientation=pyaedt.constants.PLANE.YZ, | \n|  | origin=[0, dim[\"F\"] / 2 + bobbin_thickness + primary_wire_coating + primary_wire_diameter / 2, current_turn_height], | \n|  | radius=primary_wire_diameter / 2, | \n|  | num_sides=number_segments_arcs, | \n|  | is_covered=True, | \n|  | name=f\"Primary_turn_{index}\", | \n|  | material=\"copper\", | \n|  | non_model=False | \n|  | ) | \n|  | turn_object = project.modeler.sweep_around_axis( | \n|  | assignment=turn_section, | \n|  | axis=pyaedt.constants.AXIS.Z, | \n|  | sweep_angle=360, | \n|  | draft_angle=0, | \n|  | number_of_segments=number_segments_arcs | \n|  | ) | \n|  | turn_object.section( | \n|  | plane=pyaedt.constants.PLANE.YZ, | \n|  | create_new=True | \n|  | ) | \n|  | turn_object.transparency = 0 | \n|  | conducting_section_names = project.modeler.get_objects_w_string(f\"{turn_object.name}_Section\") | \n|  | assert len(conducting_section_names) == 1 | \n|  | conducting_section = project.modeler.get_object_from_name(conducting_section_names[0]) | \n|  | sections = project.modeler.separate_bodies(conducting_section) | \n|  | assert len(sections) == 2 | \n|  | conducting_section = sections[0] | \n|  | project.modeler.delete(sections[1]) | \n|  | terminal = project.assign_coil( | \n|  | assignment=conducting_section, | \n|  | conductors_number=1, | \n|  | polarity=\"Positive\", | \n|  | name=f\"{turn_object.name}_terminal\" | \n|  | ) | \n|  | primary_terminals.append(terminal.name) | \n|  | current_turn_height -= primary_wire_diameter + 2 * primary_wire_coating | \n|  | secondary_terminals = [] | \n|  | litz_wire_material = project.materials.duplicate_material( | \n|  | material=\"copper\", | \n|  | name=f\"Litz {secondary_number_strands}x{secondary_strand_diameter * 1000}\" | \n|  | ) | \n|  | litz_wire_material.stacking_type = \"Litz Wire\" | \n|  | litz_wire_material.wire_type = \"Round\" | \n|  | litz_wire_material.strand_number = secondary_number_strands | \n|  | litz_wire_material.wire_diameter = f\"{secondary_wire_diameter}meter\" | \n|  | current_turn_height = (secondary_number_turns - 1) * (secondary_wire_diameter) / 2 | \n|  | for index in range(0, secondary_number_turns): | \n|  | turn_section = project.modeler.create_circle( | \n|  | orientation=pyaedt.constants.PLANE.YZ, | \n|  | origin=[0, dim[\"F\"] / 2 + bobbin_thickness + primary_wire_diameter + 2 * primary_wire_coating + secondary_wire_diameter / 2, current_turn_height], | \n|  | radius=secondary_wire_diameter / 2, | \n|  | num_sides=number_segments_arcs, | \n|  | is_covered=True, | \n|  | name=f\"Secondary_turn_{index}\", | \n|  | material=litz_wire_material.name, | \n|  | non_model=False | \n|  | ) | \n|  | turn_object = project.modeler.sweep_around_axis( | \n|  | assignment=turn_section, | \n|  | axis=pyaedt.constants.AXIS.Z, | \n|  | sweep_angle=360, | \n|  | draft_angle=0, | \n|  | number_of_segments=number_segments_arcs | \n|  | ) | \n|  | turn_object.section( | \n|  | plane=pyaedt.constants.PLANE.YZ, | \n|  | create_new=True | \n|  | ) | \n|  | turn_object.color = color_litz | \n|  | turn_object.transparency = 0 | \n|  | conducting_section_names = project.modeler.get_objects_w_string(f\"{turn_object.name}_Section\") | \n|  | assert len(conducting_section_names) == 1 | \n|  | conducting_section = project.modeler.get_object_from_name(conducting_section_names[0]) | \n|  | sections = project.modeler.separate_bodies(conducting_section) | \n|  | assert len(sections) == 2 | \n|  | conducting_section = sections[0] | \n|  | project.modeler.delete(sections[1]) | \n|  | terminal = project.assign_coil( | \n|  | assignment=conducting_section, | \n|  | conductors_number=1, | \n|  | polarity=\"Negative\", | \n|  | name=f\"{turn_object.name}_terminal\" | \n|  | ) | \n|  | secondary_terminals.append(terminal.name) | \n|  | current_turn_height -= secondary_wire_diameter | \n|  | primary = project.assign_winding( | \n|  | winding_type=\"Current\", | \n|  | is_solid=True, | \n|  | current=current_primary, | \n|  | resistance=0, | \n|  | inductance=0, | \n|  | voltage=0, | \n|  | parallel_branches=1, | \n|  | phase=0, | \n|  | name=\"primary\", | \n|  | ) | \n|  | secondary = project.assign_winding( | \n|  | winding_type=\"Voltage\", | \n|  | is_solid=False, | \n|  | current=0, | \n|  | resistance=voltage_secondary / current_secondary, | \n|  | inductance=0, | \n|  | voltage=voltage_secondary, | \n|  | parallel_branches=1, | \n|  | phase=0, | \n|  | name=\"secondary\", | \n|  | ) | \n|  | project.add_winding_coils( | \n|  | assignment=primary.name, | \n|  | coils=[x for i, x in enumerate(primary_terminals)] | \n|  | ) | \n|  | project.add_winding_coils( | \n|  | assignment=secondary.name, | \n|  | coils=[x for i, x in enumerate(secondary_terminals)] | \n|  | ) | \n|  | matrix = project.assign_matrix(assignment=[primary.name, secondary.name], matrix_name=\"solution_matrix\") | \n|  | padding = { | \n|  | \"x_pos\": 50, | \n|  | \"y_pos\": 50, | \n|  | \"z_pos\": 50, | \n|  | \"x_neg\": 50, | \n|  | \"y_neg\": 50, | \n|  | \"z_neg\": 50, | \n|  | } | \n|  | region = project.modeler.create_region( | \n|  | pad_percent=[padding[\"x_pos\"], padding[\"x_neg\"], padding[\"y_pos\"], padding[\"y_neg\"], padding[\"z_pos\"], padding[\"z_neg\"]], | \n|  | is_percentage=True | \n|  | ) | \n|  | setup = project.create_setup(\"Setup\") | \n|  | setup.props[\"Frequency\"] = f\"{frequency * 3}\" | \n|  | setup.props[\"PercentRefinement\"] = 10 | \n|  | setup.props[\"MaximumPasses\"] = 40 | \n|  | setup.props[\"PercentError\"] = 5 | \n|  | setup.props[\"HasSweepSetup\"] = True | \n|  | setup.add_eddy_current_sweep( | \n|  | range_type=\"LinearStep\", | \n|  | start=0.1, | \n|  | end=frequency * 3, | \n|  | count=frequency, | \n|  | units=\"Hz\", | \n|  | clear=True, | \n|  | save_all_fields=True | \n|  | ) | \n|  | project.modeler.fit_all() | \n|  | project.analyze() | \n|  | project.release_desktop(close_projects=False, close_desktop=False) |", "url": "https://wpnews.pro/news/apec-2026-s10-python-for-power-electronics-from-zero-to-ai-flyback-magnetic", "canonical_source": "https://gist.github.com/ThinkPad88/c9569a42e1cb3e7e74476bf8622093a4", "published_at": "2026-10-18 06:01:11+00:00", "updated_at": "2026-10-18 06:14:16.116724+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["Ansys", "PyAEDT", "Ansys Maxwell"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/apec-2026-s10-python-for-power-electronics-from-zero-to-ai-flyback-magnetic", "markdown": "https://wpnews.pro/news/apec-2026-s10-python-for-power-electronics-from-zero-to-ai-flyback-magnetic.md", "text": "https://wpnews.pro/news/apec-2026-s10-python-for-power-electronics-from-zero-to-ai-flyback-magnetic.txt", "jsonld": "https://wpnews.pro/news/apec-2026-s10-python-for-power-electronics-from-zero-to-ai-flyback-magnetic.jsonld"}}