Pareto front on the Binh and Korn problem using a BiLevel formulation

In this example, we illustrate the computation of a Pareto front plot for the Binh and Korn problem. We use a BiLevel formulation in order to only compute the Pareto-optimal points.

Import

The first step is to import some high-level functions and to configure the logger.

from __future__ import annotations

from logging import WARNING

from numpy import array

from gemseo import configure_logger
from gemseo import create_design_space
from gemseo import create_discipline
from gemseo import create_scenario

configure_logger()
<RootLogger root (INFO)>

Definition of the disciplines

In this example, we create the Binh and Korn disciplines from scratch by declaring their expressions and using the AnalyticDiscipline.

expr_binh_korn = {
    "obj1": "4*x1**2 + 4*x2**2",
    "obj2": "(x1-5.)**2 + (x2-5.)**2",
    "cstr1": "(x1-5.)**2 + x2**2 - 25.",
    "cstr2": "-(x1-8.)**2 - (x2+3)**2 + 7.7",
}

This constraint will be used to set obj1 to a target value for the lower-level scenario.

expr_cstr_obj1_target = {"cstr3": "obj1 - obj1_target"}

Instantiation of the disciplines

Here, we create the disciplines from their expressions.

discipline_binh_korn = create_discipline(
    "AnalyticDiscipline", expressions=expr_binh_korn
)
discipline_cstr_obj1 = create_discipline(
    "AnalyticDiscipline", expressions=expr_cstr_obj1_target
)

Definition of the lower-level design space

design_space = create_design_space()
design_space.add_variable("x1", l_b=array([0.0]), u_b=array([5.0]), value=array([2.0]))
design_space.add_variable("x2", l_b=array([-5.0]), u_b=array([3.0]), value=array([2.0]))

disciplines = [
    discipline_binh_korn,
    discipline_cstr_obj1,
]

Creation of the lower-level scenario

This scenario aims at finding the obj2 optimal value for a specific value of obj1.

sub_scenario = create_scenario(
    disciplines,
    "DisciplinaryOpt",
    "obj2",
    design_space,
)

sub_scenario.default_inputs = {"algo": "NLOPT_SLSQP", "max_iter": 100}

We add the Binh and Korn problem constraints.

sub_scenario.add_constraint("cstr1", constraint_type="ineq")
sub_scenario.add_constraint("cstr2", constraint_type="ineq")

Creation of the design space for the system-level scenario

At the system level, we will fix a target for the obj1 value of the lower-level scenario.

system_design_space = create_design_space()
system_design_space.add_variable(
    "obj1_target", l_b=array([0.1]), u_b=array([100.0]), value=array([1.0])
)

Creation of the system-level DOE Scenario

The system-level scenario will perform a DOE over the obj1_target variable. We will use the BiLevel formulation to nest the lower-level scenario into the DOE. The log level for the sub scenarios is set to WARNING to avoid getting the complete log of each sub scenario, which would be too verbose. Set it to INFO if you wish to keep the logs of each sub scenario as well.

system_scenario = create_scenario(
    sub_scenario,
    "BiLevel",
    "obj1",
    system_design_space,
    scenario_type="DOE",
    sub_scenarios_log_level=WARNING,
)
WARNING - 01:01:53: No strongly coupled disciplines detected,  MDA1 is deactivated in the BiLevel formulation

Add the system-level constraint and observables

Here, we add the constraint on the obj1_target, this way we make sure that the lower-level scenario will respect the target imposed by the system. The BiLevel formulation will automatically add the constraints from the system-level to the lower-level, if you wish to handle the constraints manually, pass apply_cstr_tosub_scenarios=False as an argument to create_scenario. Note that obj2 shall be added as an observable of scenario_doe, otherwise it cannot be used by the ParetoFront post-processing.

system_scenario.add_constraint("cstr3")
system_scenario.add_observable("obj2")
system_scenario.xdsmize()


Run the scenario

Finally, we run a full-factorial DOE using 100 samples and run the post-processing.

run_inputs = {"n_samples": 50, "algo": "fullfact"}
system_scenario.execute(run_inputs)
system_scenario.post_process(
    "ParetoFront", objectives=["obj1", "obj2"], save=False, show=True
)
Pareto front
    INFO - 01:01:53:
    INFO - 01:01:53: *** Start DOEScenario execution ***
    INFO - 01:01:53: DOEScenario
    INFO - 01:01:53:    Disciplines: MDOScenario
    INFO - 01:01:53:    MDO formulation: BiLevel
    INFO - 01:01:53: Optimization problem:
    INFO - 01:01:53:    minimize obj1(obj1_target)
    INFO - 01:01:53:    with respect to obj1_target
    INFO - 01:01:53:    subject to constraints:
    INFO - 01:01:53:       cstr3(obj1_target) == 0
    INFO - 01:01:53:    over the design space:
    INFO - 01:01:53:       +-------------+-------------+-------+-------------+-------+
    INFO - 01:01:53:       | Name        | Lower bound | Value | Upper bound | Type  |
    INFO - 01:01:53:       +-------------+-------------+-------+-------------+-------+
    INFO - 01:01:53:       | obj1_target |     0.1     |   1   |     100     | float |
    INFO - 01:01:53:       +-------------+-------------+-------+-------------+-------+
    INFO - 01:01:53: Solving optimization problem with algorithm fullfact:
    INFO - 01:01:53:      2%|▏         | 1/50 [00:00<00:06,  7.97 it/sec, obj=0.108]
    INFO - 01:01:53:      4%|▍         | 2/50 [00:00<00:04, 10.51 it/sec, obj=2.14]
    INFO - 01:01:53:      6%|▌         | 3/50 [00:00<00:03, 12.39 it/sec, obj=4.18]
    INFO - 01:01:53:      8%|▊         | 4/50 [00:00<00:03, 13.74 it/sec, obj=6.22]
    INFO - 01:01:53:     10%|█         | 5/50 [00:00<00:03, 14.70 it/sec, obj=8.26]
    INFO - 01:01:53:     12%|█▏        | 6/50 [00:00<00:02, 15.09 it/sec, obj=10.3]
    INFO - 01:01:53:     14%|█▍        | 7/50 [00:00<00:02, 15.26 it/sec, obj=12.3]
    INFO - 01:01:53:     16%|█▌        | 8/50 [00:00<00:02, 15.35 it/sec, obj=14.4]
    INFO - 01:01:53:     18%|█▊        | 9/50 [00:00<00:02, 15.49 it/sec, obj=16.4]
    INFO - 01:01:53:     20%|██        | 10/50 [00:00<00:02, 15.58 it/sec, obj=18.5]
    INFO - 01:01:53:     22%|██▏       | 11/50 [00:00<00:02, 15.90 it/sec, obj=20.5]
    INFO - 01:01:54:     24%|██▍       | 12/50 [00:00<00:02, 16.16 it/sec, obj=22.5]
    INFO - 01:01:54:     26%|██▌       | 13/50 [00:00<00:02, 16.41 it/sec, obj=24.6]
    INFO - 01:01:54:     28%|██▊       | 14/50 [00:00<00:02, 16.63 it/sec, obj=26.6]
    INFO - 01:01:54:     30%|███       | 15/50 [00:00<00:02, 16.70 it/sec, obj=28.6]
    INFO - 01:01:54:     32%|███▏      | 16/50 [00:00<00:02, 16.84 it/sec, obj=30.7]
    INFO - 01:01:54:     34%|███▍      | 17/50 [00:01<00:01, 16.96 it/sec, obj=32.7]
    INFO - 01:01:54:     36%|███▌      | 18/50 [00:01<00:01, 17.03 it/sec, obj=34.8]
    INFO - 01:01:54:     38%|███▊      | 19/50 [00:01<00:01, 17.14 it/sec, obj=36.8]
    INFO - 01:01:54:     40%|████      | 20/50 [00:01<00:01, 16.85 it/sec, obj=38.8]
    INFO - 01:01:54:     42%|████▏     | 21/50 [00:01<00:01, 16.90 it/sec, obj=40.9]
    INFO - 01:01:54:     44%|████▍     | 22/50 [00:01<00:01, 16.96 it/sec, obj=42.9]
    INFO - 01:01:54:     46%|████▌     | 23/50 [00:01<00:01, 16.86 it/sec, obj=45]
    INFO - 01:01:54:     48%|████▊     | 24/50 [00:01<00:01, 16.91 it/sec, obj=47]
    INFO - 01:01:54:     50%|█████     | 25/50 [00:01<00:01, 16.95 it/sec, obj=49]
    INFO - 01:01:54:     52%|█████▏    | 26/50 [00:01<00:01, 16.88 it/sec, obj=51.1]
    INFO - 01:01:54:     54%|█████▍    | 27/50 [00:01<00:01, 16.91 it/sec, obj=53.1]
    INFO - 01:01:54:     56%|█████▌    | 28/50 [00:01<00:01, 16.94 it/sec, obj=55.1]
    INFO - 01:01:54:     58%|█████▊    | 29/50 [00:01<00:01, 16.96 it/sec, obj=57.2]
    INFO - 01:01:55:     60%|██████    | 30/50 [00:01<00:01, 16.98 it/sec, obj=59.2]
    INFO - 01:01:55:     62%|██████▏   | 31/50 [00:01<00:01, 16.99 it/sec, obj=61.3]
    INFO - 01:01:55:     64%|██████▍   | 32/50 [00:01<00:01, 16.99 it/sec, obj=63.3]
   ERROR - 01:01:55: NLopt run failed: NLopt roundoff-limited, RoundoffLimited
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/gemseo/algos/opt/lib_nlopt.py", line 498, in _run
    nlopt_problem.optimize(x_0.real)
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/nlopt/nlopt.py", line 335, in optimize
    return _nlopt.opt_optimize(self, *args)
nlopt.RoundoffLimited: NLopt roundoff-limited
    INFO - 01:01:55:     66%|██████▌   | 33/50 [00:01<00:01, 17.00 it/sec, obj=65.3]
    INFO - 01:01:55:     68%|██████▊   | 34/50 [00:01<00:00, 17.00 it/sec, obj=67.4]
    INFO - 01:01:55:     70%|███████   | 35/50 [00:02<00:00, 17.00 it/sec, obj=69.4]
    INFO - 01:01:55:     72%|███████▏  | 36/50 [00:02<00:00, 17.04 it/sec, obj=71.5]
    INFO - 01:01:55:     74%|███████▍  | 37/50 [00:02<00:00, 17.15 it/sec, obj=73.5]
   ERROR - 01:01:55: NLopt run failed: NLopt roundoff-limited, RoundoffLimited
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/gemseo/algos/opt/lib_nlopt.py", line 498, in _run
    nlopt_problem.optimize(x_0.real)
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/nlopt/nlopt.py", line 335, in optimize
    return _nlopt.opt_optimize(self, *args)
nlopt.RoundoffLimited: NLopt roundoff-limited
    INFO - 01:01:55:     76%|███████▌  | 38/50 [00:02<00:00, 17.27 it/sec, obj=75.5]
    INFO - 01:01:55:     78%|███████▊  | 39/50 [00:02<00:00, 17.38 it/sec, obj=77.6]
   ERROR - 01:01:55: NLopt run failed: NLopt roundoff-limited, RoundoffLimited
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/gemseo/algos/opt/lib_nlopt.py", line 498, in _run
    nlopt_problem.optimize(x_0.real)
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/nlopt/nlopt.py", line 335, in optimize
    return _nlopt.opt_optimize(self, *args)
nlopt.RoundoffLimited: NLopt roundoff-limited
    INFO - 01:01:55:     80%|████████  | 40/50 [00:02<00:00, 17.52 it/sec, obj=79.6]
   ERROR - 01:01:55: NLopt run failed: NLopt roundoff-limited, RoundoffLimited
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/gemseo/algos/opt/lib_nlopt.py", line 498, in _run
    nlopt_problem.optimize(x_0.real)
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/nlopt/nlopt.py", line 335, in optimize
    return _nlopt.opt_optimize(self, *args)
nlopt.RoundoffLimited: NLopt roundoff-limited
    INFO - 01:01:55:     82%|████████▏ | 41/50 [00:02<00:00, 17.66 it/sec, obj=81.7]
   ERROR - 01:01:55: NLopt run failed: NLopt roundoff-limited, RoundoffLimited
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/gemseo/algos/opt/lib_nlopt.py", line 498, in _run
    nlopt_problem.optimize(x_0.real)
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/nlopt/nlopt.py", line 335, in optimize
    return _nlopt.opt_optimize(self, *args)
nlopt.RoundoffLimited: NLopt roundoff-limited
    INFO - 01:01:55:     84%|████████▍ | 42/50 [00:02<00:00, 17.80 it/sec, obj=83.7]
   ERROR - 01:01:55: NLopt run failed: NLopt roundoff-limited, RoundoffLimited
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/gemseo/algos/opt/lib_nlopt.py", line 498, in _run
    nlopt_problem.optimize(x_0.real)
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/nlopt/nlopt.py", line 335, in optimize
    return _nlopt.opt_optimize(self, *args)
nlopt.RoundoffLimited: NLopt roundoff-limited
    INFO - 01:01:55:     86%|████████▌ | 43/50 [00:02<00:00, 17.89 it/sec, obj=85.7]
   ERROR - 01:01:55: NLopt run failed: NLopt roundoff-limited, RoundoffLimited
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/gemseo/algos/opt/lib_nlopt.py", line 498, in _run
    nlopt_problem.optimize(x_0.real)
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/nlopt/nlopt.py", line 335, in optimize
    return _nlopt.opt_optimize(self, *args)
nlopt.RoundoffLimited: NLopt roundoff-limited
    INFO - 01:01:55:     88%|████████▊ | 44/50 [00:02<00:00, 18.02 it/sec, obj=87.8]
   ERROR - 01:01:55: NLopt run failed: NLopt roundoff-limited, RoundoffLimited
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/gemseo/algos/opt/lib_nlopt.py", line 498, in _run
    nlopt_problem.optimize(x_0.real)
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/nlopt/nlopt.py", line 335, in optimize
    return _nlopt.opt_optimize(self, *args)
nlopt.RoundoffLimited: NLopt roundoff-limited
    INFO - 01:01:55:     90%|█████████ | 45/50 [00:02<00:00, 18.15 it/sec, obj=89.8]
   ERROR - 01:01:55: NLopt run failed: NLopt roundoff-limited, RoundoffLimited
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/gemseo/algos/opt/lib_nlopt.py", line 498, in _run
    nlopt_problem.optimize(x_0.real)
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/nlopt/nlopt.py", line 335, in optimize
    return _nlopt.opt_optimize(self, *args)
nlopt.RoundoffLimited: NLopt roundoff-limited
    INFO - 01:01:55:     92%|█████████▏| 46/50 [00:02<00:00, 18.26 it/sec, obj=91.8]
    INFO - 01:01:55:     94%|█████████▍| 47/50 [00:02<00:00, 18.37 it/sec, obj=93.9]
   ERROR - 01:01:55: NLopt run failed: NLopt roundoff-limited, RoundoffLimited
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/gemseo/algos/opt/lib_nlopt.py", line 498, in _run
    nlopt_problem.optimize(x_0.real)
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/nlopt/nlopt.py", line 335, in optimize
    return _nlopt.opt_optimize(self, *args)
nlopt.RoundoffLimited: NLopt roundoff-limited
    INFO - 01:01:55:     96%|█████████▌| 48/50 [00:02<00:00, 18.47 it/sec, obj=95.9]
   ERROR - 01:01:55: NLopt run failed: NLopt roundoff-limited, RoundoffLimited
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/gemseo/algos/opt/lib_nlopt.py", line 498, in _run
    nlopt_problem.optimize(x_0.real)
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/nlopt/nlopt.py", line 335, in optimize
    return _nlopt.opt_optimize(self, *args)
nlopt.RoundoffLimited: NLopt roundoff-limited
    INFO - 01:01:55:     98%|█████████▊| 49/50 [00:02<00:00, 18.58 it/sec, obj=98]
   ERROR - 01:01:55: NLopt run failed: NLopt roundoff-limited, RoundoffLimited
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/gemseo/algos/opt/lib_nlopt.py", line 498, in _run
    nlopt_problem.optimize(x_0.real)
  File "/home/docs/checkouts/readthedocs.org/user_builds/gemseo/envs/develop/lib/python3.9/site-packages/nlopt/nlopt.py", line 335, in optimize
    return _nlopt.opt_optimize(self, *args)
nlopt.RoundoffLimited: NLopt roundoff-limited
    INFO - 01:01:55:    100%|██████████| 50/50 [00:02<00:00, 18.68 it/sec, obj=100]
    INFO - 01:01:55: Optimization result:
    INFO - 01:01:55:    Optimizer info:
    INFO - 01:01:55:       Status: None
    INFO - 01:01:55:       Message: None
    INFO - 01:01:55:       Number of calls to the objective function by the optimizer: 50
    INFO - 01:01:55:    Solution:
    INFO - 01:01:55:       The solution is feasible.
    INFO - 01:01:55:       Objective: 0.10832777706440924
    INFO - 01:01:55:       Standardized constraints:
    INFO - 01:01:55:          cstr3 = 0.008327777064409236
    INFO - 01:01:55:       Design space:
    INFO - 01:01:55:          +-------------+-------------+-------+-------------+-------+
    INFO - 01:01:55:          | Name        | Lower bound | Value | Upper bound | Type  |
    INFO - 01:01:55:          +-------------+-------------+-------+-------------+-------+
    INFO - 01:01:55:          | obj1_target |     0.1     |  0.1  |     100     | float |
    INFO - 01:01:55:          +-------------+-------------+-------+-------------+-------+
    INFO - 01:01:55: *** End DOEScenario execution (time: 0:00:02.688715) ***

<gemseo.post.pareto_front.ParetoFront object at 0x7f1191041910>

Total running time of the script: (0 minutes 2.949 seconds)

Gallery generated by Sphinx-Gallery