{ "cells": [ { "cell_type": "markdown", "id": "416bfcae", "metadata": {}, "source": [ "# Bath plate analysis\n", "\n", "This example uses PyAEDT to set up the TEAM 3 bath plate problem and\n", "solve it using the Maxwell 3D eddy current solver.\n", "# For more information on this problem, see this\n", "[paper](https://www.compumag.org/wp/wp-content/uploads/2018/06/problem3.pdf).\n", "\n", "Keywords: **Maxwell 3D**, **TEAM 3 bath plate**" ] }, { "cell_type": "markdown", "id": "48e92de8", "metadata": {}, "source": [ "## Perform imports and define constants\n", "\n", "Perform required imports." ] }, { "cell_type": "code", "execution_count": null, "id": "c806b4ac", "metadata": {}, "outputs": [], "source": [ "import os\n", "import tempfile\n", "import time" ] }, { "cell_type": "code", "execution_count": null, "id": "1645c445", "metadata": {}, "outputs": [], "source": [ "import ansys.aedt.core" ] }, { "cell_type": "markdown", "id": "d0f7101e", "metadata": {}, "source": [ "Define constants." ] }, { "cell_type": "code", "execution_count": null, "id": "f19075a8", "metadata": {}, "outputs": [], "source": [ "AEDT_VERSION = \"2024.2\"\n", "NUM_CORES = 4\n", "NG_MODE = False # Open AEDT UI when it is launched." ] }, { "cell_type": "markdown", "id": "f70c0611", "metadata": {}, "source": [ "## Create temporary directory\n", "\n", "Create a temporary directory where downloaded data or\n", "dumped data can be stored.\n", "If you'd like to retrieve the project data for subsequent use,\n", "the temporary folder name is given by ``temp_folder.name``." ] }, { "cell_type": "code", "execution_count": null, "id": "aa99a6ca", "metadata": {}, "outputs": [], "source": [ "temp_folder = tempfile.TemporaryDirectory(suffix=\".ansys\")" ] }, { "cell_type": "markdown", "id": "29815970", "metadata": {}, "source": [ "## Launch AEDT and Maxwell 3D\n", "\n", "Create an instance of the ``Maxwell3d`` class named ``m3d`` by providing\n", "the project and design names, the solver, and the version." ] }, { "cell_type": "code", "execution_count": null, "id": "e5da14b3", "metadata": {}, "outputs": [], "source": [ "m3d = ansys.aedt.core.Maxwell3d(\n", " project=os.path.join(temp_folder.name, \"COMPUMAG.aedt\"),\n", " design=\"TEAM_3_Bath_Plate\",\n", " solution_type=\"EddyCurrent\",\n", " version=AEDT_VERSION,\n", " non_graphical=NG_MODE,\n", " new_desktop=True,\n", ")\n", "uom = m3d.modeler.model_units = \"mm\"" ] }, { "cell_type": "markdown", "id": "ade53950", "metadata": {}, "source": [ "## Add variable\n", "\n", "Add a design variable named ``Coil_Position`` to use later to adjust the\n", "position of the coil." ] }, { "cell_type": "code", "execution_count": null, "id": "dc78db23", "metadata": {}, "outputs": [], "source": [ "Coil_Position = -20\n", "m3d[\"Coil_Position\"] = str(Coil_Position) + m3d.modeler.model_units" ] }, { "cell_type": "markdown", "id": "48db7259", "metadata": {}, "source": [ "## Add material\n", "\n", "Add a material named ``team3_aluminium`` for the ladder plate." ] }, { "cell_type": "code", "execution_count": null, "id": "d6a16b56", "metadata": {}, "outputs": [], "source": [ "mat = m3d.materials.add_material(name=\"team3_aluminium\")\n", "mat.conductivity = 32780000" ] }, { "cell_type": "markdown", "id": "e3e0b33a", "metadata": {}, "source": [ "## Draw background region\n", "\n", "Draw a background region that uses the default properties for an air region." ] }, { "cell_type": "code", "execution_count": null, "id": "228d41db", "metadata": {}, "outputs": [], "source": [ "m3d.modeler.create_air_region(\n", " x_pos=100, y_pos=100, z_pos=100, x_neg=100, y_neg=100, z_neg=100\n", ")" ] }, { "cell_type": "markdown", "id": "69053a57", "metadata": {}, "source": [ "## Draw ladder plate and assign material\n", "\n", "Draw a ladder plate and assign it the newly created material ``team3_aluminium``." ] }, { "cell_type": "code", "execution_count": null, "id": "9be15be7", "metadata": {}, "outputs": [], "source": [ "m3d.modeler.create_box(\n", " origin=[-30, -55, 0],\n", " sizes=[60, 110, -6.35],\n", " name=\"LadderPlate\",\n", " material=\"team3_aluminium\",\n", ")\n", "m3d.modeler.create_box(origin=[-20, -35, 0], sizes=[40, 30, -6.35], name=\"CutoutTool1\")\n", "m3d.modeler.create_box(origin=[-20, 5, 0], sizes=[40, 30, -6.35], name=\"CutoutTool2\")\n", "m3d.modeler.subtract(\n", " blank_list=\"LadderPlate\",\n", " tool_list=[\"CutoutTool1\", \"CutoutTool2\"],\n", " keep_originals=False,\n", ")" ] }, { "cell_type": "markdown", "id": "32e2be56", "metadata": {}, "source": [ "## Add mesh refinement to ladder plate" ] }, { "cell_type": "markdown", "id": "5a9bf654", "metadata": {}, "source": [ "> **Note:** You can uncomment the following code." ] }, { "cell_type": "markdown", "id": "b6985510", "metadata": {}, "source": [ "m3d.mesh.assign_length_mesh(\n", " assignment=\"LadderPlate\",\n", " maximum_length=3,\n", " maximum_elements=None,\n", " name=\"Ladder_Mesh\",\n", ")" ] }, { "cell_type": "markdown", "id": "78d18a36", "metadata": {}, "source": [ "## Draw search coil and assign excitation\n", "\n", "Draw a search coil and assign it a ``stranded`` current excitation.\n", "The stranded type forces the current density to be constant in the coil." ] }, { "cell_type": "code", "execution_count": null, "id": "5ffec421", "metadata": {}, "outputs": [], "source": [ "m3d.modeler.create_cylinder(\n", " orientation=\"Z\",\n", " origin=[0, \"Coil_Position\", 15],\n", " radius=40,\n", " height=20,\n", " name=\"SearchCoil\",\n", " material=\"copper\",\n", ")\n", "m3d.modeler.create_cylinder(\n", " orientation=\"Z\",\n", " origin=[0, \"Coil_Position\", 15],\n", " radius=20,\n", " height=20,\n", " name=\"Bore\",\n", " material=\"copper\",\n", ")\n", "m3d.modeler.subtract(blank_list=\"SearchCoil\", tool_list=\"Bore\", keep_originals=False)\n", "m3d.modeler.section(assignment=\"SearchCoil\", plane=\"YZ\")\n", "m3d.modeler.separate_bodies(assignment=\"SearchCoil_Section1\")\n", "m3d.modeler.delete(assignment=\"SearchCoil_Section1_Separate1\")\n", "m3d.assign_current(\n", " assignment=[\"SearchCoil_Section1\"],\n", " amplitude=1260,\n", " solid=False,\n", " name=\"SearchCoil_Excitation\",\n", ")" ] }, { "cell_type": "markdown", "id": "728466f4", "metadata": {}, "source": [ "## Draw a line for plotting Bz\n", "\n", "Draw a line for plotting Bz later. Bz is the Z component of the flux\n", "density. The following code also adds a small diameter cylinder to refine the\n", "mesh locally around the line." ] }, { "cell_type": "code", "execution_count": null, "id": "c0893ead", "metadata": {}, "outputs": [], "source": [ "line_points = [[\"0mm\", \"-55mm\", \"0.5mm\"], [\"0mm\", \"55mm\", \"0.5mm\"]]\n", "m3d.modeler.create_polyline(points=line_points, name=\"Line_AB\")\n", "poly = m3d.modeler.create_polyline(points=line_points, name=\"Line_AB_MeshRefinement\")\n", "poly.set_crosssection_properties(type=\"Circle\", width=\"0.5mm\")" ] }, { "cell_type": "markdown", "id": "86761749", "metadata": {}, "source": [ "## Add Maxwell 3D setup\n", "\n", "Add a Maxwell 3D setup with frequency points at 50 Hz and 200 Hz." ] }, { "cell_type": "code", "execution_count": null, "id": "79a51367", "metadata": {}, "outputs": [], "source": [ "setup = m3d.create_setup(name=\"Setup1\")\n", "setup.props[\"Frequency\"] = \"200Hz\"\n", "setup.props[\"HasSweepSetup\"] = True\n", "setup.props[\"MaximumPasses\"] = 1\n", "setup.add_eddy_current_sweep(\n", " range_type=\"LinearStep\", start=50, end=200, count=150, clear=True\n", ")" ] }, { "cell_type": "markdown", "id": "31bcbd3a", "metadata": {}, "source": [ "## Adjust eddy effects\n", "\n", "Adjust eddy effects for the ladder plate and the search coil. The setting for\n", "eddy effect is ignored for the stranded conductor type used in the search coil." ] }, { "cell_type": "code", "execution_count": null, "id": "f0f868db", "metadata": {}, "outputs": [], "source": [ "m3d.eddy_effects_on(\n", " assignment=[\"LadderPlate\"],\n", " enable_eddy_effects=True,\n", " enable_displacement_current=True,\n", ")\n", "m3d.eddy_effects_on(\n", " assignment=[\"SearchCoil\"],\n", " enable_eddy_effects=False,\n", " enable_displacement_current=True,\n", ")" ] }, { "cell_type": "markdown", "id": "765bd487", "metadata": {}, "source": [ "## Add linear parametric sweep\n", "\n", "Add a linear parametric sweep for the two coil positions." ] }, { "cell_type": "code", "execution_count": null, "id": "e5522a17", "metadata": {}, "outputs": [], "source": [ "sweep_name = \"CoilSweep\"\n", "param = m3d.parametrics.add(\n", " variable=\"Coil_Position\",\n", " start_point=-20,\n", " end_point=0,\n", " step=20,\n", " variation_type=\"LinearStep\",\n", " name=sweep_name,\n", ")\n", "param[\"SaveFields\"] = True\n", "param[\"CopyMesh\"] = False\n", "param[\"SolveWithCopiedMeshOnly\"] = True" ] }, { "cell_type": "markdown", "id": "d4122a45", "metadata": {}, "source": [ "## Solve parametric sweep\n", "\n", "Solve the parametric sweep directly so that results of all variations are available." ] }, { "cell_type": "code", "execution_count": null, "id": "f99e5780", "metadata": {}, "outputs": [], "source": [ "m3d.save_project()\n", "param.analyze(cores=NUM_CORES)" ] }, { "cell_type": "markdown", "id": "97e07ebc", "metadata": {}, "source": [ "## Create expression for Bz\n", "\n", "Create an expression for Bz using PyAEDT advanced fields calculator." ] }, { "cell_type": "code", "execution_count": null, "id": "1389240e", "metadata": {}, "outputs": [], "source": [ "bz = {\n", " \"name\": \"Bz\",\n", " \"description\": \"Z component of B\",\n", " \"design_type\": [\"Maxwell 3D\"],\n", " \"fields_type\": [\"Fields\"],\n", " \"primary_sweep\": \"Distance\",\n", " \"assignment\": \"\",\n", " \"assignment_type\": [\"Line\"],\n", " \"operations\": [\n", " \"NameOfExpression('')\",\n", " \"Operation('ScalarZ')\",\n", " \"Scalar_Constant(1000)\",\n", " \"Operation('*')\",\n", " \"Operation('Smooth')\",\n", " ],\n", " \"report\": [\"Field_3D\"],\n", "}\n", "m3d.post.fields_calculator.add_expression(bz, None)" ] }, { "cell_type": "markdown", "id": "2a443678", "metadata": {}, "source": [ "## Plot mag(Bz) as a function of frequency\n", "\n", "Plot mag(Bz) as a function of frequency for both coil positions." ] }, { "cell_type": "code", "execution_count": null, "id": "d6171cd0", "metadata": {}, "outputs": [], "source": [ "variations = {\n", " \"Distance\": [\"All\"],\n", " \"Freq\": [\"All\"],\n", " \"Phase\": [\"0deg\"],\n", " \"Coil_Position\": [\"All\"],\n", "}\n", "\n", "m3d.post.create_report(\n", " expressions=\"mag(Bz)\",\n", " variations=variations,\n", " primary_sweep_variable=\"Distance\",\n", " report_category=\"Fields\",\n", " context=\"Line_AB\",\n", " plot_name=\"mag(Bz) Along 'Line_AB' Coil\",\n", ")" ] }, { "cell_type": "markdown", "id": "a6ab2675", "metadata": {}, "source": [ "## Get simulation results from a solved setup\n", "\n", "Get simulation results from a solved setup as a ``SolutionData`` object." ] }, { "cell_type": "code", "execution_count": null, "id": "d0707ba7", "metadata": {}, "outputs": [], "source": [ "\n", "solutions = m3d.post.get_solution_data(\n", " expressions=\"mag(Bz)\",\n", " report_category=\"Fields\",\n", " context=\"Line_AB\",\n", " variations=variations,\n", " primary_sweep_variable=\"Distance\",\n", ")" ] }, { "cell_type": "markdown", "id": "47fe9148", "metadata": {}, "source": [ "## Set up sweep value and plot solution" ] }, { "cell_type": "code", "execution_count": null, "id": "785e139a", "metadata": {}, "outputs": [], "source": [ "solutions.active_variation[\"Coil_Position\"] = -0.02\n", "solutions.plot()" ] }, { "cell_type": "markdown", "id": "3d9cb6ad", "metadata": {}, "source": [ "## Change sweep value and plot solution\n", "\n", "Change the sweep value and plot the solution again.\n", "Uncomment to show plots." ] }, { "cell_type": "code", "execution_count": null, "id": "7b0cf628", "metadata": {}, "outputs": [], "source": [ "solutions.active_variation[\"Coil_Position\"] = 0\n", "# solutions.plot()" ] }, { "cell_type": "markdown", "id": "c0021295", "metadata": {}, "source": [ "## Plot induced current density on surface of ladder plate\n", "\n", "Plot the induced current density, ``\"Mag_J\"``, on the surface of the ladder plate." ] }, { "cell_type": "code", "execution_count": null, "id": "3ccde46a", "metadata": {}, "outputs": [], "source": [ "ladder_plate = m3d.modeler.objects_by_name[\"LadderPlate\"]\n", "intrinsics = {\"Freq\": \"50Hz\", \"Phase\": \"0deg\"}\n", "m3d.post.create_fieldplot_surface(\n", " assignment=ladder_plate.faces,\n", " quantity=\"Mag_J\",\n", " intrinsics=intrinsics,\n", " plot_name=\"Mag_J\",\n", ")" ] }, { "cell_type": "markdown", "id": "f9b09478", "metadata": {}, "source": [ "## Release AEDT" ] }, { "cell_type": "code", "execution_count": null, "id": "8fd9c600", "metadata": {}, "outputs": [], "source": [ "m3d.save_project()\n", "m3d.release_desktop()\n", "# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory.\n", "time.sleep(3)" ] }, { "cell_type": "markdown", "id": "64080fa3", "metadata": {}, "source": [ "## Clean up\n", "\n", "All project files are saved in the folder ``temp_folder.name``.\n", "If you've run this example as a Jupyter notebook, you\n", "can retrieve those project files. The following cell\n", "removes all temporary files, including the project folder." ] }, { "cell_type": "code", "execution_count": null, "id": "5b1ec156", "metadata": {}, "outputs": [], "source": [ "temp_folder.cleanup()" ] } ], "metadata": { "jupytext": { "cell_metadata_filter": "-all", "main_language": "python", "notebook_metadata_filter": "-all" } }, "nbformat": 4, "nbformat_minor": 5 }