3D field ROM example for images generation#

This example shows how PyTwin can be used to load and evaluate a twin model to visualize ROM results in the form of images with predefined views. The script takes the inputs to evaluate the TBROM (twin builder ROM) and displays the corresponding image. A first image is generated using the point cloud-based ROM Viewer embedded in the twin runtime. The second image is generated by loading the ROM results and postprocessing the CFD mesh using PyFluent. Finally, ROM results are postprocessed in the 3D viewer enabled by PyFluent. For more information, see the PyFluent-Visualization documentation.

Note

To generate snapshot files at initialization time, the ROM included in the twin must have its parameter field_data_storage_period set to 0 and its parameter store_snapshots set to 1.

To generate images files at initialization time, the ROM included in the twin must have the Embed Geometry and Generate Image options enabled at export time. Additionally, its parameter viewX_storage_period must be set to 0.

These parameters can be defined in the Twin Builder subsheet before twin compilation or be exposed as twin parameters.

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

Perform required imports#

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

import os

import ansys.fluent.core as pyfluent
from ansys.fluent.visualization import set_config
from ansys.fluent.visualization.pyvista import Graphics
import matplotlib.image as img
import matplotlib.pyplot as plt
import numpy as np
from pytwin import TwinModel, download_file

twin_file = download_file("ThermalTBROM_23R1_other.twin", "twin_files", force_download=True)
cfd_file = download_file("T_Junction.cas.h5", "other_files", force_download=True)

set_config(blocking=True, set_view_on_display="isometric")

Define ROM inputs#

Define the ROM inputs.

rom_inputs = {"main_inlet_temperature": 353.15, "side_inlet_temperature": 293.15}
rom_parameters = {
    "ThermalROM23R1_1_colorbar_min": 290,
    "ThermalROM23R1_1_colorbar_max": 360,
    "ThermalROM23R1_1_store_snapshots": 1,
}

Define auxiliary functions#

Define the auxiliary function for converting a ROM snapshot for data mapping on a CFD mesh.

def snapshot_to_cfd(snapshot_file, geometry_file, field_name, outputFilePath):
    """Create a Fluent Interpolation file that can be loaded in Ansys Fluent
    and map to the CFD mesh. This code shows the implementation for a single
    field of scalar data (temperature field).
    """

    geometry_data = np.fromfile(geometry_file, dtype=np.double, offset=8).reshape(-1, 3)
    snapshot_data = np.fromfile(snapshot_file, dtype=np.double, offset=8).reshape(-1, 1)
    res_list = np.hstack((geometry_data, snapshot_data))

    with open(outputFilePath, "w") as ipfile:
        ipfile.write("3\n")  # IP file format
        ipfile.write("3\n")  # 2D or 3D - 3D for now
        ipfile.write(str(len(res_list)) + "\n")  # number of data
        ipfile.write("1\n")  # number of field data
        ipfile.write(field_name + "\n")  # name of field data
        for j in range(0, len(res_list[0])):
            ipfile.write("(")
            for i in range(0, len(res_list)):
                ipfile.write(str(res_list[i][j]) + "\n")
            ipfile.write(")\n")

    return outputFilePath

Load the twin runtime and generate temperature results#

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

print("Loading model: {}".format(twin_file))
twin_model = TwinModel(twin_file)

twin_model.initialize_evaluation(inputs=rom_inputs, parameters=rom_parameters)

rom_name = twin_model.tbrom_names[0]
rom_directory = twin_model.get_rom_directory(rom_name)
snapshot = twin_model.get_snapshot_filepath(rom_name)
geometry = twin_model.get_geometry_filepath(rom_name)

temperature_file = snapshot_to_cfd(snapshot, geometry, "temperature", os.path.join(rom_directory, "cfd_file.ip"))
Loading model: C:\Users\ansys\AppData\Local\Temp\TwinExamples\twin_files\ThermalTBROM_23R1_other.twin

Postprocess with image generated by point cloud-based ROM Viewer#

Postprocess with the image generated by the point cloud-based ROM Viewer.

view_name = twin_model.get_available_view_names(rom_name)[0]
image_filepath = twin_model.get_image_filepath(rom_name, view_name)
plt.imshow(img.imread(image_filepath))
plt.show()
04 TBROM images

Postprocess with image generated by PyFluent#

Postprocess with the image generated by PyFluent.

solver = pyfluent.launch_fluent(precision="double", processor_count=2, mode="solver")
solver.file.read(file_type="case", file_name=cfd_file)
tui = solver.tui
tui.file.interpolate.read_data(temperature_file)
tui.display.objects.display("contour-1")
tui.display.save_picture(os.path.join(rom_directory, f"{view_name}_Fluent_0.000000.png"))

image = img.imread(os.path.join(rom_directory, f"{view_name}_Fluent_0.000000.png"))
plt.imshow(image)
plt.show()
04 TBROM images
Fast-loading "C:\PROGRA~1\ANSYSI~1\v222\fluent\fluent22.2.0\\addons\afd\lib\hdfio.bin"
Done.
Multicore processors detected. Processor affinity set!

Reading from pytwin-win10:"C:\Users\ansys\AppData\Local\Temp\TwinExamples\other_files\T_Junction.cas.h5" in NODE0 mode ...
  Reading mesh ...
      215876 cells,     2 cell zones ...
          76008 mixed cells,  zone id: 4
         139868 tetrahedral cells,  zone id: 5
      518843 faces,    18 face zones ...
            234 mixed wall faces,  zone id: 20
            505 mixed wall faces,  zone id: 19
          26342 mixed wall faces,  zone id: 21
          26342 mixed wall faces,  zone id: 23
            271 triangular wall faces,  zone id: 1
         162380 mixed interior faces,  zone id: 2
         266064 triangular interior faces,  zone id: 3
           6072 triangular interface faces,  zone id: 8
            117 mixed pressure-outlet faces,  zone id: 9
           3222 mixed symmetry faces,  zone id: 10
            117 mixed velocity-inlet faces,  zone id: 11
            104 mixed velocity-inlet faces,  zone id: 12
          14323 triangular wall faces,  zone id: 13
           7129 triangular interface faces,  zone id: 14
           1837 triangular symmetry faces,  zone id: 15
           3650 triangular wall faces,  zone id: 16
             65 triangular wall faces,  zone id: 17
             69 triangular wall faces,  zone id: 18
       55905 nodes,     1 node zone  ...
  Done.

  Reading data for "scenario2" profile.

Building...
     mesh
        auto partitioning mesh by Metis (fast, model-weighted),
        distributing mesh
                pairs..,
                parts..,
                faces..,
                nodes..,
                shadow nodes..,
                cells..,
        bandwidth reduction using Reverse Cuthill-McKee: 49343/1229 = 40.1489
     materials,
     interface,
     domains,
        mixture
     zones,
        wall_hot_end
        wall_cold_end
        wall_adiabatic
        symmetry_solid
        interface_solid_side
        convection
        velocity_inlet_side
        velocity_inlet_main
        symmetry_fluid
        pressure_outlet
        interface_fluid_side
        interior-solid-part_2
        interior-fluid
        wall-solid-part_2
        interface_fluid_side-non-overlapping
        interface_solid_side-non-overlapping
        interface-wall1-1-1
        interface-wall1-1-1-shadow
        solid-part_2
        fluid
     mesh interfaces,
     parallel,

Info: At least one many-to-many mesh interface is found in the case file. Such mesh interfaces will not be available in a future release of Fluent. It is recommended to convert to the current default one-to-one mesh interfaces with the following text command:
/define/mesh-interfaces/one-to-one-pairing? yes

Done.
Reading C:\\Users\\ansys\\AppData\\Local\\Temp\\TwinExamples\\twin_files\\pyTwinWorkingDir\\ThermalTBROM_23R1SP1.d18d446241044f2190cb\\ROM_files\\ThermalROM23R1_1\\cfd_file.ip...
Reading IP data ...
        x-coord
        y-coord
        z-coord
        temperature
  Done.
  Initializing values...
  Done.
Note: zone-surface: cannot create surface from sliding interface zone.
Creating empty surface.
Note: zone-surface: cannot create surface from sliding interface zone.
Creating empty surface.
Note: zone-surface: cannot create surface from sliding interface zone.
Creating empty surface.
Note: zone-surface: cannot create surface from sliding interface zone.
Creating empty surface.
Note: zone-surface: cannot create surface from sliding interface zone.
Creating empty surface.
Note: zone-surface: cannot create surface from sliding interface zone.
Creating empty surface.

Postprocess ROM results in 3D Viewer#

Postprocess the ROM results in the 3D Viewer enabled by PyFluent.

graphics = Graphics(session=solver)
temperature_contour = graphics.Contours["contour-temperature"]
temperature_contour.field = "temperature"
temperature_contour.show_edges = True
temperature_contour.surfaces_list = [
    "convection",
    "interface-side1-wall-interface_fluid_side",
    "interface-side2-wall-interface_solid_side",
    "interface-wall1-1-1",
    "interface-wall1-1-1-shadow",
    "interface_solid_side",
    "symmetry_solid",
    "wall-19",
    "wall-20",
    "wall-solid-part_2",
    "wall_adiabatic",
    "wall_cold_end",
    "wall_hot_end",
]
temperature_contour.display()
../../_images/TBROM_fluent_viewer.png
solver.exit()

Total running time of the script: ( 1 minutes 28.882 seconds)

Gallery generated by Sphinx-Gallery