.. 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 34-37 .. image:: /_static/TBROM_input_field.png :width: 400pt :align: center .. GENERATED FROM PYTHON SOURCE LINES 37-40 .. code-block:: Python # sphinx_gallery_thumbnail_path = '_static/TBROM_input_field.png' .. GENERATED FROM PYTHON SOURCE LINES 41-57 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 59-71 .. 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 73-86 .. 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 88-94 .. 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 96-102 .. 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 104-107 Perform required imports ~~~~~~~~~~~~~~~~~~~~~~~~ Perform required imports, which include downloading and importing the input files. .. GENERATED FROM PYTHON SOURCE LINES 107-121 .. 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 122-127 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 127-179 .. 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 180-183 Define ROM scalar inputs ~~~~~~~~~~~~~~~~~~~~~~~~ Define the ROM scalar inputs. .. GENERATED FROM PYTHON SOURCE LINES 183-186 .. code-block:: Python rom_inputs = [4000000, 5000000, 6000000] .. GENERATED FROM PYTHON SOURCE LINES 187-190 Load the twin runtime and generate displacement results ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Load the twin runtime and generate displacement results from the TBROM. .. GENERATED FROM PYTHON SOURCE LINES 190-196 .. code-block:: Python print("Loading model: {}".format(twin_file)) twin_model = TwinModel(twin_file) twin_model.print_model_info() .. rst-class:: sphx-glr-script-out .. code-block:: none Loading model: C:\Users\ansys\AppData\Local\Temp\TwinExamples\twin_files\ThermalTBROM_FieldInput_23R1.twin ------------------------------------- Model Info ------------------------------------- Twin Runtime Version: 2.15.0.0 Model Name: TwinModelInOutField Number of outputs: 5 Number of Inputs: 3 Number of parameters: 3 Default time end: 0.04 Default step size: 0.001 Default tolerance(Integration Accuracy): 0.0001 Output names: Name Unit Type Start Min Max Description 0 outField_mode_1 TWIN_VARPROP_NOTDEFINED Real None None None TWIN_VARPROP_NOTDEFINED 1 outField_mode_2 TWIN_VARPROP_NOTDEFINED Real None None None TWIN_VARPROP_NOTDEFINED 2 outField_mode_3 TWIN_VARPROP_NOTDEFINED Real None None None TWIN_VARPROP_NOTDEFINED 3 MinDef TWIN_VARPROP_NOTDEFINED Real None None None TWIN_VARPROP_NOTDEFINED 4 MaxDef TWIN_VARPROP_NOTDEFINED Real None None None TWIN_VARPROP_NOTDEFINED Input names: Name Unit Type Start Min Max Description 0 inputTemperature_mode_0 TWIN_VARPROP_NOTDEFINED Real 0.0 None None TWIN_VARPROP_NOTDEFINED 1 inputTemperature_mode_1 TWIN_VARPROP_NOTDEFINED Real 0.0 None None TWIN_VARPROP_NOTDEFINED 2 Pressure_Magnitude TWIN_VARPROP_NOTDEFINED Real 0.0 None None TWIN_VARPROP_NOTDEFINED Parameter names: Name Unit Type Start Min Max Description 0 solver.method TWIN_VARPROP_NOTAPPLICABLE Enumeration 1.000000000000 1.0 2.0 Solver integration method (ADAMS=1, BDF=2) 1 solver.abstol TWIN_VARPROP_NOTDEFINED Real 0.000000000001 NaN NaN Solver absolute tolerance 2 solver.reltol TWIN_VARPROP_NOTDEFINED Real 0.000100000000 NaN NaN Solver relative tolerance TBROMs information: TBROM instance name : test23R1_1 TBROM model name : test23R1 Output field name : Deformation Output field connected : True Has geometry/points file : True Input fields : Name : inputTemperature, Connected : True Parametric Field History : False Named selections : ['Group_1', 'Group_2'] Product version to generate TBROM : SVDTools 2023 R1 built on Jan 23 2023 @ 16:04:27 .. GENERATED FROM PYTHON SOURCE LINES 197-205 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 205-253 .. 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 : [np.str_('Pressure_Magnitude')] Twin physical outputs : [np.str_('MinDef'), np.str_('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 254-260 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 260-270 .. 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 271-274 Plot results ~~~~~~~~~~~~ Plot the results. .. GENERATED FROM PYTHON SOURCE LINES 274-286 .. 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 287-290 .. image:: /_static/TBROM_pointcloud_3d_viz.png :width: 400pt :align: center .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 5.002 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>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: 02-TBROM_input_field.zip <02-TBROM_input_field.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_