Download this example
Download this example as a Jupyter Notebook or as a Python script.
Bath plate analysis#
This example uses PyAEDT to set up the TEAM 3 bath plate problem and solve it using the Maxwell 3D eddy current solver.
For more information on this problem, see this paper.
Keywords: Maxwell 3D, TEAM 3 bath plate
Prerequisites#
Perform imports#
[1]:
import os
import tempfile
import time
import ansys.aedt.core
Define constants#
Constants help ensure consistency and avoid repetition throughout the example.
[2]:
AEDT_VERSION = "2025.2"
NUM_CORES = 4
NG_MODE = False # Open AEDT UI when it is launched.
Create temporary directory#
Create a temporary working directory. The name of the working folder is stored in temp_folder.name
.
Note: The final cell in the notebook cleans up the temporary folder. If you want to retrieve the AEDT project and data, do so before executing the final cell in the notebook.
[3]:
temp_folder = tempfile.TemporaryDirectory(suffix=".ansys")
Launch Maxwell 3D#
Create an instance of the Maxwell3d
class named m3d
by providing the project and design names, the solver, and the version.
[4]:
m3d = ansys.aedt.core.Maxwell3d(
project=os.path.join(temp_folder.name, "COMPUMAG.aedt"),
design="TEAM_3_Bath_Plate",
solution_type="EddyCurrent",
version=AEDT_VERSION,
non_graphical=NG_MODE,
new_desktop=True,
)
uom = m3d.modeler.model_units = "mm"
PyAEDT INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)].
PyAEDT INFO: PyAEDT version 0.22.dev0.
PyAEDT INFO: Initializing new Desktop session.
PyAEDT INFO: Log on console is enabled.
PyAEDT INFO: Log on file C:\Users\ansys\AppData\Local\Temp\pyaedt_ansys_53dbc326-e467-465b-a7c3-61caf5fa4769.log is enabled.
PyAEDT INFO: Log on AEDT is disabled.
PyAEDT INFO: Debug logger is disabled. PyAEDT methods will not be logged.
PyAEDT INFO: Launching PyAEDT with gRPC plugin.
PyAEDT INFO: New AEDT session is starting on gRPC port 65145.
PyAEDT INFO: Electronics Desktop started on gRPC port: 65145 after 10.708282470703125 seconds.
PyAEDT INFO: AEDT installation Path C:\Program Files\ANSYS Inc\v252\AnsysEM
PyAEDT INFO: Ansoft.ElectronicsDesktop.2025.2 version started with process ID 6560.
PyAEDT INFO: Project COMPUMAG has been created.
PyAEDT INFO: Added design 'TEAM_3_Bath_Plate' of type Maxwell 3D.
PyAEDT INFO: Aedt Objects correctly read
PyAEDT INFO: Modeler class has been initialized! Elapsed time: 0m 1sec
Add variable#
Add a design variable named Coil_Position
to use later to adjust the position of the coil.
[5]:
Coil_Position = -20
m3d["Coil_Position"] = str(Coil_Position) + m3d.modeler.model_units
Add material#
Add a material named team3_aluminium
for the ladder plate.
[6]:
mat = m3d.materials.add_material(name="team3_aluminium")
mat.conductivity = 32780000
PyAEDT INFO: Materials class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: Adding new material to the Project Library: team3_aluminium
PyAEDT INFO: Material has been added in Desktop.
Draw background region#
Draw a background region that uses the default properties for an air region.
[7]:
m3d.modeler.create_air_region(
x_pos=100, y_pos=100, z_pos=100, x_neg=100, y_neg=100, z_neg=100
)
[7]:
<ansys.aedt.core.modeler.cad.object_3d.Object3d at 0x25896fc60e0>
Draw ladder plate and assign material#
Draw a ladder plate and assign it the newly created material team3_aluminium
.
[8]:
m3d.modeler.create_box(
origin=[-30, -55, 0],
sizes=[60, 110, -6.35],
name="LadderPlate",
material="team3_aluminium",
)
m3d.modeler.create_box(origin=[-20, -35, 0], sizes=[40, 30, -6.35], name="CutoutTool1")
m3d.modeler.create_box(origin=[-20, 5, 0], sizes=[40, 30, -6.35], name="CutoutTool2")
m3d.modeler.subtract(
blank_list="LadderPlate",
tool_list=["CutoutTool1", "CutoutTool2"],
keep_originals=False,
)
PyAEDT INFO: Parsing design objects. This operation can take time
PyAEDT INFO: Refreshing bodies from Object Info
PyAEDT INFO: Bodies Info Refreshed Elapsed time: 0m 0sec
PyAEDT INFO: 3D Modeler objects parsed. Elapsed time: 0m 0sec
[8]:
True
Add mesh refinement to ladder plate#
Note: You can uncomment the following code.
m3d.mesh.assign_length_mesh( assignment=”LadderPlate”, maximum_length=3, maximum_elements=None, name=”Ladder_Mesh”, )
Draw search coil and assign excitation#
Draw a search coil and assign it a stranded
current excitation. The stranded type forces the current density to be constant in the coil.
[9]:
m3d.modeler.create_cylinder(
orientation="Z",
origin=[0, "Coil_Position", 15],
radius=40,
height=20,
name="SearchCoil",
material="copper",
)
m3d.modeler.create_cylinder(
orientation="Z",
origin=[0, "Coil_Position", 15],
radius=20,
height=20,
name="Bore",
material="copper",
)
m3d.modeler.subtract(blank_list="SearchCoil", tool_list="Bore", keep_originals=False)
m3d.modeler.section(assignment="SearchCoil", plane="YZ")
m3d.modeler.separate_bodies(assignment="SearchCoil_Section1")
m3d.modeler.delete(assignment="SearchCoil_Section1_Separate1")
m3d.assign_current(
assignment=["SearchCoil_Section1"],
amplitude=1260,
solid=False,
name="SearchCoil_Excitation",
)
PyAEDT INFO: Parsing design objects. This operation can take time
PyAEDT INFO: Refreshing bodies from Object Info
PyAEDT INFO: Bodies Info Refreshed Elapsed time: 0m 0sec
PyAEDT INFO: 3D Modeler objects parsed. Elapsed time: 0m 0sec
PyAEDT INFO: Parsing design objects. This operation can take time
PyAEDT INFO: Refreshing bodies from Object Info
PyAEDT INFO: Bodies Info Refreshed Elapsed time: 0m 0sec
PyAEDT INFO: 3D Modeler objects parsed. Elapsed time: 0m 0sec
PyAEDT INFO: Deleted 1 Objects: SearchCoil_Section1_Separate1.
PyAEDT INFO: Boundary Current SearchCoil_Excitation has been created.
[9]:
<ansys.aedt.core.modules.boundary.common.BoundaryObject at 0x25896fc67d0>
Draw a line for plotting \(B_z\)#
Draw a line for plotting Bz later. Bz is the Z component of the flux density. The following code also adds a small diameter cylinder to refine the mesh locally around the line.
[10]:
line_points = [["0mm", "-55mm", "0.5mm"], ["0mm", "55mm", "0.5mm"]]
m3d.modeler.create_polyline(points=line_points, name="Line_AB")
poly = m3d.modeler.create_polyline(points=line_points, name="Line_AB_MeshRefinement")
poly.set_crosssection_properties(section="Circle", width="0.5mm")
[10]:
True
Add Maxwell 3D setup#
Add a Maxwell 3D setup with frequency points at 50 Hz and 200 Hz.
[11]:
setup = m3d.create_setup(name="Setup1")
setup.props["Frequency"] = "200Hz"
setup.props["HasSweepSetup"] = True
setup.props["MaximumPasses"] = 1
setup.add_eddy_current_sweep(
sweep_type="LinearStep", start_frequency=50, stop_frequency=200, step_size=150, clear=True
)
PyAEDT INFO: Parsing C:\Users\ansys\AppData\Local\Temp\tmpirkufxq0.ansys\COMPUMAG.aedt.
PyAEDT INFO: File C:\Users\ansys\AppData\Local\Temp\tmpirkufxq0.ansys\COMPUMAG.aedt correctly loaded. Elapsed time: 0m 0sec
PyAEDT INFO: aedt file load time 0.015982389450073242
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
File C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\IPython\core\formatters.py:711, in PlainTextFormatter.__call__(self, obj)
704 stream = StringIO()
705 printer = pretty.RepresentationPrinter(stream, self.verbose,
706 self.max_width, self.newline,
707 max_seq_length=self.max_seq_length,
708 singleton_pprinters=self.singleton_printers,
709 type_pprinters=self.type_printers,
710 deferred_pprinters=self.deferred_printers)
--> 711 printer.pretty(obj)
712 printer.flush()
713 return stream.getvalue()
File C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\IPython\lib\pretty.py:419, in RepresentationPrinter.pretty(self, obj)
408 return meth(obj, self, cycle)
409 if (
410 cls is not object
411 # check if cls defines __repr__
(...)
417 and callable(_safe_getattr(cls, "__repr__", None))
418 ):
--> 419 return _repr_pprint(obj, self, cycle)
421 return _default_pprint(obj, self, cycle)
422 finally:
File C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\IPython\lib\pretty.py:787, in _repr_pprint(obj, p, cycle)
785 """A pprint that just redirects to the normal repr function."""
786 # Find newlines and replace them with p.break_()
--> 787 output = repr(obj)
788 lines = output.splitlines()
789 with p.group():
File C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ansys\aedt\core\modules\solve_sweeps.py:90, in SweepCommon.__repr__(self)
89 def __repr__(self):
---> 90 return f"{self.setup_name} : {self.name}"
AttributeError: 'SweepMaxwellEC' object has no attribute 'name'
Adjust eddy effects#
Adjust eddy effects for the ladder plate and the search coil. The setting for eddy effect is ignored for the stranded conductor type used in the search coil.
[12]:
m3d.eddy_effects_on(
assignment=["LadderPlate"],
enable_eddy_effects=True,
enable_displacement_current=True,
)
m3d.eddy_effects_on(
assignment=["SearchCoil"],
enable_eddy_effects=False,
enable_displacement_current=True,
)
[12]:
True
Add linear parametric sweep#
Add a linear parametric sweep for the two coil positions.
[13]:
sweep_name = "CoilSweep"
param = m3d.parametrics.add(
variable="Coil_Position",
start_point=-20,
end_point=0,
step=20,
variation_type="LinearStep",
name=sweep_name,
)
param["SaveFields"] = True
param["CopyMesh"] = False
param["SolveWithCopiedMeshOnly"] = True
Solve parametric sweep#
Solve the parametric sweep directly so that results of all variations are available.
[14]:
m3d.save_project()
param.analyze(cores=NUM_CORES)
PyAEDT INFO: Project COMPUMAG Saved correctly
PyAEDT INFO: Project COMPUMAG Saved correctly
PyAEDT INFO: Key Desktop/ActiveDSOConfigurations/Maxwell 3D correctly changed.
PyAEDT INFO: Solving Optimetrics
PyAEDT INFO: Design setup CoilSweep solved correctly in 0.0h 1.0m 48.0s
PyAEDT INFO: Key Desktop/ActiveDSOConfigurations/Maxwell 3D correctly changed.
[14]:
True
Postprocess#
Create expression for Bz#
Create an expression for Bz using PyAEDT advanced fields calculator.
[15]:
bz = {
"name": "Bz",
"description": "Z component of B",
"design_type": ["Maxwell 3D"],
"fields_type": ["Fields"],
"primary_sweep": "Distance",
"assignment": "",
"assignment_type": ["Line"],
"operations": [
"NameOfExpression('<Bx,By,Bz>')",
"Operation('ScalarZ')",
"Scalar_Constant(1000)",
"Operation('*')",
"Operation('Smooth')",
],
"report": ["Field_3D"],
}
m3d.post.fields_calculator.add_expression(bz, None)
PyAEDT INFO: Parsing C:\Users\ansys\AppData\Local\Temp\tmpirkufxq0.ansys\COMPUMAG.aedt.
PyAEDT INFO: File C:\Users\ansys\AppData\Local\Temp\tmpirkufxq0.ansys\COMPUMAG.aedt correctly loaded. Elapsed time: 0m 0sec
PyAEDT INFO: aedt file load time 0.03133583068847656
PyAEDT INFO: PostProcessor class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: PostProcessor class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: Post class has been initialized! Elapsed time: 0m 0sec
[15]:
'Bz'
Plot \(|B_z|\) as a function of frequency#
Plot \(|B_z|\) as a function of frequency for both coil positions.
[16]:
variations = {
"Distance": ["All"],
"Freq": ["All"],
"Phase": ["0deg"],
"Coil_Position": ["All"],
}
m3d.post.create_report(
expressions="mag(Bz)",
variations=variations,
primary_sweep_variable="Distance",
report_category="Fields",
context="Line_AB",
plot_name="mag(Bz) Along 'Line_AB' Coil",
)
[16]:
<ansys.aedt.core.visualization.report.field.Fields at 0x25896fc7610>
Get simulation results from a solved setup#
Get simulation results from a solved setup as a SolutionData
object.
[17]:
solutions = m3d.post.get_solution_data(
expressions="mag(Bz)",
report_category="Fields",
context="Line_AB",
variations=variations,
primary_sweep_variable="Distance",
)
PyAEDT INFO: Solution Data Correctly Loaded.
Time to initialize solution data:0.019149303436279297
Time to initialize solution data:0.033754587173461914
Set up sweep value and plot solution#
[18]:
solutions.active_variation["Coil_Position"] = -0.02
solutions.plot()
PyAEDT ERROR: **************************************************************
PyAEDT ERROR: File "C:\actions-runner\_work\_tool\Python\3.10.11\x64\lib\runpy.py", line 196, in _run_module_as_main
PyAEDT ERROR: return _run_code(code, main_globals, None,
PyAEDT ERROR: File "C:\actions-runner\_work\_tool\Python\3.10.11\x64\lib\runpy.py", line 86, in _run_code
PyAEDT ERROR: exec(code, run_globals)
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ipykernel_launcher.py", line 18, in <module>
PyAEDT ERROR: app.launch_new_instance()
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\traitlets\config\application.py", line 1075, in launch_instance
PyAEDT ERROR: app.start()
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ipykernel\kernelapp.py", line 758, in start
PyAEDT ERROR: self.io_loop.start()
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\tornado\platform\asyncio.py", line 211, in start
PyAEDT ERROR: self.asyncio_loop.run_forever()
PyAEDT ERROR: File "C:\actions-runner\_work\_tool\Python\3.10.11\x64\lib\asyncio\base_events.py", line 603, in run_forever
PyAEDT ERROR: self._run_once()
PyAEDT ERROR: File "C:\actions-runner\_work\_tool\Python\3.10.11\x64\lib\asyncio\base_events.py", line 1909, in _run_once
PyAEDT ERROR: handle._run()
PyAEDT ERROR: File "C:\actions-runner\_work\_tool\Python\3.10.11\x64\lib\asyncio\events.py", line 80, in _run
PyAEDT ERROR: self._context.run(self._callback, *self._args)
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ipykernel\kernelbase.py", line 701, in shell_main
PyAEDT ERROR: await self.dispatch_shell(msg, subshell_id=subshell_id)
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ipykernel\kernelbase.py", line 469, in dispatch_shell
PyAEDT ERROR: await result
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ipykernel\ipkernel.py", line 379, in execute_request
PyAEDT ERROR: await super().execute_request(stream, ident, parent)
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ipykernel\kernelbase.py", line 899, in execute_request
PyAEDT ERROR: reply_content = await reply_content
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ipykernel\ipkernel.py", line 471, in do_execute
PyAEDT ERROR: res = shell.run_cell(
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ipykernel\zmqshell.py", line 632, in run_cell
PyAEDT ERROR: return super().run_cell(*args, **kwargs)
PyAEDT ERROR: File "C:\Users\ansys\AppData\Local\Temp\ipykernel_6968\3006651278.py", line 2, in <module>
PyAEDT ERROR: solutions.plot()
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ansys\aedt\core\visualization\post\solution_data.py", line 945, in plot
PyAEDT ERROR: report_plotter = self.get_report_plotter(curves=curves, formula=formula, to_radians=to_radians, props=props)
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ansys\aedt\core\visualization\post\solution_data.py", line 877, in get_report_plotter
PyAEDT ERROR: new.add_trace([sw, self._get_data_formula(curve, formula)], name=name, properties=props)
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ansys\aedt\core\visualization\plot\matplotlib.py", line 916, in add_trace
PyAEDT ERROR: nt.cartesian_data = plot_data
PyAEDT ERROR: File "C:\actions-runner\_work\pyaedt-examples\pyaedt-examples\.venv\lib\site-packages\ansys\aedt\core\visualization\plot\matplotlib.py", line 348, in cartesian_data
PyAEDT ERROR: self._cartesian_data.append(np.zeros(len(val[-1])))
PyAEDT ERROR: Object of type 'nonetype' has no len() on add_trace
PyAEDT ERROR: Method arguments:
PyAEDT ERROR: plot_data = [array([ 0. , 0.11, 0.22, ..., 109.78, 109.89, 110. ], shape=(1001,)), None]
PyAEDT ERROR: properties = {'x_label': '', 'y_label': ''}
PyAEDT ERROR: name = (mag(Bz))_Phase=0.0,Freq=50.0
PyAEDT ERROR: **************************************************************
[18]:
False
Change sweep value and plot solution#
Change the sweep value and plot the solution again. Uncomment to show plots.
[19]:
solutions.active_variation["Coil_Position"] = 0
# solutions.plot()
Plot induced current density on surface of ladder plate#
Plot the induced current density, "Mag_J"
, on the surface of the ladder plate.
[20]:
ladder_plate = m3d.modeler.objects_by_name["LadderPlate"]
intrinsics = {"Freq": "50Hz", "Phase": "0deg"}
m3d.post.create_fieldplot_surface(
assignment=ladder_plate.faces,
quantity="Mag_J",
intrinsics=intrinsics,
plot_name="Mag_J",
)
PyAEDT INFO: Active Design set to TEAM_3_Bath_Plate
[20]:
<ansys.aedt.core.visualization.post.field_data.FieldPlot at 0x25899dd5b40>
Finish#
Save the project#
[21]:
m3d.save_project()
m3d.release_desktop()
# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory.
time.sleep(3)
PyAEDT INFO: Project COMPUMAG Saved correctly
PyAEDT INFO: Desktop has been released and closed.
Clean up#
All project files are saved in the folder temp_folder.name
. If you’ve run this example as a Jupyter notebook, you can retrieve those project files. The following cell removes all temporary files, including the project folder.
[22]:
temp_folder.cleanup()
Download this example
Download this example as a Jupyter Notebook or as a Python script.