.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples\00-twin_creation\00-TBROM_Twin_creation_evaluation.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_00-twin_creation_00-TBROM_Twin_creation_evaluation.py: .. _ref_example_pyAEDT_Twin: Static ROM creation, Twin generation and evaluation --------------------------------------------------- This example shows how you can use PyAEDT and PyTwin together. PyAEDT is used on one side to generate a static ROM based on training data, and then create and export a twin model. PyTwin is used on the other side to load and evaluate the generated twin model. Parametric field history results (i.e. transient results collected on a fixed time interval for different parameters values) have been generated out of LS-DYNA simulations. Once the twin is generated, it can be evaluated to make predictions of time series (e.g. transient displacement at a given probe location) .. note:: This example requires an installation of Ansys Twin Builder 2025R1 or above. .. GENERATED FROM PYTHON SOURCE LINES 40-43 .. image:: /_static/TBROM_parametric_field_history.png :width: 400pt :align: center .. GENERATED FROM PYTHON SOURCE LINES 43-46 .. code-block:: Python # sphinx_gallery_thumbnail_path = '_static/TBROM_parametric_field_history.png' .. GENERATED FROM PYTHON SOURCE LINES 47-51 Perform required imports ~~~~~~~~~~~~~~~~~~~~~~~~ Perform required imports, which include downloading and importing the input files. .. GENERATED FROM PYTHON SOURCE LINES 51-71 .. code-block:: Python import csv import json import os import shutil import zipfile from ansys.aedt.core import TwinBuilder, generate_unique_project_name import matplotlib.pyplot as plt import numpy as np import pandas as pd from pytwin import TwinModel, download_file, read_binary training_data_zip = "training_data.zip" download_folder = download_file(training_data_zip, "other_files", force_download=True) training_data_folder = os.path.join(os.path.dirname(download_folder), "training_data") # Unzip training data with zipfile.ZipFile(download_folder) as zf: zf.extractall(training_data_folder) .. GENERATED FROM PYTHON SOURCE LINES 72-75 Define auxiliary functions ~~~~~~~~~~~~~~~~~~~~~~~~~~ Define auxiliary functions for computing # the norm of the output field. .. GENERATED FROM PYTHON SOURCE LINES 75-86 .. code-block:: Python def norm_vector_history(field: np.ndarray, index: int): """Compute the norm of a vector field.""" result = [] for i in range(0, field.shape[0]): vec = field[i, :].reshape((-1, 3)) result.append(np.sqrt((vec * vec).sum(axis=1))[index]) return result .. GENERATED FROM PYTHON SOURCE LINES 87-94 Project settings ~~~~~~~~~~~~~~~~ Define Twin Builder project related settings and inputs files. The following code launches Twin Builder in graphical mode. You can change the Boolean parameter ``non_graphical`` to ``True`` to launch Twin Builder in non-graphical mode. You can also change the Boolean parameter ``new_thread`` to ``False`` to launch Twin Builder in an existing AEDT session if one is running. .. GENERATED FROM PYTHON SOURCE LINES 94-104 .. code-block:: Python source_build_conf_file = "SROMbuild.conf" source_props_conf_file = "SROM_props.conf" # Note : SROM_props.conf may need to be adapted if inputs names change! desktop_version = "2025.1" non_graphical = False new_thread = True confpath = os.path.join(training_data_folder, source_build_conf_file) doefile = os.path.join(training_data_folder, "doe.csv") settingsfile = os.path.join(training_data_folder, "settings.json") .. GENERATED FROM PYTHON SOURCE LINES 105-108 ROM creation ~~~~~~~~~~~~ Create a Twin Builder instance .. GENERATED FROM PYTHON SOURCE LINES 108-136 .. code-block:: Python tb = TwinBuilder( project=generate_unique_project_name(), version=desktop_version, non_graphical=non_graphical, new_desktop=new_thread ) # Switch the current desktop configuration and the schematic environment to "Twin Builder" (Static ROM Builder is # available with Twin Builder). current_desktop_config = tb.odesktop.GetDesktopConfiguration() current_schematic_environment = tb.odesktop.GetSchematicEnvironment() tb.odesktop.SetDesktopConfiguration("Twin Builder") tb.odesktop.SetSchematicEnvironment(1) # Get the static ROM builder object rom_manager = tb.odesign.GetROMManager() static_rom_builder = rom_manager.GetStaticROMBuilder() # Build the static ROM with specified configuration file static_rom_builder.Build(confpath.replace("\\", "/")) # Test if ROM was created successfully static_rom_path = os.path.join(training_data_folder, "StaticRom.rom") if os.path.exists(static_rom_path): tb.logger.info("Built intermediate rom file successfully at: %s", static_rom_path) else: tb.logger.error("Intermediate rom file not found at: %s", static_rom_path) # Create the ROM component definition in Twin Builder rom_manager.CreateROMComponent(static_rom_path.replace("\\", "/"), "staticrom") .. rst-class:: sphx-glr-script-out .. code-block:: none PyAEDT INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] PyAEDT INFO: PyAEDT version 0.12.dev0. PyAEDT INFO: Initializing new Desktop session. PyAEDT INFO: Log on console is enabled. PyAEDT INFO: Log on file C:\Users\ansys\AppData\Local\Temp\pyaedt_ansys_1f43a557-4fe4-4179-b7f1-2340623c55c5.log is enabled. PyAEDT INFO: Log on AEDT is enabled. PyAEDT INFO: Debug logger is disabled. PyAEDT methods will not be logged. PyAEDT INFO: Launching PyAEDT with gRPC plugin. PyAEDT INFO: New AEDT session is starting on gRPC port 50862 PyAEDT INFO: AEDT installation Path C:\Program Files\AnsysEM\v251\Win64 PyAEDT INFO: Ansoft.ElectronicsDesktop.2025.1 version started with process ID 10084. PyAEDT INFO: Project Project_OJD has been created. PyAEDT INFO: No design is present. Inserting a new design. PyAEDT INFO: Added design 'Twin Builder_YKO' of type Twin Builder. PyAEDT INFO: Aedt Objects correctly read PyAEDT INFO: Built intermediate rom file successfully at: C:\Users\ansys\AppData\Local\Temp\TwinExamples\other_files\training_data\StaticRom.rom .. GENERATED FROM PYTHON SOURCE LINES 137-140 Twin composition and export ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Define the grid distance for ease in calculations. .. GENERATED FROM PYTHON SOURCE LINES 140-173 .. code-block:: Python G = 0.00254 # Create the Twin Subsheet. parentDesign = "ParentDesign" subSheet = "SubSheet" tb.create_subsheet(subSheet, parentDesign) idSubSheet = len(tb.odesign.GetSubDesigns()) tb.set_active_design(parentDesign + "::SubSheet" + str(idSubSheet)) # Place the ROM component, parameterize and connect to port interfaces. rom1 = tb.modeler.schematic.create_component("ROM1", "", "staticrom", [40 * G, 25 * G]) rom1.parameters["field_data_storage_period"] = "0" rom1.parameters["store_snapshots"] = "1" tb.modeler.schematic.add_pin_iports("ROM1", rom1.id) tb.logger.info("Subsheet created, starting Twin compilation") # twin compilation twinname = "TwinModel" tb.odesign.CompileAsTwin(twinname, ["1", "0.001", "1e-4", "1e-12"]) # twin export twinFile = os.path.join(training_data_folder, twinname + ".twin") tb.modeler.schematic.o_simmodel_manager.ExportTwinModel(twinname, twinFile, "twin", "other", "1", "1") tb.logger.info("Twin compiled and exported. Closing Twin Builder.") # Restore earlier desktop configuration and schematic environment. tb.odesktop.SetDesktopConfiguration(current_desktop_config) tb.odesktop.SetSchematicEnvironment(current_schematic_environment) tb.release_desktop() .. rst-class:: sphx-glr-script-out .. code-block:: none PyAEDT INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] PyAEDT INFO: PyAEDT version 0.12.dev0. PyAEDT INFO: Returning found Desktop session with PID 10084! PyAEDT INFO: Project Project_OJD set to active. PyAEDT INFO: Added design 'ParentDesign' of type Twin Builder. PyAEDT INFO: Aedt Objects correctly read PyAEDT INFO: Python version 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] PyAEDT INFO: PyAEDT version 0.12.dev0. PyAEDT INFO: Returning found Desktop session with PID 10084! PyAEDT INFO: Project Project_OJD set to active. PyAEDT INFO: Aedt Objects correctly read PyAEDT INFO: ModelerCircuit class has been initialized! Elapsed time: 0m 0sec PyAEDT INFO: ModelerTwinBuilder class has been initialized! PyAEDT INFO: Subsheet created, starting Twin compilation PyAEDT INFO: Twin compiled and exported. Closing Twin Builder. PyAEDT INFO: Desktop has been released and closed. True .. GENERATED FROM PYTHON SOURCE LINES 174-177 Twin evaluation ~~~~~~~~~~~~~~~ Evaluate the exported Twin with PyTwin and post process the results .. GENERATED FROM PYTHON SOURCE LINES 177-204 .. code-block:: Python # Read column header names input_header_df = pd.read_csv(doefile, header=None, nrows=1, sep=r";\s+", engine="python", quoting=csv.QUOTE_ALL) # Read data, clean header names, and assemble final dataframe inputs_df = pd.read_csv(doefile, header=None, skiprows=1, sep=";") inputs_header_values = input_header_df.iloc[0][0].split(";") inputs_df.columns = inputs_header_values inputs = dict() data_index = 0 for column in inputs_df.columns[1::]: inputs[column] = inputs_df[column][data_index] # Read settings file with open(settingsfile) as f: data = json.load(f) timeGrid = data["timeSeries"]["timeStepsValues"] romdim = int(data["dimensionality"][0]) # Load and evaluate the Twin print("Loading model: {}".format(twinFile)) print("Twin inputs evaluated: {}".format(inputs)) twin_model = TwinModel(twinFile) romname = twin_model.tbrom_names[0] twin_model.initialize_evaluation(inputs=inputs) .. rst-class:: sphx-glr-script-out .. code-block:: none Loading model: C:\Users\ansys\AppData\Local\Temp\TwinExamples\other_files\training_data\TwinModel.twin Twin inputs evaluated: {'tbumper': 3.0, 'thood': 1.0} .. GENERATED FROM PYTHON SOURCE LINES 205-208 Results post processing ~~~~~~~~~~~~~~~~~~~~~~~ The time history predictions for a particular probe (point #23) are post processed and compared to reference results. .. GENERATED FROM PYTHON SOURCE LINES 208-222 .. code-block:: Python ref_snapshot = os.path.join(training_data_folder, "snapshots", inputs_df[inputs_df.columns[0]][data_index]) ref_data = read_binary(ref_snapshot).reshape(len(timeGrid), -1) snapshot = twin_model.get_snapshot_filepath(romname) snap_data = read_binary(snapshot).reshape(len(timeGrid), -1) probe_id = 23 plt.plot(timeGrid, norm_vector_history(ref_data, probe_id), label="reference") plt.plot(timeGrid, norm_vector_history(snap_data, probe_id), label="rom") plt.legend(loc="lower left") plt.title("Displacement vs Time for point {}".format(probe_id)) plt.show() # Clean up the downloaded data shutil.rmtree(training_data_folder) .. image-sg:: /examples/00-twin_creation/images/sphx_glr_00-TBROM_Twin_creation_evaluation_001.png :alt: Displacement vs Time for point 23 :srcset: /examples/00-twin_creation/images/sphx_glr_00-TBROM_Twin_creation_evaluation_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (1 minutes 40.631 seconds) .. _sphx_glr_download_examples_00-twin_creation_00-TBROM_Twin_creation_evaluation.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 00-TBROM_Twin_creation_evaluation.ipynb <00-TBROM_Twin_creation_evaluation.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 00-TBROM_Twin_creation_evaluation.py <00-TBROM_Twin_creation_evaluation.py>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: 00-TBROM_Twin_creation_evaluation.zip <00-TBROM_Twin_creation_evaluation.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_