diff --git a/examples/basics/emag_basics.py b/examples/basics/emag_basics.py index 51629c994..e0a76632e 100644 --- a/examples/basics/emag_basics.py +++ b/examples/basics/emag_basics.py @@ -25,212 +25,240 @@ Motor-CAD E-magnetic example script =================================== -This example provides a Motor-CAD E-magnetic script. This script -creates a partial custom winding pattern to change -parameter values, run the analysis, and plot results. To create -a full winding pattern, parameters must be specified -for all coils. +This example provides a Motor-CAD E-magnetic script to run calculations and plot results. """ - # %% +# This script will change model parameter values (geometry, winding pattern and materials), +# run magnetic calculations, extract and plot results. +# +# .. note:: +# This script creates a partial custom winding pattern. To create a full winding pattern, +# parameters must be specified for all coils. +# # Set up example # -------------- -# Setting up this example consists of performing imports, specifying the -# working directory, launching Motor-CAD, and disabling all popup -# messages from Motor-CAD. +# To set up the example, perform imports, specify the working directory, launch Motor-CAD, and +# disable all popup messages from Motor-CAD. # # Perform required imports # ~~~~~~~~~~~~~~~~~~~~~~~~ +# Import ``pymotorcad`` to access Motor-CAD. Import ``pyplot`` from ``matplotlib`` to display +# graphics. Import ``os``, ``shutil`` and ``tempfile`` to open and save a temporary MOT +# file if none is open. - +# sphinx_gallery_thumbnail_number = -2 import os +import shutil +import tempfile import matplotlib.pyplot as plt import ansys.motorcad.core as pymotorcad -if "QT_API" in os.environ: - os.environ["QT_API"] = "pyqt" - # %% # Specify working directory # ~~~~~~~~~~~~~~~~~~~~~~~~~ - -working_folder = os.getcwd() - -if os.path.isdir(working_folder) is False: - print("Working folder does not exist. Choose a folder that exists and try again.") - print(working_folder) - exit() +# Save the file to a temporary folder +working_folder = os.path.join(tempfile.gettempdir(), "basic_examples") +try: + shutil.rmtree(working_folder) +except: + pass +os.mkdir(working_folder) +mot_name = "EMagnetic" # %% # Launch Motor-CAD # ~~~~~~~~~~~~~~~~ - +# Connect to Motor-CAD and open a new Motor-CAD instance. 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. print("Starting initialization.") -mcad = pymotorcad.MotorCAD() +mc = pymotorcad.MotorCAD() # %% # Disable popup messages # ~~~~~~~~~~~~~~~~~~~~~~ - -mcad.set_variable("MessageDisplayState", 2) -print("Initialization completed.") -print("Running simulation.") - -# %% -# Create analysis -# --------------- -# Creating the analysis consists of showing the magnetic context, displaying -# the **Scripting** tab, setting the geometry and parameters, and saving -# the file. +# Disable all popup messages from Motor-CAD by setting the ``MessageDisplayState`` parameter to 2. # -# Show the magnetic context. -mcad.show_magnetic_context() +# .. note:: +# This will also disable crucial popups, for example prompts to save data or overwrite data, or +# dialogs used to reconcile differences in material data between the database and MOT file. In +# each case the default action will be taken. This setting will persist until Motor-CAD is +# closed. +mc.set_variable("MessageDisplayState", 2) # %% -# Display the **Scripting** tab. -mcad.display_screen("Scripting") +# Set Motor-CAD to EMag +# ~~~~~~~~~~~~~~~~~~~~~ +# Show the E-Magnetic context in Motor-CAD and ensure that the BPM +# Motor Type is set. +mc.show_magnetic_context() +mc.set_variable("Motor_Type", 0) # %% -# Set the geometry. -mcad.set_variable("Slot_Number", 24) -mcad.set_variable("Tooth_Width", 6) -mcad.set_variable("Magnet_Thickness", 4.5) +# Set up analysis +# --------------- +# Setting up the analysis consists of setting the geometry, winding and material parameters, setting +# the calculation options and operating point, and saving the file. +# +# Geometry setup +# ~~~~~~~~~~~~~~ +# Display the **Scripting** tab and set the ``Slot_Number``, ``Tooth_Width`` and +# ``Magnet_Thickness`` geometry parameters. +# +# .. note:: +# To set parameter values via automation with the GUI visible, a different tab must be displayed. +# The **Scripting** tab is chosen because no parameters on this tab will be changed in this +# script. It is best practice to display the **Scripting** tab when changing input parameters by +# automation. This is required only if the GUI is shown. +mc.display_screen("Scripting") +mc.set_variable("Slot_Number", 24) +mc.set_variable("Tooth_Width", 6) +mc.set_variable("Magnet_Thickness", 4.5) # %% -# Set parameters for creating the custom winding pattern. +# Winding setup +# ~~~~~~~~~~~~~~ +# Instead of using the automatic winding pattern, set parameters for creating a partial custom +# winding pattern. This example sets up an unevenly distributed winding pattern. # -# The following code creates only a partial winding pattern. +# The script: # -# Set the winding type to custom: -# :code:`mcad.set_variable('MagWindingType', 1)` +# * Set the winding type to *Custom*. # -# Set the path type to upper and lower: -# :code:`mcad.set_variable('MagPathType', 1)` +# * Set the path type to *Upper/Lower*. # -# Set the number of phases: -# :code:`mcad.set_variable('MagPhases', 3)` +# * Set the number of phases to 3. # -# Set the number of parallel paths: -# :code:`mcad.set_variable('ParallelPaths', 1)` +# * Set the number of parallel paths to 1. # -# Set the number of winding layers: -# :code:`mcad.set_variable('WindingLayers', 2)` +# * Set the number of winding layers to 2. +# +# * Define parameters for coil 3 using the ``set_winding_coil()`` method. Set positions to a, b, c +# etc. when using Upper/Lower paths (when Left/Right paths are selected, L or R should be used +# instead). Define the third coil to have 60 turns in the second phase. +mc.set_variable("MagneticWindingType", 2) +mc.set_variable("MagPathType", 1) +mc.set_variable("MagPhases", 3) +mc.set_variable("ParallelPaths", 1) +mc.set_variable("WindingLayers", 2) +mc.set_winding_coil(2, 1, 3, 4, "b", 18, "a", 60) + +# %% +# the changes to the winding pattern are shown below # -# Define a coil's parameters: -# :code:`set_winding_coil(phase, -# path, coil, go_slot, go_position, return_slot, return_position, turns)` +# .. image:: ../../images/basics_emag_2.png # %% -# Set the stator/rotor lamination materials. -mcad.set_component_material("Stator Lam (Back Iron)", "M250-35A") -mcad.set_component_material("Rotor Lam (Back Iron)", "M250-35A") +# Materials setup +# ~~~~~~~~~~~~~~~ +# Set the stator and rotor lamination materials. Component names are displayed in the +# *Materials* tab in Motor-CAD. Materials and their properties are defined in the Motor-CAD +# *Material database*. +mc.set_component_material("Stator Lam (Back Iron)", "M250-35A") +mc.set_component_material("Rotor Lam (Back Iron)", "M250-35A") # %% -# Set the torque calculation options. -points_per_cycle = 30 -number_cycles = 1 -mcad.set_variable("TorquePointsPerCycle", points_per_cycle) -mcad.set_variable("TorqueNumberCycles", number_cycles) +# Calculation options +# ~~~~~~~~~~~~~~~~~~~ +# Set the torque calculation options for a transient torque calculation with 30 points in 1 +# electrical cycle. +mc.set_variable("TorquePointsPerCycle", 30) +mc.set_variable("TorqueNumberCycles", 1) # %% # Disable all performance tests except the ones for transient torque. -mcad.set_variable("BackEMFCalculation", False) -mcad.set_variable("CoggingTorqueCalculation", False) -mcad.set_variable("ElectromagneticForcesCalc_OC", False) -mcad.set_variable("TorqueSpeedCalculation", False) -mcad.set_variable("DemagnetizationCalc", False) -mcad.set_variable("ElectromagneticForcesCalc_Load", False) -mcad.set_variable("InductanceCalc", False) -mcad.set_variable("BPMShortCircuitCalc", False) +mc.set_variable("BackEMFCalculation", False) +mc.set_variable("CoggingTorqueCalculation", False) +mc.set_variable("ElectromagneticForcesCalc_OC", False) +mc.set_variable("TorqueSpeedCalculation", False) +mc.set_variable("DemagnetizationCalc", False) +mc.set_variable("ElectromagneticForcesCalc_Load", False) +mc.set_variable("InductanceCalc", False) +mc.set_variable("BPMShortCircuitCalc", False) # %% -# Enable transient torque. -mcad.set_variable("TorqueCalculation", True) +# Enable transient torque calculation. +mc.set_variable("TorqueCalculation", True) # %% -# Set the operating point. -mcad.set_variable("Shaft_Speed_[RPM]", 1000) -mcad.set_variable("CurrentDefinition", 0) -mcad.set_variable("PeakCurrent", 3) -mcad.set_variable("DCBusVoltage", 350) -mcad.set_variable("PhaseAdvance", 45) +# Operating point +# ~~~~~~~~~~~~~~~ +# Set the operating point of the machine, defined by the speed, current and phase advance. Ensure +# that the current definition is set to *Peak* (index 0 of the radio group option). +mc.set_variable("Shaft_Speed_[RPM]", 1000) +mc.set_variable("CurrentDefinition", 0) +mc.set_variable("PeakCurrent", 3) +mc.set_variable("DCBusVoltage", 350) +mc.set_variable("PhaseAdvance", 45) # %% -# Save the file. -filename = os.path.join(working_folder, "../ActiveX_Scripting_EMagnetic.mot") -mcad.save_to_file(filename) +# Save the file +# ~~~~~~~~~~~~~ +# Save the file to the temporary folder and display a message that the initialisation in complete. +mc.save_to_file(working_folder + "/" + mot_name + ".mot") +print("Initialisation completed.") # %% # Run simulation # -------------- -# Run the simulation. -mcad.do_magnetic_calculation() +# Run the electromagnetic calculation in Motor-CAD (solve the e-magnetic model). +print("Running simulation.") +mc.do_magnetic_calculation() # %% # Export results to CSV file # -------------------------- -# Export results to a CSV file. -exportFile = os.path.join(working_folder, "../Export_EMag_Results.csv") +# Export results to a CSV file. Results will be saved as *Export_EMag_Results.csv* in the temporary +# working directory. A try and except block are used to raise an error in the case of the export +# failing. try: - mcad.export_results("EMagnetic", exportFile) + mc.export_results("EMagnetic", working_folder + "/Export_EMag_Results.csv") print("Results successfully exported.") -except pymotorcad.MotorCADError: - print("Results failed to export.") +except pymotorcad.MotorCADError as e: + print("Results failed to export due to Motor-CAD Error: " + str(e)) # %% -# Get and analyze results +# Get and analyse results # ----------------------- -# Get torque and voltage data. -shaft_torque = mcad.get_variable("ShaftTorque") -line_voltage = mcad.get_variable("PeakLineLineVoltage") +# Retrieve the torque and voltage output data values. +shaft_torque = mc.get_variable("ShaftTorque") +line_voltage = mc.get_variable("PeakLineLineVoltage") +print( + f"Shaft Torque: {shaft_torque:.2f} Nm, Line-Line Terminal Voltage (peak): {line_voltage:.2f} V" +) # %% -# Graph the torque data. -num_torque_points = points_per_cycle * number_cycles -rotor_position = [] -torque_vw = [] - -for n in range(num_torque_points): - (x, y) = mcad.get_magnetic_graph_point("TorqueVW", n) - rotor_position.append(x) - torque_vw.append(y) +# Retrieve the *Torque (VW)* graph data. The data type for this series is *E-Magnetics*, so use the +# ``get_magnetic_graph()`` method. +# +# .. note:: +# When retrieving graph data points, use the *Graph Viewer* under *Help* in the Motor-CAD +# interface to find the series names and data types. +rotor_position, torque_vw = mc.get_magnetic_graph("TorqueVW") # %% -# Graph the airgap flux density data. -loop = 0 -success = 0 -mech_angle = [] -airgap_flux_density = [] +# Retrieve the airgap flux density graph data. This data can be found in the *Graph Viewer* in +# Motor-CAD. The data type for this series is *FEA Path*, so use the ``get_fea_graph()`` method. +mech_angle, airgap_flux_density = mc.get_fea_graph("B Gap (on load)", 1, 0) # %% -# Keep looking until you cannot find the point. -while success == 0: - try: - (x, y) = mcad.get_fea_graph_point("B Gap (on load)", 1, loop, 0) - mech_angle.append(x) - airgap_flux_density.append(y) - loop = loop + 1 - except pymotorcad.MotorCADError: - success = 1 +# Only the most recently displayed harmonic graphs are available in Motor-CAD via the +# *Graph Viewer*. To retrieve harmonic data by using Motor-CAD automation, first display the +# relevant *Graphs -> Harmonics* tab. Use the ``initialise_tab_names()`` method to initialise the +# available tabs in the Motor-CAD user interface. When the tabs have been initialised, the +# ``display_screen()`` method can be used until either the Motor-CAD context is changed, or the +# instance is closed. +# +# Open the *Graphs -> Harmonics -> Torque* tab to make the torque harmonic data available. +mc.initialise_tab_names() +mc.display_screen("Graphs;Harmonics;Torque") # %% -# Graph the harmonic data. -mcad.initialise_tab_names() -mcad.display_screen("Graphs;Harmonics;Torque") - -num_harmonic_points = (points_per_cycle * number_cycles) + 1 -data_point = [] -torque = [] -for n in range(num_harmonic_points): - try: - (x, y) = mcad.get_magnetic_graph_point("HarmonicDataCycle", n) - data_point.append(x) - torque.append(y) - except pymotorcad.MotorCADError: - print("Results failed to export.") - +# Retrieve the torque harmonic graph data. The data type for this series is *E-Magnetics*, so use +# the ``get_fea_graph()`` method. +harmonic_order, harmonic_amplitude = mc.get_magnetic_graph("HarmonicAmplitude") print("Simulation completed.") @@ -238,7 +266,8 @@ # %% # Plot results # ------------ -# Plot results from the simulation. +# Use``pyplot`` from ``matplotlib`` (imported as ``plt``) to plot graphs of the simulation results. +# Plot the Airgap Flux Density and the Torque (VW) results as subplots in the same figure. plt.subplot(211) plt.plot(mech_angle, airgap_flux_density) plt.xlabel("Mech Angle") @@ -247,19 +276,19 @@ plt.plot(rotor_position, torque_vw) plt.xlabel("Rotor Position") plt.ylabel("TorqueVW") -plt.figure(2) -plt.plot(data_point, torque) -plt.xlabel("DataPoint") -plt.ylabel("Torque (Nm)") plt.show() # %% -# Exit Motor-CAD -# -------------- -# Exit Motor-CAD. -mcad.quit() +# Plot the Torque harmonic results as a bar chart. +plt.figure(2) +plt.bar(harmonic_order, harmonic_amplitude) +plt.xlabel("Harmonic order (Electrical)") +plt.ylabel("Harmonic amplitude (Nm)") +plt.show() # %% -# If you want to continue working with this instance of Motor-CAD, rather -# than using the preceding command, use this command: -# :code:`mcad.set_variable('MessageDisplayState', 0)` +# If you want to continue working with this instance of Motor-CAD, use the +# ``MotorCAD(keep_instance_open=True)`` option when you launch Motor-CAD. If Motor-CAD is kept open, +# it is useful to restore the popup messages that were disabled earlier, using the +# ``set_variable()`` method (). +mc.set_variable("MessageDisplayState", 0) diff --git a/examples/basics/thermal_basics.py b/examples/basics/thermal_basics.py index 54908a6bb..a4b0af971 100644 --- a/examples/basics/thermal_basics.py +++ b/examples/basics/thermal_basics.py @@ -31,123 +31,173 @@ # %% # Set up example # -------------- -# Setting up this example consists of performing imports, launching -# Motor-CAD, disabling all popup messages from Motor-CAD, and -# opening the file for the thermal analysis. - +# To set up the example, perform imports, specify the working directory, launch Motor-CAD, and +# disable all popup messages from Motor-CAD. The e8 IPM motor template is loaded for the thermal +# analysis. +# # Perform required imports # ~~~~~~~~~~~~~~~~~~~~~~~~ -# Import the required packages. +# Import ``pymotorcad`` to access Motor-CAD. Import ``pyplot`` from ``matplotlib`` to display +# graphics. Import ``os``, ``shutil`` and ``tempfile`` to open and save a temporary MOT +# file if none is open. + +# sphinx_gallery_thumbnail_number = -2 import os +import shutil +import tempfile import matplotlib.pyplot as plt import ansys.motorcad.core as pymotorcad -if "QT_API" in os.environ: - os.environ["QT_API"] = "pyqt" +# %% +# Specify working directory +# ~~~~~~~~~~~~~~~~~~~~~~~~~ +# Save the file to a temporary folder +working_folder = os.path.join(tempfile.gettempdir(), "basic_examples") +try: + shutil.rmtree(working_folder) +except: + pass +os.mkdir(working_folder) +mot_name = "e8_Thermal" # %% # Launch Motor-CAD # ~~~~~~~~~~~~~~~~ -# Initialize ActiveX automation and launch Motor-CAD. -print("Starting initialization.") -mcad = pymotorcad.MotorCAD() +# Connect to Motor-CAD and open a new Motor-CAD instance. 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. +print("Starting initialisation.") +mc = pymotorcad.MotorCAD(keep_instance_open=True) # %% # Disable popup messages # ~~~~~~~~~~~~~~~~~~~~~~ -# Disable all popup messages from Motor-CAD. -mcad.set_variable("MessageDisplayState", 2) +# Disable all popup messages from Motor-CAD by setting the ``MessageDisplayState`` parameter to 2. +# +# .. note:: +# This will also disable crucial popups, for example prompts to save data or overwrite data, or +# dialogs used to reconcile differences in material data between the database and MOT file. In +# each case the default action will be taken. This setting will persist until Motor-CAD is +# closed. +mc.set_variable("MessageDisplayState", 2) # %% -# Open relevant file +# Open template file # ~~~~~~~~~~~~~~~~~~ -# Specify the working directory and open the relevant file for the -# thermal analysis. -working_folder = os.getcwd() -mcad.load_template("e8") -mcad_name = "e8_mobility" -mcad.save_to_file(os.path.join(working_folder, mcad_name)) - -mcad.load_from_file(os.path.join(working_folder, mcad_name + ".mot")) - -print("Initialization completed.") - -# %% -# Create analysis -# --------------- -# Creating the analysis consists of showing the thermal context, displaying -# the **Scripting** tab, setting parameters, and saving the file. - -# Show thermal context -# ----------------------- -mcad.show_thermal_context() +# This example is based on the e8 IPM motor template. Open the template and save the file to the +# temporary folder. +mc.load_template("e8") +mc.save_to_file(working_folder + "/" + mot_name + ".mot") # %% -# Display the **Scripting** tab. -mcad.display_screen("Scripting") +# Set Motor-CAD to Thermal +# ~~~~~~~~~~~~~~~~~~~~~~~~ +# Show the Thermal context in Motor-CAD and ensure that the BPM +# Motor Type is set. +mc.show_thermal_context() +mc.set_variable("Motor_Type", 0) +print("Initialisation completed.") # %% -# Change the housing diameter. -mcad.set_variable("Housing_Dia", 250) +# Set up analysis +# --------------- +# Setting up the analysis consists of setting the geometry and thermal input data parameters and +# saving the file. +# +# Geometry setup +# ~~~~~~~~~~~~~~ +# Display the **Scripting** tab and set the housing outer diameter to 250 mm. +# +# .. note:: +# To set parameter values via automation with the GUI visible, a different tab must be displayed. +# The **Scripting** tab is chosen because no parameters on this tab will be changed in this +# script. It is best practice to display the **Scripting** tab when changing input parameters by +# automation. This is required only if the GUI is shown. +mc.display_screen("Scripting") +mc.set_variable("Housing_Dia", 250) # %% -# Set the flow rate of the WJ fluid volume. -mcad.set_variable("WJ_Fluid_Volume_Flow_Rate", 0.002) +# Thermal input data setup +# ~~~~~~~~~~~~~~~~~~~~~~~~ +# Set the housing water jacket cooling parameters: +# +# * Fluid volume flow rate (in units of m\ :sup:`3`/s). +# +# * Fluid inlet temperature (in units of °C). +# +# * Fluid used by the HWJ (from material database). +mc.set_variable("WJ_Fluid_Volume_Flow_Rate", 0.002) +mc.set_variable("WJ_Fluid_Inlet_Temperature", 25) +mc.set_fluid("HousingWJFluid", "Dynalene HF-LO") # %% -# Set the temperature of the WJ fluid inlet. -mcad.set_variable("WJ_Fluid_Inlet_Temperature", 25) +# Disable the option for *Active Cooling Only*, so that the HWJ channel also cools the front and +# rear housing segments. +mc.set_variable("Water_Jacket_Active_Cooling_Only", 0) # %% -# Change the cooling fluid. -mcad.set_fluid("HousingWJFluid", "Dynalene HF-LO") +# Enable the *Input h* option to allow user input of the heat transfer coefficients for HWJ cooling +# of the rear and active segments of the housing. +mc.set_variable("Calc/Input_h[WJ]_Rear_Housing", 1) +mc.set_array_variable("HousingWJ_CalcInputH_A", 0, 1) # %% -# Set the heat transfer correlation. -mcad.set_variable("Calc/Input_h[WJ]_Rear_Housing", 1) -mcad.set_array_variable("HousingWJ_CalcInputH_A", 0, 1) - -wj_fluid_k = mcad.get_variable("WJ_Fluid_Thermal_Conductivity") -wj_fluid_rho = mcad.get_variable("WJ_Fluid_Density") -wj_fluid_mu = mcad.get_variable("WJ_Fluid_Dynamic_Viscosity") -wj_fluid_u_a = mcad.get_array_variable("HousingWJ_Velocity_A", 0) -wj_fluid_u_r = mcad.get_variable("WJ_Channel_Fluid_Velocity_[Rear]") +# Get fluid properties (thermal conductivity, density and dynamic viscosity) and the fluid +# velocities for the rear and active segments of the housing. Calculate new heat transfer +# coefficients for the rear and active segments of the housing. Run a steady state thermal +# calculation to ensure that the fluid properties and velocities are correctly calculated based on +# the model changes made earlier. +# +# .. note:: +# Some Motor-CAD output parameters are not automatically updated when an input parameter is set. +# Outputs will be updated when a steady state thermal calculation runs. Alternatively, the +# relevant tab (for example, *Input Data -> Housing Water Jacket -> Heat Transfer*) can be +# displayed - however this may not be suitable when running Motor-CAD without the GUI. +mc.do_steady_state_analysis() +wj_fluid_k = mc.get_variable("WJ_Fluid_Thermal_Conductivity") +wj_fluid_rho = mc.get_variable("WJ_Fluid_Density") +wj_fluid_mu = mc.get_variable("WJ_Fluid_Dynamic_Viscosity") +wj_fluid_u_r = mc.get_variable("WJ_Channel_Fluid_Velocity_[Rear]") +wj_fluid_u_a = mc.get_array_variable("HousingWJ_Velocity_A", 0) -h_A = 0.005 * wj_fluid_k * wj_fluid_rho * wj_fluid_u_a / wj_fluid_mu h_R = 0.005 * wj_fluid_k * wj_fluid_rho * wj_fluid_u_r / wj_fluid_mu +h_A = 0.005 * wj_fluid_k * wj_fluid_rho * wj_fluid_u_a / wj_fluid_mu print("h_A = ", h_A) print("h_R = ", h_R) -mcad.set_array_variable("HousingWJ_InputH_A", 0, h_A) -mcad.set_variable("Input_Value_h[WJ]_Rear_Housing", h_R) +# %% +# Set the calculated heat transfer coefficients for HWJ cooling of the rear and active segments of +# the housing. +mc.set_array_variable("HousingWJ_InputH_A", 0, h_A) +mc.set_variable("Input_Value_h[WJ]_Rear_Housing", h_R) # %% # Save the file. -mcad.save_to_file(os.path.join(working_folder, "../MotorCAD_Thermal_Python.mot")) +mc.save_to_file(working_folder + "/" + mot_name + ".mot") # %% # Calculate steady state # ---------------------- # Calculate the steady state. try: - mcad.do_steady_state_analysis() + mc.do_steady_state_analysis() print("Thermal calculation successfully completed.") except pymotorcad.MotorCADError: print("Thermal calculation failed.") # %% # Retrieve the magnet temperature. -node_temperature = mcad.get_node_temperature(13) +node_temperature = mc.get_node_temperature(13) print("Node Temp = ", node_temperature) # %% # Retrieve the minimum, maximum, and average winding temperatures. -winding_temperature_min = mcad.get_variable("T_[Winding_Min]") -winding_temperature_max = mcad.get_variable("T_[Winding_Max]") -winding_temperature_average = mcad.get_variable("T_[Winding_Average]") +winding_temperature_min = mc.get_variable("T_[Winding_Min]") +winding_temperature_max = mc.get_variable("T_[Winding_Max]") +winding_temperature_average = mc.get_variable("T_[Winding_Average]") print("Min = ", winding_temperature_min) print("Max = ", winding_temperature_max) print("Average = ", winding_temperature_average) @@ -156,11 +206,11 @@ # Run simulation # -------------- # Run the transient simulation. -mcad.set_variable("Transient_Calculation_Type", 0) -mcad.set_variable("Transient_Time_Period", 60) +mc.set_variable("Transient_Calculation_Type", 0) +mc.set_variable("Transient_Time_Period", 60) try: - mcad.do_transient_analysis() + mc.do_transient_analysis() except pymotorcad.MotorCADError: print("Thermal calculation failed.") @@ -172,7 +222,7 @@ for timeStep in range(num_time_steps): try: - (x, y) = mcad.get_temperature_graph_point("Winding (Avg)", timeStep) + (x, y) = mc.get_temperature_graph_point("Winding (Avg)", timeStep) time.append(x) winding_temp_average_transient.append(y) except pymotorcad.MotorCADError: @@ -192,4 +242,4 @@ # Exit Motor-CAD # -------------- # Exit Motor-CAD. -mcad.quit() +mc.quit() diff --git a/src/ansys/motorcad/core/methods/rpc_methods_graphs.py b/src/ansys/motorcad/core/methods/rpc_methods_graphs.py index c84149a86..ba00dc535 100644 --- a/src/ansys/motorcad/core/methods/rpc_methods_graphs.py +++ b/src/ansys/motorcad/core/methods/rpc_methods_graphs.py @@ -54,7 +54,14 @@ def _get_graph(self, graphing_func, *args): try: while True: try: - x, y = graphing_func(*args, loop) + # fea and magnetic 3D graph point functions require additional arguments + if len(args) > 1: + ( + x, + y, + ) = graphing_func(args[0], args[1], loop, args[2]) + else: + x, y = graphing_func(*args, loop) y_points.append(y) x_points.append(x) @@ -168,12 +175,12 @@ def get_fea_graph_point(self, graph_id, slice_number, point_number, time_step_nu graph_id : str, int Name (preferred) or ID of the graph. In Motor-CAD, you can select **Help -> Graph Viewer** to see the graph name. - slice_number - + slice_number : int + Slice number to get x and y coordinate values from. point_number : int Point number to get x and y coordinate values from. - time_step_number - + time_step_number : int + Time step number to get x and y coordinate values from. Returns ------- xValue : float @@ -185,6 +192,50 @@ def get_fea_graph_point(self, graph_id, slice_number, point_number, time_step_nu params = [{"variant": graph_id}, slice_number, point_number, time_step_number] return self.connection.send_and_receive(method, params) + def get_fea_graph(self, graph_name, slice_number, time_step_number): + """Get graph points from a Motor-CAD FEA graph. + + Parameters + ---------- + graph_name : str, int + Name (preferred) or ID of the graph. In Motor-CAD, you can + select **Help -> Graph Viewer** to see the graph name. + slice_number : int + Slice number to get x and y coordinate values from. + time_step_number : int + Time step number to get x and y coordinate values from. + Returns + ------- + x_values : list + Value of x coordinates from graph + y_values : list + Value of y coordinates from graph + """ + return self._get_graph(self.get_fea_graph_point, graph_name, slice_number, time_step_number) + + def get_magnetic_3d_graph(self, graph_name, slice_number, time_step_number): + """Get graph points from a Motor-CAD magnetic 3D graph. + + Parameters + ---------- + graph_name : str, int + Name (preferred) or ID of the graph. In Motor-CAD, you can + select **Help -> Graph Viewer** to see the graph name. + slice_number : int + Slice number to get x and y coordinate values from. + time_step_number : int + Time step number to get x and y coordinate values from. + Returns + ------- + x_values : list + Value of x coordinates from graph + y_values : list + Value of y coordinates from graph + """ + return self._get_graph( + self.get_magnetic_3d_graph_point, graph_name, slice_number, time_step_number + ) + def get_magnetic_graph(self, graph_name): """Get graph points from a Motor-CAD Magnetic graph.