Gradient Sensitivity#

In this example, we illustrate the use of the GradientSensitivity post-processing on the Sobieski's SSBJ problem.

The GradientSensitivity post-processor plots histograms of the objective and the constraints derivatives.

By default, the sensitivities are calculated either at the optimum, or when the result is not feasible, at the least-non feasible point. The iteration where the sensitivities are computed can be modified via the iteration setting.

Note

In some cases, the iteration used to compute the sensitivities corresponds to a point for which the algorithm did not request the evaluation of the gradients. In this case, a ValueError is raised by GradientSensitivity. To overcome this issue, one can set the compute_missing_gradients setting to True. This way, GEMSEO will compute the gradients for the iterations where it is lacking. This can be done only if the underlying disciplines are available, explaing why why, unlike the other post-processing examples, we need to post-process directly from the MDO scenario.

Warning

Please note that this extra computation may be expensive depending on the OptimizationProblem defined by the user. Additionally, keep in mind that GEMSEO cannot compute missing gradients for an OptimizationProblem that was imported from an HDF5 file.

MDO scenario#

Let us first create and execute the MDF scenario on the Sobieski's SSBJ problem.

from __future__ import annotations

from gemseo import create_discipline
from gemseo import create_scenario
from gemseo.formulations.mdf_settings import MDF_Settings
from gemseo.problems.mdo.sobieski.core.design_space import SobieskiDesignSpace
from gemseo.settings.mda import MDAGaussSeidel_Settings
from gemseo.settings.opt import SLSQP_Settings
from gemseo.settings.post import GradientSensitivity_Settings

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

formulation_settings = MDF_Settings(
    main_mda_settings=MDAGaussSeidel_Settings(
        max_mda_iter=30,
        tolerance=1e-10,
        warm_start=True,
        use_lu_fact=True,
    ),
)

scenario = create_scenario(
    disciplines,
    "y_4",
    design_space=SobieskiDesignSpace(),
    maximize_objective=True,
    formulation_settings_model=formulation_settings,
)

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

scenario.execute(SLSQP_Settings(max_iter=20))
   INFO - 16:25:45: *** Start MDOScenario execution ***
   INFO - 16:25:45: MDOScenario
   INFO - 16:25:45:    Disciplines: SobieskiAerodynamics SobieskiMission SobieskiPropulsion SobieskiStructure
   INFO - 16:25:45:    MDO formulation: MDF
   INFO - 16:25:45: Optimization problem:
   INFO - 16:25:45:    minimize -y_4(x_shared, x_1, x_2, x_3)
   INFO - 16:25:45:    with respect to x_1, x_2, x_3, x_shared
   INFO - 16:25:45:    under the inequality constraints
   INFO - 16:25:45:       g_1(x_shared, x_1, x_2, x_3) <= 0
   INFO - 16:25:45:       g_2(x_shared, x_1, x_2, x_3) <= 0
   INFO - 16:25:45:       g_3(x_shared, x_1, x_2, x_3) <= 0
   INFO - 16:25:45:    over the design space:
   INFO - 16:25:45:       +-------------+-------------+-------+-------------+-------+
   INFO - 16:25:45:       | Name        | Lower bound | Value | Upper bound | Type  |
   INFO - 16:25:45:       +-------------+-------------+-------+-------------+-------+
   INFO - 16:25:45:       | x_shared[0] |     0.01    |  0.05 |     0.09    | float |
   INFO - 16:25:45:       | x_shared[1] |    30000    | 45000 |    60000    | float |
   INFO - 16:25:45:       | x_shared[2] |     1.4     |  1.6  |     1.8     | float |
   INFO - 16:25:45:       | x_shared[3] |     2.5     |  5.5  |     8.5     | float |
   INFO - 16:25:45:       | x_shared[4] |      40     |   55  |      70     | float |
   INFO - 16:25:45:       | x_shared[5] |     500     |  1000 |     1500    | float |
   INFO - 16:25:45:       | x_1[0]      |     0.1     |  0.25 |     0.4     | float |
   INFO - 16:25:45:       | x_1[1]      |     0.75    |   1   |     1.25    | float |
   INFO - 16:25:45:       | x_2         |     0.75    |   1   |     1.25    | float |
   INFO - 16:25:45:       | x_3         |     0.1     |  0.5  |      1      | float |
   INFO - 16:25:45:       +-------------+-------------+-------+-------------+-------+
   INFO - 16:25:45: Solving optimization problem with algorithm SLSQP:
   INFO - 16:25:45:      5%|▌         | 1/20 [00:00<00:00, 27.93 it/sec, feas=False, obj=-536]
   INFO - 16:25:45:     10%|█         | 2/20 [00:00<00:00, 31.92 it/sec, feas=False, obj=-2.12e+3]
   INFO - 16:25:45:     15%|█▌        | 3/20 [00:00<00:00, 35.14 it/sec, feas=False, obj=-2.99e+3]
WARNING - 16:25:45: MDAGaussSeidel has reached its maximum number of unsuccessful iterations, but the normalized residual norm 1.8740837693229298e-10 is still above the tolerance 1e-10.
   INFO - 16:25:45:     20%|██        | 4/20 [00:00<00:00, 35.41 it/sec, feas=True, obj=-3.96e+3]
   INFO - 16:25:45:     25%|██▌       | 5/20 [00:00<00:00, 36.90 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     30%|███       | 6/20 [00:00<00:00, 41.26 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     35%|███▌      | 7/20 [00:00<00:00, 45.13 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     40%|████      | 8/20 [00:00<00:00, 48.51 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     45%|████▌     | 9/20 [00:00<00:00, 51.74 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     50%|█████     | 10/20 [00:00<00:00, 54.67 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     55%|█████▌    | 11/20 [00:00<00:00, 57.37 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     60%|██████    | 12/20 [00:00<00:00, 59.85 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     65%|██████▌   | 13/20 [00:00<00:00, 61.73 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     70%|███████   | 14/20 [00:00<00:00, 63.96 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     75%|███████▌  | 15/20 [00:00<00:00, 66.09 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     80%|████████  | 16/20 [00:00<00:00, 64.78 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     85%|████████▌ | 17/20 [00:00<00:00, 65.95 it/sec, feas=False, obj=-3.96e+3]
WARNING - 16:25:45: MDAGaussSeidel has reached its maximum number of unsuccessful iterations, but the normalized residual norm 1.8740837693229298e-10 is still above the tolerance 1e-10.
   INFO - 16:25:45:     90%|█████████ | 18/20 [00:00<00:00, 66.15 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:     95%|█████████▌| 19/20 [00:00<00:00, 67.53 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45:    100%|██████████| 20/20 [00:00<00:00, 68.78 it/sec, feas=False, obj=-3.96e+3]
   INFO - 16:25:45: Optimization result:
   INFO - 16:25:45:    Optimizer info:
   INFO - 16:25:45:       Status: None
   INFO - 16:25:45:       Message: Maximum number of iterations reached. GEMSEO stopped the driver.
   INFO - 16:25:45:    Solution:
   INFO - 16:25:45:       The solution is feasible.
   INFO - 16:25:45:       Objective: -3956.7671439951155
   INFO - 16:25:45:       Standardized constraints:
   INFO - 16:25:45:          g_1 = [-0.0180475  -0.03333656 -0.04424176 -0.05182829 -0.05732073 -0.13720996
   INFO - 16:25:45:  -0.10279004]
   INFO - 16:25:45:          g_2 = -8.478422282021114e-07
   INFO - 16:25:45:          g_3 = [-0.75907665 -0.24092335 -0.01093685 -0.18325485]
   INFO - 16:25:45:       Design space:
   INFO - 16:25:45:          +-------------+-------------+---------------------+-------------+-------+
   INFO - 16:25:45:          | Name        | Lower bound |        Value        | Upper bound | Type  |
   INFO - 16:25:45:          +-------------+-------------+---------------------+-------------+-------+
   INFO - 16:25:45:          | x_shared[0] |     0.01    | 0.05999978803944293 |     0.09    | float |
   INFO - 16:25:45:          | x_shared[1] |    30000    |  59999.71999207715  |    60000    | float |
   INFO - 16:25:45:          | x_shared[2] |     1.4     |  1.400001146339582  |     1.8     | float |
   INFO - 16:25:45:          | x_shared[3] |     2.5     |  2.500027391560848  |     8.5     | float |
   INFO - 16:25:45:          | x_shared[4] |      40     |  69.99990541861061  |      70     | float |
   INFO - 16:25:45:          | x_shared[5] |     500     |  1499.998408125633  |     1500    | float |
   INFO - 16:25:45:          | x_1[0]      |     0.1     |  0.3999999992897073 |     0.4     | float |
   INFO - 16:25:45:          | x_1[1]      |     0.75    |  0.7500006109067197 |     1.25    | float |
   INFO - 16:25:45:          | x_2         |     0.75    |  0.7500001682365631 |     1.25    | float |
   INFO - 16:25:45:          | x_3         |     0.1     |  0.1545377155108628 |      1      | float |
   INFO - 16:25:45:          +-------------+-------------+---------------------+-------------+-------+
   INFO - 16:25:45: *** End MDOScenario execution (time: 0:00:00.294847) ***

Post-processing#

Let us now post-process the scenario by means of the GradientSensitivity.

scenario.post_process(
    settings_model=GradientSensitivity_Settings(
        compute_missing_gradients=True,
        save=False,
        show=True,
    ),
)
Derivatives of objective and constraints with respect to design variables, -y_4, g_1[0], g_1[1], g_1[2], g_1[3], g_1[4], g_1[5], g_1[6], g_2, g_3[0], g_3[1], g_3[2], g_3[3]
 WARNING - 16:25:45: MDAGaussSeidel has reached its maximum number of unsuccessful iterations, but the normalized residual norm 1.8740837693229298e-10 is still above the tolerance 1e-10.

<gemseo.post.gradient_sensitivity.GradientSensitivity object at 0x72a4f310e6c0>

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

Gallery generated by Sphinx-Gallery