Sweep Template Script

Contents

Sweep Template Script#

This template script demonstrates the fundamental workflow for conducting parametric studies using the Flow360 Python API. The script provides a structured approach to uploading meshes, configuring simulation parameters, and executing either single cases or parameter sweeps.

The script is organized into several key functions:

  • upload_mesh(): Handles mesh upload and project creation

  • make_params(): Configures simulation parameters

  • launch_sweep(): Implements parameter sweep functionality

  • main(): Orchestrates the overall workflow

The following example demonstrates an angle of attack sweep study, but the template can be adapted for other parametric studies by modifying the relevant parameters.

  1"""
  2Sample Flow 360 API scripts.
  3Requires a mesh that you are ready to upload and run cases on.
  4"""
  5
  6import os
  7
  8import flow360 as fl
  9from flow360.log import log
 10
 11# Variables we want to export in our volume solution files. Many more are available
 12vol_fields = ["Mach", "Cp", "mut", "mutRatio", "primitiveVars", "qcriterion"]
 13
 14# Variables we want to export in our surface solution files. Many more are available
 15surf_fields = ["Cp", "yPlus", "Cf", "CfVec", "primitiveVars", "wallDistance"]
 16
 17
 18######################################################################################################################
 19def upload_mesh(file_path, project_name):
 20    """
 21    Given a file path and name of the project, this function creates a project and uploads a mesh.
 22    """
 23    # length_unit should be 'm', 'mm', 'cm', 'inch' or 'ft'
 24    project = fl.Project.from_volume_mesh(file_path, length_unit="m", name=project_name)
 25    log.info(f"The project id is {project.id}")
 26
 27    return project
 28
 29
 30######################################################################################################################
 31def make_params(mesh_object):
 32    """
 33    Create the params object that contains all the run parameters.
 34    Needs the mesh_object to get the list of surfaces.
 35    """
 36    with fl.SI_unit_system:
 37        params = fl.SimulationParams(
 38            # Dimensions can  be either in inches, or m or mm or many other units
 39            reference_geometry=fl.ReferenceGeometry(
 40                moment_center=(0, 0, 0) * fl.u.m, moment_length=1 * fl.u.m, area=1 * fl.u.m * fl.u.m
 41            ),
 42            operating_condition=fl.AerospaceCondition(
 43                velocity_magnitude=100 * fl.u.m / fl.u.s, alpha=0 * fl.u.deg
 44            ),
 45            time_stepping=fl.Steady(max_steps=5000, CFL=fl.AdaptiveCFL()),
 46            models=[
 47                # These boundary names can be taken from the vm.boundary_names printout
 48                fl.Wall(
 49                    surfaces=[
 50                        mesh_object["fluid/leftWing"],
 51                        mesh_object["fluid/rightWing"],
 52                        mesh_object["fluid/fuselage"],
 53                    ],
 54                ),
 55                fl.Freestream(surfaces=mesh_object["fluid/farfield"]),  # For far field boundaries
 56                # Define what sort of physical model of a fluid we will use
 57                fl.Fluid(
 58                    navier_stokes_solver=fl.NavierStokesSolver(),
 59                    turbulence_model_solver=fl.SpalartAllmaras(),
 60                ),
 61            ],
 62            outputs=[
 63                fl.VolumeOutput(output_format="tecplot", output_fields=vol_fields),
 64                # This mesh_object['*'] will select all the boundaries in the mesh and export the surface results.
 65                # Regular expressions can be used to filter for certain boundaries
 66                fl.SurfaceOutput(
 67                    surfaces=[mesh_object["*"]], output_fields=surf_fields, output_format="tecplot"
 68                ),
 69            ],
 70        )
 71    return params
 72
 73
 74######################################################################################################################
 75def launch_sweep(params, project):
 76    """
 77    Launch a sweep of cases.
 78    """
 79
 80    # for example let's vary alpha:
 81    alphas = [-10, -5, 0, 5, 10, 11, 12]
 82
 83    for alpha_angle in alphas:
 84        # modify the alpha
 85        params.operating_condition.alpha = alpha_angle * fl.u.deg
 86
 87        # launch the case
 88        project.run_case(params=params, name=f"{alpha_angle}_case ")
 89        log.info(f"The case ID is: {project.case.id} with {alpha_angle=} ")
 90
 91
 92######################################################################################################################
 93def main():
 94    """
 95    Main function that drives the mesh upload and case launching functions.
 96    """
 97
 98    # if you want to upload a new mesh and create a new project
 99    mesh_file_path = os.path.join(os.getcwd(), "mesh_name.cgns")  # mesh could also be ugrid format
100    project_name = "project_name"
101    project = upload_mesh(mesh_file_path, project_name)
102
103    # Or as an alternative, if you want to run from an existing project:
104    # project = fl.Project.from_cloud(
105    #     'prj-XXXXXXXXXX')  # where prj-XXXXXXXXXX is an ID that can be saved from a previously created project or read off the WEBUI
106
107    vm = project.volume_mesh  # get the volume mesh entity associated with that project.
108    log.info(f"The volume mesh contains the following boundaries:{vm.boundary_names}")
109    log.info(f"The volume mesh ID is: {vm.id}")
110
111    params = make_params(vm)  # define the run params used to launch the run
112
113    # launch_sweep(params, project)  # if you want to launch a sweep
114
115    # or if you want to simply launch the case\
116    project.run_case(params=params, name=f"case_name")
117    log.info(f"case id is {project.case.id}")
118
119
120######################################################################################################################
121
122if __name__ == "__main__":
123    main()

Notes#

  • Verify boundary names in the mesh match those used in make_params() by checking vm.boundary_names

  • For parameter sweeps, adjust the alphas list in launch_sweep() to define the range of angles to study

  • The script supports both new mesh uploads and existing project loading - comment/uncomment the appropriate section in main()