Axisymmetric¶
Axisymmetric solves the r-z half-plane of a model that is symmetric about an axis, so a rotationally symmetric part such as a coil or a tubular actuator solves as a 2D problem. You author the full 3D model, and the frame sections it for the 2D solve. See Frames for what a frame decides.
import femforge as ff
config = ff.SimulationConfig(
frame=ff.Axisymmetric(axis=ff.Axis.Z),
mesh=ff.MeshConfig(step="models/tubular.step", global_mesh_size=0.5 * ff.U.mm),
domain=ff.DomainConfig(
materials=[ff.materials.Air(), ff.materials.N52()],
tags=[
ff.EntityTag(
selector={ff.TagKey.MAGNETIZATION: "N"},
conditions=[ff.Magnetization(direction=ff.Direction(0, 0, 1))],
),
ff.EntityTag(selector={ff.TagKey.NAME: "mover"}, conditions=[ff.ForceComponent(label="mover")]),
],
),
)
print(config.frame.label, config.solved_physics())
| Property | Value |
|---|---|
kind |
"axisymmetric" |
| Mesh dimension | 2 |
| Solve coordinates | X = radial (>= 0), Y = along the axis, Z = 0 |
| Elmer coordinate system | Axi Symmetric, which integrates per radian |
Fields¶
| Field | Default | Meaning |
|---|---|---|
axis |
ff.Axis.Z |
The axis of symmetry, in the authored frame. |
radial |
None |
The direction from the axis toward the half-plane femforge sections. |
femforge stores radial as its unit part perpendicular to the axis and rejects a radial parallel to the axis. With radial=None, the half-plane faces the world axis least aligned with the symmetry axis, X first: Axis.Z maps the authored X to the radial direction, and Axis.Y leaves the coordinates as authored. An unset radial is left out of the serialized config, so it adds nothing to the run identity.
For an axis that does not pass through the origin, give it an origin:
import femforge as ff
frame = ff.Axisymmetric(
axis=ff.Axis(origin=ff.Vec3(10, 0, 0), direction=ff.Direction(0, 0, 1)),
radial=ff.Direction(0, 1, 0),
)
print(frame.label, frame.plane)
Axisymmetric.plane is the SolvePlane that rule picks: the authored origin of the section and the authored directions of its +X (radial) and +Y (axis). The section and the workbench's expansion both read it.
How femforge sections the model¶
The driver converts the STEP in its first stage, prepare_geometry, through Axisymmetric.prepare_geometry:
- It builds the parametric geometry when the config has one, else it reads the authored STEP.
- import_tagged_step imports the STEP as tagged parts, one per named solid. Every body needs a
key=valuename, and a STEP that holds only faces is rejected: author the 3D model and let the frame section it. - axisymmetric_cross_section places the parts in the solve frame through
plane, then intersects each solid with the X >= 0 half of the Z = 0 plane. Each face keeps its solid's tags and color. - It writes the section to
geometry.stepin the run directory, and the mesher meshes it in 2D.
The section raises when a solid does not reach the half-plane, and when a section reaches X < 0, which Elmer's axisymmetric solve would reject silently. The mesher names each body's edge on the symmetry axis <BODY>__AXIS, and magnetostatics pins the potential to zero there.
cross_section_3D is the 3D counterpart for pictures: it cuts away a quarter wedge and keeps the tags.
Physics¶
| Selected physics | Solves as |
|---|---|
MAGNETOSTATICS |
MAGNETOSTATICS_2D |
THERMAL |
THERMAL |
| every other Physics member | raises: solve it with Solid() |
The solved stack runs in the Axi Symmetric coordinate system. Authored physics.overrides must integrate per radian too, so customize the physics after you set the frame.
Conditions¶
| Condition | Rule |
|---|---|
| CurrentDensity | The axisymmetric coil drive: a signed azimuthal current density over a winding window. |
| Magnetization | The direction must be parallel to the symmetry axis, either sign; it is emitted as its signed axial component. |
| ForceComponent | Torque is rejected: drop calculate_magnetic_torque, torque_origin and torque_axis. |
Results¶
Results come back in the solve frame: a vector's Y component is the axial one and its X component the radial one. Elmer integrates per radian in its 2D symmetric coordinate systems, and femforge converts only the typed force and torque fields to full-revolution totals:
| Quantity | Value |
|---|---|
Result.force, Result.torque, Result.component_forces, Result.component_torques |
Full revolution: the axial component times 2π, the radial component set to zero (its net is zero by symmetry). |
Result.raw |
Per radian, exactly as Elmer printed it. |
magnetic_field_energy, eddy_current_power, force_triples and the other readers of raw |
Per radian. |
| FieldQuery.integrate | The plane-slice integral ∫ value dA. |
| FieldQuery.integrate_revolved | The full-revolution volume integral ∫ value 2πr dA, with r the cell center's X. |
Result.axial_force takes an axis in the authored frame:
axis |
Returns |
|---|---|
None |
The force along the symmetry axis. |
| parallel to the symmetry axis | The axial force times the cosine to axis. |
| any other | Raises. |
The workbench field viewer shows the section as solved, mirrors it into the full plane, or revolves it around the axis back into the authored frame.
Limits¶
- Only magnetostatics and heat conduction have an axisymmetric form.
- An axisymmetric run computes no torque.
- femforge sections one half-plane and does not check that the model is symmetric.
- Every solid must cross the half-plane; a part off to the side of the section raises.