# 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()

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")


## 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()
"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.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
)

    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