Note
Click here 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 in order to visualize ROM results in the form of images with predefined views. The script takes user inputs to evaluate the ROM and will display the corresponding image. A first image is generated using the point cloud based ROM Viewer embedded in the Ansys Digital Twin Runtime, and a second image is generated by loading the ROM results and performing the post processing on the CFD mesh by using PyFluent. Finally, the ROM results are post processing in a 3D Viewer enabled by PyFluent
NOTE :
To generate snapshot files at initialization time, the ROM component included in the Twin must have its parameter “field_data_storage_period” set to 0 and “store_snapshots” set to 1.
To generate images files at initialization time, the ROM component included in the Twin must have the “Embed Geometry” and “Generate Image” options enabled at export time, and its parameter “viewX_storage_period” set to 0.
These parameters can be defined in the Twin Builder subsheet before Twin compilation, or exposed as Twin parameters.
# sphinx_gallery_thumbnail_path = '_static/TBROM_images_generation.png'
Import all necessary modules#
import os
import struct
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
from pytwin import TwinModel, download_file
twin_file = download_file("ThermalTBROM_23R1_other.twin", "twin_files")
cfd_file = download_file("T_Junction.cas.h5", "other_files")
set_config(blocking=True, set_view_on_display="isometric")
User inputs#
Defining user 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,
}
Auxiliary functions definition#
Conversion of ROM snapshot for data mapping on CFD mesh.
def snapshot_to_cfd(snapshot_file, geometry_file, field_name, outputFilePath):
"""Create a Fluent Interpolation file that can be loaded in Fluent and map to the CFD mesh. This is an example of
implementation for a single field of scalar data (e.g. temperature field)
"""
with open(geometry_file, "rb") as geo, open(snapshot_file, "rb") as snp:
nb = struct.unpack("Q", snp.read(8))[0]
struct.unpack("Q", geo.read(8))
res_list = []
for i in range(nb):
res_line = []
res_line.append(struct.unpack("d", geo.read(8))[0])
res_line.append(struct.unpack("d", geo.read(8))[0])
res_line.append(struct.unpack("d", geo.read(8))[0])
res_line.append(struct.unpack("d", snp.read(8))[0])
res_list.append(res_line)
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
Loading the Twin Runtime and generate the 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
Post-processing with image generated by 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()
Post-processing with image generated by Fluent#
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_23R1_other.5ae634c836d64e769169\\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.
Post-processing the ROM results in 3D Viewer#
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: ( 0 minutes 44.640 seconds)