Skip to content

Commit

Permalink
CHORE: SetupMaxwell refactoring to save fields and new SweepMaxwell f…
Browse files Browse the repository at this point in the history
…or EC solvers (#5670)
  • Loading branch information
gmalinve authored Feb 6, 2025
1 parent ddecb1d commit f87d9a1
Show file tree
Hide file tree
Showing 6 changed files with 395 additions and 65 deletions.
6 changes: 4 additions & 2 deletions src/ansys/aedt/core/application/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,7 @@ def _create_setup(self, name="MySetupAuto", setup_type=None, props=None):
setup = SetupSBR(self, setup_type, name)
elif setup_type in [5, 6, 7, 8, 9, 10, 56, 58, 59]:
setup = SetupMaxwell(self, setup_type, name)
elif setup_type == 14:
elif setup_type in [14, 30]:
setup = SetupQ3D(self, setup_type, name)
elif setup_type in [11, 36]:
setup = SetupIcepak(self, setup_type, name)
Expand Down Expand Up @@ -1524,13 +1524,15 @@ def get_setup(self, name):
if self.solution_type == "SBR+":
setuptype = 4
setup = SetupSBR(self, setuptype, name, is_new_setup=False)
elif self.design_type in ["Q3D Extractor", "2D Extractor", "HFSS"]:
elif self.design_type == "HFSS":
setup = SetupHFSS(self, setuptype, name, is_new_setup=False)
if setup.properties:
if "Auto Solver Setting" in setup.properties:
setup = SetupHFSSAuto(self, 0, name, is_new_setup=False)
elif setup.props and setup.props.get("SetupType", "") == "HfssDrivenAuto":
setup = SetupHFSSAuto(self, 0, name, is_new_setup=False)
elif self.design_type in ["Q3D Extractor", "2D Extractor"]:
setup = SetupQ3D(self, setuptype, name, is_new_setup=False)
elif self.design_type in ["Maxwell 2D", "Maxwell 3D"]:
setup = SetupMaxwell(self, setuptype, name, is_new_setup=False)
else:
Expand Down
11 changes: 4 additions & 7 deletions src/ansys/aedt/core/modules/setup_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,15 +290,13 @@ def HFSS3DLayout_AdaptiveFrequencyData(freq):
)
"""Maxwell electrostatic setup properties and default values."""

subrange = dict(
SweepEddyCurrent = dict(
{
"SweepSetupType": "LinearStep",
"StartValue": "1e-08GHz",
"StopValue": "1e-06GHz",
"StepSize": "1e-08GHz",
"RangeType": "LinearStep",
"RangeStart": "1e-08GHz",
"RangeEnd": "1e-06GHz",
}
)
subranges = dict({"Subrange": subrange})

EddyCurrent = dict(
{
Expand All @@ -317,7 +315,6 @@ def HFSS3DLayout_AdaptiveFrequencyData(freq):
"SmoothBHCurve": False,
"Frequency": "60Hz",
"HasSweepSetup": False,
"SweepRanges": subranges,
"UseHighOrderShapeFunc": False,
"UseMuLink": False,
}
Expand Down
203 changes: 153 additions & 50 deletions src/ansys/aedt/core/modules/solve_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
from ansys.aedt.core.modules.solve_sweeps import SweepHFSS
from ansys.aedt.core.modules.solve_sweeps import SweepHFSS3DLayout
from ansys.aedt.core.modules.solve_sweeps import SweepMatrix
from ansys.aedt.core.modules.solve_sweeps import SweepMaxwellEC
from ansys.aedt.core.modules.solve_sweeps import identify_setup


Expand Down Expand Up @@ -108,10 +109,7 @@ def sweeps(self):
setups_data = self.p_app.design_properties["AnalysisSetup"]["SolveSetups"]
if self.name in setups_data:
setup_data = setups_data[self.name]
if "Sweeps" in setup_data and self.setuptype not in [
0,
7,
]: # 0 and 7 represent setup HFSSDrivenAuto
if "Sweeps" in setup_data and self.setuptype != 0: # 0 represents setup HFSSDrivenAuto
if self.setuptype <= 4:
app = setup_data["Sweeps"]
app.pop("NextUniqueID", None)
Expand All @@ -126,6 +124,13 @@ def sweeps(self):
if isinstance(app[el], dict):
self._sweeps.append(SweepMatrix(self, el, props=app[el]))
setup_data.pop("Sweeps", None)
elif "SweepRanges" in setup_data:
app = setup_data["SweepRanges"]
if isinstance(app["Subrange"], list):
for subrange in app["Subrange"]:
self._sweeps.append(SweepMaxwellEC(self, props=subrange))
else:
self._sweeps.append(SweepMaxwellEC(self, props=app["Subrange"]))
except (TypeError, KeyError):
pass
return self._sweeps
Expand Down Expand Up @@ -2881,8 +2886,7 @@ def add_sweep(self, name=None, sweep_type="Interpolating"):
Returns
-------
:class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS` or
:class:`ansys.aedt.core.modules.solve_sweeps.SweepMatrix`
:class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS`
Sweep object.
References
Expand All @@ -2891,16 +2895,8 @@ def add_sweep(self, name=None, sweep_type="Interpolating"):
"""
if not name:
name = generate_unique_name("Sweep")
if self.setuptype == 7:
self._app.logger.warning("This method only applies to HFSS and Q3D. Use add_eddy_current_sweep method.")
return False
if self.setuptype <= 4:
sweep_n = SweepHFSS(self, name=name, sweep_type=sweep_type)
elif self.setuptype in [14, 30, 31]:
sweep_n = SweepMatrix(self, name=name, sweep_type=sweep_type)
else:
self._app.logger.warning("This method only applies to HFSS, Q2D, and Q3D.")
return False
sweep_n.create()
self.sweeps.append(sweep_n)
return sweep_n
Expand All @@ -2917,8 +2913,7 @@ def get_sweep(self, name=None):
Returns
-------
:class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS` or
:class:`ansys.aedt.core.modules.solve_sweeps.SweepMatrix`
:class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS`
Examples
--------
Expand Down Expand Up @@ -3572,7 +3567,7 @@ def add_subrange(self, range_type, start, end=None, count=None, unit="GHz", clea


class SetupMaxwell(Setup, object):
"""Initializes, creates, and updates an HFSS setup.
"""Initializes, creates, and updates a Maxwell setup.
Parameters
----------
Expand Down Expand Up @@ -3616,7 +3611,7 @@ def add_eddy_current_sweep(
step_size : int or float, optional
Frequency count or frequency step. Required for ``range_type="LinearCount"|"LinearStep"|"LogScale"``.
units : str, optional
Unit of the frequency. For example, ``"MHz`` or ``"GHz"``. The default is ``"Hz"``.
Unit of the frequency. For example, ``"Hz`` or ``"MHz"``. The default is ``"Hz"``.
clear : bool, optional
If set to ``True``, all other subranges will be suppressed except the current one under creation.
Default value is ``False``.
Expand All @@ -3626,39 +3621,55 @@ def add_eddy_current_sweep(
Returns
-------
bool
``True`` if successful, ``False`` if it fails.
"""
:class:`ansys.aedt.core.modules.solve_sweeps.SweepMaxwellEC`
Sweep object.
Example
-------
>>> import ansys.aedt.core
>>> m2d = ansys.aedt.core.Maxwell2d(version="2025.1")
>>> m2d.solution_type = SOLUTIONS.Maxwell2d.EddyCurrentXY
>>> setup = m2d.create_setup()
>>> sweep = setup.add_eddy_current_sweep(sweep_type="LinearStep", start_frequency=1, stop_frequency=20,
... step_size=2, units="Hz", clear=False)
>>> sweep.props["RangeStart"] = "0.1Hz"
>>> sweep.update()
>>> m2d.release_desktop()
"""
if self.setuptype != 7:
self._app.logger.warning("This method only applies to Maxwell Eddy Current Solution.")
return False
sweep = SweepMaxwellEC(self, sweep_type=sweep_type)
legacy_update = self.auto_update
self.auto_update = False
sweep_props = {
"RangeType": sweep_type,
"RangeStart": f"{start_frequency}{units}",
"RangeEnd": f"{stop_frequency}{units}",
}
self.props["HasSweepSetup"] = True
sweep.props["RangeType"] = sweep_type
sweep.props["RangeStart"] = f"{start_frequency}{units}"
sweep.props["RangeEnd"] = f"{stop_frequency}{units}"
if sweep_type == "LinearStep":
sweep_props["RangeStep"] = f"{step_size}{units}"
sweep.props["RangeStep"] = f"{step_size}{units}"
elif sweep_type == "LinearCount":
sweep_props["RangeCount"] = step_size
sweep.props["RangeCount"] = step_size
elif sweep_type == "LogScale":
sweep_props["RangeSamples"] = step_size
sweep.props["RangeSamples"] = step_size
elif sweep_type == "SinglePoints":
sweep_props["RangeEnd"] = f"{start_frequency}{units}"
if clear:
self.props["SweepRanges"]["Subrange"] = sweep_props
elif isinstance(self.props["SweepRanges"]["Subrange"], list):
self.props["SweepRanges"]["Subrange"].append(sweep_props)
else:
self.props["SweepRanges"]["Subrange"] = [self.props["SweepRanges"]["Subrange"], sweep_props]
sweep.props["RangeEnd"] = f"{start_frequency}{units}"
self.props["SaveAllFields"] = save_all_fields
if self.sweeps:
if clear:
self.props["SweepRanges"] = {"Subrange": [sweep.props]}
else:
if isinstance(self.props["SweepRanges"]["Subrange"], dict):
temp = self.props["SweepRanges"]["Subrange"]
self.props["SweepRanges"].pop("Subrange", None)
self.props["SweepRanges"]["Subrange"] = [temp]
self.props["SweepRanges"]["Subrange"].append(sweep.props)
else:
self.props["HasSweepSetup"] = True
self.props["SweepRanges"] = {"Subrange": [sweep.props]}
sweep.create()
self.update()
self.auto_update = legacy_update
return True
return sweep

@pyaedt_function_handler()
def enable_control_program(self, control_program_path, control_program_args=" ", call_after_last_step=False):
Expand Down Expand Up @@ -3717,6 +3728,108 @@ def enable_control_program(self, control_program_path, control_program_args=" ",

return True

@pyaedt_function_handler()
def set_save_fields(
self, enable=True, range_type="Custom", subrange_type="LinearStep", start=0, stop=100000, count=1, units="ns"
):
"""Enable the save fields option in the setup.
Parameters
----------
enable : bool, optional
Whether to enable the save fields option.
The default value is ``True``.
range_type : str, optional
Range type. The available options are ``"Custom"`` to set a custom range type
or ``"Every N Steps"`` to set the steps within the range.
The default value is ``Custom``.
subrange_type : str, optional
In case of a custom range type the ``subrange_type`` defines the subrange type.
The available options are ``"LinearStep"``, ``"LinearCount"`` and ``"SinglePoints"``.
The default option is ``"LinearStep"``.
start : float, optional
Range or steps starting point.
The default value is 0.
stop : float, optional
Range or steps starting point.
The default value is 100000.
count : float, optional
Range count or step.
The default value is 1.
units : str, optional
Time units.
The default is "ns".
Returns
-------
bool
``True`` if successful, ``False`` if it fails.
Example
-------
>>> import ansys.aedt.core
>>> m2d = ansys.aedt.core.Maxwell2d(version="2025.1")
>>> m2d.solution_type = SOLUTIONS.Maxwell2d.TransientXY
>>> setup = m2d.create_setup()
>>> setup.set_save_fields(enable=True, range_type="Custom", subrange_type="LinearStep", start=0, stop=8,
... count=2, units="ms")
>>> m2d.release_desktop()
"""
if self.setuptype != 5:
if enable:
self.props["SolveFieldOnly"] = True
else:
self.props["SolveFieldOnly"] = False
self.update()
return True
else:
if enable:
if range_type == "Custom":
if self.props["SaveFieldsType"] == "Every N Steps":
self.props.pop("Steps From", None)
self.props.pop("Steps To", None)
self.props.pop("N Steps", None)
self.props["SaveFieldsType"] = range_type
range_props = {
"RangeType": subrange_type,
"RangeStart": f"{start}{units}",
"RangeEnd": f"{stop}{units}",
}
if subrange_type == "LinearStep":
range_props["RangeStep"] = f"{count}{units}"
elif subrange_type == "LinearCount":
range_props["RangeCount"] = count
elif subrange_type == "SinglePoints":
range_props["RangeEnd"] = f"{start}{units}"
if "SweepRanges" in self.props.keys():
if isinstance(self.props["SweepRanges"]["Subrange"], dict):
temp = self.props["SweepRanges"]["Subrange"]
self.props["SweepRanges"].pop("Subrange", None)
self.props["SweepRanges"]["Subrange"] = [temp]
self.props["SweepRanges"]["Subrange"].append(range_props)
else:
self.props["SweepRanges"] = {"Subrange": [range_props]}
self.update()
return True
elif range_type == "Every N Steps":
if self.props["SaveFieldsType"] == "Custom":
self.props.pop("SweepRanges", None)
self.auto_update = False
self.props["SaveFieldsType"] = "Every N Steps"
self.props["N Steps"] = f"{count}"
self.props["Steps From"] = f"{start}{units}"
self.props["Steps To"] = f"{stop}{units}"
self.update()
return True
else:
self._app.logger.error("Invalid range type. It has to be either 'Custom' or 'Every N Steps'.")
return False
else:
self.props["SaveFieldsType"] = "None"
self.props.pop("SweepRanges", None)
self.update()
return True


class SetupQ3D(Setup, object):
"""Initializes, creates, and updates an Q3D setup.
Expand Down Expand Up @@ -4026,7 +4139,6 @@ def add_sweep(self, name=None, sweep_type="Interpolating"):
Returns
-------
:class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS` or
:class:`ansys.aedt.core.modules.solve_sweeps.SweepMatrix`
Sweep object.
Expand All @@ -4036,16 +4148,8 @@ def add_sweep(self, name=None, sweep_type="Interpolating"):
"""
if not name:
name = generate_unique_name("Sweep")
if self.setuptype == 7:
self._app.logger.warning("This method only applies to HFSS and Q3D. Use add_eddy_current_sweep method.")
return False
if self.setuptype <= 4:
sweep_n = SweepHFSS(self, name=name, sweep_type=sweep_type)
elif self.setuptype in [14, 30, 31]:
if self.setuptype in [14, 30, 31]:
sweep_n = SweepMatrix(self, name=name, sweep_type=sweep_type)
else:
self._app.logger.warning("This method only applies to HFSS, Q2D, and Q3D.")
return False
sweep_n.create()
self.sweeps.append(sweep_n)
for setup in self.p_app.setups:
Expand All @@ -4066,8 +4170,7 @@ def get_sweep(self, name=None):
Returns
-------
:class:`ansys.aedt.core.modules.solve_sweeps.SweepQ3D` or
:class:`ansys.aedt.core.modules.solve_sweeps.SweepMatrix`
:class:`ansys.aedt.core.modules.solve_sweeps.SweepQ3D`
Examples
--------
Expand Down
Loading

0 comments on commit f87d9a1

Please sign in to comment.