|
| 1 | +import os |
| 2 | +import tempfile |
| 3 | +import time |
| 4 | +import numpy as np |
| 5 | +from ansys.aedt.core import Maxwell3d |
| 6 | +from ansys.aedt.core.generic.constants import Axis |
| 7 | + |
| 8 | +# ---------- PARAMETERS ---------- |
| 9 | +AEDT_VERSION = "2025.2" |
| 10 | +NG_MODE = False |
| 11 | +PROJECT_NAME = "WPT_Transient_Final.aedt" |
| 12 | + |
| 13 | +frequency_hz = 200e3 |
| 14 | +amps_primary = 1.0 |
| 15 | +load_resistance = 10.0 |
| 16 | +sim_time = 5e-5 |
| 17 | +time_steps = 1001 |
| 18 | + |
| 19 | +coil_radius = 20.0 # mm |
| 20 | +coil_wire_diam = 4.0 # mm (height of cylinder) |
| 21 | +coil_separation = 15.0 # mm between coil centers |
| 22 | + |
| 23 | +project_dir = tempfile.TemporaryDirectory(suffix=".ansys") |
| 24 | +project_path = os.path.join(project_dir.name, PROJECT_NAME) |
| 25 | + |
| 26 | +m3d = Maxwell3d( |
| 27 | + project=project_path, |
| 28 | + version=AEDT_VERSION, |
| 29 | + design="WPT_Transient", |
| 30 | + solution_type="Transient", |
| 31 | + new_desktop=True, |
| 32 | + non_graphical=NG_MODE, |
| 33 | +) |
| 34 | +m3d.modeler.model_units = "mm" |
| 35 | + |
| 36 | +existing = m3d.modeler.object_names |
| 37 | +for name in ("Load_Tab", "R_Load", "PrimaryWinding", "SecondaryWinding", "Prim_Coil", "Sec_Coil"): |
| 38 | + if name in existing: |
| 39 | + m3d.modeler.delete(name) |
| 40 | + |
| 41 | + |
| 42 | +prim_center = [0, 0, 0] |
| 43 | +sec_center = [0, 0, coil_separation] |
| 44 | + |
| 45 | +prim = m3d.modeler.create_cylinder( |
| 46 | + orientation=Axis.Z, |
| 47 | + origin=prim_center, |
| 48 | + radius=coil_radius, |
| 49 | + height=coil_wire_diam, |
| 50 | + name="Coil_Primary", |
| 51 | + material="copper", |
| 52 | +) |
| 53 | + |
| 54 | +sec = m3d.modeler.create_cylinder( |
| 55 | + orientation=Axis.Z, |
| 56 | + origin=sec_center, |
| 57 | + radius=coil_radius, |
| 58 | + height=coil_wire_diam, |
| 59 | + name="Coil_Secondary", |
| 60 | + material="copper", |
| 61 | +) |
| 62 | + |
| 63 | + |
| 64 | +region = m3d.modeler.create_region(name="Region", extent=60) # creates region around model |
| 65 | + |
| 66 | +prim_faces = [f for f in prim.faces] |
| 67 | +sec_faces = [f for f in sec.faces] |
| 68 | + |
| 69 | +prim_top_face = max(prim_faces, key=lambda f: f.center[2]) |
| 70 | +sec_top_face = max(sec_faces, key=lambda f: f.center[2]) |
| 71 | + |
| 72 | + |
| 73 | +load_tab_origin = [coil_radius + 10.0, 1.0, coil_separation - coil_wire_diam / 2] |
| 74 | +load_tab = m3d.modeler.create_box( |
| 75 | + origin=load_tab_origin, |
| 76 | + sizes=[2.0, 2.0, coil_wire_diam], |
| 77 | + name="Load_Tab", |
| 78 | +) |
| 79 | +m3d.assign_material(load_tab, "copper") |
| 80 | + |
| 81 | +load_tab_obj = m3d.modeler["Load_Tab"] |
| 82 | +load_tab_faces = [f for f in load_tab_obj.faces] |
| 83 | +load_face = max(load_tab_faces, key=lambda f: abs(f.normal[0])) |
| 84 | + |
| 85 | +m3d.assign_resistive_sheet( |
| 86 | + assignment=load_face, |
| 87 | + resistance=f"{load_resistance}ohm", |
| 88 | + name="R_Load", |
| 89 | +) |
| 90 | + |
| 91 | +prim_coil = m3d.assign_coil(assignment=[prim_top_face], conductors_number=1, name="Prim_Coil") |
| 92 | +sec_coil = m3d.assign_coil( assignment=[sec_top_face], conductors_number=1, name="Sec_Coil") |
| 93 | + |
| 94 | +prim_coil_name = prim_coil.name if hasattr(prim_coil, "name") else str(prim_coil) |
| 95 | +sec_coil_name = sec_coil.name if hasattr(sec_coil, "name") else str(sec_coil) |
| 96 | + |
| 97 | + |
| 98 | +current_expr = f"{amps_primary}*sin(2*PI*{frequency_hz}*Time)" |
| 99 | + |
| 100 | +# Get object names as strings |
| 101 | +prim_obj_name = "Coil_Primary" # or prim.name |
| 102 | +sec_obj_name = "Coil_Secondary" # or sec.name |
| 103 | + |
| 104 | +# Assign windings to objects, not faces |
| 105 | +prim_winding = m3d.assign_winding( |
| 106 | + assignment=[prim_obj_name], # Object name, not face |
| 107 | + winding_type="Current", |
| 108 | + is_solid=True, |
| 109 | + current=current_expr, |
| 110 | + resistance=0, |
| 111 | + name="PrimaryWinding", |
| 112 | +) |
| 113 | + |
| 114 | +sec_winding = m3d.assign_winding( |
| 115 | + assignment=[sec_obj_name], # Object name, not face |
| 116 | + winding_type="Current", |
| 117 | + is_solid=True, |
| 118 | + current="0A", # Add unit |
| 119 | + resistance=load_resistance, # Set to load_resistance, not 0 |
| 120 | + name="SecondaryWinding", |
| 121 | +) |
| 122 | + |
| 123 | + |
| 124 | +m3d.add_winding_coils(assignment=prim_winding.name, coils=[prim_coil_name]) |
| 125 | +m3d.add_winding_coils(assignment=sec_winding.name, coils=[sec_coil_name]) |
| 126 | + |
| 127 | + |
| 128 | +m3d.mesh.assign_length_mesh(assignment=["Coil_Primary", "Coil_Secondary", "Load_Tab"], maximum_length=2.0, name="CoilMesh") |
| 129 | + |
| 130 | + |
| 131 | +valid = m3d.validate_simple() |
| 132 | +print("Validation result:", valid) |
| 133 | + |
| 134 | +if not valid: |
| 135 | + print("Validation FAILED. Inspect Message Manager. Exiting script before solve.") |
| 136 | +else: |
| 137 | + setup = m3d.create_setup("TransientSetup") |
| 138 | + setup.props["Time Step"] = f"{sim_time/time_steps}s" |
| 139 | + setup.props["Stop Time"] = f"{sim_time}s" |
| 140 | + setup.props["Adaptive"] = False |
| 141 | + |
| 142 | + m3d.save_project(project_path) |
| 143 | + print("Starting transient solve...") |
| 144 | + m3d.analyze_setup(setup.name) |
| 145 | + print("Solve requested. Check AEDT Message Manager for progress and results.") |
| 146 | + |
| 147 | + |
| 148 | + |
| 149 | +print("Project saved at:", project_path) |
| 150 | + |
0 commit comments