Download this example

Download this example as a Jupyter Notebook or as a Python script.


Dynamic ROM#

This example shows how to use PyAEDT to create a dynamic reduced order model (ROM) in Twin Builder and run a Twin Builder time-domain simulation.

Note: This example uses functionality only available in Twin Builder 2023 R2 and later.

Keywords: Twin Builder, Dynamic ROM.

Perform imports and define constants#

Perform required imports.

[1]:
import os
import shutil
import tempfile
import time
[2]:
import ansys.aedt.core
import matplotlib.pyplot as plt

Define constants.

[3]:
AEDT_VERSION = "2024.2"
NUM_CORES = 4
NG_MODE = False  # Open AEDT UI when it is launched.

Create temporary directory#

Create a temporary directory where downloaded data or dumped data can be stored. If you’d like to retrieve the project data for subsequent use, the temporary folder name is given by temp_folder.name.

[4]:
temp_folder = tempfile.TemporaryDirectory(suffix=".ansys")

Set up input data#

Define the file name.

[5]:
source_snapshot_data_zipfilename = "Ex1_Mechanical_DynamicRom.zip"
source_build_conf_file = "dynarom_build.conf"

Download data from the example_data repository.

[6]:
_ = ansys.aedt.core.downloads.download_twin_builder_data(
    file_name=source_snapshot_data_zipfilename,
    force_download=True,
    destination=temp_folder.name,
)
source_data_folder = ansys.aedt.core.downloads.download_twin_builder_data(
    source_build_conf_file, True, temp_folder.name
)

Toggle these for local testing.

[7]:
data_folder = os.path.join(source_data_folder, "Ex03")
[8]:
# Unzip training data and config file
ansys.aedt.core.downloads.unzip(
    os.path.join(source_data_folder, source_snapshot_data_zipfilename), data_folder
)
shutil.copyfile(
    os.path.join(source_data_folder, source_build_conf_file),
    os.path.join(data_folder, source_build_conf_file),
)
[8]:
'C:\\Users\\ansys\\AppData\\Local\\Temp\\tmprt8m2oxc.ansys\\twin_builder\\Ex03\\dynarom_build.conf'

Launch Twin Builder and build ROM component#

Launch Twin Builder using an implicit declaration and add a new design with the default setup for building the dynamic ROM component.

[9]:
project_name = os.path.join(temp_folder.name, "dynamic_rom.aedt")
tb = ansys.aedt.core.TwinBuilder(
    project=project_name,
    version=AEDT_VERSION,
    non_graphical=NG_MODE,
    new_desktop=True,
)
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_e3d69b77-62d1-4ea6-ac20-c7977259a699.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 52102
PyAEDT INFO: AEDT installation Path C:\Program Files\AnsysEM\v242\Win64
PyAEDT INFO: Ansoft.ElectronicsDesktop.2024.2 version started with process ID 7240.
PyAEDT INFO: Project dynamic_rom has been created.
PyAEDT INFO: No design is present. Inserting a new design.
PyAEDT INFO: Added design 'Twin Builder_EOK' of type Twin Builder.
PyAEDT INFO: Aedt Objects correctly read

Configure AEDT#

Note: Only run the following cell if AEDT is not configured to run Twin Builder.

The following cell configures AEDT and the schematic editor to use the Twin Builder configuration. The dynamic ROM feature is only available with a Twin Builder license. A cell at the end of this example restores the AEDT configuration. If your environment is set up to use the Twin Builder configuration, you do not need to run these code blocks.

[10]:
current_desktop_config = tb._odesktop.GetDesktopConfiguration()
current_schematic_environment = tb._odesktop.GetSchematicEnvironment()
tb._odesktop.SetDesktopConfiguration("Twin Builder")
tb._odesktop.SetSchematicEnvironment(1)
[11]:
# Get the dynamic ROM builder object.
rom_manager = tb._odesign.GetROMManager()
dynamic_rom_builder = rom_manager.GetDynamicROMBuilder()
[12]:
# Build the dynamic ROM with the specified configuration file.
conf_file_path = os.path.join(data_folder, source_build_conf_file)
dynamic_rom_builder.Build(conf_file_path.replace("\\", "/"))
[13]:
# Test if the ROM was created successfully
dynamic_rom_path = os.path.join(data_folder, "DynamicRom.dyn")
if os.path.exists(dynamic_rom_path):
    tb._odesign.AddMessage(
        "Info", "path exists: {}".format(dynamic_rom_path.replace("\\", "/")), ""
    )
else:
    tb._odesign.AddMessage(
        "Info", "path does not exist: {}".format(dynamic_rom_path), ""
    )
[14]:
# Create the ROM component definition in Twin Builder.
rom_manager.CreateROMComponent(dynamic_rom_path.replace("\\", "/"), "dynarom")

Create schematic#

Place components to create a schematic.

Define the grid distance for ease in calculations.

[15]:
G = 0.00254

Place a dynamic ROM component.

[16]:
rom1 = tb.modeler.schematic.create_component("ROM1", "", "dynarom", [36 * G, 28 * G])
PyAEDT INFO: ModelerCircuit class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: ModelerTwinBuilder class has been initialized!

Place two excitation sources.

[17]:
source1 = tb.modeler.schematic.create_periodic_waveform_source(
    None, "PULSE", 190, 0.002, "300deg", 210, 0, [20 * G, 29 * G]
)
source2 = tb.modeler.schematic.create_periodic_waveform_source(
    None, "PULSE", 190, 0.002, "300deg", 210, 0, [20 * G, 25 * G]
)

Connect components with wires.

[18]:
tb.modeler.schematic.create_wire([[22 * G, 29 * G], [33 * G, 29 * G]])
tb.modeler.schematic.create_wire(
    [[22 * G, 25 * G], [30 * G, 25 * G], [30 * G, 28 * G], [33 * G, 28 * G]]
)
[18]:
<ansys.aedt.core.modeler.circuits.object_3d_circuit.Wire at 0x2448493fd60>
[19]:
# Zoom to fit the schematic.
tb.modeler.zoom_to_fit()

Parametrize transient setup#

Parametrize the default transient setup by setting the end time.

[20]:
tb.set_end_time("1000s")
tb.set_hmin("1s")
tb.set_hmax("1s")
[20]:
True

Solve transient setup#

[21]:
tb.analyze_setup("TR", cores=NUM_CORES)
PyAEDT INFO: Key Desktop/ActiveDSOConfigurations/Twin Builder correctly changed.
PyAEDT INFO: Solving design setup TR
PyAEDT INFO: Key Desktop/ActiveDSOConfigurations/Twin Builder correctly changed.
PyAEDT INFO: Design setup TR solved correctly in 0.0h 0.0m 15.0s
[21]:
True

Get report data and plot using Matplotlib#

Get report data and plot it using Matplotlib. The following code gets and plots the values for the voltage on the pulse voltage source and the values for the output of the dynamic ROM.

[22]:
input_excitation = "PULSE1.VAL"
x = tb.post.get_solution_data(input_excitation, "TR", "Time")
plt.plot(x.intrinsics["Time"], x.data_real(input_excitation))
PyAEDT INFO: Post class has been initialized! Elapsed time: 0m 0sec
PyAEDT INFO: Solution Data Correctly Loaded.
[22]:
[<matplotlib.lines.Line2D at 0x2448718b490>]
../../../../_images/examples_low_frequency_general_twin_builder_dynamic_rom_38_2.png
[23]:
output_temperature = "ROM1.Temperature_history"
x = tb.post.get_solution_data(output_temperature, "TR", "Time")
plt.plot(x.intrinsics["Time"], x.data_real(output_temperature))
PyAEDT INFO: Solution Data Correctly Loaded.
[23]:
[<matplotlib.lines.Line2D at 0x244870f28c0>]
../../../../_images/examples_low_frequency_general_twin_builder_dynamic_rom_39_2.png
[24]:
plt.grid()
plt.xlabel("Time")
plt.ylabel("Temperature History Variation with Input Temperature Pulse")
plt.show()
../../../../_images/examples_low_frequency_general_twin_builder_dynamic_rom_40_0.png

Close Twin Builder#

After the simulation is completed, you can close Twin Builder or release it. All methods provide for saving the project before closing.

[25]:
# Clean up the downloaded data.
shutil.rmtree(source_data_folder)
[26]:
# Restore the earlier AEDT configuration and schematic environment.
tb._odesktop.SetDesktopConfiguration(current_desktop_config)
tb._odesktop.SetSchematicEnvironment(current_schematic_environment)

Release AEDT#

Release AEDT and close the example.

[27]:
tb.save_project()
tb.release_desktop()
# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory.
time.sleep(3)
PyAEDT INFO: Project dynamic_rom Saved correctly
PyAEDT INFO: Desktop has been released and closed.

Clean up#

All project files are saved in the folder temp_folder.name. If you’ve run this example as a Jupyter notebook, you can retrieve those project files. The following cell removes all temporary files, including the project folder.

[28]:
temp_folder.cleanup()

Download this example

Download this example as a Jupyter Notebook or as a Python script.