.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples\02-tbrom_examples\02-TBROM_input_field.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_02-tbrom_examples_02-TBROM_input_field.py: .. _ref_example_TBROM_inputField: 3D field ROM example for input field snapshot projection and snapshot generation on demand ------------------------------------------------------------------------------------------ This example shows how to use PyTwin to load and evaluate a twin model that has a field ROM with inputs parameterized by both scalar and field data. The example also shows how to evaluate the output field data in the form of snapshots. .. GENERATED FROM PYTHON SOURCE LINES 12-15 .. image:: /_static/TBROM_input_field.png :width: 400pt :align: center .. GENERATED FROM PYTHON SOURCE LINES 15-18 .. code-block:: Python # sphinx_gallery_thumbnail_path = '_static/TBROM_input_field.png' .. GENERATED FROM PYTHON SOURCE LINES 19-35 The example model is a valve that takes fluid pressure magnitude as a scalar input and wall temperature as vector input and gives deformation, in meters, as an output. Results are available on the full model, or can be exported on two subgroups: **Group_1**: Bolts .. image:: /_static/TBROM_Group1_bolts.png :width: 150pt :align: center **Group_2**: Body .. image:: /_static/TBROM_Group2_body.png :width: 150pt :align: center .. GENERATED FROM PYTHON SOURCE LINES 37-49 .. note:: To be able to use the functionalities to project an input field snapshot, you must have a twin with one or more TBROMs parameterized by input field data. Input mode coefficients for TBROMs are connected to the twin's inputs following these conventions: - If there are multiple TBROMs in the twin, the format for the name of the twin input must be ``{input_field_name}_mode_{mode_index}_{tbrom_name}``. - If there is a single TBROM in the twin, the format for the name of the twin input must be ``{input_field_name}_mode_{mode_index}``. .. image:: /_static/snapshot_projection.png :width: 300pt :align: center .. GENERATED FROM PYTHON SOURCE LINES 51-64 .. note:: To be able to use the functionalities to generate an output field snapshot on demand, you must have a twin with one or more TBROMs. The output mode coefficients for the TBROMs must be enabled when exporting the TBROMs and connected to twin outputs following these conventions: - If there are multiple TBROMs in the twin, the format for the name of the twin output must be ``outField_mode_{mode_index}_{tbrom_name}``. - If there is a single TBROM in the twin, the format for the name of the twin output must be ``outField_mode_{mode_index}``. .. image:: /_static/snapshot_generation.png :width: 300pt :align: center .. GENERATED FROM PYTHON SOURCE LINES 66-72 .. note:: To be able to use the functionalities to generate points file on demand, you need to have a Twin with 1 or more TBROM, for which its geometry is embedded when exporting the TBROMs to Twin Builder .. image:: /_static/point_generation.png :width: 200pt :align: center .. GENERATED FROM PYTHON SOURCE LINES 74-80 .. note:: To be able to use the functionalities to generate points or snapshot on a named selection, you need to have a Twin with 1 or more TBROM, for which Named Selections are defined. .. image:: /_static/TBROM_named_selection.png :width: 207pt :align: center .. GENERATED FROM PYTHON SOURCE LINES 82-85 Perform required imports ~~~~~~~~~~~~~~~~~~~~~~~~ Perform required imports, which include downloading and importing the input files. .. GENERATED FROM PYTHON SOURCE LINES 85-99 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np import pandas as pd from pytwin import TwinModel, download_file import pyvista as pv twin_file = download_file("ThermalTBROM_FieldInput_23R1.twin", "twin_files", force_download=True) inputfieldsnapshots = [ download_file("TEMP_1.bin", "twin_input_files/inputFieldSnapshots", force_download=True), download_file("TEMP_2.bin", "twin_input_files/inputFieldSnapshots", force_download=True), download_file("TEMP_3.bin", "twin_input_files/inputFieldSnapshots", force_download=True), ] .. GENERATED FROM PYTHON SOURCE LINES 100-105 Define auxiliary functions ~~~~~~~~~~~~~~~~~~~~~~~~~~ Define auxiliary functions for comparing and plotting the results from different input values evaluated on the twin model and for computing the norm of the output field. .. GENERATED FROM PYTHON SOURCE LINES 105-157 .. code-block:: Python def plot_result_comparison(results: pd.DataFrame): """Compare the results obtained from the different input values evaluated on the twin model. The results datasets are provided as Pandas dataframes. The function plots the results for a few variables of particular interest.""" pd.set_option("display.precision", 12) pd.set_option("display.max_columns", 20) pd.set_option("display.expand_frame_repr", False) color = ["g"] # Output ordering: T_inner, T1_out, T_outer, T2_out, T3_out x_ind = 0 y0_ind = 2 y1_ind = 3 y2_ind = 4 # Plot simulation results (outputs versus input) fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(18, 7)) fig.subplots_adjust(hspace=0.5) fig.set_tight_layout({"pad": 0.0}) axes0 = ax results.plot(x=x_ind, y=y0_ind, ax=axes0, ls="dashed", label="{}".format("Maximum Deformation (Twin output)")) results.plot( x=x_ind, y=y1_ind, ax=axes0, ls="-.", label="{}".format("Maximum Deformation (output field " "reconstruction)") ) results.plot( x=x_ind, y=y2_ind, ax=axes0, ls="-.", label="{}".format("Maximum Deformation (output field reconstruction on Group_2)"), ) axes0.set_title("T-junction deformation response") axes0.set_xlabel(results.columns[x_ind] + " [Pa]") axes0.set_ylabel("Deformation [m]") # Show plot plt.show() def norm_vector_field(field: np.ndarray): """Compute the norm of a vector field.""" vec = field.reshape((-1, 3)) return np.sqrt((vec * vec).sum(axis=1)) .. GENERATED FROM PYTHON SOURCE LINES 158-161 Define ROM scalar inputs ~~~~~~~~~~~~~~~~~~~~~~~~ Define the ROM scalar inputs. .. GENERATED FROM PYTHON SOURCE LINES 161-164 .. code-block:: Python rom_inputs = [4000000, 5000000, 6000000] .. GENERATED FROM PYTHON SOURCE LINES 165-168 Load the twin runtime and generate displacement results ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Load the twin runtime and generate displacement results from the TBROM. .. GENERATED FROM PYTHON SOURCE LINES 168-172 .. code-block:: Python print("Loading model: {}".format(twin_file)) twin_model = TwinModel(twin_file) .. rst-class:: sphx-glr-script-out .. code-block:: none Loading model: C:\Users\ansys\AppData\Local\Temp\TwinExamples\twin_files\ThermalTBROM_FieldInput_23R1.twin .. GENERATED FROM PYTHON SOURCE LINES 173-181 Evaluate the twin with different input values and collect corresponding outputs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Because the twin is based on a static model, two options can be considered: - Set the initial input value to evaluate and run the initialization function (current approach). - Create an input dataframe considering all input values to evaluate and run the batch function to evaluate. In this case, to execute the transient simulation, a time dimension must be arbitrarily defined. .. GENERATED FROM PYTHON SOURCE LINES 181-229 .. code-block:: Python results = [] input_name_all = list(twin_model.inputs.keys()) output_name_all = list(twin_model.outputs.keys()) # remove the TBROM related pins from the twin's list of inputs and outputs input_name_without_mcs = [] for i in input_name_all: if "_mode_" not in i: input_name_without_mcs.append(i) print(f"Twin physical inputs : {input_name_without_mcs}") output_name_without_mcs = [] for i in output_name_all: if "_mode_" not in i: output_name_without_mcs.append(i) print(f"Twin physical outputs : {output_name_without_mcs}") # initialize the twin and collect information related to the TBROM and input field print(f"TBROMs part of the twin : {twin_model.tbrom_names}") romname = twin_model.tbrom_names[0] print(f"Input fields associated with the TBROM {romname} : {twin_model.get_field_input_names(romname)}") fieldname = twin_model.get_field_input_names(romname)[0] print(f"Named selections associated with the TBROM {romname} : {twin_model.get_named_selections(romname)}") ns = twin_model.get_named_selections(romname)[1] input_name = input_name_without_mcs[0] for i in range(0, len(rom_inputs)): # initialize twin with input values and collect output value dp = rom_inputs[i] dp_input = {input_name: dp} dp_field_input = {romname: {fieldname: inputfieldsnapshots[i]}} twin_model.initialize_evaluation(inputs=dp_input, field_inputs=dp_field_input) outputs = [dp] for item in output_name_without_mcs: outputs.append(twin_model.outputs[item]) outfield = twin_model.generate_snapshot(romname, False) # generating the field output on the entire domain outputs.append(max(norm_vector_field(outfield))) outfieldns = twin_model.generate_snapshot(romname, False, ns) # generating the field output on "Group_2" outputs.append(max(norm_vector_field(outfieldns))) results.append(outputs) points_path = twin_model.generate_points(romname, True) # generating the points file on whole domain pointsns_path = twin_model.generate_points(romname, True, ns) # generating the points file on "Group_2"" sim_results = pd.DataFrame( results, columns=[input_name] + output_name_without_mcs + ["MaxDefSnapshot", "MaxDefSnapshotNs"], dtype=float ) .. rst-class:: sphx-glr-script-out .. code-block:: none Twin physical inputs : ['Pressure_Magnitude'] Twin physical outputs : ['MinDef', 'MaxDef'] TBROMs part of the twin : ['test23R1_1'] Input fields associated with the TBROM test23R1_1 : ['inputTemperature'] Named selections associated with the TBROM test23R1_1 : ['Group_1', 'Group_2'] .. GENERATED FROM PYTHON SOURCE LINES 230-236 Simulate the twin in batch mode ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Reset/re-initialize the twin and run the simulation in batch mode, which passes all the input data, simulates all the data points, and collects all the outputs at once. The snapshots are then generated in a post-processing step. .. GENERATED FROM PYTHON SOURCE LINES 236-246 .. code-block:: Python dp_input = {input_name: rom_inputs[0]} dp_field_input = {romname: {fieldname: inputfieldsnapshots[0]}} twin_model.initialize_evaluation(inputs=dp_input, field_inputs=dp_field_input) # creation of the input DataFrame including input field snapshots input_df = pd.DataFrame({"Time": [0.0, 1.0, 2.0], input_name_without_mcs[0]: rom_inputs}) batch_results = twin_model.evaluate_batch(inputs_df=input_df, field_inputs={romname: {fieldname: inputfieldsnapshots}}) print(batch_results) output_snapshots = twin_model.generate_snapshot_batch(batch_results, romname) .. rst-class:: sphx-glr-script-out .. code-block:: none Time outField_mode_1 outField_mode_2 outField_mode_3 MinDef MaxDef 0 0.0 0.013545837994 0.000199049416 0.000750513991 0.000006740817 0.000083469219 1 1.0 0.013545837994 0.000199049416 0.000750513991 0.000006740817 0.000083469219 2 2.0 0.045313979521 0.001502593544 -0.000167049957 0.000030702480 0.000280397005 .. GENERATED FROM PYTHON SOURCE LINES 247-250 Plot results ~~~~~~~~~~~~ Plot the results. .. GENERATED FROM PYTHON SOURCE LINES 250-262 .. code-block:: Python plot_result_comparison(sim_results) # Plot the 3D field results on point cloud. To be able to retrieve the PyVista object associated to the field results # and post process them, you need to have the geometry embedded with the TBROM when exporting it to Twin Builder. field_data = twin_model.get_tbrom_output_field(romname) plotter = pv.Plotter() plotter.set_background("white") plotter.add_axes() plotter.add_mesh(field_data, scalar_bar_args={"color": "black"}) plotter.show() .. image-sg:: /examples/02-tbrom_examples/images/sphx_glr_02-TBROM_input_field_001.png :alt: T-junction deformation response :srcset: /examples/02-tbrom_examples/images/sphx_glr_02-TBROM_input_field_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 263-266 .. image:: /_static/TBROM_pointcloud_3d_viz.png :width: 400pt :align: center .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 4.374 seconds) .. _sphx_glr_download_examples_02-tbrom_examples_02-TBROM_input_field.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 02-TBROM_input_field.ipynb <02-TBROM_input_field.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 02-TBROM_input_field.py <02-TBROM_input_field.py>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_