Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEAT: enable harmonic force #5440

Draft
wants to merge 34 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
58a68ec
FEAT: added missing input parameters (issue #4779)
anur7 Nov 5, 2024
64f8ea4
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Nov 6, 2024
ac4ca86
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Nov 12, 2024
3078699
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Nov 14, 2024
7f4c6b0
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Nov 15, 2024
bf8c9e9
FEAT: implemented method for Eddy Current solver (issue #4779)
anur7 Nov 18, 2024
d69ab75
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Nov 20, 2024
b2fd29c
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Nov 22, 2024
c869b5c
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Nov 22, 2024
3b32bd9
FEAT:minor improvement
anur7 Nov 22, 2024
e6523ca
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Nov 27, 2024
cc25c01
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Nov 28, 2024
598a53b
FEAT:improvement for transient solver
anur7 Nov 28, 2024
6dbd081
FEAT: some docstring improvements
anur7 Nov 28, 2024
e06dbe4
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Dec 2, 2024
fe0157d
FEAT: some implementation improvements
anur7 Dec 2, 2024
1e93929
FEAT:minor improvement
anur7 Dec 4, 2024
cd0ad85
FEAT:minor improvement
anur7 Dec 5, 2024
aa94b3c
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Dec 9, 2024
3d07454
doc improved, added example
anur7 Dec 9, 2024
31e2b6c
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Dec 11, 2024
ceee2bf
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Dec 11, 2024
e4c83f7
improved implementation and UT
anur7 Dec 11, 2024
1f07f26
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Dec 12, 2024
c1364de
substituted "self.solution_type = None" with "pass" as it was before
anur7 Dec 12, 2024
db81c2e
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
gmalinve Dec 18, 2024
ea81b39
fix test
gmalinve Dec 18, 2024
45c5256
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Feb 12, 2025
c3de440
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Feb 13, 2025
41d8fcd
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Feb 14, 2025
ed17fca
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Feb 17, 2025
b6d4eb7
Merge branch 'refs/heads/main' into feat/enable-harmonic-force
anur7 Feb 19, 2025
c636463
improved unit test for enable harmonic force method, made independent…
anur7 Feb 19, 2025
db146d9
unit test
anur7 Feb 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 172 additions & 43 deletions src/ansys/aedt/core/maxwell.py
Original file line number Diff line number Diff line change
Expand Up @@ -1752,70 +1752,199 @@
def enable_harmonic_force(
self,
assignment,
coordinate_system="Global",
axis=2,
is_positive=True,
force_type=0,
calculate_force=0,
window_function="Rectangular",
use_number_of_last_cycles=True,
last_cycles_number=1,
calculate_force="Harmonic",
use_number_of_cycles_from_stop_time=True,
number_of_cycles_from_stop_time=1,
start_time="0s",
use_number_of_cycles_for_stop_time=True,
number_of_cycles_for_stop_time=1,
stop_time="0.01s",
output_frequency_range_type=0,
output_frequency_range_start="0Hz",
output_frequency_range_stop="1000Hz",
number_of_output_frequencies=10,
enable_inverter_feedback=False,
switching_frequency="4000Hz",
maximum_frequency="8000Hz",
):
"""Enable the harmonic force calculation for the transient analysis.

Available for Maxwell Eddy Current and Transient designs.

Parameters
----------
assignment : list
List of object names for force calculations.
Defines a list of object names for force calculations, for example:
["arc_01","arc_02","arc_03"]
coordinate_system: str, optional
Defines the coordinate system. The default is ``Global``.
axis : int, optional
Defines the rotation axis used to generate full model for a partial model
of electric machine.``0`` for X-axis, ``1`` for Y-axis, ``2`` for Z-axis.
The default is ``2``.
is_positive : bool, optional
Defines the rotation axis direction: ``True`` if ``Positive`` and ``False`` if ``Negative``.
The default is ``True``.
force_type : int, optional
Force type. Options are ``0`` for objects, ``1`` for surface, and ``2`` for volumetric.
Force Type. ``0`` for Object Based, ``1`` for Element Based (Surface), ``2`` for
Element Based (Volumetric).
window_function : str, optional
Windowing function. Default is ``"Rectangular"``.
Available options are: ``"Rectangular"``, ``"Tri"``, ``"Van Hann"``, ``"Hamming"``,
``"Blackman"``, ``"Lanczos"``, ``"Welch"``.
use_number_of_last_cycles : bool, optional
Use number of last cycles for force calculations. Default is ``True``.
last_cycles_number : int, optional
Defines the number of cycles to compute if `use_number_of_last_cycle` is ``True``.
calculate_force : sr, optional
How to calculate force. The default is ``"Harmonic"``.
Options are ``"Harmonic"`` and ``"Transient"``.

use_number_of_cycles_from_stop_time : bool, optional
If True, the harmonic force will be computed using the transient force during the
defined number of cycles backwards from stop time.
If False, the defined time range will be used. Default is ``True``.
For ``"TransientZ"`` and ``"TransientAphiFormulation"`` it is ``False``.
number_of_cycles_from_stop_time : int, optional
Defines the number of cycles from stop time for harmonic force computation,
if `use_number_of_cycles_from_stop_time` is ``True``.
start_time : str, optional
Defines the time range start time for harmonic force computation,
if `use_number_of_cycles_from_stop_time` is ``False``.
use_number_of_cycles_for_stop_time : bool, optional
If True, the time range stop time is defined using the number of cycles.
The harmonic force will be computed using the defined number of cycles forward from the start time.
If False, the time range stop time is defined using the stop time.
The harmonic force will be computed using the transient force between the start time and the stop time.
Default is ``True``.
For ``"TransientZ"`` and ``"TransientAphiFormulation"`` it is ``False``.
number_of_cycles_for_stop_time: int, optional
Defines the time range for harmonic force computation using the number of cycles,
if `use_number_of_cycles_for_stop_time` is ``True``.
stop_time : str, optional
Defines the time range stop time for harmonic force computation,
if `use_number_of_cycles_for_stop_time` is ``False``.
output_frequency_range_type : int, optional
Defines the type of the output frequency range. ``0`` for ``"Use All"``,
``1`` for ``"Use Range"``, and ``2`` for ``"Use Number"``.
The default is ``0``.
output_frequency_range_start : str, optional
The start frequency of calculated harmonic force components.
output_frequency_range_stop : str, optional
The end frequency of calculated harmonic force components.
number_of_output_frequencies : int, optional
Number of frequencies to output.
calculate_force : int, optional
How to calculate force: ``0`` for ``"Harmonic"``, ``1`` for ``"Transient"``,
and ``2`` for``"Harmonic and Transient"``. The default is ``0``.
enable_inverter_feedback : bool, optional
If ``True`` it enables inverter feedback. The default is ``False``.
switching_frequency: str, optional
The switching frequency is available if `enable_inverter_feedback´ is ``True``.
The default value is ``"4000Hz"``.
maximum_frequency: str, optional
The maximum frequency is available if `enable_inverter_feedback´ is ``True``.
The default value is ``"8000Hz"``.

Returns
-------
bool
``True`` when successful, ``False`` when failed.

References
-----------

>>> odesign.EnableHarmonicForceCalculation

Examples
---------

Enable harmonic force in Maxwell 3D for magnetic transient solver:

>>> from ansys.aedt.core import Maxwell3d
>>> m3d = Maxwell3d()
>>> m3d.enable_harmonic_force(assignment="Stator",number_of_cycles_from_stop_time=3)

"""
if self.solution_type != SOLUTIONS.Maxwell3d.Transient:
if self.solution_type not in [

Check warning on line 1866 in src/ansys/aedt/core/maxwell.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/aedt/core/maxwell.py#L1866

Added line #L1866 was not covered by tests
"EddyCurrent",
"Transient",
"TransientAPhiFormulation",
]:
raise AEDTRuntimeError("This methods work only with Maxwell Transient Analysis.")

assignment = self.modeler.convert_to_selections(assignment, True)
self.odesign.EnableHarmonicForceCalculation(
[
"EnabledObjects:=",
assignment,
"ForceType:=",
force_type,
"WindowFunctionType:=",
window_function,
"UseNumberOfLastCycles:=",
use_number_of_last_cycles,
"NumberOfLastCycles:=",
last_cycles_number,
"StartTime:=",
"0s",
"UseNumberOfCyclesForStopTime:=",
True,
"NumberOfCyclesForStopTime:=",
1,
"StopTime:=",
"0.01s",
"OutputFreqRangeType:=",
"Use All",
"CaculateForceType:=",
calculate_force + " Force",
]
)
return True
if self.solution_type == "EddyCurrent":
if not self.is3d and axis != 2:
axis = 2
self.logger.warning("For 2D EddyCurrent solver only Z-axis is available.")
self.odesign.EnableHarmonicForceCalculation(

Check warning on line 1876 in src/ansys/aedt/core/maxwell.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/aedt/core/maxwell.py#L1872-L1876

Added lines #L1872 - L1876 were not covered by tests
[
"EnabledObjects:=",
assignment,
"Coordinate System:=",
coordinate_system,
"Axis:=",
axis,
"Is Positive:=",
is_positive,
]
)
return True
elif self.solution_type in ["Transient", "TransientAPhiFormulation"]:
force = ["Harmonic", "Transient", "Harmonic and Transient"]
calculate_force = force[calculate_force]
range_type = ["Use All", "Use Range", "Use Number"]
output_frequency_range_type = range_type[output_frequency_range_type]
if not self.is3d and self.geometry_mode == "about Z" or self.solution_type == "TransientAPhiFormulation":
if force_type == 0 and calculate_force == "Transient":
calculate_force = "Harmonic"
self.logger.warning(

Check warning on line 1897 in src/ansys/aedt/core/maxwell.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/aedt/core/maxwell.py#L1888-L1897

Added lines #L1888 - L1897 were not covered by tests
"Object-Based Transient Force calculation is not supported for "
"non-rotational transient solutions. Only Harmonic Force will be calculated."
)
if not self.is3d and self.geometry_mode == "about Z":
if use_number_of_cycles_from_stop_time or use_number_of_cycles_for_stop_time:
self.logger.warning(

Check warning on line 1903 in src/ansys/aedt/core/maxwell.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/aedt/core/maxwell.py#L1901-L1903

Added lines #L1901 - L1903 were not covered by tests
" ``number_of_cycles_from_stop_time´´ and ``number_of_cycles_for_stop_time´´"
"are not available for TransientZ."
)
use_number_of_cycles_from_stop_time = False
use_number_of_cycles_for_stop_time = False
Comment on lines +1894 to +1908
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anur7 this part is very confusing. I'd simplify it. I also add an extra check on 2d and transient because use_number_of_cycles_from_stop_time and use_number_of_cycles_for_stop_time can be True in 3d Transient and Transient Aphi designs.
But this part has to be reviewed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gmalinve if I'm not wrong the Maxwell project used in UT contains only a transient 3d design. To increase the code coverage we need also a 2d design for testing.

self.odesign.EnableHarmonicForceCalculation(

Check warning on line 1909 in src/ansys/aedt/core/maxwell.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/aedt/core/maxwell.py#L1907-L1909

Added lines #L1907 - L1909 were not covered by tests
[
"EnabledObjects:=",
assignment,
"ForceType:=",
force_type,
"WindowFunctionType:=",
window_function,
"UseNumberOfLastCycles:=",
use_number_of_cycles_from_stop_time,
"NumberOfLastCycles:=",
number_of_cycles_from_stop_time,
"StartTime:=",
start_time,
"UseNumberOfCyclesForStopTime:=",
use_number_of_cycles_for_stop_time,
"NumberOfCyclesForStopTime:=",
number_of_cycles_for_stop_time,
"StopTime:=",
stop_time,
"OutputFreqRangeType:=",
output_frequency_range_type,
"OutputFreqRangeStart:=",
output_frequency_range_start,
"OutputFreqRangeStop:=",
output_frequency_range_stop,
"OutputFreqRangeNum:=",
str(number_of_output_frequencies),
"CaculateForceType:=",
calculate_force + " Force",
"EnableInverterFeedback:=",
enable_inverter_feedback,
"SwitchingFrequency:=",
switching_frequency,
"MaximumFrequency:=",
maximum_frequency,
]
)
return True

Check warning on line 1947 in src/ansys/aedt/core/maxwell.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/aedt/core/maxwell.py#L1947

Added line #L1947 was not covered by tests

@pyaedt_function_handler(layout_component_name="assignment")
def enable_harmonic_force_on_layout_component(
Expand Down
17 changes: 16 additions & 1 deletion tests/system/solvers/test_00_analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ def circuit_com(add_app):
@pytest.fixture(scope="class")
def m3dtransient(add_app):
app = add_app(application=Maxwell3d, project_name=transient, subfolder=test_subfolder)
return app
yield app
app.close_project(app.project_name)


class TestClass:
Expand Down Expand Up @@ -506,6 +507,20 @@ def test_05d_circuit_push_excitation_time(self, circuit_app):
assert circuit_app.push_time_excitations(instance="U1", setup=setup_name)

def test_06_m3d_harmonic_forces(self, m3dtransient):
assert m3dtransient.enable_harmonic_force(
["Stator"],
force_type=2,
window_function="Rectangular",
use_number_of_cycles_from_stop_time=True,
number_of_cycles_from_stop_time=3,
calculate_force=0,
)
m3dtransient.solution_type = m3dtransient.SOLUTIONS.Maxwell3d.EddyCurrent
assert m3dtransient.enable_harmonic_force(assignment=["Stator"])
m3dtransient.solution_type = m3dtransient.SOLUTIONS.Maxwell3d.TransientAPhiFormulation
assert m3dtransient.enable_harmonic_force(assignment=["Stator"], calculate_force=1)

def test_06_export_element_based_harmonic_force(self, m3dtransient):
assert m3dtransient.export_element_based_harmonic_force(
start_frequency=1, stop_frequency=100, number_of_frequency=None
)
Expand Down
Loading