From ddc98ae07fbb69286f78ae8589b9c4dcc6225e42 Mon Sep 17 00:00:00 2001 From: maxcapodi78 Date: Tue, 21 Nov 2023 17:51:13 +0100 Subject: [PATCH 1/4] Improve method get_solution_data to avoid intrinsics as arguments and to add the method to the setups objects --- _unittest/test_12_PostProcessing.py | 18 +- pyaedt/application/Analysis.py | 2 +- pyaedt/application/design_solutions.py | 39 ++- pyaedt/modeler/modeler3d.py | 37 ++- pyaedt/modules/PostProcessor.py | 36 ++- pyaedt/modules/SolveSetup.py | 397 +++++++++++++++++++++++++ 6 files changed, 496 insertions(+), 33 deletions(-) diff --git a/_unittest/test_12_PostProcessing.py b/_unittest/test_12_PostProcessing.py index 5b5db41e60a..1457c97ba9b 100644 --- a/_unittest/test_12_PostProcessing.py +++ b/_unittest/test_12_PostProcessing.py @@ -209,14 +209,9 @@ def test_09_manipulate_report_D(self, field_test): def test_09_manipulate_report_E(self, field_test): field_test.modeler.create_polyline([[0, 0, 0], [0, 5, 30]], name="Poly1", non_model=True) variations2 = field_test.available_variations.nominal_w_values_dict - variations2["Theta"] = ["All"] - variations2["Phi"] = ["All"] - variations2["Freq"] = ["30GHz"] - variations2["Distance"] = ["All"] - assert field_test.post.create_report( + + assert field_test.setups[0].create_report( "Mag_E", - field_test.nominal_adaptive, - variations=variations2, primary_sweep_variable="Distance", context="Poly1", report_category="Fields", @@ -226,11 +221,10 @@ def test_09_manipulate_report_E(self, field_test): new_report.polyline = "Poly1" assert new_report.create() new_report = field_test.post.reports_by_category.modal_solution("S(1,1)") - new_report.plot_type = "Smith Chart" + new_report.report_type = "Smith Chart" assert new_report.create() - data = field_test.post.get_solution_data( + data = field_test.setups[0].get_solution_data( "Mag_E", - field_test.nominal_adaptive, variations=variations2, primary_sweep_variable="Theta", context="Poly1", @@ -269,7 +263,7 @@ def test_17_circuit(self, circuit_test): circuit_test.analyze_setup("LNA") circuit_test.analyze_setup("Transient") assert circuit_test.setups[0].is_solved - assert circuit_test.post.create_report(["dB(S(Port1, Port1))", "dB(S(Port1, Port2))"], "LNA") + assert circuit_test.setups[0].create_report(["dB(S(Port1, Port1))", "dB(S(Port1, Port2))"]) new_report = circuit_test.post.reports_by_category.standard( ["dB(S(Port1, Port1))", "dB(S(Port1, Port2))"], "LNA" ) @@ -382,7 +376,7 @@ def test_55_time_plot(self, sbr_test): assert sbr_test.setups[0].is_solved solution_data = sbr_test.post.get_solution_data( expressions=["NearEX", "NearEY", "NearEZ"], - variations={"_u": ["All"], "_v": ["All"], "Freq": ["All"]}, + # variations={"_u": ["All"], "_v": ["All"], "Freq": ["All"]}, context="Near_Field", report_category="Near Fields", ) diff --git a/pyaedt/application/Analysis.py b/pyaedt/application/Analysis.py index 7c490d965fa..07e8cdebe20 100644 --- a/pyaedt/application/Analysis.py +++ b/pyaedt/application/Analysis.py @@ -1195,7 +1195,7 @@ def _create_setup(self, setupname="MySetupAuto", setuptype=None, props=None): setup = SetupHFSSAuto(self, setuptype, name) elif setuptype == 4: setup = SetupSBR(self, setuptype, name) - elif setuptype in [5, 6, 7, 8, 9, 10]: + elif setuptype in [5, 6, 7, 8, 9, 10, 56]: setup = SetupMaxwell(self, setuptype, name) elif setuptype in [14]: setup = SetupQ3D(self, setuptype, name) diff --git a/pyaedt/application/design_solutions.py b/pyaedt/application/design_solutions.py index 7d6207c5d73..e497c10fb1a 100644 --- a/pyaedt/application/design_solutions.py +++ b/pyaedt/application/design_solutions.py @@ -110,7 +110,7 @@ "name": None, "options": None, "report_type": None, - "default_setup": None, + "default_setup": 8, "default_adaptive": "LastAdaptive", "intrinsics": ["Freq", "Phase"], }, @@ -118,7 +118,7 @@ "name": None, "options": None, "report_type": None, - "default_setup": None, + "default_setup": 8, "default_adaptive": "LastAdaptive", }, "ElectroDCConduction": { @@ -138,13 +138,21 @@ }, }, "Twin Builder": { - "TR": {"name": None, "options": None, "report_type": "Standard", "default_setup": 35, "default_adaptive": None}, + "TR": { + "name": None, + "options": None, + "report_type": "Standard", + "default_setup": 35, + "default_adaptive": None, + "intrinsics": ["Time"], + }, "AC": { "name": None, "options": None, "report_type": "Standard", "default_setup": None, "default_adaptive": None, + "intrinsics": ["Freq"], }, "DC": { "name": None, @@ -161,6 +169,7 @@ "report_type": "Standard", "default_setup": 15, "default_adaptive": None, + "intrinsics": ["Freq"], }, "NexximDC": { "name": None, @@ -175,6 +184,7 @@ "report_type": "Standard", "default_setup": 17, "default_adaptive": None, + "intrinsics": ["Time"], }, "NexximVerifEye": { "name": None, @@ -182,6 +192,7 @@ "report_type": "Standard", "default_setup": 19, "default_adaptive": None, + "intrinsics": ["Time"], }, "NexximQuickEye": { "name": None, @@ -189,6 +200,7 @@ "report_type": "Standard", "default_setup": 18, "default_adaptive": None, + "intrinsics": ["Time"], }, "NexximAMI": { "name": None, @@ -196,6 +208,7 @@ "report_type": "Standard", "default_setup": 20, "default_adaptive": None, + "intrinsics": ["Time"], }, "NexximOscillatorRSF": { "name": None, @@ -203,6 +216,7 @@ "report_type": "Standard", "default_setup": 21, "default_adaptive": None, + "intrinsics": ["Freq"], }, "NexximOscillator1T": { "name": None, @@ -210,6 +224,7 @@ "report_type": "Standard", "default_setup": 22, "default_adaptive": None, + "intrinsics": ["Freq"], }, "NexximOscillatorNT": { "name": None, @@ -217,6 +232,7 @@ "report_type": "Standard", "default_setup": 23, "default_adaptive": None, + "intrinsics": ["Freq"], }, "NexximHarmonicBalance1T": { "name": None, @@ -224,6 +240,7 @@ "report_type": "Standard", "default_setup": 24, "default_adaptive": None, + "intrinsics": ["Freq"], }, "NexximHarmonicBalanceNT": { "name": None, @@ -231,6 +248,7 @@ "report_type": "Standard", "default_setup": 25, "default_adaptive": None, + "intrinsics": ["Freq"], }, "NexximSystem": { "name": None, @@ -238,6 +256,7 @@ "report_type": "Standard", "default_setup": 26, "default_adaptive": None, + "intrinsics": ["Time"], }, "NexximTVNoise": { "name": None, @@ -245,6 +264,7 @@ "report_type": "Standard", "default_setup": 27, "default_adaptive": None, + "intrinsics": ["Freq"], }, "HSPICE": { "name": None, @@ -252,8 +272,16 @@ "report_type": "Standard", "default_setup": 28, "default_adaptive": None, + "intrinsics": ["Time"], + }, + "TR": { + "name": None, + "options": None, + "report_type": "Standard", + "default_setup": 17, + "default_adaptive": None, + "intrinsics": ["Time"], }, - "TR": {"name": None, "options": None, "report_type": "Standard", "default_setup": 17, "default_adaptive": None}, }, "2D Extractor": { "Open": { @@ -353,6 +381,7 @@ "report_type": "Modal Solution Data", "default_setup": 4, "default_adaptive": "Sweep", + "intrinsics": ["Freq", "Phase"], }, }, "Icepak": { @@ -439,6 +468,7 @@ "report_type": "Standard", "default_setup": 41, "default_adaptive": None, + "intrinsics": ["Freq"], }, "LNA3DLayout": { "name": None, @@ -446,6 +476,7 @@ "report_type": "Standard", "default_setup": 42, "default_adaptive": None, + "intrinsics": ["Freq"], }, }, "Mechanical": { diff --git a/pyaedt/modeler/modeler3d.py b/pyaedt/modeler/modeler3d.py index 7ebb7fccb7a..a70450d6a99 100644 --- a/pyaedt/modeler/modeler3d.py +++ b/pyaedt/modeler/modeler3d.py @@ -889,7 +889,16 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import lines = f.read().splitlines() id = 0 for line in lines: - line_split = [line[i : i + 8] for i in range(0, len(line), 8)] + if line.startswith("$") or line.startswith("*"): + continue + if "*" in line: + line = line.strip()[:-1] + lines[lines.index(line) + 1][8:] + line_split = [line[:8]] + [line[i : i + 16] for i in range(8, len(line), 16)] + else: + line_split = [line[i : i + 8] for i in range(0, len(line), 8)] + + line_split = [i for i in line_split if i.replace(" ", "").replace("\t", "")] + if len(line_split) < 5: continue if line_split[0].startswith("GRID"): @@ -915,7 +924,16 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import nas_to_dict["PointsId"][int(line_split[1])] = id id += 1 except: - pass + try: + nas_to_dict["Points"][int(line_split[1])] = [ + float(line_split[2]), + float(line_split[3]), + float(line_split[4]), + ] + nas_to_dict["PointsId"][int(line_split[1])] = id + id += 1 + except: + pass elif line_split[0].startswith("CTRIA3"): if int(line_split[2]) in nas_to_dict["Triangles"]: nas_to_dict["Triangles"][int(line_split[2])].append( @@ -926,13 +944,16 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import ] ) else: - nas_to_dict["Triangles"][int(line_split[2])] = [ - [ - int(line_split[3]), - int(line_split[4]), - int(line_split[5]), + try: + nas_to_dict["Triangles"][int(line_split[2])] = [ + [ + int(line_split[3]), + int(line_split[4]), + int(line_split[5]), + ] ] - ] + except: + pass elif line_split[0].startswith("CPENTA"): if int(line_split[2]) in nas_to_dict["Solids"]: nas_to_dict["Solids"][int(line_split[2])].append( diff --git a/pyaedt/modules/PostProcessor.py b/pyaedt/modules/PostProcessor.py index 7a79917c1ce..e8f51209f24 100644 --- a/pyaedt/modules/PostProcessor.py +++ b/pyaedt/modules/PostProcessor.py @@ -1585,6 +1585,15 @@ def create_report( ... "InputCurrent(PHA)", domain="Time", primary_sweep_variable="Time", plotname="Winding Plot 1" ... ) """ + if not setup_sweep_name: + setup_sweep_name = self._app.nominal_sweep + if not domain: + domain = "Sweep" + setup_name = setup_sweep_name.split(":")[0] + if setup_name: + for setup in self._app.setups: + if setup.name == setup_name and "Time" in setup.default_intrinsics: + domain = "Time" if domain in ["Spectral", "Spectrum"]: report_category = "Spectrum" elif not report_category and not self._app.design_solutions.report_type: @@ -1598,8 +1607,7 @@ def create_report( report_class = TEMPLATES_BY_NAME["Fields"] else: report_class = TEMPLATES_BY_NAME["Standard"] - if not setup_sweep_name: - setup_sweep_name = self._app.nominal_sweep + report = report_class(self, report_category, setup_sweep_name) if not expressions: expressions = [ @@ -1607,6 +1615,8 @@ def create_report( ] report.expressions = expressions report.domain = domain + if not variations: + variations = self._app.available_variations.nominal_w_values_dict if primary_sweep_variable: report.primary_sweep = primary_sweep_variable elif domain == "DCIR": # pragma: no cover @@ -1617,8 +1627,8 @@ def create_report( variations = {"Index": "All"} if secondary_sweep_variable: report.secondary_sweep = secondary_sweep_variable - if variations: - report.variations = variations + + report.variations = variations report.report_type = plot_type report.sub_design_id = subdesign_id report.point_number = polyline_points @@ -1669,7 +1679,7 @@ def get_solution_data( self, expressions=None, setup_sweep_name=None, - domain="Sweep", + domain=None, variations=None, primary_sweep_variable=None, report_category=None, @@ -1696,7 +1706,7 @@ def get_solution_data( Plot Domain. Options are "Sweep" for frequency domain related results and "Time" for transient related data. variations : dict, optional Dictionary of all families including the primary sweep. - The default is ``None`` which will use the nominal variations of the design. + The default is ``None`` which will use the nominal variations of the setup. primary_sweep_variable : str, optional Name of the primary sweep. The default is ``"None"`` which, depending on the context, will internally assign the primary sweep to: @@ -1784,6 +1794,15 @@ def get_solution_data( ...) """ expressions = [expressions] if isinstance(expressions, str) else expressions + if not setup_sweep_name: + setup_sweep_name = self._app.nominal_sweep + if not domain: + domain = "Sweep" + setup_name = setup_sweep_name.split(":")[0] + if setup_name: + for setup in self._app.setups: + if setup.name == setup_name and "Time" in setup.default_intrinsics: + domain = "Time" if domain in ["Spectral", "Spectrum"]: report_category = "Spectrum" if not report_category and not self._app.design_solutions.report_type: @@ -1797,8 +1816,7 @@ def get_solution_data( report_class = TEMPLATES_BY_NAME["Fields"] else: report_class = TEMPLATES_BY_NAME["Standard"] - if not setup_sweep_name: - setup_sweep_name = self._app.nominal_sweep + report = report_class(self, report_category, setup_sweep_name) if not expressions: expressions = [ @@ -1812,6 +1830,8 @@ def get_solution_data( report.primary_sweep = primary_sweep_variable if variations: report.variations = variations + else: + report.variations = self._app.available_variations.nominal_w_values_dict report.sub_design_id = subdesign_id report.point_number = polyline_points if context == "Differential Pairs": diff --git a/pyaedt/modules/SolveSetup.py b/pyaedt/modules/SolveSetup.py index 91ff27b461a..1322f9f0744 100644 --- a/pyaedt/modules/SolveSetup.py +++ b/pyaedt/modules/SolveSetup.py @@ -220,6 +220,241 @@ def name(self, name): self._setupname = name self.props["Name"] = name + @pyaedt_function_handler() + def get_solution_data( + self, + expressions=None, + domain=None, + variations=None, + primary_sweep_variable=None, + report_category=None, + context=None, + polyline_points=1001, + math_formula=None, + sweep_name=None, + ): + """Get a simulation result from a solved setup and cast it in a ``SolutionData`` object. + Data to be retrieved from Electronics Desktop are any simulation results available in that + specific simulation context. + Most of the argument have some defaults which works for most of the ``Standard`` report quantities. + + Parameters + ---------- + expressions : str or list, optional + One or more formulas to add to the report. Example is value ``"dB(S(1,1))"`` or a list of values. + Default is `None` which will return all traces. + domain : str, optional + Plot Domain. Options are "Sweep" for frequency domain related results and "Time" for transient related data. + variations : dict, optional + Dictionary of all families including the primary sweep. + The default is ``None`` which will use the nominal variations of the setup. + primary_sweep_variable : str, optional + Name of the primary sweep. The default is ``"None"`` which, depending on the context, + will internally assign the primary sweep to: + 1. ``Freq`` for frequency domain results, + 2. ``Time`` for transient results, + 3. ``Theta`` for radiation patterns, + 4. ``distance`` for field plot over a polyline. + report_category : str, optional + Category of the Report to be created. If `None` default data Report will be used. + The Report Category can be one of the types available for creating a report depend on the simulation setup. + For example for a Far Field Plot in HFSS the UI shows the report category as "Create Far Fields Report". + The report category will be in this case "Far Fields". + Depending on the setup different categories are available. + If `None` default category will be used (the first item in the Results drop down menu in AEDT). + To get the list of available categories user can use method ``available_report_types``. + context : str, dict, optional + This is the context of the report. + The default is ``None``. It can be: + 1. `None` + 2. Infinite Sphere name for Far Fields Plot. + 3. Dictionary. If dictionary is passed, key is the report property name and value is property value. + polyline_points : int, optional + Number of points on which to create the report for plots on polylines. + This parameter is valid for ``Fields`` plot only. + math_formula : str, optional + One of the available AEDT mathematical formulas to apply. For example, ``abs, dB``. + sweep_name : str, optional + Name of the sweep adaptive setup from which get solutions. Default is ``LastAdaptive``. + + Returns + ------- + :class:`pyaedt.modules.solutions.SolutionData` + Solution Data object. + + References + ---------- + + >>> oModule.GetSolutionDataPerVariation + + Examples + -------- + >>> from pyaedt import Hfss + >>> aedtapp = Hfss() + >>> aedtapp.post.create_report("dB(S(1,1))") + + >>> variations = aedtapp.available_variations.nominal_w_values_dict + >>> variations["Theta"] = ["All"] + >>> variations["Phi"] = ["All"] + >>> variations["Freq"] = ["30GHz"] + >>> data1 = aedtapp.post.get_solution_data( + ... "GainTotal", + ... aedtapp.nominal_adaptive, + ... variations=variations, + ... primary_sweep_variable="Phi", + ... secondary_sweep_variable="Theta", + ... context="3D", + ... report_category="Far Fields", + ...) + + >>> data2 =aedtapp.post.get_solution_data( + ... "S(1,1)", + ... aedtapp.nominal_sweep, + ... variations=variations, + ...) + >>> data2.plot() + + >>> from pyaedt import Maxwell2d + >>> maxwell_2d = Maxwell2d() + >>> data3 = maxwell_2d.post.get_solution_data( + ... "InputCurrent(PHA)", domain="Time", primary_sweep_variable="Time", + ... ) + >>> data3.plot("InputCurrent(PHA)") + + >>> from pyaedt import Circuit + >>> circuit = Circuit() + >>> context = {"algorithm": "FFT", "max_frequency": "100MHz", "time_stop": "2.5us", "time_start": "0ps"} + >>> spectralPlotData = circuit.post.get_solution_data( + ... expressions="V(Vprobe1)", primary_sweep_variable="Spectrum", domain="Spectral", + ... context=context + ...) + """ + if sweep_name: + setup_sweep_name = [ + i for i in self._app.existing_analysis_sweeps if self.name == i.split(" : ")[0] and sweep_name in i + ] + else: + setup_sweep_name = [i for i in self._app.existing_analysis_sweeps if self.name == i.split(" : ")[0]] + if setup_sweep_name: + return self._app.post.get_solution_data( + expressions=expressions, + domain=domain, + variations=variations, + primary_sweep_variable=primary_sweep_variable, + report_category=report_category, + context=context, + polyline_points=polyline_points, + math_formula=math_formula, + setup_sweep_name=setup_sweep_name[0], + ) + return None + + @pyaedt_function_handler() + def create_report( + self, + expressions=None, + domain="Sweep", + variations=None, + primary_sweep_variable=None, + secondary_sweep_variable=None, + report_category=None, + plot_type="Rectangular Plot", + context=None, + subdesign_id=None, + polyline_points=1001, + plotname=None, + sweep_name=None, + ): + """Create a report in AEDT. It can be a 2D plot, 3D plot, polar plots or data tables. + + Parameters + ---------- + expressions : str or list, optional + One or more formulas to add to the report. Example is value = ``"dB(S(1,1))"``. + domain : str, optional + Plot Domain. Options are "Sweep", "Time", "DCIR". + variations : dict, optional + Dictionary of all families including the primary sweep. The default is ``{"Freq": ["All"]}``. + primary_sweep_variable : str, optional + Name of the primary sweep. The default is ``"Freq"``. + secondary_sweep_variable : str, optional + Name of the secondary sweep variable in 3D Plots. + report_category : str, optional + Category of the Report to be created. If `None` default data Report will be used. + The Report Category can be one of the types available for creating a report depend on the simulation setup. + For example for a Far Field Plot in HFSS the UI shows the report category as "Create Far Fields Report". + The report category will be in this case "Far Fields". + Depending on the setup different categories are available. + If `None` default category will be used (the first item in the Results drop down menu in AEDT). + plot_type : str, optional + The format of Data Visualization. Default is ``Rectangular Plot``. + context : str, optional + The default is ``None``. It can be `None`, `"Differential Pairs"`,`"RL"`, + `"Sources"`, `"Vias"`,`"Bondwires"`, `"Probes"` for Hfss3dLayout or + Reduce Matrix Name for Q2d/Q3d solution or Infinite Sphere name for Far Fields Plot. + plotname : str, optional + Name of the plot. The default is ``None``. + polyline_points : int, optional, + Number of points on which create the report for plots on polylines. + subdesign_id : int, optional + Specify a subdesign ID to export a Touchstone file of this subdesign. Valid for Circuit Only. + The default value is ``None``. + context : str, optional + sweep_name : str, optional + Name of the sweep adaptive setup from which get solutions. Default is ``LastAdaptive``. + + Returns + ------- + :class:`pyaedt.modules.report_templates.Standard` + ``True`` when successful, ``False`` when failed. + + + References + ---------- + + >>> oModule.CreateReport + + Examples + -------- + >>> from pyaedt import Circuit + >>> aedtapp = Circuit() + >>> aedtapp.post.create_report("dB(S(1,1))") + + >>> variations = aedtapp.available_variations.nominal_w_values_dict + >>> aedtapp.post.setups[0].create_report( + ... "dB(S(1,1))", + ... variations=variations, + ... primary_sweep_variable="Freq", + ...) + + >>> aedtapp.post.create_report( + ... "S(1,1)", + ... variations=variations, + ... plot_type="Smith Chart", + ...) + """ + if sweep_name: + setup_sweep_name = [ + i for i in self._app.existing_analysis_sweeps if self.name == i.split(" : ")[0] and sweep_name in i + ] + else: + setup_sweep_name = [i for i in self._app.existing_analysis_sweeps if self.name == i.split(" : ")[0]] + if setup_sweep_name: + return self._app.post.create_report( + expressions=expressions, + domain=domain, + variations=variations, + primary_sweep_variable=primary_sweep_variable, + secondary_sweep_variable=secondary_sweep_variable, + report_category=report_category, + plot_type=plot_type, + context=context, + polyline_points=polyline_points, + plotname=plotname, + setup_sweep_name=setup_sweep_name[0], + ) + return None + class Setup(CommonSetup): """Initializes, creates, and updates a 3D setup. @@ -1181,6 +1416,168 @@ def disable(self, setup_name=None): self._odesign.EnableSolutionSetup(setup_name, False) return True + @pyaedt_function_handler() + def get_solution_data( + self, + expressions=None, + domain=None, + variations=None, + primary_sweep_variable=None, + report_category=None, + context=None, + subdesign_id=None, + polyline_points=1001, + math_formula=None, + ): + """Get a simulation result from a solved setup and cast it in a ``SolutionData`` object. + Data to be retrieved from Electronics Desktop are any simulation results available in that + specific simulation context. + Most of the argument have some defaults which works for most of the ``Standard`` report quantities. + + Parameters + ---------- + expressions : str or list, optional + One or more formulas to add to the report. Example is value ``"dB(S(1,1))"`` or a list of values. + Default is `None` which will return all traces. + domain : str, optional + Plot Domain. Options are "Sweep" for frequency domain related results and "Time" for transient related data. + variations : dict, optional + Dictionary of all families including the primary sweep. + The default is ``None`` which will use the nominal variations of the setup. + primary_sweep_variable : str, optional + Name of the primary sweep. The default is ``"None"`` which, depending on the context, + will internally assign the primary sweep to: + 1. ``Freq`` for frequency domain results, + 2. ``Time`` for transient results, + 3. ``Theta`` for radiation patterns, + 4. ``distance`` for field plot over a polyline. + report_category : str, optional + Category of the Report to be created. If `None` default data Report will be used. + The Report Category can be one of the types available for creating a report depend on the simulation setup. + For example for a Far Field Plot in HFSS the UI shows the report category as "Create Far Fields Report". + The report category will be in this case "Far Fields". + Depending on the setup different categories are available. + If `None` default category will be used (the first item in the Results drop down menu in AEDT). + To get the list of available categories user can use method ``available_report_types``. + context : str, dict, optional + This is the context of the report. + The default is ``None``. It can be: + 1. `None` + 2. ``"Differential Pairs"`` + 3. Reduce Matrix Name for Q2d/Q3d solution + 4. Infinite Sphere name for Far Fields Plot. + 5. Dictionary. If dictionary is passed, key is the report property name and value is property value. + subdesign_id : int, optional + Subdesign ID for exporting a Touchstone file of this subdesign. + This parameter is valid for ``Circuit`` only. + The default value is ``None``. + polyline_points : int, optional + Number of points on which to create the report for plots on polylines. + This parameter is valid for ``Fields`` plot only. + math_formula : str, optional + One of the available AEDT mathematical formulas to apply. For example, ``abs, dB``. + + + Returns + ------- + :class:`pyaedt.modules.solutions.SolutionData` + Solution Data object. + + References + ---------- + + >>> oModule.GetSolutionDataPerVariation + """ + return self._app.post.get_solution_data( + expressions=expressions, + domain=domain, + variations=variations, + primary_sweep_variable=primary_sweep_variable, + report_category=report_category, + context=context, + subdesign_id=subdesign_id, + polyline_points=polyline_points, + math_formula=math_formula, + setup_sweep_name=self.name, + ) + + @pyaedt_function_handler() + def create_report( + self, + expressions=None, + domain="Sweep", + variations=None, + primary_sweep_variable=None, + secondary_sweep_variable=None, + report_category=None, + plot_type="Rectangular Plot", + context=None, + subdesign_id=None, + polyline_points=1001, + plotname=None, + ): + """Create a report in AEDT. It can be a 2D plot, 3D plot, polar plots or data tables. + + Parameters + ---------- + expressions : str or list, optional + One or more formulas to add to the report. Example is value = ``"dB(S(1,1))"``. + domain : str, optional + Plot Domain. Options are "Sweep", "Time", "DCIR". + variations : dict, optional + Dictionary of all families including the primary sweep. The default is ``{"Freq": ["All"]}``. + primary_sweep_variable : str, optional + Name of the primary sweep. The default is ``"Freq"``. + secondary_sweep_variable : str, optional + Name of the secondary sweep variable in 3D Plots. + report_category : str, optional + Category of the Report to be created. If `None` default data Report will be used. + The Report Category can be one of the types available for creating a report depend on the simulation setup. + For example for a Far Field Plot in HFSS the UI shows the report category as "Create Far Fields Report". + The report category will be in this case "Far Fields". + Depending on the setup different categories are available. + If `None` default category will be used (the first item in the Results drop down menu in AEDT). + plot_type : str, optional + The format of Data Visualization. Default is ``Rectangular Plot``. + context : str, optional + The default is ``None``. It can be `None`, `"Differential Pairs"`,`"RL"`, + `"Sources"`, `"Vias"`,`"Bondwires"`, `"Probes"` for Hfss3dLayout or + Reduce Matrix Name for Q2d/Q3d solution or Infinite Sphere name for Far Fields Plot. + plotname : str, optional + Name of the plot. The default is ``None``. + polyline_points : int, optional, + Number of points on which create the report for plots on polylines. + subdesign_id : int, optional + Specify a subdesign ID to export a Touchstone file of this subdesign. Valid for Circuit Only. + The default value is ``None``. + context : str, optional + + Returns + ------- + :class:`pyaedt.modules.report_templates.Standard` + ``True`` when successful, ``False`` when failed. + + + References + ---------- + + >>> oModule.CreateReport + """ + return self._app.post.create_report( + expressions=expressions, + domain=domain, + variations=variations, + primary_sweep_variable=primary_sweep_variable, + secondary_sweep_variable=secondary_sweep_variable, + report_category=report_category, + plot_type=plot_type, + context=context, + polyline_points=polyline_points, + plotname=plotname, + subdesign_id=subdesign_id, + setup_sweep_name=self.name, + ) + class Setup3DLayout(CommonSetup): """Initializes, creates, and updates a 3D Layout setup. From 962f4df93f776b739ecc995005216045f939f4ca Mon Sep 17 00:00:00 2001 From: maxcapodi78 Date: Wed, 22 Nov 2023 13:27:11 +0100 Subject: [PATCH 2/4] fix import_nastran --- pyaedt/modeler/modeler3d.py | 369 +++++++++++++++++++++++------------- 1 file changed, 235 insertions(+), 134 deletions(-) diff --git a/pyaedt/modeler/modeler3d.py b/pyaedt/modeler/modeler3d.py index a70450d6a99..745e5b13e4f 100644 --- a/pyaedt/modeler/modeler3d.py +++ b/pyaedt/modeler/modeler3d.py @@ -889,151 +889,252 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import lines = f.read().splitlines() id = 0 for line in lines: + line_type = line[:8].strip() if line.startswith("$") or line.startswith("*"): continue - if "*" in line: - line = line.strip()[:-1] + lines[lines.index(line) + 1][8:] - line_split = [line[:8]] + [line[i : i + 16] for i in range(8, len(line), 16)] - else: - line_split = [line[i : i + 8] for i in range(0, len(line), 8)] - - line_split = [i for i in line_split if i.replace(" ", "").replace("\t", "")] - - if len(line_split) < 5: - continue - if line_split[0].startswith("GRID"): - try: - import re - - out = re.findall("^.{24}(.{8})(.{8})(.{8})", line)[0] - n1 = out[0].replace(".-", ".e-").strip() - n2 = out[1].replace(".-", ".e-").strip() - n3 = out[2].replace(".-", ".e-").strip() - - if "-" in n1[1:]: - n1 = n1[0] + n1[1:].replace("-", "e-") - n1 = float(n1) - if "-" in n2[1:]: - n2 = n2[0] + n2[1:].replace("-", "e-") - n2 = float(n2) - if "-" in n3[1:]: - n3 = n3[0] + n3[1:].replace("-", "e-") - n3 = float(n3) - - nas_to_dict["Points"][int(line_split[1])] = [n1, n2, n3] - nas_to_dict["PointsId"][int(line_split[1])] = id + elif line_type in ["GRID", "CTRIA3"]: + grid_id = int(line[8:16]) + tria_id = int(line[16:24]) + n1 = line[24:32].strip() + if "-" in n1[1:]: + n1 = n1[0] + n1[1:].replace("-", "e-") + n2 = line[32:40].strip() + if "-" in n2[1:]: + n2 = n2[0] + n2[1:].replace("-", "e-") + n3 = line[40:48].strip() + if "-" in n3[1:]: + n3 = n3[0] + n3[1:].replace("-", "e-") + if line_type == "GRID": + nas_to_dict["Points"][grid_id] = [float(n1), float(n2), float(n3)] + nas_to_dict["PointsId"][grid_id] = grid_id id += 1 - except: - try: - nas_to_dict["Points"][int(line_split[1])] = [ - float(line_split[2]), - float(line_split[3]), - float(line_split[4]), - ] - nas_to_dict["PointsId"][int(line_split[1])] = id - id += 1 - except: - pass - elif line_split[0].startswith("CTRIA3"): - if int(line_split[2]) in nas_to_dict["Triangles"]: - nas_to_dict["Triangles"][int(line_split[2])].append( - [ - int(line_split[3]), - int(line_split[4]), - int(line_split[5]), - ] - ) else: - try: - nas_to_dict["Triangles"][int(line_split[2])] = [ + if tria_id in nas_to_dict["Triangles"]: + nas_to_dict["Triangles"][tria_id].append( [ - int(line_split[3]), - int(line_split[4]), - int(line_split[5]), + int(n1), + int(n2), + int(n3), + ] + ) + else: + nas_to_dict["Triangles"][tria_id] = [ + [ + int(n1), + int(n2), + int(n3), ] ] - except: - pass - elif line_split[0].startswith("CPENTA"): - if int(line_split[2]) in nas_to_dict["Solids"]: - nas_to_dict["Solids"][int(line_split[2])].append( - [ - line_split[0].strip(), - int(line_split[3]), - int(line_split[4]), - int(line_split[5]), - int(line_split[6]), - int(line_split[7]), - int(line_split[8]), - ] - ) - else: - nas_to_dict["Solids"][int(line_split[2])] = [ - [ - line_split[0].strip(), - int(line_split[3]), - int(line_split[4]), - int(line_split[5]), - int(line_split[6]), - int(line_split[7]), - int(line_split[8]), - ] - ] - elif line_split[0].startswith("CHEXA"): - if int(line_split[2]) in nas_to_dict["Solids"]: - nas_to_dict["Solids"][int(line_split[2])].append( - [ - line_split[0].strip(), - int(line_split[3]), - int(line_split[4]), - int(line_split[5]), - int(line_split[6]), - int(line_split[7]), - int(line_split[8]), - int(line_split[9]), - int(line_split[10]), - ] - ) + elif line_type in ["GRID*", "CTRIA3*"]: + grid_id = int(line[8:24]) + if line_type == "CTRIA3*": + tria_id = int(line[24:40]) + n1 = line[40:56].strip() + if "-" in n1[1:]: + n1 = n1[0] + n1[1:].replace("-", "e-") + n2 = line[56:72].strip() + if "-" in n2[1:]: + n2 = n2[0] + n2[1:].replace("-", "e-") + + n3 = line[72:88].strip() + if not n3 or n3 == "*": + n3 = lines[lines.index(line) + 1][8:24].strip() + if "-" in n3[1:]: + n3 = n3[0] + n3[1:].replace("-", "e-") + if line_type == "GRID*": + nas_to_dict["Points"][grid_id] = [float(n1), float(n2), float(n3)] + nas_to_dict["PointsId"][grid_id] = id + id += 1 else: - nas_to_dict["Solids"][int(line_split[2])] = [ - [ - line_split[0].strip(), - int(line_split[3]), - int(line_split[4]), - int(line_split[5]), - int(line_split[6]), - int(line_split[7]), - int(line_split[8]), - int(line_split[9]), - int(line_split[10]), - ] - ] - elif line_split[0].startswith("CTETRA"): - if int(line_split[2]) in nas_to_dict["Solids"]: - nas_to_dict["Solids"][int(line_split[2])].append( - [ - line_split[0].strip(), - int(line_split[3]), - int(line_split[4]), - int(line_split[5]), - int(line_split[6]), + if tria_id in nas_to_dict["Triangles"]: + nas_to_dict["Triangles"][tria_id].append( + [ + int(n1), + int(n2), + int(n3), + ] + ) + else: + nas_to_dict["Triangles"][tria_id] = [ + [ + int(n1), + int(n2), + int(n3), + ] ] - ) + elif line_type in ["CPENTA", "CHEXA", "CTETRA"]: + obj_id = int(line[16:24]) + n1 = int(line[24:32]) + n2 = int(line[32:40]) + n3 = int(line[40:48]) + n4 = int(line[48:56]) + obj_list = [line_type, n1, n2, n3, n4] + if line_type == "CPENTA": + n5 = int(line[56:64]) + n6 = int(line[64:72]) + obj_list.extend([n5, n6]) + + if line_type == "CHEXA": + n5 = int(line[56:64]) + n6 = int(line[64:72]) + n7 = int(line[56:64]) + n8 = int(line[64:72]) + obj_list.extend([n5, n6, n7, n8]) + if obj_id in nas_to_dict["Solids"]: + nas_to_dict["Solids"][obj_id].append(obj_list) else: - nas_to_dict["Solids"][int(line_split[2])] = [ - [ - line_split[0].strip(), - int(line_split[3]), - int(line_split[4]), - int(line_split[5]), - int(line_split[6]), - ] - ] - elif line_split[0].startswith("CROD") or line_split[0].startswith("CBEAM"): - if int(line_split[2]) in nas_to_dict["Lines"]: - nas_to_dict["Lines"][int(line_split[2])].append([int(line_split[3]), int(line_split[4])]) + nas_to_dict["Solids"][obj_id] = [[i for i in obj_list]] + elif line_type in ["CROD", "CBEAM"]: + obj_id = int(line[16:24]) + n1 = int(line[24:32]) + n2 = int(line[32:40]) + if obj_id in nas_to_dict["Lines"]: + nas_to_dict["Lines"][obj_id].append([n1, n2]) else: - nas_to_dict["Lines"][int(line_split[2])] = [[int(line_split[3]), int(line_split[4])]] + nas_to_dict["Lines"][obj_id] = [[n1, n2]] + # if "*" in line: + # line = line.strip()[:-1] + lines[lines.index(line) + 1][8:] + # line_split = [line[:8]] + [line[i : i + 16] for i in range(8, len(line), 16)] + # else: + # line_split = [line[i : i + 8] for i in range(0, len(line), 8)] + # + # line_split = [i for i in line_split if i.replace(" ", "").replace("\t", "")] + + # if len(line_split) < 5: + # continue + # if line_split[0].startswith("GRID"): + # try: + # import re + # + # out = re.findall("^.{24}(.{8})(.{8})(.{8})", line)[0] + # n1 = out[0].replace(".-", ".e-").strip() + # n2 = out[1].replace(".-", ".e-").strip() + # n3 = out[2].replace(".-", ".e-").strip() + # + # if "-" in n1[1:]: + # n1 = n1[0] + n1[1:].replace("-", "e-") + # n1 = float(n1) + # if "-" in n2[1:]: + # n2 = n2[0] + n2[1:].replace("-", "e-") + # n2 = float(n2) + # if "-" in n3[1:]: + # n3 = n3[0] + n3[1:].replace("-", "e-") + # n3 = float(n3) + # + # nas_to_dict["Points"][int(line_split[1])] = [n1, n2, n3] + # nas_to_dict["PointsId"][int(line_split[1])] = id + # id += 1 + # except: + # try: + # nas_to_dict["Points"][int(line_split[1])] = [ + # float(line_split[2]), + # float(line_split[3]), + # float(line_split[4]), + # ] + # nas_to_dict["PointsId"][int(line_split[1])] = id + # id += 1 + # except: + # pass + # elif line_split[0].startswith("CTRIA3"): + # if int(line_split[2]) in nas_to_dict["Triangles"]: + # nas_to_dict["Triangles"][int(line_split[2])].append( + # [ + # int(line_split[3]), + # int(line_split[4]), + # int(line_split[5]), + # ] + # ) + # else: + # try: + # nas_to_dict["Triangles"][int(line_split[2])] = [ + # [ + # int(line_split[3]), + # int(line_split[4]), + # int(line_split[5]), + # ] + # ] + # except: + # pass + # elif line_split[0].startswith("CPENTA"): + # if int(line_split[2]) in nas_to_dict["Solids"]: + # nas_to_dict["Solids"][int(line_split[2])].append( + # [ + # line_split[0].strip(), + # int(line_split[3]), + # int(line_split[4]), + # int(line_split[5]), + # int(line_split[6]), + # int(line_split[7]), + # int(line_split[8]), + # ] + # ) + # else: + # nas_to_dict["Solids"][int(line_split[2])] = [ + # [ + # line_split[0].strip(), + # int(line_split[3]), + # int(line_split[4]), + # int(line_split[5]), + # int(line_split[6]), + # int(line_split[7]), + # int(line_split[8]), + # ] + # ] + # elif line_split[0].startswith("CHEXA"): + # if int(line_split[2]) in nas_to_dict["Solids"]: + # nas_to_dict["Solids"][int(line_split[2])].append( + # [ + # line_split[0].strip(), + # int(line_split[3]), + # int(line_split[4]), + # int(line_split[5]), + # int(line_split[6]), + # int(line_split[7]), + # int(line_split[8]), + # int(line_split[9]), + # int(line_split[10]), + # ] + # ) + # else: + # nas_to_dict["Solids"][int(line_split[2])] = [ + # [ + # line_split[0].strip(), + # int(line_split[3]), + # int(line_split[4]), + # int(line_split[5]), + # int(line_split[6]), + # int(line_split[7]), + # int(line_split[8]), + # int(line_split[9]), + # int(line_split[10]), + # ] + # ] + # elif line_split[0].startswith("CTETRA"): + # if int(line_split[2]) in nas_to_dict["Solids"]: + # nas_to_dict["Solids"][int(line_split[2])].append( + # [ + # line_split[0].strip(), + # int(line_split[3]), + # int(line_split[4]), + # int(line_split[5]), + # int(line_split[6]), + # ] + # ) + # else: + # nas_to_dict["Solids"][int(line_split[2])] = [ + # [ + # line_split[0].strip(), + # int(line_split[3]), + # int(line_split[4]), + # int(line_split[5]), + # int(line_split[6]), + # ] + # ] + # elif line_split[0].startswith("CROD") or line_split[0].startswith("CBEAM"): + # if int(line_split[2]) in nas_to_dict["Lines"]: + # nas_to_dict["Lines"][int(line_split[2])].append([int(line_split[3]), int(line_split[4])]) + # else: + # nas_to_dict["Lines"][int(line_split[2])] = [[int(line_split[3]), int(line_split[4])]] self.logger.info_timer("File loaded") objs_before = [i for i in self.object_names] if nas_to_dict["Triangles"]: From 9216592bbf8ecc1600bd85b5f88a3de025ccc74f Mon Sep 17 00:00:00 2001 From: maxcapodi78 Date: Thu, 23 Nov 2023 11:27:53 +0100 Subject: [PATCH 3/4] Minor improvements --- pyaedt/modeler/modeler3d.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyaedt/modeler/modeler3d.py b/pyaedt/modeler/modeler3d.py index 745e5b13e4f..aeaa0e631bc 100644 --- a/pyaedt/modeler/modeler3d.py +++ b/pyaedt/modeler/modeler3d.py @@ -894,7 +894,8 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import continue elif line_type in ["GRID", "CTRIA3"]: grid_id = int(line[8:16]) - tria_id = int(line[16:24]) + if line_type == "CTRIA3": + tria_id = int(line[16:24]) n1 = line[24:32].strip() if "-" in n1[1:]: n1 = n1[0] + n1[1:].replace("-", "e-") From b594056ea09c7c3eb9f4326cd0284fff48f75788 Mon Sep 17 00:00:00 2001 From: maxcapodi78 Date: Thu, 23 Nov 2023 12:33:56 +0100 Subject: [PATCH 4/4] Minor improvements --- _unittest/example_models/T20/test_cad.nas | 29 ++-- _unittest/example_models/T20/test_cad_2.nas | 24 ++++ _unittest/test_20_HFSS.py | 2 + pyaedt/modeler/modeler3d.py | 149 +------------------- 4 files changed, 45 insertions(+), 159 deletions(-) create mode 100644 _unittest/example_models/T20/test_cad_2.nas diff --git a/_unittest/example_models/T20/test_cad.nas b/_unittest/example_models/T20/test_cad.nas index 948c6b48f5a..640b41ee14f 100644 --- a/_unittest/example_models/T20/test_cad.nas +++ b/_unittest/example_models/T20/test_cad.nas @@ -23,7 +23,7 @@ GRID 17 -142.085-81.8469969.8416 GRID 18 338.1222.4335859436.2341 GRID 19 328.0788-91.8056 418.809 GRID 20 260.6554-89.1117 459.994 -GRID 21 1574.546 -4.1-111484.805 +GRID 21 1574.546 -34.1-11484.805 GRID 22 4411.665-98.6627 505.296 GRID 23 4410.392-95.7236504.7545 GRID 24 4412.102-93.0528505.4793 @@ -38,18 +38,18 @@ GRID 32 4410.434-95.7239504.6637 GRID 33 4414.683-98.9433506.4686 GRID 34 4416.393-96.2763507.1935 GRID 35 4413.413-96.0004505.9284 -GRID 40 0.0 0.0 0.0 -GRID 41 1.0 0.0 0.0 -GRID 42 1.0 1.0 0.0 -GRID 43 0.0 1.0 0.0 -GRID 44 0.0 0.0 1.0 -GRID 45 1.0 0.0 1.0 -GRID 46 1.0 1.0 1.0 -GRID 47 0.0 1.0 1.0 -GRID 50 0.0 0.0 0.0 -GRID 51 2.0 0.0 0.0 -GRID 52 0.0 2.0 0.0 -GRID 53 0.0 0.0 2.0 +GRID 40 0.0 0.0 0.0 +GRID 41 1.0 0.0 0.0 +GRID 42 1.0 1.0 0.0 +GRID 43 0.0 1.0 0.0 +GRID 44 0.0 0.0 1.0 +GRID 45 1.0 0.0 1.0 +GRID 46 1.0 1.0 1.0 +GRID 47 0.0 1.0 1.0 +GRID 50 0.0 0.0 0.0 +GRID 51 2.0 0.0 0.0 +GRID 52 0.0 2.0 0.0 +GRID 53 0.0 0.0 2.0 CTRIA3 92455 31 4 5 6 CTRIA3 92456 31 5 10 11 CTRIA3 92457 31 21 20 16 @@ -64,7 +64,8 @@ CPENTA 25229 9 27 22 28 33 29 35 CPENTA 25279 9 25 28 24 30 35 31 CPENTA 25284 9 26 27 28 34 33 35 CPENTA 25328 9 26 28 25 34 35 30 -CHEXA 1 105 40 41 42 43 44 45 46 47 +CHEXA 1 105 40 41 42 43 44 45 +* 46 47 CTETRA 1 115 50 51 52 53 ENDDATA diff --git a/_unittest/example_models/T20/test_cad_2.nas b/_unittest/example_models/T20/test_cad_2.nas new file mode 100644 index 00000000000..f41ccef4bea --- /dev/null +++ b/_unittest/example_models/T20/test_cad_2.nas @@ -0,0 +1,24 @@ +$ +$ Settings : +$ +$ Output format : MSC Nastran +$ +$ Output : Visible +$ +$ +$ +$ +BEGIN BULK +GRID* 4 627.87512 568.96751* +* 1942.1985 +GRID* 5 812.95973 486.74968* +* 1495.9564 +GRID* 6 812.99916 484.24676* +* 1470.1764 +CTRIA3* 75986 19 4 5 +* 6 + + +ENDDATA +$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ diff --git a/_unittest/test_20_HFSS.py b/_unittest/test_20_HFSS.py index 72f828818a7..07bf7b9f848 100644 --- a/_unittest/test_20_HFSS.py +++ b/_unittest/test_20_HFSS.py @@ -1421,9 +1421,11 @@ def test_58_create_near_field_line(self): def test_59_test_nastran(self): self.aedtapp.insert_design("Nas_teest") example_project = os.path.join(local_path, "../_unittest/example_models", test_subfolder, "test_cad.nas") + example_project2 = os.path.join(local_path, "../_unittest/example_models", test_subfolder, "test_cad_2.nas") cads = self.aedtapp.modeler.import_nastran(example_project) assert len(cads) > 0 + assert self.aedtapp.modeler.import_nastran(example_project2) def test_60_set_variable(self): self.aedtapp.variable_manager.set_variable("var_test", expression="123") diff --git a/pyaedt/modeler/modeler3d.py b/pyaedt/modeler/modeler3d.py index aeaa0e631bc..b2f2fdb9b32 100644 --- a/pyaedt/modeler/modeler3d.py +++ b/pyaedt/modeler/modeler3d.py @@ -978,8 +978,9 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import if line_type == "CHEXA": n5 = int(line[56:64]) n6 = int(line[64:72]) - n7 = int(line[56:64]) - n8 = int(line[64:72]) + n7 = int(lines[lines.index(line) + 1][8:16].strip()) + n8 = int(lines[lines.index(line) + 1][16:24].strip()) + obj_list.extend([n5, n6, n7, n8]) if obj_id in nas_to_dict["Solids"]: nas_to_dict["Solids"][obj_id].append(obj_list) @@ -993,149 +994,7 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import nas_to_dict["Lines"][obj_id].append([n1, n2]) else: nas_to_dict["Lines"][obj_id] = [[n1, n2]] - # if "*" in line: - # line = line.strip()[:-1] + lines[lines.index(line) + 1][8:] - # line_split = [line[:8]] + [line[i : i + 16] for i in range(8, len(line), 16)] - # else: - # line_split = [line[i : i + 8] for i in range(0, len(line), 8)] - # - # line_split = [i for i in line_split if i.replace(" ", "").replace("\t", "")] - - # if len(line_split) < 5: - # continue - # if line_split[0].startswith("GRID"): - # try: - # import re - # - # out = re.findall("^.{24}(.{8})(.{8})(.{8})", line)[0] - # n1 = out[0].replace(".-", ".e-").strip() - # n2 = out[1].replace(".-", ".e-").strip() - # n3 = out[2].replace(".-", ".e-").strip() - # - # if "-" in n1[1:]: - # n1 = n1[0] + n1[1:].replace("-", "e-") - # n1 = float(n1) - # if "-" in n2[1:]: - # n2 = n2[0] + n2[1:].replace("-", "e-") - # n2 = float(n2) - # if "-" in n3[1:]: - # n3 = n3[0] + n3[1:].replace("-", "e-") - # n3 = float(n3) - # - # nas_to_dict["Points"][int(line_split[1])] = [n1, n2, n3] - # nas_to_dict["PointsId"][int(line_split[1])] = id - # id += 1 - # except: - # try: - # nas_to_dict["Points"][int(line_split[1])] = [ - # float(line_split[2]), - # float(line_split[3]), - # float(line_split[4]), - # ] - # nas_to_dict["PointsId"][int(line_split[1])] = id - # id += 1 - # except: - # pass - # elif line_split[0].startswith("CTRIA3"): - # if int(line_split[2]) in nas_to_dict["Triangles"]: - # nas_to_dict["Triangles"][int(line_split[2])].append( - # [ - # int(line_split[3]), - # int(line_split[4]), - # int(line_split[5]), - # ] - # ) - # else: - # try: - # nas_to_dict["Triangles"][int(line_split[2])] = [ - # [ - # int(line_split[3]), - # int(line_split[4]), - # int(line_split[5]), - # ] - # ] - # except: - # pass - # elif line_split[0].startswith("CPENTA"): - # if int(line_split[2]) in nas_to_dict["Solids"]: - # nas_to_dict["Solids"][int(line_split[2])].append( - # [ - # line_split[0].strip(), - # int(line_split[3]), - # int(line_split[4]), - # int(line_split[5]), - # int(line_split[6]), - # int(line_split[7]), - # int(line_split[8]), - # ] - # ) - # else: - # nas_to_dict["Solids"][int(line_split[2])] = [ - # [ - # line_split[0].strip(), - # int(line_split[3]), - # int(line_split[4]), - # int(line_split[5]), - # int(line_split[6]), - # int(line_split[7]), - # int(line_split[8]), - # ] - # ] - # elif line_split[0].startswith("CHEXA"): - # if int(line_split[2]) in nas_to_dict["Solids"]: - # nas_to_dict["Solids"][int(line_split[2])].append( - # [ - # line_split[0].strip(), - # int(line_split[3]), - # int(line_split[4]), - # int(line_split[5]), - # int(line_split[6]), - # int(line_split[7]), - # int(line_split[8]), - # int(line_split[9]), - # int(line_split[10]), - # ] - # ) - # else: - # nas_to_dict["Solids"][int(line_split[2])] = [ - # [ - # line_split[0].strip(), - # int(line_split[3]), - # int(line_split[4]), - # int(line_split[5]), - # int(line_split[6]), - # int(line_split[7]), - # int(line_split[8]), - # int(line_split[9]), - # int(line_split[10]), - # ] - # ] - # elif line_split[0].startswith("CTETRA"): - # if int(line_split[2]) in nas_to_dict["Solids"]: - # nas_to_dict["Solids"][int(line_split[2])].append( - # [ - # line_split[0].strip(), - # int(line_split[3]), - # int(line_split[4]), - # int(line_split[5]), - # int(line_split[6]), - # ] - # ) - # else: - # nas_to_dict["Solids"][int(line_split[2])] = [ - # [ - # line_split[0].strip(), - # int(line_split[3]), - # int(line_split[4]), - # int(line_split[5]), - # int(line_split[6]), - # ] - # ] - # elif line_split[0].startswith("CROD") or line_split[0].startswith("CBEAM"): - # if int(line_split[2]) in nas_to_dict["Lines"]: - # nas_to_dict["Lines"][int(line_split[2])].append([int(line_split[3]), int(line_split[4])]) - # else: - # nas_to_dict["Lines"][int(line_split[2])] = [[int(line_split[3]), int(line_split[4])]] + self.logger.info_timer("File loaded") objs_before = [i for i in self.object_names] if nas_to_dict["Triangles"]: