Skip to content

Commit 44f5334

Browse files
RobPasMuepre-commit-ci[bot]pyansys-ci-botPipKat
authored
docs: add geometry preparation for Fluent simulation (#1183)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: pyansys-ci-bot <pyansys.github.bot@ansys.com> Co-authored-by: Kathy Pippert <84872299+PipKat@users.noreply.github.com>
1 parent 4c1797b commit 44f5334

File tree

9 files changed

+162
-6
lines changed

9 files changed

+162
-6
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
docs: add geometry preparation for Fluent simulation
53 KB
Loading

doc/source/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ def intersphinx_pyansys_geometry(switcher_version: str):
278278
"examples/03_modeling/sweep_chain_profile": "_static/thumbnails/sweep_chain_profile.png",
279279
"examples/03_modeling/export_design": "_static/thumbnails/export_design.png",
280280
"examples/04_applied/01_naca_airfoils": "_static/thumbnails/naca_airfoils.png",
281+
"examples/04_applied/02_naca_fluent": "_static/thumbnails/naca_fluent.png",
281282
}
282283
nbsphinx_epilog = """
283284
----

doc/source/examples.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,4 @@ applications.
5151
.. nbgallery::
5252

5353
examples/04_applied/01_naca_airfoils.mystnb
54+
examples/04_applied/02_naca_fluent.mystnb
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
*.fmd
1+
*.fmd
2+
*.scdocx
3+
*.pmdb

doc/source/examples/04_applied/01_naca_airfoils.mystnb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,10 @@ design.plot()
245245

246246
### Save the design
247247

248+
In this case, the design is saved as an SCDOCX file.
249+
248250
```{code-cell} ipython3
249251
# Save the design
250-
file = design.export_to_fmd()
252+
file = design.export_to_scdocx()
251253
print(f"Design saved to {file}")
252254
```
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
---
2+
jupytext:
3+
text_representation:
4+
extension: .mystnb
5+
format_name: myst
6+
format_version: 0.13
7+
jupytext_version: 1.14.1
8+
kernelspec:
9+
display_name: Python 3 (ipykernel)
10+
language: python
11+
name: python3
12+
---
13+
# Applied: Prepare a NACA airfoil for a Fluent simulation
14+
15+
Once a NACA airfoil is designed, it is necessary to prepare the geometry for a CFD simulation. This notebook demonstrates
16+
how to prepare a NACA 6412 airfoil for a Fluent simulation. The starting point of this example is the previously designed
17+
NACA 6412 airfoil. The airfoil was saved in an SCDOCX file, which is now imported into the notebook. The geometry is then
18+
prepared for the simulation.
19+
20+
In case you want to run this notebook, make sure that you have run the previous notebook to design the NACA 6412 airfoil.
21+
22+
## Import the NACA 6412 airfoil
23+
24+
The following code starts up the Geometry Service and imports the NACA 6412 airfoil. The airfoil is then displayed in the
25+
notebook.
26+
27+
```{code-cell} ipython3
28+
import os
29+
30+
from ansys.geometry.core import launch_modeler
31+
32+
# Launch the modeler
33+
modeler = launch_modeler()
34+
35+
# Import the NACA 6412 airfoil
36+
design = modeler.open_file(os.path.join(os.getcwd(), f"NACA_Airfoil_6412.scdocx"))
37+
38+
# Retrieve the airfoil body
39+
airfoil = design.bodies[0]
40+
41+
# Display the airfoil
42+
design.plot()
43+
```
44+
45+
## Prepare the geometry for the simulation
46+
47+
The current design is only composed of the airfoil. To prepare the geometry for the simulation,
48+
you must define the domain around the airfoil. The following code creates a rectangular
49+
fluid domain around the airfoil.
50+
51+
The airfoil has the following dimensions:
52+
53+
* Chord length: 1 (X-axis)
54+
* Thickness: Depends on NACA value (Y-axis)
55+
56+
Define the fluid domain as a large box with these dimensions:
57+
58+
* Length (X-axis) - 10 times the chord length
59+
* Width (Z-axis) - 5 times the chord length
60+
* Height (Y-axis) - 4 times the chord length
61+
62+
Place the airfoil at the center of the fluid domain.
63+
64+
```{code-cell} ipython3
65+
from ansys.geometry.core.math import Point2D, Plane, Point3D
66+
from ansys.geometry.core.sketch import Sketch
67+
68+
BOX_LENGTH = 10 # X-Axis
69+
BOX_WIDTH = 5 # Z-Axis
70+
BOX_HEIGHT = 4 # Y-Axis
71+
72+
# Create the sketch
73+
fluid_sketch = Sketch(
74+
plane=Plane(origin=Point3D([0, 0, 0.5 - (BOX_WIDTH / 2)]))
75+
)
76+
fluid_sketch.box(
77+
center=Point2D([0.5, 0]),
78+
height=BOX_HEIGHT,
79+
width=BOX_LENGTH,
80+
)
81+
82+
# Extrude the fluid domain
83+
fluid = design.extrude_sketch("Fluid", fluid_sketch, BOX_WIDTH)
84+
```
85+
86+
## Create named selections
87+
88+
Named selections are used to define boundary conditions in Fluent. The following code creates named selections for the
89+
inlet, outlet, and walls of the fluid domain. The airfoil is also assigned a named selection.
90+
91+
The airfoil is aligned with the X axis. The inlet is located at the left side of the airfoil, the outlet is located at the
92+
right side of the airfoil, and the walls are located at the top and bottom of the airfoil. The inlet face has therefore
93+
a negative X-axis normal vector, and the outlet face has a positive X-axis normal vector. The rest of the faces, therefore,
94+
constitute the walls.
95+
96+
```{code-cell} ipython3
97+
# Create named selections in the fluid domain (inlet, outlet, and surrounding faces)
98+
# Add also the airfoil as a named selection
99+
fluid_faces = fluid.faces
100+
surrounding_faces = []
101+
inlet_faces = []
102+
outlet_faces = []
103+
for face in fluid_faces:
104+
if face.normal().x == 1:
105+
outlet_faces.append(face)
106+
elif face.normal().x == -1:
107+
inlet_faces.append(face)
108+
else:
109+
surrounding_faces.append(face)
110+
111+
design.create_named_selection("Outlet Fluid", faces=outlet_faces)
112+
design.create_named_selection("Inlet Fluid", faces=inlet_faces)
113+
design.create_named_selection("Surrounding Faces", faces=surrounding_faces)
114+
design.create_named_selection("Airfoil Faces", faces=airfoil.faces)
115+
```
116+
117+
## Display the geometry
118+
119+
The geometry is now ready for the simulation. The following code displays the geometry in the notebook.
120+
This example uses the ``PlotterHelper`` class to display the geometry for
121+
the airfoil and fluid domain in different colors with a specified opacity level.
122+
123+
The airfoil is displayed in green, and the fluid domain is displayed in blue with an opacity of 0.25.
124+
125+
```{code-cell} ipython3
126+
from ansys.geometry.core.plotting import PlotterHelper
127+
128+
plotter_helper = PlotterHelper()
129+
plotter_helper.add(airfoil, color="green")
130+
plotter_helper.add(fluid, color="blue", opacity=0.15)
131+
plotter_helper.show_plotter()
132+
```
133+
134+
## Export the geometry
135+
136+
Export the geometry into a Fluent-compatible format. The following code exports the geometry
137+
into a PMDB file, which retains the named selections.
138+
139+
```{code-cell} ipython3
140+
# Save the design
141+
file = design.export_to_pmdb()
142+
print(f"Design saved to {file}.")
143+
```
144+
145+
You can import the exported PMDB file into Fluent to set up the mesh and perform the simulation.
146+
For an example of how to set up the mesh and boundary conditions in Fluent, see the [Modeling External Compressible Flow](https://fluent.docs.pyansys.com/version/stable/examples/00-fluent/external_compressible_flow.html) example in the Fluent documentation.
147+
148+
The main difference between the Fluent example and this geometry is the coordinate system. The Fluent example
149+
defines the airfoil in the XY plane, while this geometry defines the airfoil in the XZ plane.

tests/integration/test_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def test_client_through_channel(modeler: Modeler):
5353
client_repr = repr(client)
5454
assert "Target" in client_repr
5555
assert "Connection" in client_repr
56-
assert client.target() == target
56+
assert target == client.target().lstrip("dns:///")
5757
assert client.channel
5858

5959

tests/integration/test_launcher_local.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def test_local_launcher_connect(
8585
pytest.skip("Docker local launcher tests are not runnable.")
8686

8787
# Get the existing target
88-
target = modeler.client.target().split(":")
88+
target = modeler.client.target().lstrip("dns:///").split(":")
8989
port = int(target[1])
9090

9191
# Trying to deploy a service there will lead to an error...
@@ -118,7 +118,7 @@ def test_local_launcher_connect_with_restart(
118118
image = get_geometry_container_type(docker_instance)
119119

120120
# Get the existing target
121-
target = modeler.client.target().split(":")
121+
target = modeler.client.target().lstrip("dns:///").split(":")
122122
port = int(target[1])
123123
new_port = port + 1
124124

@@ -173,7 +173,7 @@ def test_try_deploying_container_with_same_name(
173173
image = get_geometry_container_type(docker_instance)
174174

175175
# Get the existing target
176-
target = modeler.client.target().split(":")
176+
target = modeler.client.target().lstrip("dns:///").split(":")
177177
port = int(target[1])
178178
new_port = port + 1
179179
new_port_2 = port + 2

0 commit comments

Comments
 (0)