Permanent magnet synchronous electric motor
In this tutorial, a 3D permanent magnet synchronous electric motor is considered under magnetostatic conditions using the φ-formulation.
Model definition
Section titled “Model definition”Instead of the whole motor, only a 1/8 slice of the motor is modeled. The 1/8 slice functions as a symmetry cell, which can be set up to simulate the whole motor with symmetry conditions. The symmetry cell has its periodic face aligned with the X-axis.

| Element | Dimensions [m] |
|---|---|
| Stator steel outer radius | |
| Stator steel inner radius | |
| Rotor steel outer radius | |
| Rotor steel inner radius | |
| Permanent magnet outer radius | |
| Air gap thickness |
Material Data
Section titled “Material Data”- Linear steel
| Property | Value |
|---|---|
| Magnetic permeability |
Boundary conditions
Section titled “Boundary conditions”| Name | Type | Value |
|---|---|---|
| left and right Y-planes | periodicity: rotation | antiperiodic |
| rotor-stator interface | continuity | potential equality on both sides |
Output Results
Section titled “Output Results”- Torque [Nm]
Step-by-step guide
Section titled “Step-by-step guide”Here you’ll find a detailed step-by-step tutorial on how to simulate a permanent magnet synchronous electric motor in Quanscient Allsolve.
Step 1 - Build the geometry
Section titled “Step 1 - Build the geometry”-
Start with a new project and name it
PMSM Electric motor. -
Import the STEP file containing the motor slice geometry. File download link: pmsm-electric-motor.step

-
Add a
Translateoperation targetting the rotating region:Name Element type Target Translation [m] Copy translate TranslateoperationVolumes 1-5X: 0No Y: 0Z: 0.02The
Translateoperation is done in this tutorial to separate the rotor and stator for meshing, and to have a duplicate mesh on the rotor-stator interface.
The rotor is moved back into place at simulation time.
Step 2 - Define variables, materials and shared regions
Section titled “Step 2 - Define variables, materials and shared regions”-
Go to the
Commonsidebar. -
Define variables:
Name Description Expression I Current amplitude [A] 300alpha Mechanical angle [deg] 27phase Electrical angle [deg] 0 -
Add the
Airmaterial:Material Target Air permanent magnet domain and all air domains (volumes 6-9, 17-20)
-
Add the
Carbon steel AISI 1020material:Material Target Carbon steel AISI 1020 steel domain (volumes 13-16)
-
Instead of nonlinear permeability, linear permeability is applied to the steel in this tutorial. Edit
Carbon steel AISI 1020material properties:Property Updated value Magnetic permeability 2000 * mu0 -
Define shared regions:
Region name Region type Target rotorVolume all rotating regions with half of the airgap (volumes 16-20)airgapVolume volumes 6, 20

Step 3 - Define the physics and apply boundary conditions
Section titled “Step 3 - Define the physics and apply boundary conditions”-
Go to the
Physicssection. -
Add the
Magnetism φphysics:Physics Target Magnetism φ All volumes except the windings (volumes 6-9, 13-20)
-
Add a
Constraintinteraction to Magnetism φ:Name Interaction type Target Value Constraint Constrainta corner point on the permanent magnet 0This constraint is the gauge condition for the scalar potential φ. It will guarantee the uniqueness of the solution.

-
Add a
Remanenceinteraction to Magnetism φ:Interaction name Interaction type Target Value [X; Y; Z] Remanence RemanencePermanent magnet volume [0.5*x/sqrt(x*x+y*y); 0.5*y/sqrt(x*x+y*y); 0]This introduces a radial magnetization to the motor.

-
Add a
Periodicityinteraction and select target surfaces:Interaction name Interaction type Periodicity target 1 Periodicity target 2 Periodicity PeriodicitySide surfaces parallel to X-axis Side surfaces opposite to target 1 

-
Select remaining options in the
Periodicityinteraction:Interaction name Interaction type Type Rotation center [X; Y; Z] Rotation angle [X; Y; Z] Antiperiodicity Periodicity PeriodicityRotation [0; 0; 0][0; 0; 45]Yes 
-
Add a
Continuityinteraction:Interaction name Interaction type Continuity target 1 Continuity target 2 Continuity ContinuityStator interface surface 23Rotor interface surface 143

-
Add
Lump I/V cutinteractions to introduce current sources on the windings:Interaction name Interaction type Target Actuation mode Current Lump I/V cut Lump I/V cutCounterclockwise loop around left-most winding Current I * sin((phase + 4.0 * alpha - 120.0) * pi/180.0)Lump I/V cut 2 Lump I/V cutCounterclockwise loop around middle winding Current I * sin((phase + 4.0 * alpha - 60.0) * pi/180.0)Lump I/V cut 3 Lump I/V cutCounterclockwise loop around right-most winding Current I * sin((phase + 4.0 * alpha - 0.0) * pi/180.0)


There are 7 interactions in total:

Step 4 - Generate the mesh
Section titled “Step 4 - Generate the mesh”-
Go to the
Simulationssection. -
Create a new mesh.
-
Set mesh quality to
Expert settings. -
Set mesh element max size to
0.001. -
Enable
Curved mesh. -
Add a mesh refinement entity:
Mesh refinement entity type Target Max size Volumeair gap volumes 0.0005
-
Apply settings and generate the mesh.
-
Check the preview:

Step 5 - Apply simulation settings
Section titled “Step 5 - Apply simulation settings”-
Create a new simulation.
-
Set Analysis type to
Steady state. -
Select
Mesh 1as the mesh for your simulation. -
Add a magnetic flux density
Bfield output. As target, select all volumes except the windings.
Step 6 - Modify the script
Section titled “Step 6 - Modify the script”The following modifications need to be done by scripting:
- Move the rotor back to its original position and apply rotation.
- Apply antioperiodicity and rotation for the continuity condition.
- Calculate the torque.
To do these modifications, do the following:
-
Open the script for your simulation.
-
Enable scripting mode.
-
Add these lines to the script right below the initial mesh loading stage:
# Moving the rotor back to it's original position and applying rotationmesh.mesh.shift(reg.rotor, 0.0, 0.0, -0.02)mesh.mesh.rotate(reg.rotor, 0.0, 0.0, expr.alpha)
-
To address the antiperiodicity regarding the rotated position for the continuity condition, add the following arguments on the
continuitycondition()function:qs.continuitycondition(..., [0,0,0], expr.alpha, 45.0, -1.0)
-
To calculate the torque via Arkkio’s method 1 and via Maxwell’s Stress Tensor, add the following lines to the very end of the script:
# Calculating torque:# The torque is scaled (8*5) to the actual z length of the motor 0.05 m and to take into account full 360 degrees of the motor.# 1) Using Arkkio's methodrs = 0.059 # outer radius of airgaprr = 0.058 # inner radius of airgapradius = qs.sqrt( qs.pow(qs.getx(),2) + qs.pow(qs.gety(),2) )ephi = qs.array3x1(-qs.gety()/radius, qs.getx()/radius, 0.0)er = qs.array3x1(qs.getx()/radius, qs.gety()/radius, 0.0)Bphi = df.B*ephiBr = df.B*erdr = (rs-rr)magforcedensity1 = (8*5*radius*Br*Bphi/qs.getmu0()/dr)torque1 = magforcedensity1.allintegrate(reg.airgap,5)# 2) Using Maxwell stress tensorleverarm = qs.array3x1(qs.getx(), qs.gety(), 0.0)T = 1/qs.getmu0() * ( df.B*qs.transpose(df.B) - 0.5*df.B*df.B * qs.eye(3) )magforcedensity2 = qs.on(reg.airgap, T)*qs.normal(reg.airgap)torque2 = 8*5*qs.compz(qs.crossproduct(leverarm, magforcedensity2)).allintegrate(reg.continuity_target_2, 5)qs.setoutputvalue("Mechanical angle", qs.evaluate(expr.alpha)[0])qs.setoutputvalue("Torque (Arkkio)", qs.evaluate(torque1))qs.setoutputvalue("Torque (Maxwell's Stress Tensor)", qs.evaluate(torque2)) -
Save the script.
Step 7 - Running the simulation and checking results
Section titled “Step 7 - Running the simulation and checking results”-
Run Simulation 1.
-
To follow the simulation progress, open the
Logs.
-
Once the simulation has finished, add a
Bfield visualization. -
Add a
Glyphfilter to the visualization:Filter Layer Max sample points Scaling mode Scale factor Glyph B - Cool to Warm 50000data 0.0050.0002 - 1.0 -
Activate the visualization.

-
To see the value of torque [Nm] at the applied mechanical angle [deg], see the
Summary.
References
Section titled “References”Footnotes
Section titled “Footnotes”-
Arkkio’s Method for Torque Computation, https://www.anttilehikoinen.fi/research-work/arkkios-method-torque-computation/ ↩