{ "cells": [ { "cell_type": "markdown", "id": "2be3ce16", "metadata": {}, "source": [ "# Dynamic ROM\n", "\n", "This example shows how to use PyAEDT to create a dynamic reduced order model (ROM)\n", "in Twin Builder and run a Twin Builder time-domain simulation.\n", "\n", "> **Note:** This example uses functionality only available in Twin\n", "> Builder 2023 R2 and later.\n", "\n", "Keywords: **Twin Builder**, **Dynamic ROM**." ] }, { "cell_type": "markdown", "id": "f54c8743", "metadata": {}, "source": [ "## Perform imports and define constants\n", "\n", "Perform required imports." ] }, { "cell_type": "code", "execution_count": null, "id": "25a66ce0", "metadata": {}, "outputs": [], "source": [ "import os\n", "import shutil\n", "import tempfile\n", "import time" ] }, { "cell_type": "code", "execution_count": null, "id": "ede1cff0", "metadata": {}, "outputs": [], "source": [ "import ansys.aedt.core\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "id": "37dbd80d", "metadata": {}, "source": [ "Define constants." ] }, { "cell_type": "code", "execution_count": null, "id": "99ec4178", "metadata": {}, "outputs": [], "source": [ "AEDT_VERSION = \"2024.2\"\n", "NUM_CORES = 4\n", "NG_MODE = False # Open AEDT UI when it is launched." ] }, { "cell_type": "markdown", "id": "440bd62a", "metadata": {}, "source": [ "## Create temporary directory\n", "\n", "Create a temporary directory where downloaded data or\n", "dumped data can be stored.\n", "If you'd like to retrieve the project data for subsequent use,\n", "the temporary folder name is given by ``temp_folder.name``." ] }, { "cell_type": "code", "execution_count": null, "id": "65837adf", "metadata": {}, "outputs": [], "source": [ "temp_folder = tempfile.TemporaryDirectory(suffix=\".ansys\")" ] }, { "cell_type": "markdown", "id": "2565dd35", "metadata": {}, "source": [ "## Set up input data\n", "\n", "Define the file name." ] }, { "cell_type": "code", "execution_count": null, "id": "a426281a", "metadata": {}, "outputs": [], "source": [ "source_snapshot_data_zipfilename = \"Ex1_Mechanical_DynamicRom.zip\"\n", "source_build_conf_file = \"dynarom_build.conf\"" ] }, { "cell_type": "markdown", "id": "6f9f1b67", "metadata": {}, "source": [ "Download data from the ``example_data`` repository." ] }, { "cell_type": "code", "execution_count": null, "id": "7833b345", "metadata": {}, "outputs": [], "source": [ "_ = ansys.aedt.core.downloads.download_twin_builder_data(\n", " file_name=source_snapshot_data_zipfilename,\n", " force_download=True,\n", " destination=temp_folder.name,\n", ")\n", "source_data_folder = ansys.aedt.core.downloads.download_twin_builder_data(\n", " source_build_conf_file, True, temp_folder.name\n", ")" ] }, { "cell_type": "markdown", "id": "c181982d", "metadata": {}, "source": [ "Toggle these for local testing." ] }, { "cell_type": "code", "execution_count": null, "id": "2914ed29", "metadata": {}, "outputs": [], "source": [ "data_folder = os.path.join(source_data_folder, \"Ex03\")" ] }, { "cell_type": "code", "execution_count": null, "id": "5a86b173", "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "# Unzip training data and config file\n", "ansys.aedt.core.downloads.unzip(\n", " os.path.join(source_data_folder, source_snapshot_data_zipfilename), data_folder\n", ")\n", "shutil.copyfile(\n", " os.path.join(source_data_folder, source_build_conf_file),\n", " os.path.join(data_folder, source_build_conf_file),\n", ")" ] }, { "cell_type": "markdown", "id": "5531f121", "metadata": {}, "source": [ "## Launch Twin Builder and build ROM component\n", "\n", "Launch Twin Builder using an implicit declaration and add a new design with\n", "the default setup for building the dynamic ROM component." ] }, { "cell_type": "code", "execution_count": null, "id": "f6748ba8", "metadata": {}, "outputs": [], "source": [ "project_name = os.path.join(temp_folder.name, \"dynamic_rom.aedt\")\n", "tb = ansys.aedt.core.TwinBuilder(\n", " project=project_name,\n", " version=AEDT_VERSION,\n", " non_graphical=NG_MODE,\n", " new_desktop=True,\n", ")" ] }, { "cell_type": "markdown", "id": "1f11ab1d", "metadata": {}, "source": [ "## Configure AEDT\n", "\n", "> **Note:** Only run the following cell if AEDT is not configured to run Twin Builder.\n", ">\n", "> The following cell configures AEDT and the schematic editor\n", "> to use the ``Twin Builder`` configuration.\n", "> The dynamic ROM feature is only available with a Twin Builder license.\n", "> A cell at the end of this example restores the AEDT configuration. If your\n", "> environment is set up to use the ``Twin Builder`` configuration, you do not\n", "> need to run these code blocks." ] }, { "cell_type": "code", "execution_count": null, "id": "5d1aff19", "metadata": {}, "outputs": [], "source": [ "current_desktop_config = tb._odesktop.GetDesktopConfiguration()\n", "current_schematic_environment = tb._odesktop.GetSchematicEnvironment()\n", "tb._odesktop.SetDesktopConfiguration(\"Twin Builder\")\n", "tb._odesktop.SetSchematicEnvironment(1)" ] }, { "cell_type": "code", "execution_count": null, "id": "b576dbf6", "metadata": {}, "outputs": [], "source": [ "# Get the dynamic ROM builder object.\n", "rom_manager = tb._odesign.GetROMManager()\n", "dynamic_rom_builder = rom_manager.GetDynamicROMBuilder()" ] }, { "cell_type": "code", "execution_count": null, "id": "8c70dda9", "metadata": {}, "outputs": [], "source": [ "# Build the dynamic ROM with the specified configuration file.\n", "conf_file_path = os.path.join(data_folder, source_build_conf_file)\n", "dynamic_rom_builder.Build(conf_file_path.replace(\"\\\\\", \"/\"))" ] }, { "cell_type": "code", "execution_count": null, "id": "59c6c360", "metadata": {}, "outputs": [], "source": [ "# Test if the ROM was created successfully\n", "dynamic_rom_path = os.path.join(data_folder, \"DynamicRom.dyn\")\n", "if os.path.exists(dynamic_rom_path):\n", " tb._odesign.AddMessage(\n", " \"Info\", \"path exists: {}\".format(dynamic_rom_path.replace(\"\\\\\", \"/\")), \"\"\n", " )\n", "else:\n", " tb._odesign.AddMessage(\n", " \"Info\", \"path does not exist: {}\".format(dynamic_rom_path), \"\"\n", " )" ] }, { "cell_type": "code", "execution_count": null, "id": "0b1f91c4", "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "# Create the ROM component definition in Twin Builder.\n", "rom_manager.CreateROMComponent(dynamic_rom_path.replace(\"\\\\\", \"/\"), \"dynarom\")" ] }, { "cell_type": "markdown", "id": "afb5d35d", "metadata": {}, "source": [ "## Create schematic\n", "\n", "Place components to create a schematic." ] }, { "cell_type": "markdown", "id": "d564be9d", "metadata": {}, "source": [ "Define the grid distance for ease in calculations." ] }, { "cell_type": "code", "execution_count": null, "id": "a985ed73", "metadata": {}, "outputs": [], "source": [ "G = 0.00254" ] }, { "cell_type": "markdown", "id": "027c1c95", "metadata": {}, "source": [ "Place a dynamic ROM component." ] }, { "cell_type": "code", "execution_count": null, "id": "49a11df7", "metadata": {}, "outputs": [], "source": [ "rom1 = tb.modeler.schematic.create_component(\"ROM1\", \"\", \"dynarom\", [36 * G, 28 * G])" ] }, { "cell_type": "markdown", "id": "6d06bdb3", "metadata": {}, "source": [ "Place two excitation sources." ] }, { "cell_type": "code", "execution_count": null, "id": "dba30e64", "metadata": {}, "outputs": [], "source": [ "source1 = tb.modeler.schematic.create_periodic_waveform_source(\n", " None, \"PULSE\", 190, 0.002, \"300deg\", 210, 0, [20 * G, 29 * G]\n", ")\n", "source2 = tb.modeler.schematic.create_periodic_waveform_source(\n", " None, \"PULSE\", 190, 0.002, \"300deg\", 210, 0, [20 * G, 25 * G]\n", ")" ] }, { "cell_type": "markdown", "id": "b14787b4", "metadata": {}, "source": [ "Connect components with wires." ] }, { "cell_type": "code", "execution_count": null, "id": "f931bea8", "metadata": {}, "outputs": [], "source": [ "tb.modeler.schematic.create_wire([[22 * G, 29 * G], [33 * G, 29 * G]])\n", "tb.modeler.schematic.create_wire(\n", " [[22 * G, 25 * G], [30 * G, 25 * G], [30 * G, 28 * G], [33 * G, 28 * G]]\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "e90cf871", "metadata": {}, "outputs": [], "source": [ "# Zoom to fit the schematic.\n", "tb.modeler.zoom_to_fit()" ] }, { "cell_type": "markdown", "id": "90b4c50c", "metadata": {}, "source": [ "## Parametrize transient setup\n", "\n", "Parametrize the default transient setup by setting the end time." ] }, { "cell_type": "code", "execution_count": null, "id": "aacba132", "metadata": {}, "outputs": [], "source": [ "tb.set_end_time(\"1000s\")\n", "tb.set_hmin(\"1s\")\n", "tb.set_hmax(\"1s\")" ] }, { "cell_type": "markdown", "id": "b39a3a05", "metadata": {}, "source": [ "## Solve transient setup" ] }, { "cell_type": "code", "execution_count": null, "id": "85ce2737", "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "tb.analyze_setup(\"TR\", cores=NUM_CORES)" ] }, { "cell_type": "markdown", "id": "7d1c76d7", "metadata": {}, "source": [ "## Get report data and plot using Matplotlib\n", "\n", "Get report data and plot it using Matplotlib. The following code gets and plots\n", "the values for the voltage on the pulse voltage source and the values for the\n", "output of the dynamic ROM." ] }, { "cell_type": "code", "execution_count": null, "id": "453c5e85", "metadata": {}, "outputs": [], "source": [ "input_excitation = \"PULSE1.VAL\"\n", "x = tb.post.get_solution_data(input_excitation, \"TR\", \"Time\")\n", "plt.plot(x.intrinsics[\"Time\"], x.data_real(input_excitation))" ] }, { "cell_type": "code", "execution_count": null, "id": "6a1f6e1d", "metadata": {}, "outputs": [], "source": [ "output_temperature = \"ROM1.Temperature_history\"\n", "x = tb.post.get_solution_data(output_temperature, \"TR\", \"Time\")\n", "plt.plot(x.intrinsics[\"Time\"], x.data_real(output_temperature))" ] }, { "cell_type": "code", "execution_count": null, "id": "27a7547f", "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "plt.grid()\n", "plt.xlabel(\"Time\")\n", "plt.ylabel(\"Temperature History Variation with Input Temperature Pulse\")\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "583b345d", "metadata": {}, "source": [ "## Close Twin Builder\n", "\n", "After the simulation is completed, you can close Twin Builder or release it.\n", "All methods provide for saving the project before closing." ] }, { "cell_type": "code", "execution_count": null, "id": "6e9de3f4", "metadata": {}, "outputs": [], "source": [ "# Clean up the downloaded data.\n", "shutil.rmtree(source_data_folder)" ] }, { "cell_type": "code", "execution_count": null, "id": "d9598256", "metadata": {}, "outputs": [], "source": [ "# Restore the earlier AEDT configuration and schematic environment.\n", "tb._odesktop.SetDesktopConfiguration(current_desktop_config)\n", "tb._odesktop.SetSchematicEnvironment(current_schematic_environment)" ] }, { "cell_type": "markdown", "id": "54f72f61", "metadata": {}, "source": [ "## Release AEDT\n", "\n", "Release AEDT and close the example." ] }, { "cell_type": "code", "execution_count": null, "id": "44e2d299", "metadata": {}, "outputs": [], "source": [ "tb.save_project()\n", "tb.release_desktop()\n", "# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory.\n", "time.sleep(3)" ] }, { "cell_type": "markdown", "id": "c7f117f9", "metadata": {}, "source": [ "## Clean up\n", "\n", "All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you\n", "can retrieve those project files. The following cell removes all temporary files, including the project folder." ] }, { "cell_type": "code", "execution_count": null, "id": "bc968f12", "metadata": {}, "outputs": [], "source": [ "temp_folder.cleanup()" ] } ], "metadata": { "jupytext": { "cell_metadata_filter": "-all", "main_language": "python", "notebook_metadata_filter": "-all" } }, "nbformat": 4, "nbformat_minor": 5 }