From eb9f17171cb273424bd1fedf81ec58bae38a0f53 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Mon, 22 Jul 2024 09:32:10 +0200 Subject: [PATCH] REFACTOR: Intrinsics management (#4921) Co-authored-by: maxcapodi78 Co-authored-by: Giulia Malinverno Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- _unittest_solvers/test_00_analyze.py | 21 +- pyaedt/application/Analysis.py | 45 +++ pyaedt/modules/AdvancedPostProcessing.py | 36 ++- pyaedt/modules/PostProcessor.py | 331 ++++++++++++++++------- 4 files changed, 323 insertions(+), 110 deletions(-) diff --git a/_unittest_solvers/test_00_analyze.py b/_unittest_solvers/test_00_analyze.py index eec974cc0e1..6d93fd40eb0 100644 --- a/_unittest_solvers/test_00_analyze.py +++ b/_unittest_solvers/test_00_analyze.py @@ -190,15 +190,32 @@ def test_02_hfss_export_results(self, hfss_app): matrix_type="Y", ) assert len(exported_files) > 0 - fld_file1 = os.path.join(self.local_scratch.path, "test_fld_hfss1.fld") assert hfss_app.post.export_field_file(quantity="Mag_E", output_file=fld_file1, assignment="Box1", intrinsics="1GHz", phase="5deg") assert os.path.exists(fld_file1) fld_file2 = os.path.join(self.local_scratch.path, "test_fld_hfss2.fld") assert hfss_app.post.export_field_file(quantity="Mag_E", output_file=fld_file2, assignment="Box1", - intrinsics="1GHz") + intrinsics={"frequency":"1GHz"}) + assert os.path.exists(fld_file2) + fld_file2 = os.path.join(self.local_scratch.path, "test_fld_hfss3.fld") + assert hfss_app.post.export_field_file(quantity="Mag_E", output_file=fld_file2, assignment="Box1", + intrinsics={"frequency":"1GHz", "phase":"30deg"}) + assert os.path.exists(fld_file2) + fld_file2 = os.path.join(self.local_scratch.path, "test_fld_hfss4.fld") + assert hfss_app.post.export_field_file(quantity="Mag_E", output_file=fld_file2, assignment="Box1", + intrinsics={"frequency": "1GHz"}, phase="30deg") assert os.path.exists(fld_file2) + fld_file2 = os.path.join(self.local_scratch.path, "test_fld_hfss5.fld") + assert hfss_app.post.export_field_file(quantity="Mag_E", output_file=fld_file2, assignment="Box1", + ) + assert os.path.exists(fld_file2) + fld_file2 = os.path.join(self.local_scratch.path, "test_fld_hfss6.fld") + with pytest.raises(AttributeError): + hfss_app.post.export_field_file(quantity="Mag_E", output_file=fld_file2, assignment="Box1", + intrinsics=[]) + assert not os.path.exists(fld_file2) + def test_03a_icepak_analyze_and_export_summary(self): self.icepak_app.solution_type = self.icepak_app.SOLUTIONS.Icepak.SteadyFlowOnly diff --git a/pyaedt/application/Analysis.py b/pyaedt/application/Analysis.py index 4409de6c51f..8e426870c40 100644 --- a/pyaedt/application/Analysis.py +++ b/pyaedt/application/Analysis.py @@ -533,6 +533,51 @@ def excitation_objects(self): return self._excitation_objects + @pyaedt_function_handler() + def _check_intrinsics(self, input_data, input_phase=None, setup=None, return_list=False): + intrinsics = {} + if input_data is None: + if setup is None: + try: + setup = self.existing_analysis_sweeps[0].split(":")[0].strip() + except Exception: + setup = None + else: + setup = setup.split(":")[0].strip() + for set_obj in self.setups: + if set_obj.name == setup: + intrinsics = set_obj.default_intrinsics + break + + elif isinstance(input_data, str): + if "Freq" in self.design_solutions.intrinsics: + intrinsics["Freq"] = input_data + if "Phase" in self.design_solutions.intrinsics: + intrinsics["Phase"] = input_phase if input_phase else "0deg" + elif "Time" in self.design_solutions.intrinsics: + intrinsics["Time"] = input_data + elif isinstance(input_data, dict): + for k, v in input_data.items(): + if k in ["Freq", "freq", "frequency", "Frequency"]: + intrinsics["Freq"] = v + elif k in ["Phase", "phase"]: + intrinsics["Phase"] = v + elif k in ["Time", "time"]: + intrinsics["Time"] = v + if input_phase: + intrinsics["Phase"] = input_phase + if "Phase" in self.design_solutions.intrinsics and "Phase" not in intrinsics: + intrinsics["Phase"] = "0deg" + else: + raise AttributeError("Intrinsics has to be a string or list.") + if return_list: + intrinsics_list = [] + for k, v in intrinsics.items(): + intrinsics_list.append("{}:=".format(k)) + intrinsics_list.append(v) + return intrinsics_list + return intrinsics + @pyaedt_function_handler() def get_traces_for_plot( self, diff --git a/pyaedt/modules/AdvancedPostProcessing.py b/pyaedt/modules/AdvancedPostProcessing.py index 0572310fbd1..70869f2879d 100644 --- a/pyaedt/modules/AdvancedPostProcessing.py +++ b/pyaedt/modules/AdvancedPostProcessing.py @@ -497,9 +497,17 @@ def plot_field( ``"CutPlane"``, ``"Surface"``, and ``"Volume"``. setup : str, optional Setup and sweep name on which create the field plot. Default is None for nominal setup usage. - intrinsics : dict, optional. - Intrinsic dictionary that is needed for the export. - The default is ``None`` which try to retrieve intrinsics from setup. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. mesh_on_fields : bool, optional Whether to create and plot the mesh over the fields. The default is ``False``. @@ -542,16 +550,13 @@ def plot_field( :class:`pyaedt.generic.plot.ModelPlotter` Model Object. """ + intrinsics = self._app._check_intrinsics(intrinsics, setup=setup) if filter_objects is None: filter_objects = [] if os.getenv("PYAEDT_DOC_GENERATION", "False").lower() in ("true", "1", "t"): # pragma: no cover show = False if not setup: setup = self._app.existing_analysis_sweeps[0] - if not intrinsics: - for i in self._app.setups: - if i.name == setup.split(" : ")[0]: - intrinsics = i.default_intrinsics # file_to_add = [] if plot_type == "Surface": @@ -630,9 +635,17 @@ def plot_animated_field( ``"CutPlane"``, ``"Surface"``, and ``"Volume"``. setup : str, optional Setup and sweep name on which create the field plot. Default is None for nominal setup usage. - intrinsics : dict, optional. - Intrinsic dictionary that is needed for the export. - The default is ``None`` which try to retrieve intrinsics from setup. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. variation_variable : str, optional Variable to vary. The default is ``"Phi"``. variations : list, optional @@ -675,12 +688,11 @@ def plot_animated_field( :class:`pyaedt.generic.plot.ModelPlotter` Model Object. """ + intrinsics = self._app._check_intrinsics(intrinsics, setup=setup) if variations is None: variations = ["0deg"] if os.getenv("PYAEDT_DOC_GENERATION", "False").lower() in ("true", "1", "t"): # pragma: no cover show = False - if intrinsics is None: - intrinsics = {} if not export_path: export_path = self._app.working_directory if not filter_objects: diff --git a/pyaedt/modules/PostProcessor.py b/pyaedt/modules/PostProcessor.py index 18b683cd30a..df2306acbdf 100644 --- a/pyaedt/modules/PostProcessor.py +++ b/pyaedt/modules/PostProcessor.py @@ -2608,9 +2608,17 @@ def get_scalar_field_value( The default is ``None``. is_vector : bool, optional Whether the quantity is a vector. The default is ``False``. - intrinsics : str, optional - This parameter is mandatory for a frequency field calculation. - The default is ``None``. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. phase : str, optional Field phase. The default is ``None``. object_name : str, optional @@ -2638,7 +2646,27 @@ def get_scalar_field_value( >>> oModule.EnterVol >>> oModule.ClcEval >>> GetTopEntryValue + + Examples + -------- + >>> from pyaedt import Hfss + >>> aedtapp = Hfss() + >>> # Intrinsics is explicitly provided as a dictionary. + >>> intrinsics = {"Freq": "5GHz", "Phase": "180deg"} + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name, intrinsics=intrinsics) + >>> plot1 = aedtapp.post.create_fieldplot_cutplane(cutlist, quantity_name, setup_name, intrinsics=intrinsics) + >>> # Intrinsics is provided as a string. Phase is automatically assigned to 0deg. + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name, intrinsics="5GHz") + >>> plot1 = aedtapp.post.create_fieldplot_cutplane(cutlist, quantity_name, setup_name, intrinsics="5GHz") + >>> # Intrinsics is provided as a dictionary. Phase is automatically assigned to 0deg. + >>> intrinsics = {"Freq": "5GHz"} + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name, intrinsics=intrinsics) + >>> plot1 = aedtapp.post.create_fieldplot_cutplane(cutlist, quantity_name, setup_name, intrinsics=intrinsics) + >>> # Intrinsics is not provided and is automatically computed from the setup. + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name) + >>> plot1 = aedtapp.post.create_fieldplot_cutplane(cutlist, quantity_name, setup_name) """ + intrinsics = self._app._check_intrinsics(intrinsics, phase, solution, return_list=True) self.logger.info("Exporting {} field. Be patient".format(quantity)) if not solution: solution = self._app.existing_analysis_sweeps[0] @@ -2679,19 +2707,7 @@ def get_scalar_field_value( variation.append(el + ":=") variation.append(value) - if intrinsics: - if "Transient" in solution: # pragma: no cover - variation.append("Time:=") - variation.append(intrinsics) - else: - variation.append("Freq:=") - variation.append(intrinsics) - if self._app.design_type not in ["Icepak", "Mechanical", "Q3D Extractor"]: - variation.append("Phase:=") - if phase: # pragma: no cover - variation.append(phase) - else: - variation.append("0deg") + variation.extend(intrinsics) file_name = os.path.join(self._app.working_directory, generate_unique_name("temp_fld") + ".fld") self.ofieldsreporter.CalculatorWrite(file_name, ["Solution:=", solution], variation) @@ -2763,9 +2779,17 @@ def export_field_file_on_grid( The default is ``[0, 0, 0]``. is_vector : bool, optional Whether the quantity is a vector. The default is ``False``. - intrinsics : str, optional - This parameter is mandatory for a frequency field calculation. - The default is ``None``. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. phase : str, optional Field phase. The default is ``None``. export_with_sample_points : bool, optional @@ -2805,6 +2829,8 @@ def export_field_file_on_grid( >>> path = "Field.fld" >>> hfss.post.export_field_file_on_grid("E",setup,var,path,'Cartesian',[0, 0, 0],intrinsics="8GHz") """ + intrinsics = self._app._check_intrinsics(intrinsics, phase, solution, return_list=True) + self.logger.info("Exporting %s field. Be patient", quantity) if grid_step is None: grid_step = [0, 0, 0] if grid_start is None: @@ -2861,20 +2887,7 @@ def export_field_file_on_grid( for el, value in variations.items(): variation.append(el + ":=") variation.append(value) - - if intrinsics: - if "Transient" in solution: - variation.append("Time:=") - variation.append(intrinsics) - else: - variation.append("Freq:=") - variation.append(intrinsics) - if self._app.design_type not in ["Icepak", "Mechanical", "Q3D Extractor"]: - variation.append("Phase:=") - if phase: - variation.append(phase) - else: - variation.append("0deg") + variation.extend(intrinsics) export_options = [ "NAME:ExportOption", @@ -2933,7 +2946,7 @@ def export_field_file( Parameters ---------- - quantity : + quantity : str Name of the quantity to export. For example, ``"Temp"``. solution : str, optional Name of the solution in the format ``"solution: sweep"``. @@ -2950,11 +2963,20 @@ def export_field_file( Type of objects to export. The default is ``"Vol"``. Options are ``"Surf"`` for surface and ``"Vol"`` for volume. - intrinsics : str, optional - This parameter is mandatory for a frequency or transient field calculation. - The default is ``None``. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. phase : str, optional Field phase. The default is ``None``. + This argument is deprecated. Please use ``intrinsics`` and provide the phase as a dictionary key instead. sample_points_file : str, optional Name of the file with sample points. The default is ``None``. sample_points : list, optional @@ -2987,7 +3009,28 @@ def export_field_file( >>> oModule.EnterVol >>> oModule.CalculatorWrite >>> oModule.ExportToFile + + Examples + -------- + + >>> from pyaedt import Maxwell3d + >>> m3d = Maxwell3d() + >>> # Intrinsics is provided as a string. + >>> fld_file1 = "test_fld_hfss1.fld" + >>> hfss_app.post.export_field_file(quantity="Mag_E", output_file=fld_file1, assignment="Box1", + >>> intrinsics="1GHz", phase="5deg") + >>> # Intrinsics is provided as dictionary. Phase is automatically assigned to 0deg. + >>> fld_file2 = "test_fld_hfss2.fld" + >>> hfss_app.post.export_field_file(quantity="Mag_E", output_file=fld_file2, assignment="Box1", + >>> intrinsics={"frequency":"1GHz"}) + >>> # Intrinsics is provided as dictionary. Phase is provided. + >>> hfss_app.post.export_field_file(quantity="Mag_E", output_file=fld_file2, assignment="Box1", + >>> intrinsics={"frequency":"1GHz", "phase":"30deg"}) + >>> # Intrinsics is not provided. It is computed from the setup arguments. + >>> hfss_app.post.export_field_file(quantity="Mag_E", output_file=fld_file2, assignment="Box1", + >>> ) """ + intrinsics = self._app._check_intrinsics(intrinsics, phase, solution, return_list=True) self.logger.info("Exporting %s field. Be patient", quantity) if not solution: if not self._app.existing_analysis_sweeps: @@ -3013,20 +3056,8 @@ def export_field_file( for el, value in variations.items(): variation.append(el + ":=") variation.append(value) + variation.extend(intrinsics) - if intrinsics: - if "Transient" in solution: - variation.append("Time:=") - variation.append(intrinsics) - else: - variation.append("Freq:=") - variation.append(intrinsics) - if self._app.design_type not in ["Icepak", "Mechanical", "Q3D Extractor"]: - variation.append("Phase:=") - if phase: - variation.append(phase) - else: - variation.append("0deg") if not sample_points_file and not sample_points: if objects_type == "Vol": self.ofieldsreporter.EnterVol(assignment) @@ -3206,14 +3237,12 @@ def _create_fieldplot( field_type=None, create_plot=True, ): + intrinsics = self._app._check_intrinsics(intrinsics, None, setup) if not list_type.startswith("Layer") and self._app.design_type != "HFSS 3D Layout Design": assignment = self._app.modeler.convert_to_selections(assignment, True) if not setup: setup = self._app.existing_analysis_sweeps[0] - if not intrinsics: - for i in self._app.setups: - if i.name == setup.split(" : ")[0]: - intrinsics = i.default_intrinsics + self._desktop.CloseAllWindows() try: self._app.modeler.fit_all() @@ -3325,9 +3354,17 @@ def create_fieldplot_line( setup is used. Be sure to build a setup string in the form of ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to use in the export or ``LastAdaptive``. - intrinsics : dict, optional - Dictionary containing all intrinsic variables. - The default is ``None``. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. plot_name : str, optional Name of the field plot to create. field_type : str, optional @@ -3340,11 +3377,28 @@ def create_fieldplot_line( References ---------- - >>> oModule.CreateFieldPlot + + Examples + -------- + >>> from pyaedt import Hfss + >>> aedtapp = Hfss() + >>> # Intrinsics is provided as a dictionary. + >>> intrinsics = {"Freq": "5GHz", "Phase": "180deg"} + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name, intrinsics=intrinsics) + >>> plot1 = aedtapp.post.create_fieldplot_line("Polyline1", quantity_name, setup_name, intrinsics=intrinsics) + >>> # Intrinsics is provided as a string. Phase is automatically assigned to 0deg. + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name, intrinsics="5GHz") + >>> plot1 = aedtapp.post.create_fieldplot_line("Polyline1", quantity_name, setup_name, intrinsics="5GHz") + >>> # Intrinsics is provided as a dictionary. Phase is automatically assigned to 0deg. + >>> intrinsics = {"Freq": "5GHz"} + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name, intrinsics=intrinsics) + >>> plot1 = aedtapp.post.create_fieldplot_line("Polyline1", quantity_name, setup_name, intrinsics=intrinsics) + >>> # Intrinsics is not provided and is computed from the setup. + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name) + >>> plot1 = aedtapp.post.create_fieldplot_line("Polyline1", quantity_name, setup_name) """ - if intrinsics is None: - intrinsics = {} + intrinsics = self._app._check_intrinsics(intrinsics, setup=setup) if plot_name and plot_name in list(self.field_plots.keys()): self.logger.info("Plot {} exists. returning the object.".format(plot_name)) return self.field_plots[plot_name] @@ -3375,9 +3429,17 @@ def create_fieldplot_line_traces( setup : str, optional Name of the setup in the format ``"setupName : sweepName"``. The default is ``None``. - intrinsics : dict, optional - Dictionary containing all intrinsic variables. - The default is ``None``. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. plot_name : str, optional Name of the field plot to create. The default is ``None``. field_type : str, optional @@ -3390,14 +3452,30 @@ def create_fieldplot_line_traces( References ---------- - >>> oModule.CreateFieldPlot + + Examples + -------- + >>> from pyaedt import Maxwell2d + >>> aedtapp = Maxwell2d() + >>> # Intrinsics is provided as a dictionary. + >>> intrinsics = {"Freq": "5GHz", "Phase": "180deg"} + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name, intrinsics=intrinsics) + >>> plot1 = aedtapp.post.create_fieldplot_line_traces(seeding_faces=["Ground", "Electrode", "Region"], + >>> in_volume_tracing_objs="Region", + >>> plot_name="LineTracesTest", + >>> intrinsics=intrinsics) + >>> # Intrinsics is provided as a string. Phase is automatically assigned to 0deg. + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name, intrinsics="5GHz") + >>> plot1 = aedtapp.post.create_fieldplot_line_traces(seeding_faces=["Ground", "Electrode", "Region"], + >>> in_volume_tracing_objs="Region", + >>> plot_name="LineTracesTest", + >>> intrinsics="200Hz") """ + intrinsics = self._app._check_intrinsics(intrinsics, setup=setup) if self._app.solution_type != "Electrostatic": self.logger.error("Field line traces is valid only for electrostatic solution") return False - if intrinsics is None: - intrinsics = {} if plot_name and plot_name in list(self.field_plots.keys()): self.logger.info("Plot {} exists. returning the object.".format(plot_name)) return self.field_plots[plot_name] @@ -3533,9 +3611,17 @@ def create_fieldplot_layers( use in the export or ``LastAdaptive``. nets : list, optional List of nets to filter the field plot. Optional. - intrinsics : dict, optional - Dictionary containing all intrinsic variables. - The default is ``None``. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. name : str, optional Name of the field plot to create. @@ -3546,9 +3632,9 @@ def create_fieldplot_layers( References ---------- - >>> oModule.CreateFieldPlot """ + intrinsics = self._app._check_intrinsics(intrinsics, setup=setup) if not setup: setup = self._app.existing_analysis_sweeps[0] if nets is None: @@ -3558,8 +3644,6 @@ def create_fieldplot_layers( ) and not self._app.design_type in ["HFSS", "HFSS 3D Layout Design"]: self.logger.error("This method requires AEDT 2023 R2 and Maxwell 3D Transient APhi Formulation.") return False - if intrinsics is None: - intrinsics = {} if name and name in list(self.field_plots.keys()): self.logger.info("Plot {} exists. returning the object.".format(name)) return self.field_plots[name] @@ -3619,9 +3703,17 @@ def create_fieldplot_layers_nets( setup is used. Make sure to build a setup string in the form of ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to use in the export or ``LastAdaptive``. - intrinsics : dict, optional - Dictionary containing all intrinsic variables. - The default is ``None``. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. plot_on_surface : bool, optional Whether the plot is to be on the surface or volume of traces. plot_name : str, optional @@ -3634,10 +3726,9 @@ def create_fieldplot_layers_nets( References ---------- - >>> oModule.CreateFieldPlot """ - + intrinsics = self._app._check_intrinsics(intrinsics, setup=setup) if not ( "APhi" in self.post_solution_type and settings.aedt_version >= "2023.2" ) and not self._app.design_type in ["HFSS", "HFSS 3D Layout Design"]: @@ -3699,9 +3790,17 @@ def create_fieldplot_surface( setup is used. Be sure to build a setup string in the form of ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to use in the export or ``LastAdaptive``. - intrinsics : dict, optional - Dictionary containing all intrinsic variables. - The default is ``None``. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. plot_name : str, optional Name of the field plot to create. field_type : str, optional @@ -3714,7 +3813,6 @@ def create_fieldplot_surface( References ---------- - >>> oModule.CreateFieldPlot """ if intrinsics is None: @@ -3759,9 +3857,17 @@ def create_fieldplot_cutplane( Name of the setup. The default is ``None``, in which case the ``nominal_adaptive`` setup is used. Be sure to build a setup string in the form of ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to use in the export or ``LastAdaptive``. - intrinsics : dict, optional - Dictionary containing all intrinsic variables. - The default is ``None``. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. plot_name : str, optional Name of the field plot to create. filter_objects : list, optional @@ -3777,8 +3883,26 @@ def create_fieldplot_cutplane( References ---------- - >>> oModule.CreateFieldPlot + + Examples + -------- + >>> from pyaedt import Hfss + >>> aedtapp = Hfss() + >>> # Intrinsics is provided as a dictionary. + >>> intrinsics = {"Freq": "5GHz", "Phase": "180deg"} + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name, intrinsics=intrinsics) + >>> plot1 = aedtapp.post.create_fieldplot_cutplane(cutlist, quantity_name, setup_name, intrinsics=intrinsics) + >>> # Intrinsics is provided as a string. Phase is automatically assigned to 0deg. + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name, intrinsics="5GHz") + >>> plot1 = aedtapp.post.create_fieldplot_cutplane(cutlist, quantity_name, setup_name, intrinsics="5GHz") + >>> # Intrinsics is provided as a dictionary. Phase is automatically assigned to 0deg. + >>> intrinsics = {"Freq": "5GHz"} + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name, intrinsics=intrinsics) + >>> plot1 = aedtapp.post.create_fieldplot_cutplane(cutlist, quantity_name, setup_name, intrinsics=intrinsics) + >>> # Intrinsics is not provided and is computed from the setup. + >>> min_value = aedtapp.post.get_scalar_field_value(quantity_name, "Minimum", setup_name) + >>> plot1 = aedtapp.post.create_fieldplot_cutplane(cutlist, quantity_name, setup_name) """ if intrinsics is None: intrinsics = {} @@ -3817,9 +3941,17 @@ def create_fieldplot_volume( setup is used. Be sure to build a setup string in the form of ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to use in the export or ``LastAdaptive``. - intrinsics : dict, optional - Dictionary containing all intrinsic variables. - The default is ``None``. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. plot_name : str, optional Name of the field plot to create. @@ -3833,8 +3965,8 @@ def create_fieldplot_volume( >>> oModule.CreateFieldPlot """ - if intrinsics is None: - intrinsics = {} + intrinsics = self._app._check_intrinsics(intrinsics, setup=setup) + if plot_name and plot_name in list(self.field_plots.keys()): self.logger.info("Plot {} exists. returning the object.".format(plot_name)) return self.field_plots[plot_name] @@ -4214,10 +4346,17 @@ def export_mesh_obj(self, setup=None, intrinsics=None, export_air_objects=False, setup is used. Be sure to build a setup string in the form of ``"SetupName : SetupSweep"``, where ``SetupSweep`` is the sweep name to use in the export or ``LastAdaptive``. - intrinsics : dict, optional. - Intrinsic dictionary that is needed for the export. - The default is ``None``, which assumes that no variables are present in - the dictionary or nominal values are used. + intrinsics : dict, str, optional + Intrinsic variables required to compute the field before the export. + These are typically: frequency, time and phase. + It can be provided either as a dictionary or as a string. + If it is a dictionary, keys depend on the solution type and can be expressed as: + - ``"Freq"`` or ``"Frequency"`` + - ``"Time"`` + - ``"Phase"`` + in lower or camel case. + If it is a string, it can either be ``"Freq"`` or ``"Time"`` depending on the solution type. + The default is ``None`` in which case the intrinsics value is automatically computed based on the setup. export_air_objects : bool, optional Whether to include vacuum objects for the copied objects. The default is ``False``. @@ -4239,12 +4378,12 @@ def export_mesh_obj(self, setup=None, intrinsics=None, export_air_objects=False, >>> # Export report using arguments. >>> hfss.post.export_mesh_obj(setup="MySetup : LastAdaptive",intrinsics={"w1":"5mm", "l1":"3mm"}) """ - if intrinsics is None: - intrinsics = {} project_path = self._app.working_directory if not setup: setup = self._app.nominal_adaptive + intrinsics = self._app._check_intrinsics(intrinsics, setup=setup) + mesh_list = [] obj_list = self._app.modeler.object_names for el in obj_list: