Skip to content

Commit

Permalink
FEAT: implement resistive sheet (#5473)
Browse files Browse the repository at this point in the history
Co-authored-by: Sébastien Morais <146729917+SMoraisAnsys@users.noreply.github.com>
Co-authored-by: Sebastien Morais <sebastien.morais@ansys.com>
  • Loading branch information
3 people authored Nov 26, 2024
1 parent 2944348 commit cf37ddd
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 0 deletions.
124 changes: 124 additions & 0 deletions src/ansys/aedt/core/maxwell.py
Original file line number Diff line number Diff line change
Expand Up @@ -2961,6 +2961,130 @@ def assign_zero_tangential_h_field(self, assignment, boundary=None):
return bound
return False

@pyaedt_function_handler()
def assign_resistive_sheet(
self,
assignment,
resistance="1ohm",
name=None,
non_linear=False,
anode_a="300000000",
anode_b="5",
anode_c="110000000000000",
anode_d="2",
cathode_a="300000000",
cathode_b="10",
cathode_c="110000000000000",
cathode_d="2",
):
"""Assign a resistive sheet boundary between two conductors.
Available for Maxwell 3D Magnetostatic, Eddy Current and Transient designs.
For 3D Magnetostatic designs, the user can specify the nonlinear anode and cathode coefficients.
To understand the nonlinear relationship used by AEDT between the conductivity and current density,
please refer to Maxwell Help guide.
Parameters
----------
assignment : list of int or :class:`ansys.aedt.core.modeler.cad.object_3d.Object3d`
List of objects to assign an end connection to.
resistance : str, optional
Resistance value with unit.
For 3D Magnetostatic designs if non_linear is ``True``, it is not available.
The default is ``1ohm``.
name : str, optional
Name of the boundary. The default is ``None``, in which case the default name is used.
non_linear: bool, optional
Whether the boundary is non-linear. The default is ``False``.
Valid for 3D Magnetostatic designs only.
anode_a : str, optional
Anode a value that corresponds to the a coefficient in the non-linear relationship
between conductivity and current density.
The default value is ``"300000000"``.
anode_b : str, optional
Anode b value that corresponds to the b coefficient in the non-linear relationship
between conductivity and current density.
The default value is ``"10"``.
anode_c : str, optional
Anode c value that corresponds to the c coefficient in the non-linear relationship
between conductivity and current density.
The default value is ``"110000000000000"``.
anode_d : str, optional
Anode d value that corresponds to the d coefficient in the non-linear relationship
between conductivity and current density.
The default value is ``"2"``.
cathode_a : str, optional
Cathode a value that corresponds to the a coefficient in the non-linear relationship
between conductivity and current density.
The default value is ``"300000000"``.
cathode_b : str, optional
Cathode b value that corresponds to the b coefficient in the non-linear relationship
between conductivity and current density.
The default value is ``"10"``.
cathode_c : str, optional
Cathode c value that corresponds to the c coefficient in the non-linear relationship
between conductivity and current density.
The default value is ``"110000000000000"``.
cathode_d : str, optional
Cathode d value that corresponds to the d coefficient in the non-linear relationship
between conductivity and current density.
The default value is ``"2"``.
Returns
-------
:class:`ansys.aedt.core.modules.boundary.BoundaryObject`
Newly created object. ``False`` if it fails.
References
----------
>>> oModule.AssignResistiveSheet
Examples
--------
>>> import ansys.aedt.core
>>> from ansys.aedt.core.generic.constants import SOLUTIONS
>>> m3d = ansys.aedt.core.Maxwell3d(solution_type="Transient")
>>> my_box = m3d.modeler.create_box(origin=[0, 0, 0], sizes=[0.4, -1, 0.8], material="copper")
>>> resistive_face = my_box.faces[0]
>>> bound = self.aedtapp.assign_resistive_sheet(assignment=resistive_face, resistance="3ohm")
>>> self.aedtapp.solution_type = SOLUTIONS.Maxwell3d.Magnetostatic
>>> bound = self.aedtapp.assign_resistive_sheet(assignment=resistive_face, non_linear=True)
>>> m3d.release_desktop()
"""
if self.solution_type not in ["EddyCurrent", "Transient", "Magnetostatic"]:
self.logger.error(
"Resistive sheet is applicable only to Eddy current, transient and magnetostatic solvers."
)
return False

assignment = self.modeler.convert_to_selections(assignment, True)

if not name:
boundary = generate_unique_name("ResistiveSheet")

props = {
"Faces": assignment,
}

if self.solution_type in ["EddyCurrent", "Transient"]:
props["Resistance"] = resistance
elif self.solution_type == "Magnetostatic":
props["Nonlinear"] = non_linear
props["AnodeParA"] = anode_a
props["AnodeParB"] = anode_b
props["AnodeParC"] = anode_c
props["AnodeParD"] = anode_d
props["CathodeParA"] = cathode_a
props["CathodeParB"] = cathode_b
props["CathodeParC"] = cathode_c
props["CathodeParD"] = cathode_d

bound = BoundaryObject(self, boundary, props, "ResistiveSheet")
if bound.create():
self._boundaries[bound.name] = bound
return bound
return False


class Maxwell2d(Maxwell, FieldAnalysis3D, object):
"""Provides the Maxwell 2D app interface.
Expand Down
2 changes: 2 additions & 0 deletions src/ansys/aedt/core/modules/boundary.py
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,8 @@ def create(self):
self._app.oboundary.AssignFluxTangential(self._get_args())
elif bound_type == "Plane Incident Wave":
self._app.oboundary.AssignPlaneWave(self._get_args())
elif bound_type == "ResistiveSheet":
self._app.oboundary.AssignResistiveSheet(self._get_args())
else:
return False
return True
Expand Down
18 changes: 18 additions & 0 deletions tests/system/general/test_28_Maxwell3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -1127,3 +1127,21 @@ def test_59_assign_floating(self):
self.aedtapp.solution_type = SOLUTIONS.Maxwell3d.Magnetostatic
floating = self.aedtapp.assign_floating(assignment=box, charge_value=3)
assert not floating

def test_60_resistive_sheet(self):
self.aedtapp.insert_design("ResistiveSheet")
self.aedtapp.solution_type = SOLUTIONS.Maxwell3d.EddyCurrent
my_box = self.aedtapp.modeler.create_box(
origin=[0, 0, 0], sizes=[0.4, -1, 0.8], name="my_box", material="copper"
)
resistive_face = my_box.faces[0]
bound = self.aedtapp.assign_resistive_sheet(assignment=resistive_face, resistance="3ohm")
assert bound
assert bound.props["Faces"][0] == resistive_face.id
assert bound.props["Resistance"] == "3ohm"
self.aedtapp.solution_type = SOLUTIONS.Maxwell3d.Magnetostatic
bound = self.aedtapp.assign_resistive_sheet(assignment=resistive_face, non_linear=True)
assert bound.props["Nonlinear"]
assert bound.props["Faces"][0] == resistive_face.id
self.aedtapp.solution_type = SOLUTIONS.Maxwell3d.ACConduction
assert not self.aedtapp.assign_resistive_sheet(assignment=resistive_face, resistance="3ohm")
40 changes: 40 additions & 0 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from unittest.mock import MagicMock
from unittest.mock import patch

import pytest


@pytest.fixture
def maxwell_3d_setup():
"""Fixture used to setup a Maxwell3d instance."""

with patch("ansys.aedt.core.maxwell.FieldAnalysis3D") as mock_fiel_analysis_3d, patch(
"ansys.aedt.core.maxwell.Maxwell"
) as mock_maxwell:
mock_fiel_analysis_3d.return_value = MagicMock()
mock_maxwell.return_value = MagicMock()
yield {"FieldAnalysis3D": mock_fiel_analysis_3d, "Maxwell": mock_maxwell}
40 changes: 40 additions & 0 deletions tests/unit/test_maxwell_3d.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from unittest.mock import MagicMock
from unittest.mock import patch

from ansys.aedt.core.maxwell import Maxwell3d


@patch.object(Maxwell3d, "solution_type", "Transient")
@patch("ansys.aedt.core.maxwell.BoundaryObject", autospec=True)
def test_maxwell_3d_assign_resistive_sheet_failure(mock_boundary_object, maxwell_3d_setup):
boundary_object = MagicMock()
boundary_object.create.return_value = False
mock_boundary_object.return_value = boundary_object
maxwell = Maxwell3d()
maxwell._modeler = MagicMock()

assert not maxwell.assign_resistive_sheet(None, None)

0 comments on commit cf37ddd

Please sign in to comment.