-
Notifications
You must be signed in to change notification settings - Fork 0
Optimize OML
This page provides instructions for performing Aerodynamic Shape Optimization (ASO) using adjoint design methods and Free-Form Deformation (FFD) techniques. Before you start, you should have already created a simulation.
NOTE: Optimization is not setup to work with adaptive meshing. Do NOT use an adapted mesh for optimization as it will yield incorrect gradients once the geometry changes (the initial adapted mesh will no longer be valid for the new flow; partials will be inconsistent). Instead, use volumetric controls to globally refine the mesh as shown in the RAE 2822 (Optimize) example.
The optimization algorithm is implemented in python, which makes calls to STAR-CCM+ whenever a function evaluation or gradient is needed, as shown below. This communication is accomplished through the Java API, where Java classes were written to read CSV file inputs, update appropriate fields in STAR-CCM+, and write back outputs to CSV file for Python. The Java framework can be thought of as a wrapper that allows Python to treat STAR-CCM+ as any regular function call.
In order to run optimization, the following inputs are needed:
- Simulation file (*.sim) -- STAR-CCM+ simulation to use for solving the physics
- ASO_jar -- folder containing ASO *.jar files
- DependentVariables.csv -- a file containing gradients, constraints, and objectives
- IndependentVariables.csv -- a file containing design variable values
- RunASO.py -- a script that contains the main logic for optimization
- RunOptimizationMacro.java -- a script that evaluates STAR-CCM+ (called by RunASO.py)
- SubmitJob.pbs (cluster only) -- a script to run on the cluster
The following outputs will be created:
- Simulation file (*.sim) will be overwritten with latest solution
- DependentVariables.csv will be overwritten with latest gradients, constraints, and objectives
- IndependentVariables.csv will be overwritten with latest design
- python.out -- optimizer history
- starccm+.out -- cfd history
The simulation file must contain certain elements. Click here to check the requirements.
In order to solve an optimization problem, you must first define it. The "IndependentVariables.csv" contains information about the design space. The columns contained in the file are:
- VarName -- any name you want to give the design variables (except "alpha")
- Note: "alpha" is a special name reserved for the angle of attack (in degrees)
- X -- the current value of the design variables
- X0 -- the initial value of the design variables
- Xmin -- lower bound constraint
- Xmax -- upper bound constraint
- TypicalX -- value by which to scale variables (place holder - not currently implemented)
- ControlPointTableID -- name of table containing control point XYZ coordinates in STAR-CCM+
- ControlPointTableRow -- the row to which the design variable corresponds to
- ControlPointTableCol -- the column to which the design variable corresponds to
Except for angle of attack (alpha), which is a special type of design variable, the design variables are the XYZ coordinates of the control points used for Free-Form Deformation (FFD). So if you have 20 control points and each control points has three degrees of freedom (XYZ), then you can have up to 3 x 20 = 60 design variables. The framework uses knowledge of what (row, col) each design variable corresponds to in order to properly update their coordinates according to:
- X = X0 + dX
- Y = Y0 + dY
- Z = Z0 + dZ
The image below helps explain how this works.
The next step in defining the optimization problem is to specify constraints and objective functions. This is accomplished through the "DependentVariables.csv" file, as shown in the figure below. There is one response per row and the framework recognizes three key words for each type of response:
- Objective -- declares that this is an objective function
- Equality -- declares that this is an equality constraint
- Inequality -- declares that this is an inequality constraint
The columns are as follows, where the values of F and dFdx are overwritten at each optimizer iteration:
- Type -- the type of function (objective, equality, inequality)
- Name -- the name of the function (must correspond to STAR-CCM+ cost function report name)
- Target -- the target value of the cost function, e.g. h = CL - Target = 0
- F -- the current value of the response
- dFdx1, dFdx2, ... -- the partial derivatives (if alpha present, then dFdalpha, dFdx1, dFdx2, ...)
Note: The framework is setup such that you must manually add a column header for every partial derivative. Hence, if you have 24 variables plus angle of attack (alpha, x1, x2, ..., x24), then you need to add 801 columns (dFdalpha, dFdx1, dFdx2, ..., dFdx24). The values can be initialized to zero.
Finally, the last step in the setup is to specify run-time options in the macro. Open the file in an editor and update the user inputs as desired:
// ----------------------- USER INPUTS START HERE --------------------------
private void setUserInputs(){
// - Files -
independentVariableFilepath = sim.getSessionDir() + File.separator + "IndependentVariables.csv"; // <-- optional (only change if for whatever reason you changed the name of the CSV file)
dependentVariableFilepath = sim.getSessionDir() + File.separator + "DependentVariables.csv"; // <-- optional (only change if for whatever reason you changed the name of the CSV file)
// - Flags -
isRunAdjoint = true; // <-- optional (used this to deactivate gradient computation during line search; actually overridden by framework)
isFlow2D = true; // <-- required (specifies whether simulation file is 2D or 3D)
cfd.flightCondition.setEulerFlag(true); // <-- required (specifies whether simulation is RANS or Euler)
// - Names -
fluidRegionName = "Fluid"; // <-- optional (must match name of region in simulation file)
freestreamBoundaryName = "Domain.Farfield"; // <-- optional (must match name of fresstream boundary condition in simulation file)
PhysicsContinuumName = "Physics"; // <-- optional (must match name of physics continuum)
// - Solver -
numberPrimalSteps = 1000; // <-- required (max number of steps to run primal solver)
number1stOrderGMRESAdjointSteps = 25; // <-- required (max number of steps to run adjoint solver for 1st-order warm-up)
number2ndOrderGMRESAdjointSteps = 15; // <-- required (max number of steps to run adjoint solver with 2nd-order scheme)
cfd.solver.setPrimalCFL(10.0); // <-- required (CFL number for primal solution)
cfd.solver.setAdjointCFL(25.0); // <-- required (CFL number for adjoint solution)
// - Flight conditions -
cfd.flightCondition.setDragCoefficientReportName("CD"); // <-- optional (must match name in simulation)
cfd.flightCondition.setLiftCoefficientReportName("CL"); // <-- optional (must match name in simulation)
cfd.flightCondition.setReferencePressure(101325.0); // <-- required (reference pressure, Pa)
cfd.flightCondition.setMachNumber(0.73); // <-- required
cfd.flightCondition.setFreestreamDynamicViscosity(0.00001789); // <-- required (Pa-s)
cfd.flightCondition.setFreestreamSpeedOfSound(340.0); // <-- required (m/s)
cfd.flightCondition.setFreestreamGaugePressure(0.0); // <-- required (Pa)
cfd.flightCondition.setFreestreamTemperature(288.15); // <-- required (K)
cfd.flightCondition.setFreestreamDensity(1.225); // <-- required (kg/m3)
cfd.flightCondition.setAngleOfAttack(2.00); // <-- required (deg)(overriden by "IndependentVariables.csv" if "alpha" present)
}
// ----------------------- USER INPUTS END HERE ----------------------------
Once the inputs have been setup, you can run optimization either locally on your desktop or remotely on the cluster, but first make sure you've properly followed the installation guidelines.
The working directory {dir} should now contain the following files:
- Simulation.sim)
- DependentVariables.csv
- IndependentVariables.csv
- RunASO.py
- RunOptimizationMacro.java
To run locally on your desktop, open a terminal and type the following at the command lines:
cd {dir}
python RunASO.py -maxiter {opt_iter} -pwd {dir} -N {np} -sim {sim} -macro {macro} -pod {pod} -lic {lic}
where you should replace {...} with proper values. For example, on my local windows system:
{opt_iter} = 15
{dir} = C:\Users\SHB\PycharmProjects\StarASO_Examples\RAE2822-Optimize-Example
{np} = 12
{sim} = Airfoil.sim
{doe} = DOE.csv
{macro} = AdaptMesh.java
{pod} = <my-podkey-number>
{lic} = 1999@flex.cd-adapco.com
Note: These instructions assume you know how to use a cluster. If not, this guide might help.
On the remote cluster, the working directory {dir} should contain the following files:
- Simulation.sim)
- DependentVariables.csv
- IndependentVariables.csv
- RunASO.py
- RunOptimizationMacro.java
- ASO_jar
- SubmitJob.pbs
To submit a job, just type the following from the command line:
qsub SubmitJob.pbs
The contents of the PBS file should be modified accordingly, but here is an example:
#!/bin/bash
# ----------------QSUB Parameters----------------- #
#PBS -N Enter-Job-Name-Here
#PBS -l nodes=1:ppn=24
#PBS -l pmem=8gb
#PBS -l walltime=24:00:00
#PBS -q Enter-Queue-Name-Here
#PBS -j oe
#PBS -o Job.out
# ----------------Load Modules-------------------- #
cd $PBS_O_WORKDIR
module load starccmplus/12.02.010
module load impi/5.0.1.035
module load anaconda3/4.2.0
# ----------------Print Some Info-------------------- #
echo Running on host `hostname`
echo Time is `date`
echo Directory is `pwd`
echo This jobs runs on the following processors:
NODES=`cat $PBS_NODEFILE`
echo $NODES
# Compute the number of processors
NPROCS=`wc -l < $PBS_NODEFILE`
echo This job has allocated $NPROCS nodes
# ---------------Execute Script ------------------ #
python -u RunASO.py -maxiter 15 -hpc -nodes $PBS_NODEFILE -pwd $PBS_O_WORKDIR -N $NPROCS -jar $PBS_O_WORKDIR/ASO_jar -sim $PBS_O_WORKDIR/Airfoil.sim -macro $PBS_O_WORKDIR/RunOptimizationMacro.java -lic '1999@flex.cd-adapco.com' -pod "my-pod-key-here" > python.out
# ----------------Print end time-------------------- #
echo Done... Time is `date`
#####
# To run interactively, modify the following example command:
# qsub -I -X -q asdl -l nodes=1:ppn=24,walltime=2:00:00,pmem=8gb