Application (Wing-Fuselage)

Post-processing of a CFD simulation with a multi-block structured cell-centered dataset.

In this tutorial, you will process solution data from a typical external aerodynamic test case. The actual structured mesh used has been coarsened four times to alleviate memory costs. Please download the associated data at https://www.cerfacs.fr/antares/downloads/application3_tutorial_data.tgz

untar the archive in the working directory

copy the app3_aircraft.ipynb in the directory application3

Preliminary Steps

import os and antares packages

create a directory named OUTPUT under application3

import os
import antares

if not os.path.isdir('OUTPUT'):
    os.makedirs('OUTPUT')

Part I: Read Input Data

The topic of this part is to create the basic structures from the data of a CFD simulation of typical wing-fuselage configuration. It will be used later throughout the tutorial.

The first step is to create a Base named base by reading grids from files MESH/mesh_XXXX (Tecplot binary format) as shared data. You must also give topological information contained in script_topology.py and the zones must be named BlockXXXX to insure coherence with the topological data. Have fun with your data. Compute the total number nodes using the grid_points attribute of the Base object.

r = antares.Reader('bin_tp')
r['filename'] = os.path.join('MESH', 'mesh_<zone>')
r['zone_prefix'] = 'Block'
r['topology_file'] = os.path.join('script_topology.py')
r['shared'] = True
base = r.read()

print('Total number of nodes = {}'.format(base.grid_points))

Now add the solution stored in files FLOW/flow_XXXX (Tecplot binary format) to your existing base.

The solution given here is located at nodes.

r = antares.Reader('bin_tp')
r['base'] = base
r['filename'] = os.path.join('FLOW', 'flow_<zone>')
r['zone_prefix'] = 'Block'
r.read()

Part II: Extract Skin Data

This part details the steps to extract data on the aircraft skin in order to visualize the static pressure distribution.

In this part, we will focus on skin extraction. It would be at least interesting to locate the aircraft. Therefore, it is necessary to extract the mesh coordinates on the aircraft skin. As topological information have been read in script_topology.py, the base already contains families. Print the families to see the family names. Then, build a new family aircraft_family including all families except JOIN and NREF

print(base.families)

# build a new family
aircraft_family = antares.Family()
aircraft_family['FUSELAGE'] = base.families['FUSELAGE']
aircraft_family['LEFT_WING'] = base.families['LEFT_WING']
aircraft_family['RIGHT_WING'] = base.families['RIGHT_WING']
aircraft_family['V_STAB'] = base.families['V_STAB']
aircraft_family['LEFT_H_STAB'] = base.families['LEFT_H_STAB']
aircraft_family['RIGHT_H_STAB'] = base.families['RIGHT_H_STAB']
# add the new family to the base
base.families['SKIN'] = aircraft_family

# extracting the skin base
skin_base = base[base.families['SKIN']]
print(skin_base)

Secondly, we would like to visualize the static pressure on the aircraft skin. To do so, we will use the Base method compute(). Look in Antares documentation to know how to use it. Beforehand, we have to declare the computer model internal with the Base method set_computer_model().

skin_base.set_computer_model('internal')

skin_base.compute('psta')

To finally visualize the skin, write the base skin_base in VTK binary format (compatible with Paraview software) in directory OUTPUT/SKIN/.

writer = antares.Writer('hdf_antares')
writer['base'] = skin_base
writer['filename'] = os.path.join('OUTPUT', 'skin')
writer.dump()

Part III: Create Cut

This part will teach you how to extract the Mach number field on a geometrical plane cut.

We want to visualize the Mach number on a geometrical cut. Use the function compute() to compute this variable on your base. Do not forget to declare a computer model.

base.set_computer_model('internal')
base.compute('mach')

Use cut treatment (see documentation for more information) to perform a geometrical cut in your domain at a constant x value of 2.25. The base obtained after cut will be named cut_base.

plane_cut = antares.Treatment('cut')
plane_cut['base'] = base
plane_cut['type'] = 'plane'
plane_cut['origin'] = [2.25, 0., 0.]
plane_cut['normal'] = [1., 0., 0.]
cut_base = plane_cut.execute()

To finally visualize the cut, write the base cut_base in VTK binary format (compatible with Paraview software) in directory OUTPUT/XCUT/.

writer = antares.Writer('hdf_antares')
writer['base'] = cut_base
writer['filename'] = os.path.join('OUTPUT', 'cut_x')
writer.dump()

Part IV: Plot Data Over Line

The objective of this part is to plot the pressure distribution on the wing at a given ‘y’ coordinate.

We want now to vizualize the wing pressure distribution at constant y value of 0.4. As we have already extracted the skin base skin_base (tutorial part II), apply a cut treatment to extract values at constant y (y=0.4).

plane_cut = antares.Treatment('cut')
plane_cut['base'] = skin_base
plane_cut['type'] = 'plane'
plane_cut['origin'] = [0., 0.4, 0.]
plane_cut['normal'] = [0., 1., 0.]
cut_base = plane_cut.execute()

Use the threshold treatment (see documentation to learn how it works) to isolate the right wing (0.15 < y and 0.78 < x < 1.47). Then use the merge treatment (see documentation to learn how it works) to merge and the unwrapline treatment reorganize the line points. The base obtained will be named line_base.

clip = antares.Treatment('threshold')
clip['base'] = cut_base
clip['variables'] = ['x', 'y']
clip['threshold'] = [(0.78, 1.47), (0.15, None)]
line_base = clip.execute()

merge = antares.Treatment('merge')
merge['base'] = line_base
line_base1 = merge.execute()

unw = antares.Treatment('unwrapline')
unw['base'] = line_base1
line_base = unw.execute()

To visualize data stored in the base line_base use matplotlib. Plot the static pressure distribution as a function of x.

import matplotlib.pyplot as plt
plt.plot(line_base[0][0]['x'], line_base[0][0]['psta'], lw=2.5)
plt.grid()
plt.xlabel('{}'.format('x'), fontsize=18)
plt.ylabel('{}'.format('psta'), fontsize=18)
plt.autoscale(axis='x')
plt.autoscale(axis='y')
plt.show()
plt.close()

Write the base line_base in directory OUTPUT/LINE/ in the column format.

writer = antares.Writer('column')
writer['base'] = line_base
writer['filename'] = os.path.join('OUTPUT', 'line.dat')
writer.dump()