MDF-based DOE on the Sobieski SSBJ test case

from os import name as os_name

from gemseo.api import configure_logger
from gemseo.api import create_discipline
from gemseo.api import create_scenario
from gemseo.problems.sobieski.core.problem import SobieskiProblem
from matplotlib import pyplot as plt

configure_logger()

Out:

<RootLogger root (INFO)>

Instantiate the disciplines

First, we instantiate the four disciplines of the use case: SobieskiPropulsion, SobieskiAerodynamics, SobieskiMission and SobieskiStructure.

disciplines = create_discipline(
    [
        "SobieskiPropulsion",
        "SobieskiAerodynamics",
        "SobieskiMission",
        "SobieskiStructure",
    ]
)

Build, execute and post-process the scenario

Then, we build the scenario which links the disciplines with the formulation and the optimization algorithm. Here, we use the BiLevel formulation. We tell the scenario to minimize -y_4 instead of minimizing y_4 (range), which is the default option.

We need to define the design space.

design_space = SobieskiProblem().design_space

Instantiate the scenario

scenario = create_scenario(
    disciplines,
    formulation="MDF",
    objective_name="y_4",
    design_space=design_space,
    maximize_objective=True,
    scenario_type="DOE",
)

Set the design constraints

for constraint in ["g_1", "g_2", "g_3"]:
    scenario.add_constraint(constraint, "ineq")

Execute the scenario

Use provided analytic derivatives

scenario.set_differentiation_method("user")

Multiprocessing

It is possible to run a DOE in parallel using multiprocessing, in order to do this, we specify the number of processes to be used for the computation of the samples.

#    The multiprocessing option has some limitations on Windows.
#    Due to problems with sphinx, we disable it in this example.
#    For Python versions < 3.7 and Numpy < 1.20.0, subprocesses may get hung
#    randomly during execution. It is strongly recommended to update your
#    environment to avoid this problem.
#    The features :class:`.MemoryFullCache` and :class:`.HDF5Cache` are not
#    available for multiprocessing on Windows.
#    As an alternative, we recommend the method
#    :meth:`.DOEScenario.set_optimization_history_backup`.

We define the algorithm options. Here the criterion = center option of pyDOE centers the points within the sampling intervals.

algo_options = {
    "criterion": "center",
    # Evaluate gradient of the MDA
    # with coupled adjoint
    "eval_jac": True,
    # Run in parallel on 1 or 4 processors
    "n_processes": 1 if os_name == "nt" else 4,
}

scenario.execute({"n_samples": 30, "algo": "lhs", "algo_options": algo_options})

Out:

    INFO - 10:05:43:
    INFO - 10:05:43: *** Start DOEScenario execution ***
    INFO - 10:05:43: DOEScenario
    INFO - 10:05:43:    Disciplines: SobieskiPropulsion SobieskiAerodynamics SobieskiMission SobieskiStructure
    INFO - 10:05:43:    MDO formulation: MDF
    INFO - 10:05:43: Optimization problem:
    INFO - 10:05:43:    minimize -y_4(x_shared, x_1, x_2, x_3)
    INFO - 10:05:43:    with respect to x_1, x_2, x_3, x_shared
    INFO - 10:05:43:    subject to constraints:
    INFO - 10:05:43:       g_1(x_shared, x_1, x_2, x_3) <= 0.0
    INFO - 10:05:43:       g_2(x_shared, x_1, x_2, x_3) <= 0.0
    INFO - 10:05:43:       g_3(x_shared, x_1, x_2, x_3) <= 0.0
    INFO - 10:05:43:    over the design space:
    INFO - 10:05:43:    +----------+-------------+-------+-------------+-------+
    INFO - 10:05:43:    | name     | lower_bound | value | upper_bound | type  |
    INFO - 10:05:43:    +----------+-------------+-------+-------------+-------+
    INFO - 10:05:43:    | x_shared |     0.01    |  0.05 |     0.09    | float |
    INFO - 10:05:43:    | x_shared |    30000    | 45000 |    60000    | float |
    INFO - 10:05:43:    | x_shared |     1.4     |  1.6  |     1.8     | float |
    INFO - 10:05:43:    | x_shared |     2.5     |  5.5  |     8.5     | float |
    INFO - 10:05:43:    | x_shared |      40     |   55  |      70     | float |
    INFO - 10:05:43:    | x_shared |     500     |  1000 |     1500    | float |
    INFO - 10:05:43:    | x_1      |     0.1     |  0.25 |     0.4     | float |
    INFO - 10:05:43:    | x_1      |     0.75    |   1   |     1.25    | float |
    INFO - 10:05:43:    | x_2      |     0.75    |   1   |     1.25    | float |
    INFO - 10:05:43:    | x_3      |     0.1     |  0.5  |      1      | float |
    INFO - 10:05:43:    +----------+-------------+-------+-------------+-------+
    INFO - 10:05:43: Solving optimization problem with algorithm lhs:
    INFO - 10:05:43: ...   0%|          | 0/30 [00:00<?, ?it]
    INFO - 10:05:43: Running DOE in parallel on n_processes = 4
    INFO - 10:05:44: ...   3%|▎         | 1/30 [00:00<00:00, 47.77 it/sec, obj=-285]
    INFO - 10:05:44: ...  10%|█         | 3/30 [00:00<00:00, 36.33 it/sec, obj=-567]
    INFO - 10:05:44: ...  13%|█▎        | 4/30 [00:00<00:00, 31.12 it/sec, obj=-344]
    INFO - 10:05:44: ...  20%|██        | 6/30 [00:01<00:00, 26.11 it/sec, obj=-429]
    INFO - 10:05:44: ...  23%|██▎       | 7/30 [00:01<00:00, 23.09 it/sec, obj=-481]
    INFO - 10:05:44: ...  27%|██▋       | 8/30 [00:01<00:01, 21.37 it/sec, obj=-519]
    INFO - 10:05:44: ...  30%|███       | 9/30 [00:01<00:01, 19.81 it/sec, obj=-538]
    INFO - 10:05:45: ...  33%|███▎      | 10/30 [00:01<00:01, 18.27 it/sec, obj=-419]
    INFO - 10:05:45: ...  37%|███▋      | 11/30 [00:01<00:01, 17.16 it/sec, obj=-306]
    INFO - 10:05:45: ...  40%|████      | 12/30 [00:01<00:01, 16.01 it/sec, obj=-495]
    INFO - 10:05:45: ...  47%|████▋     | 14/30 [00:02<00:01, 14.11 it/sec, obj=-621]
    INFO - 10:05:45: ...  53%|█████▎    | 16/30 [00:02<00:01, 12.76 it/sec, obj=-1.07e+3]
    INFO - 10:05:46: ...  63%|██████▎   | 19/30 [00:02<00:00, 11.17 it/sec, obj=-287]
    INFO - 10:05:46: ...  70%|███████   | 21/30 [00:02<00:00, 10.69 it/sec, obj=-247]
    INFO - 10:05:46: ...  77%|███████▋  | 23/30 [00:03<00:00,  9.51 it/sec, obj=-1.18e+3]
    INFO - 10:05:46: ...  87%|████████▋ | 26/30 [00:03<00:00,  8.82 it/sec, obj=-383]
    INFO - 10:05:47: ...  93%|█████████▎| 28/30 [00:03<00:00,  8.18 it/sec, obj=-351]
    INFO - 10:05:47: ... 100%|██████████| 30/30 [00:03<00:00,  7.94 it/sec, obj=-485]
    INFO - 10:05:47: Optimization result:
    INFO - 10:05:47:    Optimizer info:
    INFO - 10:05:47:       Status: None
    INFO - 10:05:47:       Message: None
    INFO - 10:05:47:       Number of calls to the objective function by the optimizer: 30
    INFO - 10:05:47:    Solution:
    INFO - 10:05:47:       The solution is feasible.
    INFO - 10:05:47:       Objective: -485.49229968733584
    INFO - 10:05:47:       Standardized constraints:
    INFO - 10:05:47:          g_1 = [-0.11350951 -0.10812292 -0.1045109  -0.10204971 -0.10028641 -0.01838903
    INFO - 10:05:47:  -0.22161097]
    INFO - 10:05:47:          g_2 = -0.02400000000000002
    INFO - 10:05:47:          g_3 = [-0.33063134 -0.66936866 -0.73821755 -0.07789536]
    INFO - 10:05:47:       Design space:
    INFO - 10:05:47:       +----------+-------------+---------------------+-------------+-------+
    INFO - 10:05:47:       | name     | lower_bound |        value        | upper_bound | type  |
    INFO - 10:05:47:       +----------+-------------+---------------------+-------------+-------+
    INFO - 10:05:47:       | x_shared |     0.01    | 0.05400000000000001 |     0.09    | float |
    INFO - 10:05:47:       | x_shared |    30000    |        46500        |    60000    | float |
    INFO - 10:05:47:       | x_shared |     1.4     |  1.686666666666667  |     1.8     | float |
    INFO - 10:05:47:       | x_shared |     2.5     |         5.2         |     8.5     | float |
    INFO - 10:05:47:       | x_shared |      40     |         66.5        |      70     | float |
    INFO - 10:05:47:       | x_shared |     500     |  583.3333333333334  |     1500    | float |
    INFO - 10:05:47:       | x_1      |     0.1     |        0.185        |     0.4     | float |
    INFO - 10:05:47:       | x_1      |     0.75    |  0.9416666666666667 |     1.25    | float |
    INFO - 10:05:47:       | x_2      |     0.75    |        0.775        |     1.25    | float |
    INFO - 10:05:47:       | x_3      |     0.1     |        0.115        |      1      | float |
    INFO - 10:05:47:       +----------+-------------+---------------------+-------------+-------+
    INFO - 10:05:47: *** End DOEScenario execution (time: 0:00:03.795060) ***

{'eval_jac': False, 'algo': 'lhs', 'algo_options': {'criterion': 'center', 'eval_jac': True, 'n_processes': 4, 'seed': 1, 'n_samples': 30}, 'n_samples': 30}

Warning

On Windows, the progress bar may show duplicated instances during the initialization of each subprocess. In some cases it may also print the conclusion of an iteration ahead of another one that was concluded first. This is a consequence of the pickling process and does not affect the computations of the scenario.

Plot the optimization history view

scenario.post_process("OptHistoryView", show=False, save=False)
  • Evolution of the optimization variables
  • Evolution of the objective value
  • Distance to the optimum
  • Hessian diagonal approximation
  • Evolution of the inequality constraints

Out:

<gemseo.post.opt_history_view.OptHistoryView object at 0x7fdbe198f8b0>

Tip

Each post-processing method requires different inputs and offers a variety of customization options. Use the API function get_post_processing_options_schema() to print a table with the attributes for any post-processing algo. Or refer to our dedicated page: Post-processing algorithms.

Plot the scatter matrix

scenario.post_process(
    "ScatterPlotMatrix", show=False, save=False, variable_names=["y_4", "x_shared"]
)
plot doe sobieski mdf example

Out:

<gemseo.post.scatter_mat.ScatterPlotMatrix object at 0x7fdbe0b4dc10>

Plot correlations

scenario.post_process("Correlations", show=False, save=False)
# Workaround for HTML rendering, instead of ``show=True``
plt.show()
R=0.98987, R=0.97511, R=0.99671, R=0.96235, R=0.99119, R=0.99866, R=0.95205, R=0.98584, R=0.99618, R=0.99936

Out:

INFO - 10:05:50: Detected 10 correlations > 0.95

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

Gallery generated by Sphinx-Gallery