3D field ROM example for field snapshot input and output as Numpy array#

This example shows how the example given in 3D field ROM example for input field snapshot projection and snapshot generation on demand can be modified to take inputs as Numpy arrays, rather than reading from disk. Similarly, outputs are produced as Numpy arrays.

The results arrays will be unflattened and results combined into a DataFrame of x, y and z location and corresponding x, y and z displacement components.

Results will be exported for the whole model and a named selection consisting only of the bolts.

../../_images/TBROM_input_field.png
# sphinx_gallery_thumbnail_path = '_static/TBROM_input_field.png'

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.

To project an input field snapshot, one or more of the TBROMs must be parameterized by input field data.

To be able to use the functionalities to generate points file on demand for a TBROM, the geometry must have been embedded when exporting the TBROMs to Twin Builder, prior to building the twin.

The twin inputs and outputs must follow specific naming conventions, summarised here and described in detail in 3D field ROM example for input field snapshot projection and snapshot generation on demand.

  • 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} and the 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 input must be {input_field_name}_mode_{mode_index} and the output must be outField_mode_{mode_index}.

Perform required imports#

Perform required imports, which include downloading and importing the input files.

import numpy as np
import pandas as pd
from pytwin import TwinModel, download_file, read_binary

twin_file = download_file("ThermalTBROM_FieldInput_23R1.twin", "twin_files", force_download=True)
inputfieldsnapshot = download_file("TEMP_1.bin", "twin_input_files/inputFieldSnapshots", force_download=True)

Define auxiliary functions#

Define auxiliary function to unflatten a vector.

def unflatten_vector(vector: np.ndarray, dimensionality: int):
    """Unflatten a vector to array with specified number of columns."""
    return vector.reshape(-1, dimensionality)

Define ROM inputs#

Define the twin scalar input pressure as 4 MPa.

scalar_input = {"Pressure_Magnitude": 4000000.0}

Read one vector input from a file (this input could have been generated by a separate program).

Enter information regarding TBROM, input fields and output named selection (see 3D field ROM example for input field snapshot projection and snapshot generation on demand for examples of setting this programmatically).

romname = "test23R1_1"
fieldname = "inputTemperature"
out_ns = "Group_1"
input_name = "Pressure_Magnitude"
field_input = {romname: {fieldname: temperature_array}}

Load the twin runtime and generate displacement results#

Load the twin runtime and generate temperature results from the TBROM.

print("Loading model: {}".format(twin_file))
twin_model = TwinModel(twin_file)
Loading model: C:\Users\ansys\AppData\Local\Temp\TwinExamples\twin_files\ThermalTBROM_FieldInput_23R1.twin

Evaluate the twin with one set of input values and collect corresponding outputs#

Because the twin is based on a static model, results for any inputs can be obtained by setting the initial input values to the desired values and running the initialization function.

# initialize twin with input values
twin_model.initialize_evaluation(inputs=scalar_input, field_inputs=field_input)
# generate the field output array on the entire domain
outfield = twin_model.generate_snapshot(romname, on_disk=False)
# generate the field output on "Group_1"
outfield_bolts = twin_model.generate_snapshot(romname, on_disk=False, named_selection=out_ns)
# generate the points location array for the whole domain
points = twin_model.generate_points(romname, on_disk=False)
# generate the points location array on "Group_1"
points_bolts = twin_model.generate_points(romname, on_disk=False, named_selection=out_ns)

Unflatten vectors and combine into DataFrame. Both point location and displacement have three components when unflattening.

disp_xyz = unflatten_vector(outfield, 3)
loc_xyz = unflatten_vector(points, 3)
results = pd.DataFrame(
    {
        "x": loc_xyz[:, 0],
        "y": loc_xyz[:, 1],
        "z": loc_xyz[:, 2],
        "ux": disp_xyz[:, 0],
        "uy": disp_xyz[:, 1],
        "uz": disp_xyz[:, 2],
    }
)
print(f"Full results table:\n{results}")
Full results table:
                      x                 y                z              ux              uy              uz
0        0.000000000000   20.500000000000  63.900000000000 -0.000022676445 -0.000007411823  0.000052865856
1        4.649511030118   20.500000000000  65.265219617652 -0.000019859374 -0.000006857729  0.000053471027
2        7.822835160049   20.500000000000  68.927430888184 -0.000017849438 -0.000007524893  0.000055345678
3        8.512464400176   20.500000000000  73.723907609150 -0.000017359600 -0.000009429828  0.000057934634
4        6.499446339447   20.500000000000  78.131802311929 -0.000018478304 -0.000011935615  0.000060357393
...                 ...               ...              ...             ...             ...             ...
104417 -22.082190395836  278.847782340126  22.925958081233 -0.000008267303  0.000013355841  0.000008686018
104418 -28.202723064351  267.915752025538  12.456531177246 -0.000001400765  0.000008837837  0.000000612639
104419 -25.772944541100  217.207183109828  23.286920211768 -0.000016712107  0.000002634787  0.000007296183
104420   0.452412968499  214.007611933540  33.306747725383 -0.000009092836 -0.000001948173  0.000012971703
104421 -18.251845983458  205.734785172493  38.919245779059 -0.000021904075  0.000011531835  0.000023193705

[104422 rows x 6 columns]

Repeat for the subset of results on the bolts only

disp_xyz = unflatten_vector(outfield_bolts, 3)
loc_xyz = unflatten_vector(points_bolts, 3)
results_bolts = pd.DataFrame(
    {
        "x": loc_xyz[:, 0],
        "y": loc_xyz[:, 1],
        "z": loc_xyz[:, 2],
        "ux": disp_xyz[:, 0],
        "uy": disp_xyz[:, 1],
        "uz": disp_xyz[:, 2],
    }
)
print(f"Bolt results table:\n{results_bolts}")
Bolt results table:
                    x                y                z              ux              uy              uz
0      0.000000000000  20.500000000000  63.900000000000 -0.000022676445 -0.000007411823  0.000052865856
1      4.649511030118  20.500000000000  65.265219617652 -0.000019859374 -0.000006857729  0.000053471027
2      7.822835160049  20.500000000000  68.927430888184 -0.000017849438 -0.000007524893  0.000055345678
3      8.512464400176  20.500000000000  73.723907609150 -0.000017359600 -0.000009429828  0.000057934634
4      6.499446339447  20.500000000000  78.131802311929 -0.000018478304 -0.000011935615  0.000060357393
...               ...              ...              ...             ...             ...             ...
26193  5.365215157701 -19.973737738871  67.406774673048 -0.000009163648 -0.000028770279  0.000034626634
26194  5.519814179923 -20.500000000000  69.067558970773 -0.000008964800 -0.000029851127  0.000035325543
26195  4.864884965080 -19.973737716675  68.189211872924 -0.000009454929 -0.000029289763  0.000035071210
26196 -5.519814179923 -20.500000000000  69.067558970773 -0.000015171755 -0.000032449556  0.000035190673
26197 -4.864884965080 -19.973737716675  68.189211872924 -0.000014946633 -0.000031554289  0.000034938767

[26198 rows x 6 columns]

Total running time of the script: (0 minutes 0.973 seconds)

Gallery generated by Sphinx-Gallery