Skip to content

Commit 67db4e7

Browse files
EamonTraceyEamon Tracey
andauthored
Write CFD example into documentation (#3953)
Co-authored-by: Eamon Tracey <[email protected]>
1 parent f0101e7 commit 67db4e7

File tree

3 files changed

+136
-0
lines changed

3 files changed

+136
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# TaskVine Example: Computational Fluid Dynamics
2+
3+
This workflow utilizes Ansys Fluent to run multiple computational fluid
4+
dynamics (CFD) simulations on a matrix of angle of attack and Mach number
5+
input parameters where each simulation outputs the aerodynamic forces and
6+
torques on an input mesh. This script has been utilized by the Notre Dame
7+
Rocketry Team to understand the aerodynamic forces experienced by a high
8+
power rocket launch vehicle.
9+
10+
```
11+
--8<-- "../../taskvine/src/examples/vine_example_cfd.py"
12+
```
13+

doc/manuals/taskvine/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ The following examples show more complex applications and various features of Ta
151151
- [Gradient Descent Example](example-gradient-descent.md)
152152
- [Watch Files Example](example-watch.md)
153153
- [Functional Example](example-functional.md)
154+
- [CFD Example](example-cfd.md)
154155

155156
Read on to learn how to build applications from scratch and run large numbers of workers at scale.
156157

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#!/usr/bin/env python
2+
3+
# This example runs multiple computational fluid dynamics (CFD)
4+
# simulations using Ansys Fluent on a matrix of angle of attack
5+
# and Mach number input parameters. Each simulation outputs the
6+
# converged aerodynamic force and torque values.
7+
8+
# The program demonstrates how users can handle multiple input
9+
# and output files from each task and create an interactive
10+
# script to launch many computationally intensive scientific tasks.
11+
12+
from datetime import datetime
13+
import logging
14+
from math import cos, radians, sin
15+
import os
16+
17+
import click
18+
import ndcctools.taskvine as vine
19+
20+
logger = logging.getLogger(__name__)
21+
logging.basicConfig(level=logging.INFO, format="%(message)s")
22+
23+
24+
@click.command(context_settings={"show_default": True})
25+
@click.argument("case")
26+
@click.option("--attacks",
27+
"-a",
28+
multiple=True,
29+
default=(0.0, 5.0, 10.0, 15.0, 20.0),
30+
help="The angles of attack to parameterize.")
31+
@click.option("--machs",
32+
"-m",
33+
multiple=True,
34+
default=(0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6),
35+
help="The mach numbers to parameterize.")
36+
@click.option("--iterations",
37+
"-i",
38+
default=500,
39+
help="The number of iterations to execute the CFD run.")
40+
@click.option("--port",
41+
"-p",
42+
default=9340,
43+
help="The port on which the TaskVine manager listens.")
44+
def cfd(case: str, attacks: tuple[int, ...], machs: tuple[int, ...],
45+
iterations: int, port: int):
46+
"""Launch parameterized Ansys Fluent CFD jobs via TaskVine.
47+
48+
The case file must contain the vehicle mesh and four boundaries: farfield,
49+
inlet, outlet, and launchvehicle. The vehicle's roll axis must coincide
50+
with the x axis such that the drag force acts in the positive x direction.
51+
"""
52+
# Create the TaskVine manager.
53+
manager = vine.Manager(port)
54+
case_vine_file = manager.declare_file(case)
55+
logging.info(f"TaskVine manager listening on port {port}")
56+
57+
# Retrieve the basename of the case file.
58+
case_name = os.path.basename(case)
59+
case_name = case_name.split(".", 2)[0]
60+
61+
# Load the journal template.
62+
journal_file = f"data/journal.jou"
63+
journal_template: str
64+
with open(journal_file, "r") as file:
65+
journal_template = file.read()
66+
67+
# Make the output directory.
68+
now = datetime.now().strftime("%Y%m%d%H%M%S")
69+
output_directory = f"data/cfd/{now}"
70+
os.makedirs(output_directory, exist_ok=True)
71+
logger.info(f"Created output directory {output_directory}")
72+
73+
for attack in attacks:
74+
for mach in machs:
75+
name = f"{case_name}_{attack}_{mach}_{iterations}"
76+
77+
# To induce an angle of attack, split the x and y components of the
78+
# flow velocity vector. Note that we assume the vehicle's roll axis
79+
# coincides with the x axis.
80+
angle_of_attack = radians(attack)
81+
flow_vector_x = cos(angle_of_attack)
82+
flow_vector_y = sin(angle_of_attack)
83+
84+
# Paramterize the journal template.
85+
journal_paramaterized = journal_template.format(
86+
mach=mach,
87+
flow_vector_x=flow_vector_x,
88+
flow_vector_y=flow_vector_y,
89+
iterations=iterations)
90+
91+
# Create the task with inputs and outputs.
92+
task = vine.Task(
93+
f"module load ansys/2024R1; fluent 3ddp -t1 -g < journal.jou > log 2>&1"
94+
)
95+
journal_vine_buffer = manager.declare_buffer(journal_paramaterized)
96+
axial_vine_file = manager.declare_file(
97+
f"{output_directory}/{name}.axial")
98+
normal_vine_file = manager.declare_file(
99+
f"{output_directory}/{name}.normal")
100+
log_vine_file = manager.declare_file(
101+
f"{output_directory}/{name}.log")
102+
task.add_input(case_vine_file, "case.cas.h5")
103+
task.add_input(journal_vine_buffer, "journal.jou")
104+
task.add_output(axial_vine_file, "axial.out")
105+
task.add_output(normal_vine_file, "normal.out")
106+
task.add_output(log_vine_file, "log")
107+
108+
# Submit the task to TaskVine.
109+
manager.submit(task)
110+
logger.info(
111+
f"Submitted computational fluid dynamics task {task.id} with {case_name=} {attack=} {mach=} {iterations=}"
112+
)
113+
114+
while not manager.empty():
115+
task = manager.wait(10)
116+
if task is not None:
117+
logger.info(
118+
f"Completed task {task.id} with exit code {task.exit_code}")
119+
120+
121+
if __name__ == "__main__":
122+
cfd()

0 commit comments

Comments
 (0)