diff --git a/src/ansys/aedt/core/application/analysis.py b/src/ansys/aedt/core/application/analysis.py index 1e16cfa9cc3..ff1819d4641 100644 --- a/src/ansys/aedt/core/application/analysis.py +++ b/src/ansys/aedt/core/application/analysis.py @@ -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) @@ -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: diff --git a/src/ansys/aedt/core/modules/setup_templates.py b/src/ansys/aedt/core/modules/setup_templates.py index 2bc42ffc1e9..04e5b49d3ea 100644 --- a/src/ansys/aedt/core/modules/setup_templates.py +++ b/src/ansys/aedt/core/modules/setup_templates.py @@ -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( { @@ -317,7 +315,6 @@ def HFSS3DLayout_AdaptiveFrequencyData(freq): "SmoothBHCurve": False, "Frequency": "60Hz", "HasSweepSetup": False, - "SweepRanges": subranges, "UseHighOrderShapeFunc": False, "UseMuLink": False, } diff --git a/src/ansys/aedt/core/modules/solve_setup.py b/src/ansys/aedt/core/modules/solve_setup.py index 7325f8d82c8..7939aebe100 100644 --- a/src/ansys/aedt/core/modules/solve_setup.py +++ b/src/ansys/aedt/core/modules/solve_setup.py @@ -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 @@ -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) @@ -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 @@ -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 @@ -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 @@ -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 -------- @@ -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 ---------- @@ -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``. @@ -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): @@ -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. @@ -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. @@ -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: @@ -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 -------- diff --git a/src/ansys/aedt/core/modules/solve_sweeps.py b/src/ansys/aedt/core/modules/solve_sweeps.py index 3b85a3b29e9..7fa5ba3a832 100644 --- a/src/ansys/aedt/core/modules/solve_sweeps.py +++ b/src/ansys/aedt/core/modules/solve_sweeps.py @@ -35,6 +35,7 @@ from ansys.aedt.core.generic.load_aedt_file import load_entire_aedt_file from ansys.aedt.core.generic.settings import settings from ansys.aedt.core.modules.setup_templates import Sweep3DLayout +from ansys.aedt.core.modules.setup_templates import SweepEddyCurrent from ansys.aedt.core.modules.setup_templates import SweepHfss3D from ansys.aedt.core.modules.setup_templates import SweepSiwave @@ -608,7 +609,6 @@ class SweepMatrix(object): props : dict Dictionary of the properties. The default is ``None``, in which case the default properties are retrieved. - """ def __init__(self, setup, name, sweep_type="Interpolating", props=None): @@ -827,6 +827,151 @@ def _get_args(self, props=None): return arg +class SweepMaxwellEC(object): + """Initializes, creates, and updates sweeps in Maxwell Eddy Current. + + Parameters + ---------- + setup : :class 'from ansys.aedt.core.modules.solve_setup.Setup' + Setup used for the analysis. + name : str + Name of the sweep. + sweep_type : str, optional + Type of the sweep. Options are ``"LinearStep"``, ``"LinearCount"``, + ``"LogScale"`` and ``"SinglePoints"``. The default is ``"LinearStep"``. + props : dict + Dictionary of the properties. The default is ``None``, in which case + the default properties are retrieved. + """ + + def __init__(self, setup, sweep_type="LinearStep", props=None): + self._setup = setup + self.oanalysis = setup.omodule + self.setup_name = setup.name + self.props = {} + if props: + self.props = props + else: + self.props = copy.deepcopy(SweepEddyCurrent) + self.props["RangeType"] = sweep_type + if sweep_type == "LinearStep": + self.props["RangeStep"] = "10Hz" + elif sweep_type == "LinearCount": + self.props["RangeCount"] = "10" + elif sweep_type == "LogScale": + self.props["RangeSamples"] = "2" + elif sweep_type == "SinglePoints": + self.props["RangeEnd"] = self.props["RangeStart"] + + @property + def is_solved(self): + """Verify if solutions are available for the sweep. + + Returns + ------- + bool + `True` if solutions are available. + """ + expressions = [ + i for i in self._setup.p_app.post.available_report_quantities(solution=self._setup.p_app.nominal_sweep) + ] + sol = self._setup.p_app.post.reports_by_category.standard( + expressions=expressions[0], setup=self._setup.p_app.nominal_sweep + ) + if identify_setup(self.props): + sol.domain = "Time" + return True if sol.get_solution_data() else False + + @property + def frequencies(self): + """List of all frequencies of the active sweep. + + To see values, the project must be saved and solved. + + Returns + ------- + list of float + Frequency points. + """ + expressions = [ + i for i in self._setup.p_app.post.available_report_quantities(solution=self._setup.p_app.nominal_sweep) + ] + sol = self._setup.p_app.post.reports_by_category.standard( + expressions=expressions[0], setup=self._setup.p_app.nominal_sweep + ) + soldata = sol.get_solution_data() + if soldata and "Freq" in soldata.intrinsics: + return soldata.intrinsics["Freq"] + return [] + + @pyaedt_function_handler() + def create(self): + """Create a Maxwell Eddy Current sweep. + + Returns + ------- + bool + ``True`` when successful, ``False`` when failed. + + """ + self.oanalysis.EditSetup(self.setup_name, self._get_args(self._setup.props)) + return True + + @pyaedt_function_handler() + def update(self): + """Update a Maxwell Eddy Current sweep. + + Returns + ------- + bool + ``True`` when successful, ``False`` when failed. + """ + self.oanalysis.EditSetup(self.setup_name, self._get_args(self._setup.props)) + return True + + @pyaedt_function_handler() + def delete(self): + """Delete a Maxwell Eddy Current sweep. + + Returns + ------- + bool + ``True`` when successful, ``False`` when failed. + """ + setup_sweeps = self._setup.props["SweepRanges"]["Subrange"] + if isinstance(setup_sweeps, list): + for sweep in setup_sweeps: + if self.props == sweep: + self._setup.props["SweepRanges"]["Subrange"].remove(self.props) + else: + pass + + self.oanalysis.EditSetup(self.setup_name, self._get_args(self._setup.props)) + return True + + @pyaedt_function_handler() + def _get_args(self, props=None): + """Get arguments. + + Parameters + ---------- + props : dict, optional + Dictionary of the properties. The default is ``None``, in which + case the default properties are retrieved. + + Returns + ------- + dict + Dictionary of the properties. + + """ + if props is None: + props = self.props + arg = ["NAME:" + self.setup_name] + _dict2arg(props, arg) + return arg + + class SetupProps(dict): """Provides internal parameters for the AEDT boundary component.""" diff --git a/tests/system/general/test_27_Maxwell2D.py b/tests/system/general/test_27_Maxwell2D.py index 44cf6209865..21bbf755002 100644 --- a/tests/system/general/test_27_Maxwell2D.py +++ b/tests/system/general/test_27_Maxwell2D.py @@ -635,3 +635,50 @@ def test_assign_voltage(self, local_scratch, m2d_app): rect = m2d_app.modeler.create_rectangle([32, 1.5, 0], [8, 3], is_covered=True) assert m2d_app.assign_voltage(assignment=[region_id.name, rect.name], amplitude=3, name="GRD4") assert len(m2d_app.boundaries) == 4 + + def test_set_save_fields(self, m2d_app): + m2d_app.solution_type = SOLUTIONS.Maxwell2d.MagnetostaticXY + + setup = m2d_app.create_setup() + assert setup.set_save_fields(enable=True) + assert setup.set_save_fields(enable=False) + + m2d_app.solution_type = SOLUTIONS.Maxwell2d.TransientXY + setup = m2d_app.create_setup() + assert setup.set_save_fields( + enable=True, range_type="Custom", subrange_type="LinearStep", start=0, stop=8, count=2, units="ms" + ) + assert len(setup.props["SweepRanges"]["Subrange"]) == 1 + assert setup.props["SweepRanges"]["Subrange"][0]["RangeType"] == "LinearStep" + assert setup.props["SweepRanges"]["Subrange"][0]["RangeStart"] == "0ms" + assert setup.props["SweepRanges"]["Subrange"][0]["RangeEnd"] == "8ms" + assert setup.props["SweepRanges"]["Subrange"][0]["RangeStep"] == "2ms" + assert setup.set_save_fields( + enable=True, range_type="Custom", subrange_type="LinearCount", start=0, stop=8, count=2, units="ms" + ) + assert len(setup.props["SweepRanges"]["Subrange"]) == 2 + assert setup.props["SweepRanges"]["Subrange"][1]["RangeType"] == "LinearCount" + assert setup.props["SweepRanges"]["Subrange"][1]["RangeStart"] == "0ms" + assert setup.props["SweepRanges"]["Subrange"][1]["RangeEnd"] == "8ms" + assert setup.props["SweepRanges"]["Subrange"][1]["RangeCount"] == 2 + assert setup.set_save_fields( + enable=True, range_type="Custom", subrange_type="SinglePoints", start=3, units="ms" + ) + assert len(setup.props["SweepRanges"]["Subrange"]) == 3 + assert setup.props["SweepRanges"]["Subrange"][2]["RangeType"] == "SinglePoints" + assert setup.props["SweepRanges"]["Subrange"][2]["RangeStart"] == "3ms" + assert setup.props["SweepRanges"]["Subrange"][2]["RangeEnd"] == "3ms" + assert setup.set_save_fields(enable=True, range_type="Every N Steps", start=0, stop=10, count=1, units="ms") + assert setup.props["SaveFieldsType"] == "Every N Steps" + assert setup.props["Steps From"] == "0ms" + assert setup.props["Steps To"] == "10ms" + assert setup.props["N Steps"] == "1" + assert setup.set_save_fields( + enable=True, range_type="Custom", subrange_type="SinglePoints", start=3, units="ms" + ) + assert len(setup.props["SweepRanges"]["Subrange"]) == 1 + assert setup.props["SweepRanges"]["Subrange"][0]["RangeType"] == "SinglePoints" + assert setup.props["SweepRanges"]["Subrange"][0]["RangeStart"] == "3ms" + assert setup.props["SweepRanges"]["Subrange"][0]["RangeEnd"] == "3ms" + assert setup.set_save_fields(enable=False) + assert not setup.set_save_fields(enable=True, range_type="invalid") diff --git a/tests/system/general/test_28_Maxwell3D.py b/tests/system/general/test_28_Maxwell3D.py index 6f80e0b1064..d3f03e18d77 100644 --- a/tests/system/general/test_28_Maxwell3D.py +++ b/tests/system/general/test_28_Maxwell3D.py @@ -168,7 +168,7 @@ def test_eddy_effects_on(self, m3d_app): assert not m3d_app.oboundary.GetEddyEffect("Plate") assert not m3d_app.oboundary.GetDisplacementCurrent("Plate") - def test_create_setup(self, m3d_app): + def test_eddy_current_sweep(self, m3d_app): m3d_app.solution_type = SOLUTIONS.Maxwell3d.EddyCurrent setup = m3d_app.create_setup() setup.props["MaximumPasses"] = 12 @@ -179,17 +179,53 @@ def test_create_setup(self, m3d_app): dc_freq = 0.1 stop_freq = 10 count = 1 - assert setup.add_eddy_current_sweep("LinearStep", dc_freq, stop_freq, count, clear=True) - assert isinstance(setup.props["SweepRanges"]["Subrange"], dict) + sweep = setup.add_eddy_current_sweep( + sweep_type="LinearStep", start_frequency=dc_freq, stop_frequency=stop_freq, step_size=count, clear=True + ) + assert sweep.props["RangeType"] == "LinearStep" + assert sweep.props["RangeStart"] == "0.1Hz" + assert sweep.props["RangeEnd"] == "10Hz" + assert sweep.props["RangeStep"] == "1Hz" + assert isinstance(setup.props["SweepRanges"]["Subrange"], list) + m3d_app.save_project() + assert len(setup.props["SweepRanges"]["Subrange"]) == 1 assert setup.props["SaveAllFields"] - assert setup.add_eddy_current_sweep("LinearCount", dc_freq, stop_freq, count, clear=False) + sweep = setup.add_eddy_current_sweep( + sweep_type="LinearCount", start_frequency=dc_freq, stop_frequency=stop_freq, step_size=count, clear=False + ) + assert sweep.props["RangeType"] == "LinearCount" + assert sweep.props["RangeStart"] == "0.1Hz" + assert sweep.props["RangeEnd"] == "10Hz" + assert sweep.props["RangeCount"] == 1 + assert isinstance(setup.props["SweepRanges"]["Subrange"], list) + m3d_app.save_project() + assert len(setup.props["SweepRanges"]["Subrange"]) == 2 + sweep = setup.add_eddy_current_sweep( + sweep_type="LogScale", start_frequency=dc_freq, stop_frequency=stop_freq, step_size=count, clear=True + ) + assert sweep.props["RangeType"] == "LogScale" + assert sweep.props["RangeStart"] == "0.1Hz" + assert sweep.props["RangeEnd"] == "10Hz" + assert sweep.props["RangeSamples"] == 1 assert isinstance(setup.props["SweepRanges"]["Subrange"], list) - assert setup.add_eddy_current_sweep("SinglePoints", start_frequency=0.01, clear=False) + m3d_app.save_project() + assert len(setup.props["SweepRanges"]["Subrange"]) == 1 + sweep = setup.add_eddy_current_sweep(sweep_type="SinglePoints", start_frequency=0.01, clear=False) + assert sweep.props["RangeType"] == "SinglePoints" + assert sweep.props["RangeStart"] == "0.01Hz" + assert sweep.props["RangeEnd"] == "0.01Hz" + m3d_app.save_project() + assert len(setup.props["SweepRanges"]["Subrange"]) == 2 + assert sweep.delete() + m3d_app.save_project() + assert len(setup.props["SweepRanges"]["Subrange"]) == 1 assert setup.update() assert setup.enable_expression_cache(["CoreLoss"], "Fields", "Phase='0deg' ", True) assert setup.props["UseCacheFor"] == ["Pass", "Freq"] assert setup.disable() assert setup.enable() + assert not sweep.is_solved + assert isinstance(sweep.frequencies, list) def test_create_parametrics(self, m3d_app): m3d_app.create_setup()