-
Notifications
You must be signed in to change notification settings - Fork 0
Home
GmshCFD is a Python tool based on Gmsh for creating CFD meshes around lifting surfaces suitable for external aerodynamic analysis.

If you only want to use GmshCFD, you can install it using
python3 -m pip install . [--user]and then run a case using
python3 path/to/case.pyIf you need to develop in GmshCFD before using it, you do not need to install anything, and you can just run your case from the repo folder using
python3 run.py path/to/case.pyIn order to run a case using GmshCFD, you just need to define a configuration file containing the information about the wing geometry. Example configuration files can be found under the examples directory. A configuration file typically contains the following lines
cfd = gmshcfd.GmshCFD(model_name, cfg) # initialize
cfd.generate_geometry() # generate geometry
cfd.generate_mesh() # generate mesh
cfd.write_geometry() # write geometry (Gmsh format) to disk
cfd.write_mesh(format) # write mesh to diskwhere model_name is a str defining the name of the model, cfg is a dict defining the parameters required to build the geometry and the mesh, and format is a str defining the format in which the mesh will be written (see Mesh.Format formats).
The configuration dictionary is split into multiple sub-dictionary and contains the following fields
cfg = {
'wings': {...},
'domain': {...},
'mesh': {...}
}where wings contains the definition of the lifting surfaces, domain contains the definition of the fluid domain, mesh contains the definition of the mesh and options contains additional parameters.
wings contains several fields
'wings': {
str: { # name of the lifting surface
'offset': 1X2 list, # x and z distances between the leading edge of the lifting surface root and the origin
'le_offsets': nX3 list, # x, y and z distances between the leading edge of each cross-section and the root leading edge
'airfoils': 1Xn list, # path to files containing the airfoil coordinates of each cross-section
'chords': 1Xn list, # chord lengths of each airfoil cross section
'incidences': 1Xn list # incidence angle of each airfoil cross section
}
}where n denotes the number of cross-sections used to define the wing. The files containing the airfoil coordinates must be formatted according to the Selig standard. That is, the coordinates must start at the trailing edge on the suction side, pass through the leading edge and end at the trailing edge on the pressure side. The trailing edge point must be duplicated and located at x=1, while the leading edge must not be duplicated and located at x=0. The other x-coordinates must be valued between 0 and 1. Note that each dictionary entry in wings will define a lifting surface and must have a unique name.
domain contains two fields
domain: {
'type': ['potential', 'euler', 'rans'], # rectangular (potential) or spherical (euler, rans) domain
'length': float, # the distance between the boundaries of the fluid domain and the origin
'merge_wake': [None, 'all', 'last'] # whether to merge wake surfaces (optional, defaults to None)
}Choosing the option euler or rans will generate a spherical domain, while selecting potential will generate a box-shaped domain containing embedded wake surfaces. rans can only be used with blunt trailing edge wings while potential can only be used with sharp trailing edges. The optional parameter merge_wake controls whether to merge embedded wake surfaces in a potential domain (None: no merging, all: merge all surfaces, last: merge last two surfaces). It is only needed when type=potential and defaults to None.
mesh contains three fields
'mesh': {
'wing_sizes': {
# EITHER
str: { # name of the lifting surface
'te': 1Xn list, # mesh sizes at the trailing edges of each cross section
'le': 1Xn list # mesh sizes at the trailing edges of each cross section
}
# OR (only when domain['type'] = 'rans')
str: { # name of the lifting surface
'num_cell_chord': float, # number of cells along the chord
'num_cell_span': 1X(n-1) list, # number of cells along the span between each cross section
'prog_chord': float # coefficient controlling the refinement at the leading and trailing edges (beta law)
}
},
'boundary_layer': {
str: { # name of the lifting surface
'num_layer': float, # number of extruded prismatic layers
'growth_ratio': float, # height ration between two successive layers (geometric series)
'hgt_first_layer': float # height of first layer
},
'write_tags': bool # whether to write the extruded prismatic boundary layer surface boundaries and volume in dedicated physical tags
},
'domain_size': float # mesh size at the farfield boundary
}The boundary_layer field is only needed for RANS computations (domain['type']=rans). It should contain one dictionary entry per lifting surface. A structured (transfinite) surface mesh may be better suited for RANS computation. In that case, the number of cells along the chord and the span must be provided instead of the mesh sizes at the surface. This is only available when domain['type']=rans.
GmshCFD is shipped with various utilities:
-
compute_wing_cfg: create a list of leading edge coordinates and chord lengths for each cross-section of a wing given its planform definition -
compute_ff_mesh_size: compute the mesh size at the outer fluid domain boundaries given the mesh size at the wing surface and a growth ratio -
add_section: interpolate and add a new cross-section on the wing at a given normalized y-coordinate -
interpolate_coords: interpolate airfoil coordinates between two given airfoil coordinates -
sharpen_te: modify the coordinates of an airfoil blunt trailing edge to sharpen it
The exact functions signature and documentation can be found in utils.
gmshcfd, (c) Adrien Crovato