From f0101e7fd020c673ffae40e48a194bea6fcb60eb Mon Sep 17 00:00:00 2001 From: Benjamin Tovar Date: Sat, 14 Dec 2024 10:19:53 -0500 Subject: [PATCH 1/2] ignore uge_submit_workers (#4008) --- work_queue/src/.gitignore | 1 + work_queue/src/uge_submit_workers | 79 ------------------------------- 2 files changed, 1 insertion(+), 79 deletions(-) delete mode 100755 work_queue/src/uge_submit_workers diff --git a/work_queue/src/.gitignore b/work_queue/src/.gitignore index ce18c651c9..168695743c 100644 --- a/work_queue/src/.gitignore +++ b/work_queue/src/.gitignore @@ -1,5 +1,6 @@ mpi_queue_worker sge_submit_workers +uge_submit_workers work_queue_example work_queue_priority_test work_queue_status diff --git a/work_queue/src/uge_submit_workers b/work_queue/src/uge_submit_workers deleted file mode 100755 index e086f69202..0000000000 --- a/work_queue/src/uge_submit_workers +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh - -UGE_WARNING=1 - -SUBMIT_COMMON=$(which work_queue_submit_common) -if [ -z "$SUBMIT_COMMON" ]; -then - echo "Please add 'work_queue_submit_common' to your PATH." 1>&2 - exit 1 -else - . $SUBMIT_COMMON -fi - - -show_help() -{ - - echo " -j Use job array to submit workers." - echo " -p UGE qsub parameters." -} - -use_jobarray=0 -uge_parameters="" - -# Used options (as in the getopts format): aM:N:C:t:d:w:i:b:z:A:O:s:P:jp:h -parse_arguments() -{ - if [ -z "$cores" -o "$cores" = 0 ] - then - cores=1 - fi - - while [ $# -gt 0 ] - do - case $1 in - -j) - use_jobarray=1 - ;; - -p) - shift - uge_parameters="$uge_parameters $1" - ;; - *) - break - ;; - esac - shift - done -} - -submit_workers_command() -{ - qsub=`which qsub 2>/dev/null` - if [ $? != 0 ] - then - echo "$0: please add 'qsub' to your PATH." - exit 1 - fi - - cat >worker.sh < Date: Thu, 19 Dec 2024 11:02:28 -0500 Subject: [PATCH 2/2] Write CFD example into documentation (#3953) Co-authored-by: Eamon Tracey --- doc/manuals/taskvine/example-cfd.md | 13 +++ doc/manuals/taskvine/index.md | 1 + taskvine/src/examples/vine_example_cfd.py | 122 ++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 doc/manuals/taskvine/example-cfd.md create mode 100644 taskvine/src/examples/vine_example_cfd.py diff --git a/doc/manuals/taskvine/example-cfd.md b/doc/manuals/taskvine/example-cfd.md new file mode 100644 index 0000000000..8a0b00dcfc --- /dev/null +++ b/doc/manuals/taskvine/example-cfd.md @@ -0,0 +1,13 @@ +# TaskVine Example: Computational Fluid Dynamics + +This workflow utilizes Ansys Fluent to run multiple computational fluid +dynamics (CFD) simulations on a matrix of angle of attack and Mach number +input parameters where each simulation outputs the aerodynamic forces and +torques on an input mesh. This script has been utilized by the Notre Dame +Rocketry Team to understand the aerodynamic forces experienced by a high +power rocket launch vehicle. + +``` +--8<-- "../../taskvine/src/examples/vine_example_cfd.py" +``` + diff --git a/doc/manuals/taskvine/index.md b/doc/manuals/taskvine/index.md index 655eb88d4d..90982a903c 100644 --- a/doc/manuals/taskvine/index.md +++ b/doc/manuals/taskvine/index.md @@ -151,6 +151,7 @@ The following examples show more complex applications and various features of Ta - [Gradient Descent Example](example-gradient-descent.md) - [Watch Files Example](example-watch.md) - [Functional Example](example-functional.md) +- [CFD Example](example-cfd.md) Read on to learn how to build applications from scratch and run large numbers of workers at scale. diff --git a/taskvine/src/examples/vine_example_cfd.py b/taskvine/src/examples/vine_example_cfd.py new file mode 100644 index 0000000000..3e36d60742 --- /dev/null +++ b/taskvine/src/examples/vine_example_cfd.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python + +# This example runs multiple computational fluid dynamics (CFD) +# simulations using Ansys Fluent on a matrix of angle of attack +# and Mach number input parameters. Each simulation outputs the +# converged aerodynamic force and torque values. + +# The program demonstrates how users can handle multiple input +# and output files from each task and create an interactive +# script to launch many computationally intensive scientific tasks. + +from datetime import datetime +import logging +from math import cos, radians, sin +import os + +import click +import ndcctools.taskvine as vine + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO, format="%(message)s") + + +@click.command(context_settings={"show_default": True}) +@click.argument("case") +@click.option("--attacks", + "-a", + multiple=True, + default=(0.0, 5.0, 10.0, 15.0, 20.0), + help="The angles of attack to parameterize.") +@click.option("--machs", + "-m", + multiple=True, + default=(0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6), + help="The mach numbers to parameterize.") +@click.option("--iterations", + "-i", + default=500, + help="The number of iterations to execute the CFD run.") +@click.option("--port", + "-p", + default=9340, + help="The port on which the TaskVine manager listens.") +def cfd(case: str, attacks: tuple[int, ...], machs: tuple[int, ...], + iterations: int, port: int): + """Launch parameterized Ansys Fluent CFD jobs via TaskVine. + + The case file must contain the vehicle mesh and four boundaries: farfield, + inlet, outlet, and launchvehicle. The vehicle's roll axis must coincide + with the x axis such that the drag force acts in the positive x direction. + """ + # Create the TaskVine manager. + manager = vine.Manager(port) + case_vine_file = manager.declare_file(case) + logging.info(f"TaskVine manager listening on port {port}") + + # Retrieve the basename of the case file. + case_name = os.path.basename(case) + case_name = case_name.split(".", 2)[0] + + # Load the journal template. + journal_file = f"data/journal.jou" + journal_template: str + with open(journal_file, "r") as file: + journal_template = file.read() + + # Make the output directory. + now = datetime.now().strftime("%Y%m%d%H%M%S") + output_directory = f"data/cfd/{now}" + os.makedirs(output_directory, exist_ok=True) + logger.info(f"Created output directory {output_directory}") + + for attack in attacks: + for mach in machs: + name = f"{case_name}_{attack}_{mach}_{iterations}" + + # To induce an angle of attack, split the x and y components of the + # flow velocity vector. Note that we assume the vehicle's roll axis + # coincides with the x axis. + angle_of_attack = radians(attack) + flow_vector_x = cos(angle_of_attack) + flow_vector_y = sin(angle_of_attack) + + # Paramterize the journal template. + journal_paramaterized = journal_template.format( + mach=mach, + flow_vector_x=flow_vector_x, + flow_vector_y=flow_vector_y, + iterations=iterations) + + # Create the task with inputs and outputs. + task = vine.Task( + f"module load ansys/2024R1; fluent 3ddp -t1 -g < journal.jou > log 2>&1" + ) + journal_vine_buffer = manager.declare_buffer(journal_paramaterized) + axial_vine_file = manager.declare_file( + f"{output_directory}/{name}.axial") + normal_vine_file = manager.declare_file( + f"{output_directory}/{name}.normal") + log_vine_file = manager.declare_file( + f"{output_directory}/{name}.log") + task.add_input(case_vine_file, "case.cas.h5") + task.add_input(journal_vine_buffer, "journal.jou") + task.add_output(axial_vine_file, "axial.out") + task.add_output(normal_vine_file, "normal.out") + task.add_output(log_vine_file, "log") + + # Submit the task to TaskVine. + manager.submit(task) + logger.info( + f"Submitted computational fluid dynamics task {task.id} with {case_name=} {attack=} {mach=} {iterations=}" + ) + + while not manager.empty(): + task = manager.wait(10) + if task is not None: + logger.info( + f"Completed task {task.id} with exit code {task.exit_code}") + + +if __name__ == "__main__": + cfd()