.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples\03-Maxwell\Maxwell2D_PMSynchronousMotor.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_03-Maxwell_Maxwell2D_PMSynchronousMotor.py: Maxwell 2D: PM synchronous motor transient analysis --------------------------------------------------- This example shows how you can use PyAEDT to create a Maxwell 2D transient analysis for an interior permanent magnet electric motor. .. GENERATED FROM PYTHON SOURCE LINES 9-12 Perform required imports ~~~~~~~~~~~~~~~~~~~~~~~~ Perform required imports. .. GENERATED FROM PYTHON SOURCE LINES 12-19 .. code-block:: Python from math import sqrt as mysqrt import csv import os import pyaedt .. GENERATED FROM PYTHON SOURCE LINES 20-23 Set AEDT version ~~~~~~~~~~~~~~~~ Set AEDT version. .. GENERATED FROM PYTHON SOURCE LINES 23-26 .. code-block:: Python aedt_version = "2024.1" .. GENERATED FROM PYTHON SOURCE LINES 27-31 Initialize Maxwell 2D ~~~~~~~~~~~~~~~~~~~~~ Initialize Maxwell 2D, providing the version, path to the project, and the design name and type. .. GENERATED FROM PYTHON SOURCE LINES 31-38 .. code-block:: Python setup_name = "MySetupAuto" solver = "TransientXY" project_name = pyaedt.generate_unique_project_name() design_name = "Sinusoidal" .. GENERATED FROM PYTHON SOURCE LINES 39-43 Initialize definitions for stator, rotor, and shaft ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Initialize geometry parameter definitions for the stator, rotor, and shaft. The naming refers to RMxprt primitives. .. GENERATED FROM PYTHON SOURCE LINES 43-56 .. code-block:: Python geom_params = { "DiaGap": "132mm", "DiaStatorYoke": "198mm", "DiaStatorInner": "132mm", "DiaRotorLam": "130mm", "DiaShaft": "44.45mm", "DiaOuter": "198mm", "Airgap": "1mm", "SlotNumber": "48", "SlotType": "3" } .. GENERATED FROM PYTHON SOURCE LINES 57-61 Initialize definitions for stator windings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Initialize geometry parameter definitions for the stator windings. The naming refers to RMxprt primitives. .. GENERATED FROM PYTHON SOURCE LINES 61-76 .. code-block:: Python wind_params = { "Layers": "1", "ParallelPaths": "2", "R_Phase": "7.5mOhm", "WdgExt_F": "5mm", "SpanExt": "30mm", "SegAngle": "0.25", "CoilPitch": "5", # coil pitch in slots "Coil_SetBack": "3.605732823mm", "SlotWidth": "2.814mm", # RMxprt Bs0 "Coil_Edge_Short": "3.769235435mm", "Coil_Edge_Long": "15.37828521mm" } .. GENERATED FROM PYTHON SOURCE LINES 77-80 Initialize definitions for model setup ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Initialize geometry parameter definitions for the model setup. .. GENERATED FROM PYTHON SOURCE LINES 80-94 .. code-block:: Python mod_params = { "NumPoles": "8", "Model_Length": "80mm", "SymmetryFactor": "8", "Magnetic_Axial_Length": "150mm", "Stator_Lam_Length": "0mm", "StatorSkewAngle": "0deg", "NumTorquePointsPerCycle": "30", "mapping_angle": "0.125*4deg", "num_m": "16", "Section_Angle": "360deg/SymmetryFactor" } .. GENERATED FROM PYTHON SOURCE LINES 95-99 Initialize definitions for operational machine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Initialize geometry parameter definitions for the operational machine. This identifies the operating point for the transient setup. .. GENERATED FROM PYTHON SOURCE LINES 99-112 .. code-block:: Python oper_params = { "InitialPositionMD": "180deg/4", "IPeak": "480A", "MachineRPM": "3000rpm", "ElectricFrequency": "MachineRPM/60rpm*NumPoles/2*1Hz", "ElectricPeriod": "1/ElectricFrequency", "BandTicksinModel": "360deg/NumPoles/mapping_angle", "TimeStep": "ElectricPeriod/(2*BandTicksinModel)", "StopTime": "ElectricPeriod", "Theta_i": "135deg" } .. GENERATED FROM PYTHON SOURCE LINES 113-118 Set non-graphical mode ~~~~~~~~~~~~~~~~~~~~~~ Set non-graphical mode. ``"PYAEDT_NON_GRAPHICAL"`` is needed to generate documentation only. You can set ``non_graphical`` either to ``True`` or ``False``. .. GENERATED FROM PYTHON SOURCE LINES 118-121 .. code-block:: Python non_graphical = False .. GENERATED FROM PYTHON SOURCE LINES 122-125 Launch Maxwell 2D ~~~~~~~~~~~~~~~~~ Launch Maxwell 2D and save the project. .. GENERATED FROM PYTHON SOURCE LINES 125-134 .. code-block:: Python M2D = pyaedt.Maxwell2d(projectname=project_name, specified_version=aedt_version, designname=design_name, solution_type=solver, new_desktop_session=True, non_graphical=non_graphical ) .. 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 12064 is still running _warn("subprocess %s is still running" % self.pid, C:\actions-runner\_work\pyaedt\pyaedt\.venv\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 135-138 Create object to access 2D modeler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Create the object ``mod2D`` to access the 2D modeler easily. .. GENERATED FROM PYTHON SOURCE LINES 138-143 .. code-block:: Python mod2D = M2D.modeler mod2D.delete() mod2D.model_units = "mm" .. GENERATED FROM PYTHON SOURCE LINES 144-147 Define variables from dictionaries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Define design variables from the created dictionaries. .. GENERATED FROM PYTHON SOURCE LINES 147-157 .. code-block:: Python for k, v in geom_params.items(): M2D[k] = v for k, v in wind_params.items(): M2D[k] = v for k, v in mod_params.items(): M2D[k] = v for k, v in oper_params.items(): M2D[k] = v .. GENERATED FROM PYTHON SOURCE LINES 158-162 Define path for non-linear material properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Define the path for non-linear material properties. Materials are stored in text files. .. GENERATED FROM PYTHON SOURCE LINES 162-165 .. code-block:: Python filename_lam, filename_PM = pyaedt.downloads.download_leaf() .. GENERATED FROM PYTHON SOURCE LINES 166-169 Create first material ~~~~~~~~~~~~~~~~~~~~~ Create the material ``"Copper (Annealed)_65C"``. .. GENERATED FROM PYTHON SOURCE LINES 169-175 .. code-block:: Python mat_coils = M2D.materials.add_material("Copper (Annealed)_65C") mat_coils.update() mat_coils.conductivity = "49288048.9198" mat_coils.permeability = "1" .. GENERATED FROM PYTHON SOURCE LINES 176-182 Create second material ~~~~~~~~~~~~~~~~~~~~~~ Create the material ``"Arnold_Magnetics_N30UH_80C"``. The BH curve is read from a tabbed CSV file, and a list (``BH_List_PM``) is created. This list is passed to the ``mat_PM.permeability.value`` method. .. GENERATED FROM PYTHON SOURCE LINES 182-196 .. code-block:: Python mat_PM = M2D.materials.add_material("Arnold_Magnetics_N30UH_80C_new") mat_PM.update() mat_PM.conductivity = "555555.5556" mat_PM.set_magnetic_coercivity(value=-800146.66287534, x=1, y=0, z=0) mat_PM.mass_density = "7500" BH_List_PM = [] with open(filename_PM) as f: reader = csv.reader(f, delimiter='\t') next(reader) for row in reader: BH_List_PM.append([float(row[0]), float(row[1])]) mat_PM.permeability.value = BH_List_PM .. GENERATED FROM PYTHON SOURCE LINES 197-202 Create third material ~~~~~~~~~~~~~~~~~~~~~ Create the laminated material ``30DH_20C_smooth``. This material has a BH curve and a core loss model, which is set to electrical steel. .. GENERATED FROM PYTHON SOURCE LINES 202-221 .. code-block:: Python mat_lam = M2D.materials.add_material("30DH_20C_smooth") mat_lam.update() mat_lam.conductivity = "1694915.25424" kh = 71.7180985413 kc = 0.25092214579 ke = 12.1625774023 kdc = 0.001 eq_depth = 0.001 mat_lam.set_electrical_steel_coreloss(kh, kc, ke, kdc, eq_depth) mat_lam.mass_density = "7650" BH_List_lam = [] with open(filename_lam) as f: reader = csv.reader(f, delimiter='\t') next(reader) for row in reader: BH_List_lam.append([float(row[0]), float(row[1])]) mat_lam.permeability.value = BH_List_lam .. GENERATED FROM PYTHON SOURCE LINES 222-227 Create geometry for stator ~~~~~~~~~~~~~~~~~~~~~~~~~~ Create the geometry for the stator. It is created via the RMxprt user-defined primitive. A list of lists is created with the proper UDP parameters. .. GENERATED FROM PYTHON SOURCE LINES 227-242 .. code-block:: Python udp_par_list_stator = [["DiaGap", "DiaGap"], ["DiaYoke", "DiaStatorYoke"], ["Length", "Stator_Lam_Length"], ["Skew", "StatorSkewAngle"], ["Slots", "SlotNumber"], ["SlotType", "SlotType"], ["Hs0", "1.2mm"], ["Hs01", "0mm"], ["Hs1", "0.4834227384999mm"], ["Hs2", "17.287669825502mm"], ["Bs0", "2.814mm"], ["Bs1", "4.71154109036mm"], ["Bs2", "6.9777285790998mm"], ["Rs", "2mm"], ["FilletType", "1"], ["HalfSlot", "0"], ["VentHoles", "0"], ["HoleDiaIn", "0mm"], ["HoleDiaOut", "0mm"], ["HoleLocIn", "0mm"], ["HoleLocOut", "0mm"], ["VentDucts", "0"], ["DuctWidth", "0mm"], ["DuctPitch", "0mm"], ["SegAngle", "0deg"], ["LenRegion", "Model_Length"], ["InfoCore", "0"]] stator_id = mod2D.create_udp(dll="RMxprt/VentSlotCore.dll", parameters=udp_par_list_stator, library='syslib', name='my_stator') # name not taken .. GENERATED FROM PYTHON SOURCE LINES 243-247 Assign properties to stator ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Assign properties to the stator. The following code assigns the material, name, color, and ``solve_inside`` properties. .. GENERATED FROM PYTHON SOURCE LINES 247-254 .. code-block:: Python M2D.assign_material(obj=stator_id, mat="30DH_20C_smooth") stator_id.name = "Stator" stator_id.color = (0, 0, 255) # rgb stator_id.solve_inside = True # to be reassigned: M2D.assign material puts False if not dielectric .. GENERATED FROM PYTHON SOURCE LINES 255-262 Create geometry for PMs ~~~~~~~~~~~~~~~~~~~~~~~ Create the geometry for the PMs (permanent magnets). In Maxwell 2D, you assign magnetization via the coordinate system. Because each PM needs to have a coordinate system in the face center, auxiliary functions are created. Here, you use the auxiliary function ``find_elements(lst1, lst2)`` to find the elements in list ``lst1`` with indexes in list ``lst2``. .. GENERATED FROM PYTHON SOURCE LINES 262-267 .. code-block:: Python def find_elements(lst1, lst2): return [lst1[i] for i in lst2] .. GENERATED FROM PYTHON SOURCE LINES 268-272 Find largest elements in list ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Use the auxiliary function ``find_n_largest (input_len_list, n_largest_edges)`` to find the ``n`` largest elements in the list ``input_len_list``. .. GENERATED FROM PYTHON SOURCE LINES 272-284 .. code-block:: Python def find_n_largest(input_len_list, n_largest_edges): tmp = list(input_len_list) copied = list(input_len_list) copied.sort() # sort list so that largest elements are on the far right index_list = [] for n in range(1, n_largest_edges + 1): # get index of the nth largest element index_list.append(tmp.index(copied[-n])) tmp[tmp.index(copied[-n])] = 0 # index can only get the first occurrence that solves the problem return index_list .. GENERATED FROM PYTHON SOURCE LINES 285-291 Create coordinate system for PMs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Create the coordinate system for the PMs. The inputs are the object name, coordinate system name, and inner or outer magnetization. Find the two longest edges of the magnets and get the midpoint of the outer edge. You must have this point to create the face coordinate systems in case of outer magnetization. .. GENERATED FROM PYTHON SOURCE LINES 291-316 .. code-block:: Python def create_cs_magnets(pm_id, cs_name, point_direction): pm_face_id = mod2D.get_object_faces(pm_id.name)[0] # works with name only pm_edges = mod2D.get_object_edges(pm_id.name) # gets the edges of the PM object edge_len_list = list( map(mod2D.get_edge_length, pm_edges)) # apply method get_edge_length to all elements of list pm_edges index_2_longest = find_n_largest(edge_len_list, 2) # find the 2 longest edges of the PM longest_edge_list = find_elements(pm_edges, index_2_longest) edge_center_list = list(map(mod2D.get_edge_midpoint, longest_edge_list)) # apply method get_edge_midpoint to all elements of list longest_edge_list rad = lambda x: mysqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]) index_largest_r = find_n_largest(list(map(rad, edge_center_list)), 2) longest_edge_list2 = [longest_edge_list[i] for i in index_largest_r] # reorder: outer first element of the list if point_direction == 'outer': my_axis_pos = longest_edge_list2[0] elif point_direction == 'inner': my_axis_pos = longest_edge_list2[1] mod2D.create_face_coordinate_system(face=pm_face_id, origin=pm_face_id, axis_position=my_axis_pos, axis="X", name=cs_name) pm_id.part_coordinate_system = cs_name mod2D.set_working_coordinate_system('Global') .. GENERATED FROM PYTHON SOURCE LINES 317-320 Create outer and inner PMs ~~~~~~~~~~~~~~~~~~~~~~~~~~ Create the outer and inner PMs and assign color to them. .. GENERATED FROM PYTHON SOURCE LINES 320-332 .. code-block:: Python IM1_points = [[56.70957112, 3.104886585, 0], [40.25081875, 16.67243502, 0], [38.59701538, 14.66621111, 0], [55.05576774, 1.098662669, 0]] OM1_points = [[54.37758185, 22.52393189, 0], [59.69688156, 9.68200639, 0], [63.26490432, 11.15992981, 0], [57.94560461, 24.00185531, 0]] IPM1_id = mod2D.create_polyline(points=IM1_points, cover_surface=True, name="PM_I1", material="Arnold_Magnetics_N30UH_80C_new") IPM1_id.color = (0, 128, 64) OPM1_id = mod2D.create_polyline(points=OM1_points, cover_surface=True, name="PM_O1", material="Arnold_Magnetics_N30UH_80C_new") OPM1_id.color = (0, 128, 64) .. GENERATED FROM PYTHON SOURCE LINES 333-336 Create coordinate system for PMs in face center ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Create the coordinate system for PMs in the face center. .. GENERATED FROM PYTHON SOURCE LINES 336-340 .. code-block:: Python create_cs_magnets(IPM1_id, 'CS_' + IPM1_id.name, 'outer') create_cs_magnets(OPM1_id, 'CS_' + OPM1_id.name, 'outer') .. GENERATED FROM PYTHON SOURCE LINES 341-344 Duplicate and mirror PMs ~~~~~~~~~~~~~~~~~~~~~~~~ Duplicate and mirror the PMs along with the local coordinate system. .. GENERATED FROM PYTHON SOURCE LINES 344-349 .. code-block:: Python mod2D.duplicate_and_mirror([IPM1_id, OPM1_id], origin=[0, 0, 0], vector=["cos((360deg/SymmetryFactor/2)+90deg)", "sin((360deg/SymmetryFactor/2)+90deg)", 0]) id_PMs = mod2D.get_objects_w_string("PM", case_sensitive=True) .. GENERATED FROM PYTHON SOURCE LINES 350-353 Create coils ~~~~~~~~~~~~ Create the coils. .. GENERATED FROM PYTHON SOURCE LINES 353-363 .. code-block:: Python coil_id = mod2D.create_rectangle(origin=['DiaRotorLam/2+Airgap+Coil_SetBack', '-Coil_Edge_Short/2', 0], sizes=['Coil_Edge_Long', 'Coil_Edge_Short', 0], name='Coil', material="Copper (Annealed)_65C") coil_id.color = (255, 128, 0) M2D.modeler.rotate(assignment=coil_id, axis="Z", angle="360deg/SlotNumber/2") coil_id.duplicate_around_axis(axis="Z", angle="360deg/SlotNumber", nclones='CoilPitch+1', create_new_objects=True) id_coils = mod2D.get_objects_w_string("Coil", case_sensitive=True) .. GENERATED FROM PYTHON SOURCE LINES 364-367 Create shaft and region ~~~~~~~~~~~~~~~~~~~~~~~ Create the shaft and region. .. GENERATED FROM PYTHON SOURCE LINES 367-373 .. code-block:: Python region_id = mod2D.create_circle(position=[0, 0, 0], radius='DiaOuter/2', num_sides='SegAngle', is_covered=True, name='Region') shaft_id = mod2D.create_circle(position=[0, 0, 0], radius='DiaShaft/2', num_sides='SegAngle', is_covered=True, name='Shaft') .. GENERATED FROM PYTHON SOURCE LINES 374-377 Create bands ~~~~~~~~~~~~ Create the inner band, band, and outer band. .. GENERATED FROM PYTHON SOURCE LINES 377-385 .. code-block:: Python bandIN_id = mod2D.create_circle(position=[0, 0, 0], radius='(DiaGap - (1.5 * Airgap))/2', num_sides='mapping_angle', is_covered=True, name='Inner_Band') bandMID_id = mod2D.create_circle(position=[0, 0, 0], radius='(DiaGap - (1.0 * Airgap))/2', num_sides='mapping_angle', is_covered=True, name='Band') bandOUT_id = mod2D.create_circle(position=[0, 0, 0], radius='(DiaGap - (0.5 * Airgap))/2', num_sides='mapping_angle', is_covered=True, name='Outer_Band') .. GENERATED FROM PYTHON SOURCE LINES 386-389 Assign motion setup to object ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Assign a motion setup to a ``Band`` object named ``RotatingBand_mid``. .. GENERATED FROM PYTHON SOURCE LINES 389-393 .. code-block:: Python M2D.assign_rotate_motion(assignment='Band', coordinate_system="Global", axis="Z", positive_movement=True, start_position="InitialPositionMD", angular_velocity="MachineRPM") .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 394-397 Create list of vacuum objects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Create a list of vacuum objects and assign color. .. GENERATED FROM PYTHON SOURCE LINES 397-402 .. code-block:: Python vacuum_obj_id = [shaft_id, region_id, bandIN_id, bandMID_id, bandOUT_id] # put shaft first for item in vacuum_obj_id: item.color = (128, 255, 255) .. GENERATED FROM PYTHON SOURCE LINES 403-407 Create rotor ~~~~~~~~~~~~ Create the rotor. Holes are specific to the lamination. Allocated PMs are created. .. GENERATED FROM PYTHON SOURCE LINES 407-434 .. code-block:: Python rotor_id = mod2D.create_circle(position=[0, 0, 0], radius='DiaRotorLam/2', num_sides=0, name="Rotor", material="30DH_20C_smooth") rotor_id.color = (0, 128, 255) mod2D.subtract(rotor_id, shaft_id, keep_originals=True) void_small_1_id = mod2D.create_circle(position=[62, 0, 0], radius="2.55mm", num_sides=0, name="void1", material="vacuum") M2D.modeler.duplicate_around_axis(void_small_1_id, axis="Z", angle="360deg/SymmetryFactor", clones=2, create_new_objects=False) void_big_1_id = mod2D.create_circle(position=[29.5643, 12.234389332712, 0], radius='9.88mm/2', num_sides=0, name="void_big", material="vacuum") mod2D.subtract(rotor_id, [void_small_1_id, void_big_1_id], keep_originals=False) slot_IM1_points = [[37.5302872, 15.54555396, 0], [55.05576774, 1.098662669, 0], [57.33637589, 1.25, 0], [57.28982158, 2.626565019, 0], [40.25081875, 16.67243502, 0]] slot_OM1_points = [[54.37758185, 22.52393189, 0], [59.69688156, 9.68200639, 0], [63.53825619, 10.5, 0], [57.94560461, 24.00185531, 0]] slot_IM_id = mod2D.create_polyline(points=slot_IM1_points, cover_surface=True, name="slot_IM1", material="vacuum") slot_OM_id = mod2D.create_polyline(points=slot_OM1_points, cover_surface=True, name="slot_OM1", material="vacuum") M2D.modeler.duplicate_and_mirror(assignment=[slot_IM_id, slot_OM_id], origin=[0, 0, 0], vector=["cos((360deg/SymmetryFactor/2)+90deg)", "sin((360deg/SymmetryFactor/2)+90deg)", 0]) id_holes = mod2D.get_objects_w_string("slot_", case_sensitive=True) M2D.modeler.subtract(rotor_id, id_holes, keep_originals=True) .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 435-439 Create section of machine ~~~~~~~~~~~~~~~~~~~~~~~~~ Create a section of the machine. This allows you to take advantage of symmetries. .. GENERATED FROM PYTHON SOURCE LINES 439-453 .. code-block:: Python object_list = [stator_id, rotor_id] + vacuum_obj_id mod2D.create_coordinate_system(origin=[0, 0, 0], reference_cs="Global", name="Section", mode="axis", x_pointing=["cos(360deg/SymmetryFactor)", "sin(360deg/SymmetryFactor)", 0], y_pointing=["-sin(360deg/SymmetryFactor)", "cos(360deg/SymmetryFactor)", 0]) mod2D.set_working_coordinate_system("Section") mod2D.split(object_list, "ZX", sides="NegativeOnly") mod2D.set_working_coordinate_system("Global") mod2D.split(object_list, "ZX", sides="PositiveOnly") .. rst-class:: sphx-glr-script-out .. code-block:: none ['Stator,Rotor,Shaft,Region,Inner_Band,Band,Outer_Band'] .. GENERATED FROM PYTHON SOURCE LINES 454-459 Create boundary conditions ~~~~~~~~~~~~~~~~~~~~~~~~~~ Create independent and dependent boundary conditions. Edges for assignment are picked by position. The points for edge picking are in the airgap. .. GENERATED FROM PYTHON SOURCE LINES 459-467 .. code-block:: Python pos_1 = "((DiaGap - (1.0 * Airgap))/4)" id_bc_1 = mod2D.get_edgeid_from_position(position=[pos_1, 0, 0], assignment='Region') id_bc_2 = mod2D.get_edgeid_from_position( position=[pos_1 + "*cos((360deg/SymmetryFactor))", pos_1 + "*sin((360deg/SymmetryFactor))", 0], assignment='Region') M2D.assign_master_slave(independent=id_bc_1, dependent=id_bc_2, reverse_master=False, reverse_slave=True, same_as_master=False, boundary="Matching") .. rst-class:: sphx-glr-script-out .. code-block:: none (, ) .. GENERATED FROM PYTHON SOURCE LINES 468-471 Assign vector potential ~~~~~~~~~~~~~~~~~~~~~~~ Assign a vector potential of ``0`` to the second position. .. GENERATED FROM PYTHON SOURCE LINES 471-478 .. code-block:: Python pos_2 = "(DiaOuter/2)" id_bc_az = mod2D.get_edgeid_from_position( position=[pos_2 + "*cos((360deg/SymmetryFactor/2))", pos_2 + "*sin((360deg/SymmetryFactor)/2)", 0], assignment='Region') M2D.assign_vector_potential(id_bc_az, vector_value=0, boundary="VectorPotentialZero") .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 479-482 Create excitations ~~~~~~~~~~~~~~~~~~ Create excitations, defining phase currents for the windings. .. GENERATED FROM PYTHON SOURCE LINES 482-487 .. code-block:: Python PhA_current = "IPeak * cos(2*pi*ElectricFrequency*time+Theta_i)" PhB_current = "IPeak * cos(2*pi * ElectricFrequency*time - 120deg+Theta_i)" PhC_current = "IPeak * cos(2*pi * ElectricFrequency*time - 240deg+Theta_i)" .. GENERATED FROM PYTHON SOURCE LINES 488-491 Define windings in phase A ~~~~~~~~~~~~~~~~~~~~~~~~~~ Define windings in phase A. .. GENERATED FROM PYTHON SOURCE LINES 491-498 .. code-block:: Python M2D.assign_coil(assignment=["Coil"], conductors_number=6, polarity="Positive", name="CT_Ph1_P2_C1_Go") M2D.assign_coil(assignment=["Coil_5"], conductors_number=6, polarity="Negative", name="CT_Ph1_P2_C1_Ret") M2D.assign_winding(assignment=None, winding_type="Current", is_solid=False, current=PhA_current, parallel_branches=1, name="Phase_A") M2D.add_winding_coils(assignment="Phase_A", coils=["CT_Ph1_P2_C1_Go", "CT_Ph1_P2_C1_Ret"]) .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 499-502 Define windings in phase B ~~~~~~~~~~~~~~~~~~~~~~~~~~ Define windings in phase B. .. GENERATED FROM PYTHON SOURCE LINES 502-509 .. code-block:: Python M2D.assign_coil(assignment="Coil_3", conductors_number=6, polarity="Positive", name="CT_Ph3_P1_C2_Go") M2D.assign_coil(assignment="Coil_4", conductors_number=6, polarity="Positive", name="CT_Ph3_P1_C1_Go") M2D.assign_winding(assignment=None, winding_type="Current", is_solid=False, current=PhB_current, parallel_branches=1, name="Phase_B") M2D.add_winding_coils(assignment="Phase_B", coils=["CT_Ph3_P1_C2_Go", "CT_Ph3_P1_C1_Go"]) .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 510-513 Define windings in phase C ~~~~~~~~~~~~~~~~~~~~~~~~~~ Define windings in phase C. .. GENERATED FROM PYTHON SOURCE LINES 513-520 .. code-block:: Python M2D.assign_coil(assignment="Coil_1", conductors_number=6, polarity="Negative", name="CT_Ph2_P2_C2_Ret") M2D.assign_coil(assignment="Coil_2", conductors_number=6, polarity="Negative", name="CT_Ph2_P2_C1_Ret") M2D.assign_winding(assignment=None, winding_type="Current", is_solid=False, current=PhC_current, parallel_branches=1, name="Phase_C") M2D.add_winding_coils(assignment="Phase_C", coils=["CT_Ph2_P2_C2_Ret", "CT_Ph2_P2_C1_Ret"]) .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 521-524 Assign total current on PMs ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Assign a total current of ``0`` on the PMs. .. GENERATED FROM PYTHON SOURCE LINES 524-529 .. code-block:: Python PM_list = id_PMs for item in PM_list: M2D.assign_current(item, amplitude=0, solid=True, name=item + "_I0") .. GENERATED FROM PYTHON SOURCE LINES 530-533 Create mesh operations ~~~~~~~~~~~~~~~~~~~~~~ Create the mesh operations. .. GENERATED FROM PYTHON SOURCE LINES 533-538 .. code-block:: Python M2D.mesh.assign_length_mesh(id_coils, inside_selection=True, maximum_length=3, maximum_elements=None, name="coils") M2D.mesh.assign_length_mesh(stator_id, inside_selection=True, maximum_length=3, maximum_elements=None, name="stator") M2D.mesh.assign_length_mesh(rotor_id, inside_selection=True, maximum_length=3, maximum_elements=None, name="rotor") .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 539-542 Turn on eddy effects ~~~~~~~~~~~~~~~~~~~~ Turn on eddy effects. .. GENERATED FROM PYTHON SOURCE LINES 542-545 .. code-block:: Python # M2D.eddy_effects_on(eddy_effects_list,activate_eddy_effects=True, activate_displacement_current=False) .. GENERATED FROM PYTHON SOURCE LINES 546-549 Turn on core loss ~~~~~~~~~~~~~~~~~ Turn on core loss. .. GENERATED FROM PYTHON SOURCE LINES 549-553 .. code-block:: Python core_loss_list = ['Rotor', 'Stator'] M2D.set_core_losses(core_loss_list) .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 554-557 Compute transient inductance ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Compute the transient inductance. .. GENERATED FROM PYTHON SOURCE LINES 557-560 .. code-block:: Python M2D.change_inductance_computation(compute_transient_inductance=True, incremental_matrix=False) .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 561-564 Set model depth ~~~~~~~~~~~~~~~ Set the model depth. .. GENERATED FROM PYTHON SOURCE LINES 564-567 .. code-block:: Python M2D.model_depth = "Magnetic_Axial_Length" .. GENERATED FROM PYTHON SOURCE LINES 568-571 Set symmetry factor ~~~~~~~~~~~~~~~~~~~ Set the symmetry factor. .. GENERATED FROM PYTHON SOURCE LINES 571-574 .. code-block:: Python M2D.change_symmetry_multiplier("SymmetryFactor") .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 575-578 Create setup and validate ~~~~~~~~~~~~~~~~~~~~~~~~~ Create the setup and validate it. .. GENERATED FROM PYTHON SOURCE LINES 578-592 .. code-block:: Python setup = M2D.create_setup(name=setup_name) setup.props["StopTime"] = "StopTime" setup.props["TimeStep"] = "TimeStep" setup.props["SaveFieldsType"] = "None" setup.props["OutputPerObjectCoreLoss"] = True setup.props["OutputPerObjectSolidLoss"] = True setup.props["OutputError"] = True setup.update() M2D.validate_simple() model = M2D.plot(show=False) model.plot(os.path.join(M2D.working_directory, "Image.jpg")) .. image-sg:: /examples/03-Maxwell/images/sphx_glr_Maxwell2D_PMSynchronousMotor_001.png :alt: Maxwell2D PMSynchronousMotor :srcset: /examples/03-Maxwell/images/sphx_glr_Maxwell2D_PMSynchronousMotor_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 593-597 Initialize definitions for output variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Initialize the definitions for the output variables. These will be used later to generate reports. .. GENERATED FROM PYTHON SOURCE LINES 597-639 .. code-block:: Python output_vars = { "Current_A": "InputCurrent(Phase_A)", "Current_B": "InputCurrent(Phase_B)", "Current_C": "InputCurrent(Phase_C)", "Flux_A": "FluxLinkage(Phase_A)", "Flux_B": "FluxLinkage(Phase_B)", "Flux_C": "FluxLinkage(Phase_C)", "pos": "(Moving1.Position -InitialPositionMD) *NumPoles/2", "cos0": "cos(pos)", "cos1": "cos(pos-2*PI/3)", "cos2": "cos(pos-4*PI/3)", "sin0": "sin(pos)", "sin1": "sin(pos-2*PI/3)", "sin2": "sin(pos-4*PI/3)", "Flux_d": "2/3*(Flux_A*cos0+Flux_B*cos1+Flux_C*cos2)", "Flux_q": "-2/3*(Flux_A*sin0+Flux_B*sin1+Flux_C*sin2)", "I_d": "2/3*(Current_A*cos0 + Current_B*cos1 + Current_C*cos2)", "I_q": "-2/3*(Current_A*sin0 + Current_B*sin1 + Current_C*sin2)", "Irms": "sqrt(I_d^2+I_q^2)/sqrt(2)", "ArmatureOhmicLoss_DC": "Irms^2*R_phase", "Lad": "L(Phase_A,Phase_A)*cos0 + L(Phase_A,Phase_B)*cos1 + L(Phase_A,Phase_C)*cos2", "Laq": "L(Phase_A,Phase_A)*sin0 + L(Phase_A,Phase_B)*sin1 + L(Phase_A,Phase_C)*sin2", "Lbd": "L(Phase_B,Phase_A)*cos0 + L(Phase_B,Phase_B)*cos1 + L(Phase_B,Phase_C)*cos2", "Lbq": "L(Phase_B,Phase_A)*sin0 + L(Phase_B,Phase_B)*sin1 + L(Phase_B,Phase_C)*sin2", "Lcd": "L(Phase_C,Phase_A)*cos0 + L(Phase_C,Phase_B)*cos1 + L(Phase_C,Phase_C)*cos2", "Lcq": "L(Phase_C,Phase_A)*sin0 + L(Phase_C,Phase_B)*sin1 + L(Phase_C,Phase_C)*sin2", "L_d": "(Lad*cos0 + Lbd*cos1 + Lcd*cos2) * 2/3", "L_q": "(Laq*sin0 + Lbq*sin1 + Lcq*sin2) * 2/3", "OutputPower": "Moving1.Speed*Moving1.Torque", "Ui_A": "InducedVoltage(Phase_A)", "Ui_B": "InducedVoltage(Phase_B)", "Ui_C": "InducedVoltage(Phase_C)", "Ui_d": "2/3*(Ui_A*cos0 + Ui_B*cos1 + Ui_C*cos2)", "Ui_q": "-2/3*(Ui_A*sin0 + Ui_B*sin1 + Ui_C*sin2)", "U_A": "Ui_A+R_Phase*Current_A", "U_B": "Ui_B+R_Phase*Current_B", "U_C": "Ui_C+R_Phase*Current_C", "U_d": "2/3*(U_A*cos0 + U_B*cos1 + U_C*cos2)", "U_q": "-2/3*(U_A*sin0 + U_B*sin1 + U_C*sin2)" } .. GENERATED FROM PYTHON SOURCE LINES 640-643 Create output variables for postprocessing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Create output variables for postprocessing. .. GENERATED FROM PYTHON SOURCE LINES 643-647 .. code-block:: Python for k, v in output_vars.items(): M2D.create_output_variable(k, v) .. GENERATED FROM PYTHON SOURCE LINES 648-651 Initialize definition for postprocessing plots ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Initialize the definition for postprocessing plots. .. GENERATED FROM PYTHON SOURCE LINES 651-655 .. code-block:: Python post_params = { "Moving1.Torque": "TorquePlots" } .. GENERATED FROM PYTHON SOURCE LINES 656-659 Initialize definition for postprocessing multiplots ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Initialize the definition for postprocessing multiplots. .. GENERATED FROM PYTHON SOURCE LINES 659-679 .. code-block:: Python post_params_multiplot = { # reports ("U_A", "U_B", "U_C", "Ui_A", "Ui_B", "Ui_C"): "PhaseVoltages", ("CoreLoss", "SolidLoss", "ArmatureOhmicLoss_DC"): "Losses", ("InputCurrent(Phase_A)", "InputCurrent(Phase_B)", "InputCurrent(Phase_C)"): "PhaseCurrents", ("FluxLinkage(Phase_A)", "FluxLinkage(Phase_B)", "FluxLinkage(Phase_C)"): "PhaseFluxes", ("I_d", "I_q"): "Currents_dq", ("Flux_d", "Flux_q"): "Fluxes_dq", ("Ui_d", "Ui_q"): "InducedVoltages_dq", ("U_d", "U_q"): "Voltages_dq", ("L(Phase_A,Phase_A)", "L(Phase_B,Phase_B)", "L(Phase_C,Phase_C)", "L(Phase_A,Phase_B)", "L(Phase_A,Phase_C)", "L(Phase_B,Phase_C)"): "PhaseInductances", ("L_d", "L_q"): "Inductances_dq", ("CoreLoss", "CoreLoss(Stator)", "CoreLoss(Rotor)"): "CoreLosses", ("EddyCurrentLoss", "EddyCurrentLoss(Stator)", "EddyCurrentLoss(Rotor)"): "EddyCurrentLosses (Core)", ("ExcessLoss", "ExcessLoss(Stator)", "ExcessLoss(Rotor)"): "ExcessLosses (Core)", ("HysteresisLoss", "HysteresisLoss(Stator)", "HysteresisLoss(Rotor)"): "HysteresisLosses (Core)", ("SolidLoss", "SolidLoss(IPM1)", "SolidLoss(IPM1_1)", "SolidLoss(OPM1)", "SolidLoss(OPM1_1)"): "SolidLoss" } .. GENERATED FROM PYTHON SOURCE LINES 680-683 Create report ~~~~~~~~~~~~~ Create a report. .. GENERATED FROM PYTHON SOURCE LINES 683-690 .. code-block:: Python for k, v in post_params.items(): M2D.post.create_report(expressions=k, setup_sweep_name="", domain="Sweep", variations=None, primary_sweep_variable="Time", secondary_sweep_variable=None, report_category=None, plot_type="Rectangular Plot", context=None, subdesign_id=None, polyline_points=1001, plot_name=v) .. GENERATED FROM PYTHON SOURCE LINES 691-694 Create multiplot report ~~~~~~~~~~~~~~~~~~~~~~~ Create a multiplot report. .. GENERATED FROM PYTHON SOURCE LINES 694-702 .. code-block:: Python # for k, v in post_params_multiplot.items(): # M2D.post.create_report(expressions=list(k), setup_sweep_name="", domain="Sweep", variations=None, # primary_sweep_variable="Time", secondary_sweep_variable=None, # report_category=None, plot_type="Rectangular Plot", context=None, subdesign_id=None, # polyline_points=1001, plotname=v) .. GENERATED FROM PYTHON SOURCE LINES 703-706 Analyze and save project ~~~~~~~~~~~~~~~~~~~~~~~~ Analyze and save the project. .. GENERATED FROM PYTHON SOURCE LINES 706-710 .. code-block:: Python M2D.save_project() M2D.analyze_setup(setup_name, use_auto_settings=False) .. rst-class:: sphx-glr-script-out .. code-block:: none True .. GENERATED FROM PYTHON SOURCE LINES 711-715 Create flux lines plot on region ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Create a flux lines plot on a region. The ``object_list`` is formerly created when the section is applied. .. GENERATED FROM PYTHON SOURCE LINES 715-720 .. code-block:: Python faces_reg = mod2D.get_object_faces(object_list[1].name) # Region plot1 = M2D.post.create_fieldplot_surface(assignment=faces_reg, quantity='Flux_Lines', intrinsics={ "Time": M2D.variable_manager.variables["StopTime"].evaluated_value}, plot_name="Flux_Lines") .. GENERATED FROM PYTHON SOURCE LINES 721-724 Export a field plot to an image file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Export the flux lines plot to an image file using Python PyVista. .. GENERATED FROM PYTHON SOURCE LINES 724-727 .. code-block:: Python M2D.post.plot_field_from_fieldplot(plot1.name, show=False) .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 728-732 Get solution data ~~~~~~~~~~~~~~~~~ Get a simulation result from a solved setup and cast it in a ``SolutionData`` object. Plot the desired expression by using Matplotlib plot(). .. GENERATED FROM PYTHON SOURCE LINES 732-737 .. code-block:: Python solutions = M2D.post.get_solution_data(expressions="Moving1.Torque", primary_sweep_variable="Time") #solutions.plot() .. GENERATED FROM PYTHON SOURCE LINES 738-741 Retrieve the data magnitude of an expression ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ List of shaft torque points and compute average. .. GENERATED FROM PYTHON SOURCE LINES 741-745 .. code-block:: Python mag = solutions.data_magnitude() avg = sum(mag) / len(mag) .. GENERATED FROM PYTHON SOURCE LINES 746-749 Export a report to a file ~~~~~~~~~~~~~~~~~~~~~~~~~ Export a 2D Plot data to a .csv file. .. GENERATED FROM PYTHON SOURCE LINES 749-754 .. code-block:: Python M2D.post.export_report_to_file(output_dir=M2D.toolkit_directory, plot_name="TorquePlots", extension=".csv") .. rst-class:: sphx-glr-script-out .. code-block:: none 'D:/Temp/pyaedt_prj_RNH/Project_4IO.pyaedt\\TorquePlots.csv' .. GENERATED FROM PYTHON SOURCE LINES 755-758 Close AEDT ~~~~~~~~~~ Close AEDT. .. GENERATED FROM PYTHON SOURCE LINES 758-760 .. code-block:: Python M2D.release_desktop() .. rst-class:: sphx-glr-script-out .. code-block:: none True .. rst-class:: sphx-glr-timing **Total running time of the script:** (3 minutes 1.201 seconds) .. _sphx_glr_download_examples_03-Maxwell_Maxwell2D_PMSynchronousMotor.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: Maxwell2D_PMSynchronousMotor.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: Maxwell2D_PMSynchronousMotor.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_