Optimizer Module

The optimizer module is designed to define all components required by an evolution algorithm based on the inspyred logic:

  • generator: a function used to sample an initial population,
  • observer: a function executed after each evaluation,
  • evaluator: a function used to evaluate the candidates of each generation,
  • some additional optimization arguments.

The framework currently supports two optimization libraries : inspyred and pymoo. Thus, Optimizer attributes and methods are passed to the evolutionary computation algorithm (see ec framework for inspyred and algorithms in pymoo) and its optimization method (see ec.evolve for inspyred and optimize.minimize for pymoo). To do so, the Evolution class ensures that the algorithm object and the optimization method are set and executed according to the chosen library requirements.

Optimizer

The Optimizer abstract class extracts general arguments from the "optim" and "study" dictionaries of the configuration file such as:

  • [optim] n_design (int): the number of design points i.e. the dimension of the problem,
  • [optim] doe_size (int): the doe/population size i.e. the number of individuals per generation,
  • [optim] max_generations (int): the maximal number of generations to evaluate,
  • [study] file (str): the baseline geometry file,
  • [study] outdir (str): the optimization output directory,
  • [study] study_type (str): the type of study i.e. the meshing routine to use.

It instantiates optimization related objects:

  • generator (Generator): object to sample the initial DOE,
  • ffd (FFD_2D): object to deform the baseline geometry,
  • gmsh_mesh (Mesh): object to mesh the deformed geometry.

It also implements the following three base methods:

  • process_config: which goes through the configuration file making sure expected entries are well defined,
  • deform: which generates the deformed candidate,
  • mesh: which meshes the deformed candidates.

Regardless of the optimization library, the Optimizer class acts as an evaluator and must hence implement an _evaluate method that is used during the optimization. However since they both have their own specificities in terms of candidate management, typing and structure, the choice has been made to inherit the Optimizer class separately for each library.

Tip

The Generator class is based on scipy.qmc samplers. It supports three different sampling techniques: "lhs", "halton" and "sobol". The sampling technique is selected with the sampler_name entry of the "optim" dictionary in the configuration file.

Note

All optimizer parameters are described in their respective class definition (see Optimizer, WolfOptimizer (inspyred), WolfOptimizer (pymoo)).

Wolf Optimizer

The WolfOptimizer class illustrates how Optimizer can be inherited to perform a Wolf-based optimization. It is the default optimizer used when running optim.

Regardless of the optimization library, it first instantiates a WolfSimulator attribute that is then used in the _evaluate method where for all candidates, the following steps are performed:

1) geometry deformation,

2) deformed geometry meshing,

3) simulation execution,

4) post-processing i.e. QoI extraction and constraint application.

Note

Design constraints penalizing inadequate geometries both in terms of area and lift coefficient are managed with apply_constraints for inspyred (see here) and for pymoo (see here).

In the end, all simulations QoIs are returned either as a list of floats (with inspyred) or as a numpy array (with pymoo). In addition, after each evaluation the _observe method is called (automatically with inspyred, explicitly with pymoo) to write or display the results of each generation candidates.

The overall optimization progress is illustrated as the evolution of the generations statistics plotted and saved with the final_observe method.

Debug Optimizer

The DebugOptimizer class was introduced to facilitate prototyping and debugging. It is based on the DebugSimulator and follows a simplified structure of a classic optimizer without constraints, no geometry deformation nor meshing but where candidates are simply evaluation of the Ackley function. This optimizer is used when running optim with the --debug option.

In addition, the _observe method does not generate any figure but only updates the optimization statistics which are finally plotted and saved with final_observe.

Note

For this class, candidates are not evaluated concurrently in distinct subprocesses but sequentially inside the _evaluate method.

Quick Experiments

The main_optim.py scripts is called with the optim command. It enable to launch a full optimization in accordance with the configuration file specifications:

usage: optim [-h] [-c CONFIG] [-p] [-i] [-f CUSTOM_FILE] [-d] [-v VERBOSE]

options:
  -h, --help            show this help message and exit
  -c CONFIG, --config CONFIG
                        /path/to/config.json (default: None)
  -p, --pymoo           use the pymoo library (default: False)
  -i, --inspyred        use the inspyred library (default: False)
  -f CUSTOM_FILE, --custom-file CUSTOM_FILE
                        /path/to/custom_file.py (default: )
  -d, --debug           use DEBUG mode (default: False)
  -v VERBOSE, --verbose VERBOSE
                        logger verbosity level (default: 3)

For instance, setting doe_size and max_generations to 20 in naca_base.json and running the command below:

# from aero-optim to naca_base
cd examples/NACA12/naca_base
optim -c naca_base.json --inspyred
will perfom a 20 generations x 20 candidates optimization with inspyred and yield the following figure:

Using the --pymoo option instead will yield the following graph:

The main difference between these two results stems from the fact that, as opposed to pymoo which does not explicitly modify the fitness value of a penalized candidate, the inspyred optimizer does. Hence, any penalized candidate gets its fitness increased by one. Although this does not affect the optimization behavior, it does change the generations statistics.

Note

By default, the area penalization sanctions any candidate whose area is greater/smaller than the baseline area +/- 40%. This constraint can be altered for instance by setting area_margin to any other percentage value in the "optim" sub-dictionary of the configuration file.

Tip

In the configuration file, the budget entry should be adapted to the amount of resources available to the user.