.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples\06-Multiphysics\Maxwell3D_Icepak_2Way_Coupling.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_06-Multiphysics_Maxwell3D_Icepak_2Way_Coupling.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_06-Multiphysics_Maxwell3D_Icepak_2Way_Coupling.py:


Multiphysics: Maxwell 3D - Icepak electrothermal analysis
---------------------------------------------------------
This example uses PyAEDT to set up a simple Maxwell design consisting of a coil and a ferrite core.
Coil current is set to 100A, and coil resistance and ohmic loss are analyzed.
Ohmic loss is mapped to Icepak, and a thermal analysis is performed. Icepak calculates a temperature distribution,
and it is mapped back to Maxwell (2-way coupling). Coil resistance and ohmic loss are analyzed again in Maxwell.
Results are printed in AEDT Message Manager.

.. GENERATED FROM PYTHON SOURCE LINES 11-14

Perform required imports
~~~~~~~~~~~~~~~~~~~~~~~~
Perform required imports.

.. GENERATED FROM PYTHON SOURCE LINES 14-18

.. code-block:: Python


    import pyaedt
    from pyaedt.generic.constants import AXIS








.. GENERATED FROM PYTHON SOURCE LINES 19-22

Set AEDT version
~~~~~~~~~~~~~~~~
Set AEDT version.

.. GENERATED FROM PYTHON SOURCE LINES 22-25

.. code-block:: Python


    aedt_version = "2024.1"








.. GENERATED FROM PYTHON SOURCE LINES 26-30

Set non-graphical mode
~~~~~~~~~~~~~~~~~~~~~~
Set non-graphical mode.
You can set ``non_graphical`` either to ``True`` or ``False``.

.. GENERATED FROM PYTHON SOURCE LINES 30-33

.. code-block:: Python


    non_graphical = False








.. GENERATED FROM PYTHON SOURCE LINES 34-38

Launch AEDT and Maxwell 3D
~~~~~~~~~~~~~~~~~~~~~~~~~~
Launch AEDT and Maxwell 3D. The following code sets up the project and design names, the solver, and
the version. It also creates an instance of the ``Maxwell3d`` class named ``m3d``.

.. GENERATED FROM PYTHON SOURCE LINES 38-51

.. code-block:: Python


    project_name = "Maxwell-Icepak-2way-Coupling"
    maxwell_design_name = "1 Maxwell"
    icepak_design_name = "2 Icepak"

    m3d = pyaedt.Maxwell3d(
        projectname=project_name,
        designname=maxwell_design_name,
        solution_type="EddyCurrent",
        specified_version=aedt_version,
        non_graphical=non_graphical,
    )





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    C:\actions-runner\_work\_tool\Python\3.10.9\x64\lib\subprocess.py:1072: ResourceWarning: subprocess 12780 is still running
      _warn("subprocess %s is still running" % self.pid,
    C:\actions-runner\_work\pyaedt\pyaedt\.venv\lib\site-packages\pyaedt\generic\settings.py:383: ResourceWarning: unclosed file <_io.TextIOWrapper name='D:\\Temp\\pyaedt_ansys.log' mode='a' encoding='cp1252'>
      self._logger = val




.. GENERATED FROM PYTHON SOURCE LINES 52-55

Create geometry in Maxwell
~~~~~~~~~~~~~~~~~~~~~~~~~~
Create the coil, coil terminal, core, and region.

.. GENERATED FROM PYTHON SOURCE LINES 55-74

.. code-block:: Python


    coil = m3d.modeler.create_rectangle(
        orientation="XZ", origin=[70, 0, -11], sizes=[11, 110], name="Coil"
    )

    coil.sweep_around_axis(axis=AXIS.Z)

    coil_terminal = m3d.modeler.create_rectangle(
        orientation="XZ", origin=[70, 0, -11], sizes=[11, 110], name="Coil_terminal"
    )

    core = m3d.modeler.create_rectangle(
        orientation="XZ", origin=[45, 0, -18], sizes=[7, 160], name="Core"
    )
    core.sweep_around_axis(axis=AXIS.Z)

    # Magnetic flux is not concentrated by the core in +z-direction. Therefore, more padding is needed in that direction.
    region = m3d.modeler.create_region(pad_percent=[20, 20, 500, 20, 20, 100])








.. GENERATED FROM PYTHON SOURCE LINES 75-79

Assign materials
~~~~~~~~~~~~~~~~
Create a material: Copper AWG40 Litz wire, strand diameter = 0.08mm, 24 parallel strands.
Assign materials: Assign Coil to AWG40 copper, core to ferrite, and region to vacuum.

.. GENERATED FROM PYTHON SOURCE LINES 79-93

.. code-block:: Python


    no_strands = 24
    strand_diameter = 0.08

    cu_litz = m3d.materials.duplicate_material("copper", "copper_litz")
    cu_litz.stacking_type = "Litz Wire"
    cu_litz.wire_diameter = str(strand_diameter) + "mm"
    cu_litz.wire_type = "Round"
    cu_litz.strand_number = no_strands

    m3d.assign_material(region.name, "vacuum")
    m3d.assign_material(coil.name, "copper_litz")
    m3d.assign_material(core.name, "ferrite")





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    True



.. GENERATED FROM PYTHON SOURCE LINES 94-98

Assign excitation
~~~~~~~~~~~~~~~~~
Assign coil current, coil consists of 20 turns, total current 10A.
Note that each coil turn consists of 24 parallel Litz strands, see above.

.. GENERATED FROM PYTHON SOURCE LINES 98-106

.. code-block:: Python


    no_turns = 20
    coil_current = 10
    m3d.assign_coil(["Coil_terminal"], conductors_number=no_turns, name="Coil_terminal")
    m3d.assign_winding(is_solid=False, current=coil_current, name="Winding1")

    m3d.add_winding_coils(assignment="Winding1", coils=["Coil_terminal"])





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    True



.. GENERATED FROM PYTHON SOURCE LINES 107-111

Assign mesh operations
~~~~~~~~~~~~~~~~~~~~~~
Mesh operations are not necessary in eddy current solver because of auto-adaptive meshing.
However, with appropriate mesh operations, less adaptive passes are needed.

.. GENERATED FROM PYTHON SOURCE LINES 111-115

.. code-block:: Python


    m3d.mesh.assign_length_mesh(["Core"], maximum_length=15, maximum_elements=None, name="Inside_Core")
    m3d.mesh.assign_length_mesh(["Coil"], maximum_length=30, maximum_elements=None, name="Inside_Coil")





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <pyaedt.modules.Mesh.MeshOperation object at 0x000002265ED1AE90>



.. GENERATED FROM PYTHON SOURCE LINES 116-119

Set conductivity temperature coefficient
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Set conductivity as a function of temperature. Resistivity increases by 0.393% per K.

.. GENERATED FROM PYTHON SOURCE LINES 119-123

.. code-block:: Python


    cu_resistivity_temp_coefficient = 0.00393
    cu_litz.conductivity.add_thermal_modifier_free_form("1.0/(1.0+{}*(Temp-20))".format(cu_resistivity_temp_coefficient))





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    True



.. GENERATED FROM PYTHON SOURCE LINES 124-128

Set object temperature and enable feedback
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Set the temperature of the objects to default temperature (22deg C)
and enable temperature feedback for two-way coupling.

.. GENERATED FROM PYTHON SOURCE LINES 128-131

.. code-block:: Python


    m3d.modeler.set_objects_temperature(["Coil"])





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    True



.. GENERATED FROM PYTHON SOURCE LINES 132-135

Assign matrix
~~~~~~~~~~~~~
Resistance and inductance calculation.

.. GENERATED FROM PYTHON SOURCE LINES 135-138

.. code-block:: Python


    m3d.assign_matrix(["Winding1"], matrix_name="Matrix1")





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <pyaedt.modules.Boundary.MaxwellParameters object at 0x000002265ED185E0>



.. GENERATED FROM PYTHON SOURCE LINES 139-142

Create and analyze simulation setup
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Simulation frequency 150kHz.

.. GENERATED FROM PYTHON SOURCE LINES 142-147

.. code-block:: Python


    setup = m3d.create_setup(name="Setup1")
    setup.props["Frequency"] = "150kHz"
    m3d.analyze_setup("Setup1")





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    True



.. GENERATED FROM PYTHON SOURCE LINES 148-152

Postprocessing
~~~~~~~~~~~~~~
Calculate analytical DC resistance and compare it with the simulated coil resistance,
print them in the message manager, as well as ohmic loss in coil before temperature feedback.

.. GENERATED FROM PYTHON SOURCE LINES 152-173

.. code-block:: Python


    report = m3d.post.create_report(expressions="Matrix1.R(Winding1,Winding1)")
    solution = report.get_solution_data()
    resistance = solution.data_magnitude()[0]

    report_loss = m3d.post.create_report(expressions="StrandedLossAC")
    solution_loss = report_loss.get_solution_data()
    em_loss = solution_loss.data_magnitude()[0]

    # Analytical calculation of the DC resistance of the coil
    cu_cond = float(cu_litz.conductivity.value)
    # average radius of a coil turn = 0.125m
    l_conductor = no_turns*2*0.125*3.1415
    # R = resistivity * length / area / no_strand
    r_analytical_DC = (1.0 / cu_cond) * l_conductor / (3.1415 * (strand_diameter / 1000 / 2) ** 2) / no_strands

    # Print results in the Message Manager
    m3d.logger.info("*******Coil analytical DC resistance =  {:.2f}Ohm".format(r_analytical_DC))
    m3d.logger.info("*******Coil resistance at 150kHz BEFORE temperature feedback =  {:.2f}Ohm".format(resistance))
    m3d.logger.info("*******Ohmic loss in coil BEFORE temperature feedback =  {:.2f}W".format(em_loss / 1000))








.. GENERATED FROM PYTHON SOURCE LINES 174-177

Icepak design
~~~~~~~~~~~~~
Insert Icepak design, copy solid objects from Maxwell, and modify region dimensions.

.. GENERATED FROM PYTHON SOURCE LINES 177-187

.. code-block:: Python


    ipk = pyaedt.Icepak(designname=icepak_design_name)
    ipk.copy_solid_bodies_from(m3d, no_pec=False)

    # Set domain dimensions suitable for natural convection using the diameter of the coil
    ipk.modeler["Region"].delete()
    coil_dim = coil.bounding_dimension[0]
    ipk.modeler.create_region(0, False)
    ipk.modeler.edit_region_dimensions([coil_dim / 2, coil_dim / 2, coil_dim / 2, coil_dim / 2, coil_dim * 2, coil_dim])





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    True



.. GENERATED FROM PYTHON SOURCE LINES 188-191

Map coil losses
~~~~~~~~~~~~~~~
Map ohmic losses from Maxwell to the Icepak design.

.. GENERATED FROM PYTHON SOURCE LINES 191-194

.. code-block:: Python


    ipk.assign_em_losses(design="1 Maxwell", setup=m3d.setups[0].name, sweep="LastAdaptive", assignment=["Coil"])





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <pyaedt.modules.Boundary.BoundaryObject object at 0x0000022601061630>



.. GENERATED FROM PYTHON SOURCE LINES 195-198

Boundary conditions
~~~~~~~~~~~~~~~~~~~
Assign opening.

.. GENERATED FROM PYTHON SOURCE LINES 198-203

.. code-block:: Python


    faces = ipk.modeler["Region"].faces
    face_names = [face.id for face in faces]
    ipk.assign_free_opening(face_names, boundary_name="Opening1")





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <pyaedt.modules.Boundary.BoundaryObject object at 0x0000022601061420>



.. GENERATED FROM PYTHON SOURCE LINES 204-207

Assign monitor
~~~~~~~~~~~~~~
Temperature monitor on the coil surface

.. GENERATED FROM PYTHON SOURCE LINES 207-210

.. code-block:: Python


    temp_monitor = ipk.assign_point_monitor([70, 0, 0], monitor_name="PointMonitor1")








.. GENERATED FROM PYTHON SOURCE LINES 211-213

Icepak solution setup
~~~~~~~~~~~~~~~~~~~~~

.. GENERATED FROM PYTHON SOURCE LINES 213-226

.. code-block:: Python


    solution_setup = ipk.create_setup()
    solution_setup.props["Convergence Criteria - Max Iterations"] = 50
    solution_setup.props["Flow Regime"] = "Turbulent"
    solution_setup.props["Turbulent Model Eqn"] = "ZeroEquation"
    solution_setup.props["Radiation Model"] = "Discrete Ordinates Model"
    solution_setup.props["Include Flow"] = True
    solution_setup.props["Include Gravity"] = True
    solution_setup.props["Solution Initialization - Z Velocity"] = "0.0005m_per_sec"
    solution_setup.props["Convergence Criteria - Flow"] = 0.0005
    solution_setup.props["Flow Iteration Per Radiation Iteration"] = "5"









.. GENERATED FROM PYTHON SOURCE LINES 227-232

Add 2-way coupling and solve the project
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Enable mapping temperature distribution back to Maxwell.
Default number Maxwell <--> Icepak iterations is 2,
but for increased accuracy it can be increased (number_of_iterations).

.. GENERATED FROM PYTHON SOURCE LINES 232-236

.. code-block:: Python


    ipk.assign_2way_coupling()
    ipk.analyze_setup(name=solution_setup.name)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    True



.. GENERATED FROM PYTHON SOURCE LINES 237-240

Postprocessing
~~~~~~~~~~~~~~
Plot temperature on the object surfaces.

.. GENERATED FROM PYTHON SOURCE LINES 240-259

.. code-block:: Python


    surface_list = []
    for name in ["Coil", "Core"]:
        surface_list.extend(ipk.modeler.get_object_faces(name))

    surf_temperature = ipk.post.create_fieldplot_surface(surface_list, quantity="SurfTemperature",
                                                         plot_name="Surface Temperature")

    velocity_cutplane = ipk.post.create_fieldplot_cutplane(assignment=["Global:XZ"], quantity="Velocity Vectors",
                                                           plot_name="Velocity Vectors")

    surf_temperature.export_image()
    velocity_cutplane.export_image(orientation="right")

    report_temp = ipk.post.create_report(expressions="PointMonitor1.Temperature", primary_sweep_variable="X")
    solution_temp = report_temp.get_solution_data()
    temp = solution_temp.data_magnitude()[0]
    m3d.logger.info("*******Coil temperature =  {:.2f}deg C".format(temp))








.. GENERATED FROM PYTHON SOURCE LINES 260-263

Get new resistance from Maxwell
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Temperature of the coil increases, and consequently also coil resistance increases.

.. GENERATED FROM PYTHON SOURCE LINES 263-277

.. code-block:: Python


    report_new = m3d.post.create_report(expressions="Matrix1.R(Winding1,Winding1)")
    solution_new = report_new.get_solution_data()
    resistance_new = solution_new.data_magnitude()[0]
    resistance_increase = (resistance_new - resistance)/resistance * 100

    report_loss_new = m3d.post.create_report(expressions="StrandedLossAC")
    solution_loss_new = report_loss_new.get_solution_data()
    em_loss_new = solution_loss_new.data_magnitude()[0]

    m3d.logger.info("*******Coil resistance at 150kHz AFTER temperature feedback =  {:.2f}Ohm".format(resistance_new))
    m3d.logger.info("*******Coil resistance increased by {:.2f}%".format(resistance_increase))
    m3d.logger.info("*******Ohmic loss in coil AFTER temperature feedback =  {:.2f}W".format(em_loss_new/1000))








.. GENERATED FROM PYTHON SOURCE LINES 278-280

Release desktop
~~~~~~~~~~~~~~~

.. GENERATED FROM PYTHON SOURCE LINES 280-282

.. code-block:: Python


    ipk.release_desktop(True, True)




.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    True




.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (6 minutes 26.673 seconds)


.. _sphx_glr_download_examples_06-Multiphysics_Maxwell3D_Icepak_2Way_Coupling.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: Maxwell3D_Icepak_2Way_Coupling.ipynb <Maxwell3D_Icepak_2Way_Coupling.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: Maxwell3D_Icepak_2Way_Coupling.py <Maxwell3D_Icepak_2Way_Coupling.py>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_