.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples\adaptive_library\BezierCurveRotorPockets.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_adaptive_library_BezierCurveRotorPockets.py: Bezier curve rotor pockets ========================== This script applies the adaptive templates functionality to modify rotor pockets with a custom curve defined using a Bezier function. .. GENERATED FROM PYTHON SOURCE LINES 30-32 .. note:: This script requires Motor-CAD 2024 R2 or later. .. GENERATED FROM PYTHON SOURCE LINES 34-47 This script is designed to be run from a Motor-CAD model based on the e4a template (a 48 slot, 8 pole IPM machine). The model is modified from the template by adjusting the Standard Template geometry parameters as follows: * Set L1 Bridge thickness to 2 mm. * Set L1 Pole V Angle to 180 degrees. * Set L1 Magnet Post to 0 mm. * Set L1 Magnet Separation to 0 mm. * Set L1 Mag Gap Inner to 0 mm. .. GENERATED FROM PYTHON SOURCE LINES 49-50 .. image:: ../../images/Adaptive_Geometry_Bezier_e4a_1.png .. GENERATED FROM PYTHON SOURCE LINES 52-54 If no Motor-CAD file is open, the e4a template is loaded and the geometry is adjusted as described earlier. .. GENERATED FROM PYTHON SOURCE LINES 56-64 Perform required imports ------------------------ Import the ``pymotorcad`` package to access Motor-CAD. Import the ``Coordinate``, ``Arc``, ``Line`` and ``rt_to_xy`` objects to define the adaptive template geometry. Import ``bezier`` used to draw the curve. Import the ``os``, ``shutil``, ``sys`` and ``tempfile`` packages to open and save a temporary MOT file if none is open. .. GENERATED FROM PYTHON SOURCE LINES 64-77 .. code-block:: Python import os import shutil import sys import tempfile import bezier import numpy as np import ansys.motorcad.core as pymotorcad from ansys.motorcad.core.geometry import Arc, Coordinate, Line, rt_to_xy from ansys.motorcad.core.geometry_fitting import return_entity_list .. GENERATED FROM PYTHON SOURCE LINES 79-90 Connect to Motor-CAD -------------------- If this script is loaded into the Adaptive Templates file in Motor-CAD, the current Motor-CAD instance is used. If the script is run externally, these actions occur: a new Motor-CAD instance is opened, the e4a IPM motor template is loaded, the geometry changes described earlier are applied and the file is saved to a temporary folder. To keep a new Motor-CAD instance open after executing the script, use the ``MotorCAD(keep_instance_open=True)`` option when opening the new instance. Alternatively, use the ``MotorCAD()`` method, which closes the Motor-CAD instance after the script is executed. .. GENERATED FROM PYTHON SOURCE LINES 90-122 .. code-block:: Python if pymotorcad.is_running_in_internal_scripting(): # Use existing Motor-CAD instance if possible mc = pymotorcad.MotorCAD(open_new_instance=False) else: mc = pymotorcad.MotorCAD(keep_instance_open=True) # Disable popup messages mc.set_variable("MessageDisplayState", 2) mc.set_visible(True) mc.load_template("e4a") # Set Standard Template geometry ready for Adaptive Templates script mc.set_array_variable("BridgeThickness_Array", 0, 2) # Bridge thickness set to 0 mc.set_array_variable("PoleVAngle_Array", 0, 180) # Pole V angle set to 180 mc.set_array_variable("VShapeMagnetPost_Array", 0, 0) # Magnet Post set to 0 mc.set_array_variable("MagnetSeparation_Array", 0, 0) # Magnet Separation set to 0 mc.set_array_variable("VShape_Magnet_ClearanceInner", 0, 0) # Magnet Inner Gap set to 0 # Open relevant file working_folder = os.path.join(tempfile.gettempdir(), "adaptive_library") try: shutil.rmtree(working_folder) except: pass os.mkdir(working_folder) mot_name = "IPM_Pocket_Bezier" mc.save_to_file(working_folder + "/" + mot_name + ".mot") # Reset geometry to default mc.reset_adaptive_geometry() .. GENERATED FROM PYTHON SOURCE LINES 123-127 Set adaptive parameter if required ---------------------------------- The ``set_default_parameter`` function is defined to check if a parameter exists. If not, it creates the parameter with a default value. .. GENERATED FROM PYTHON SOURCE LINES 127-134 .. code-block:: Python def set_default_parameter(parameter_name, default_value): try: mc.get_adaptive_parameter_value(parameter_name) except pymotorcad.MotorCADError: mc.set_adaptive_parameter_value(parameter_name, default_value) .. GENERATED FROM PYTHON SOURCE LINES 135-137 Use the ``set_default_parameter()`` function to set the required ``L1 Bezier Curve Projection``, ``L1 Upper Convex`` and ``L1 Lower Concave`` parameters if undefined. .. GENERATED FROM PYTHON SOURCE LINES 137-141 .. code-block:: Python set_default_parameter("L1 Bezier Curve Projection", 6) set_default_parameter("L1 Upper Convex", 0.5) set_default_parameter("L1 Lower Concave", -0.3) .. GENERATED FROM PYTHON SOURCE LINES 142-156 The adaptive parameters are used to define the curved rotor pocket geometry with a Bezier function. The parameters relate to the rotor pocket shape as follows: * ``L1 Bezier Curve Projection``: Defines the rotor pocket extension beyond the magnet edge in the direction of the magnet length in mm. * ``L1 Upper Convex``: Defines the concave rotor pocket extension beyond the magnet edge in the direction of the magnet thickness. This parameter is dependent on the magnet thickness (a Standard Template parameter). * ``L1 Lower Concave``: Defines the convex rotor pocket curvature in the direction of the magnet thickness. This parameter is dependent on the magnet thickness (a Standard Template parameter). .. image:: ../../images/Adaptive_Geometry_Bezier_e4a_2.png .. GENERATED FROM PYTHON SOURCE LINES 159-164 Get required parameters and objects ----------------------------------- From Motor-CAD, get the adaptive parameters and their values. Get the standard template rotor region. This can be drawn for debugging if required. .. GENERATED FROM PYTHON SOURCE LINES 164-169 .. code-block:: Python rotor_region = mc.get_region("Rotor") rotor_radius = mc.get_variable("RotorDiameter") / 2 poles = mc.get_variable("Pole_Number") pole_angle = 360 / (poles * 2) .. GENERATED FROM PYTHON SOURCE LINES 170-171 Get the adaptive parameters specified in Motor-CAD, and their values .. GENERATED FROM PYTHON SOURCE LINES 171-175 .. code-block:: Python totalprojection = mc.get_adaptive_parameter_value("L1 Bezier Curve Projection") upperconvex = mc.get_adaptive_parameter_value("L1 Upper Convex") lowerconcave = mc.get_adaptive_parameter_value("L1 Lower Concave") .. GENERATED FROM PYTHON SOURCE LINES 176-177 Get the Rotor Pocket regions .. GENERATED FROM PYTHON SOURCE LINES 177-182 .. code-block:: Python Rotor_Pocket_regions = [] for i in rotor_region.child_names: if "Pocket" in i: Rotor_Pocket_regions.append(mc.get_region(i)) .. GENERATED FROM PYTHON SOURCE LINES 183-184 Get the magnet regions .. GENERATED FROM PYTHON SOURCE LINES 184-189 .. code-block:: Python Magnet_regions = [] for i in rotor_region.child_names: if "Magnet" in i: Magnet_regions.append(mc.get_region(i)) .. GENERATED FROM PYTHON SOURCE LINES 190-191 Find the magnet edge that is shared with the first rotor pocket .. GENERATED FROM PYTHON SOURCE LINES 191-197 .. code-block:: Python for j in Magnet_regions: for i in j.entities: MagnetFaceLine = Rotor_Pocket_regions[0].find_entity_from_coordinates(i.start, i.end) if MagnetFaceLine is not None: break .. GENERATED FROM PYTHON SOURCE LINES 198-199 Get properties of the magnet edge that are to be used to define the new rotor pocket geometry .. GENERATED FROM PYTHON SOURCE LINES 199-202 .. code-block:: Python LineLength = MagnetFaceLine.length StartCoordinate = MagnetFaceLine.start .. GENERATED FROM PYTHON SOURCE LINES 203-206 Create the Adaptive Templates geometry -------------------------------------- Remove all existing entities from the first rotor pocket .. GENERATED FROM PYTHON SOURCE LINES 206-208 .. code-block:: Python Rotor_Pocket_regions[0].entities.clear() .. GENERATED FROM PYTHON SOURCE LINES 209-211 Define the x-y points that are to be used to draw the new rotor pocket. The points are defined relative to a vertical magnet edge (parallel to the y axis). .. GENERATED FROM PYTHON SOURCE LINES 211-223 .. code-block:: Python xlist = np.array( [ 0.0, totalprojection * -0.2, totalprojection * -0.5, -1 * totalprojection, totalprojection * -0.5, 0.0, ] ) ylist = np.array([0, 1 - 1 * lowerconcave, -0.5, 0.5, 1 + upperconvex, 1]) * LineLength .. GENERATED FROM PYTHON SOURCE LINES 224-225 Define nodes from points and create curve using bezier .. GENERATED FROM PYTHON SOURCE LINES 225-233 .. code-block:: Python nodes2 = np.asfortranarray( [ xlist, ylist, ] ) curve2 = bezier.Curve.from_nodes(nodes2) .. GENERATED FROM PYTHON SOURCE LINES 234-235 Create set of points for drawing the calculated bezier curve .. GENERATED FROM PYTHON SOURCE LINES 235-239 .. code-block:: Python num_pts = 256 s_vals = np.linspace(0.0, 1.0, num_pts) points2 = curve2.evaluate_multi(s_vals) .. GENERATED FROM PYTHON SOURCE LINES 240-241 Add the points as ``Coordinate`` objects to a list .. GENERATED FROM PYTHON SOURCE LINES 241-246 .. code-block:: Python xylist = [] for i in range(num_pts): c = Coordinate(points2[0, i], points2[1, i]) xylist.append(c) .. GENERATED FROM PYTHON SOURCE LINES 247-248 Create a list of entities from the curve points .. GENERATED FROM PYTHON SOURCE LINES 248-252 .. code-block:: Python linetolerance = 0.01 arctolerance = 0.01 bez_curve_entities = return_entity_list(xylist, linetolerance, arctolerance) .. GENERATED FROM PYTHON SOURCE LINES 253-255 Add the new entities that make up the curve to the first rotor pocket region Counts the number of arcs and lines .. GENERATED FROM PYTHON SOURCE LINES 255-264 .. code-block:: Python arccount = 0 linecount = 0 for ent in bez_curve_entities: Rotor_Pocket_regions[0].add_entity(ent) if isinstance(ent, Arc): arccount = arccount + 1 if isinstance(ent, Line): linecount = linecount + 1 .. GENERATED FROM PYTHON SOURCE LINES 265-266 Translate (move) the rotor pocket region in the x-y plane to the magnet edge .. GENERATED FROM PYTHON SOURCE LINES 266-268 .. code-block:: Python Rotor_Pocket_regions[0].translate(StartCoordinate.x, StartCoordinate.y) .. GENERATED FROM PYTHON SOURCE LINES 269-270 Rotate the rotor pocket region to match the magnet edge .. GENERATED FROM PYTHON SOURCE LINES 270-272 .. code-block:: Python Rotor_Pocket_regions[0].rotate(StartCoordinate, -(90 - MagnetFaceLine.angle)) .. GENERATED FROM PYTHON SOURCE LINES 273-274 Add the magnet edge line to the rotor pocket region .. GENERATED FROM PYTHON SOURCE LINES 274-276 .. code-block:: Python Rotor_Pocket_regions[0].add_entity(MagnetFaceLine) .. GENERATED FROM PYTHON SOURCE LINES 277-278 Check that the rotor pocket region is joined up and set the region in Motor-CAD .. GENERATED FROM PYTHON SOURCE LINES 278-281 .. code-block:: Python if Rotor_Pocket_regions[0].is_closed(): mc.set_region(Rotor_Pocket_regions[0]) .. GENERATED FROM PYTHON SOURCE LINES 282-285 Mirror the first rotor pocket region on the other half of the rotor. Define the mirror line from the origin and use the ``Region.mirror()`` method to create a new region named ``mirroredRegion`` from the rotor pocket region. .. GENERATED FROM PYTHON SOURCE LINES 285-289 .. code-block:: Python mirrorlinex, mirrorliney = rt_to_xy(rotor_radius, pole_angle) mirrorLine = Line(Coordinate(0, 0), Coordinate(mirrorlinex, mirrorliney)) mirroredRegion = Rotor_Pocket_regions[0].mirror(mirrorLine) .. GENERATED FROM PYTHON SOURCE LINES 290-293 Use the ``Region.replace()`` method to replace the entities in the second rotor pocket with those from the new ``mirroredRegion``. The properties of the second rotor pocket (such as name, material, colour) are retained. .. GENERATED FROM PYTHON SOURCE LINES 293-295 .. code-block:: Python Rotor_Pocket_regions[1].replace(mirroredRegion) .. GENERATED FROM PYTHON SOURCE LINES 296-297 Check that the rotor pocket region is joined up and set the region in Motor-CAD .. GENERATED FROM PYTHON SOURCE LINES 297-300 .. code-block:: Python if Rotor_Pocket_regions[1].is_closed(): mc.set_region(Rotor_Pocket_regions[1]) .. GENERATED FROM PYTHON SOURCE LINES 301-303 .. image:: ../../images/Adaptive_Geometry_Bezier_e4a_3.png :width: 300pt .. GENERATED FROM PYTHON SOURCE LINES 305-315 Load in Adaptive Templates script if required --------------------------------------------- When this script is run externally, the script executes the following: * Set **Geometry type** to **Adaptive**. * Load the script into the **Adaptive Templates** tab. * Go to the **Geometry -> Radial** tab to run the Adaptive Templates script and display the new geometry. .. GENERATED FROM PYTHON SOURCE LINES 317-320 .. note:: When running in a Jupyter Notebook, you must provide the path for the Adaptive Templates script (PY file) instead of ``sys.argv[0]`` when using the ``load_adaptive_script()`` method. .. GENERATED FROM PYTHON SOURCE LINES 320-324 .. code-block:: Python if not pymotorcad.is_running_in_internal_scripting(): mc.set_variable("GeometryTemplateType", 1) mc.load_adaptive_script(sys.argv[0]) mc.display_screen("Geometry;Radial") .. rst-class:: sphx-glr-timing **Total running time of the script:** (1 minutes 21.220 seconds) .. _sphx_glr_download_examples_adaptive_library_BezierCurveRotorPockets.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: BezierCurveRotorPockets.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: BezierCurveRotorPockets.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: BezierCurveRotorPockets.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_