Note
Go to the end to download the full example code
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.
# 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, read_binary
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 = read_binary(geometry_file).reshape(-1, 3)
snapshot_data = read_binary(snapshot_file).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()
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()
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.f13b837d8d4f4583be1c\\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()
solver.exit()
Total running time of the script: (1 minutes 27.818 seconds)