.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/exterior_penalty/exterior_penalty_sobieski.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_exterior_penalty_exterior_penalty_sobieski.py: Example for exterior penalty applied to the Sobieski test case. =============================================================== .. GENERATED FROM PYTHON SOURCE LINES 21-53 This section describes how to set up and solve the MDO problem relative to the :ref:`Sobieski test case ` with |g| applying external penalty. .. seealso:: To start with a simpler MDO problem, and for a detailed description of how to plug a test case into |g|, see :ref:`sellar_mdo`. .. _sobieski_use_case: Solving with an :ref:`MDF formulation ` -------------------------------------------------------- In this example, we solve the range optimization using the following :ref:`MDF formulation `: - The :ref:`MDF formulation ` couples all the disciplines during the :ref:`mda` at each optimization iteration. - All the :term:`design variables` are equally treated, concatenated in a single vector and given to a single :term:`optimization algorithm` as the unknowns of the problem. - There is no specific :term:`constraint` due to the :ref:`MDF formulation `. - Only the design :term:`constraints` :math:`g\_1`, :math:`g\_2` and :math:`g\_3` are added to the problem. - The :term:`objective function` is the range (the :math:`y\_4` variable in the model), computed after the :ref:`mda`. Imports ------- All the imports needed for the tutorials are performed here. .. GENERATED FROM PYTHON SOURCE LINES 53-65 .. code-block:: default from __future__ import annotations from gemseo.api import configure_logger from gemseo.api import create_discipline from gemseo.api import create_scenario from gemseo.api import get_available_formulations from gemseo.disciplines.utils import get_all_inputs from gemseo.disciplines.utils import get_all_outputs from gemseo.problems.sobieski.core.problem import SobieskiProblem configure_logger() .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 66-72 Step 1: Creation of :class:`.MDODiscipline` ------------------------------------------- To build the scenario, we first instantiate the disciplines. Here, the disciplines themselves have already been developed and interfaced with |g| (see :ref:`benchmark_problems`). .. GENERATED FROM PYTHON SOURCE LINES 72-82 .. code-block:: default disciplines = create_discipline( [ "SobieskiPropulsion", "SobieskiAerodynamics", "SobieskiMission", "SobieskiStructure", ] ) .. GENERATED FROM PYTHON SOURCE LINES 83-90 .. tip:: For the disciplines that are not interfaced with |g|, the |g|'s :mod:`~gemseo.api` eases the creation of disciplines without having to import them. See :ref:`api`. .. GENERATED FROM PYTHON SOURCE LINES 92-108 Step 2: Creation of :class:`.Scenario` -------------------------------------- The scenario delegates the creation of the optimization problem to the :ref:`MDO formulation `. Therefore, it needs the list of :code:`disciplines`, the names of the formulation, the name of the objective function and the design space. - The :code:`design_space` (shown below for reference) defines the unknowns of the optimization problem, and their bounds. It contains all the design variables needed by the :ref:`MDF formulation `. It can be imported from a text file, or created from scratch with the methods :meth:`~gemseo.api.create_design_space` and :meth:`~gemseo.algos.design_space.DesignSpace.add_variable`. In this case, we will retrieve it from the ``SobieskiProblem`` already defined in |g|. .. GENERATED FROM PYTHON SOURCE LINES 108-110 .. code-block:: default design_space = SobieskiProblem().design_space x_0 = design_space.get_current_value(as_dict=True) .. GENERATED FROM PYTHON SOURCE LINES 111-143 .. code:: name lower_bound value upper_bound type x_shared 0.01 0.05 0.09 float x_shared 30000.0 45000.0 60000.0 float x_shared 1.4 1.6 1.8 float x_shared 2.5 5.5 8.5 float x_shared 40.0 55.0 70.0 float x_shared 500.0 1000.0 1500.0 float x_1 0.1 0.25 0.4 float x_1 0.75 1.0 1.25 float x_2 0.75 1.0 1.25 float x_3 0.1 0.5 1.0 float y_14 24850.0 50606.9741711 77100.0 float y_14 -7700.0 7306.20262124 45000.0 float y_32 0.235 0.50279625 0.795 float y_31 2960.0 6354.32430691 10185.0 float y_24 0.44 4.15006276 11.13 float y_34 0.44 1.10754577 1.98 float y_23 3365.0 12194.2671934 26400.0 float y_21 24850.0 50606.9741711 77250.0 float y_12 24850.0 50606.9742 77250.0 float y_12 0.45 0.95 1.5 float - The available :ref:`MDO formulations ` are located in the **gemseo.formulations** package, see :ref:`extending-gemseo` for extending GEMSEO with other formulations. - The :code:`formulation` classname (here, :code:`"MDF"`) shall be passed to the scenario to select them. - The list of available formulations can be obtained by using :meth:`~gemseo.api.get_available_formulations`. .. GENERATED FROM PYTHON SOURCE LINES 143-144 .. code-block:: default get_available_formulations() .. rst-class:: sphx-glr-script-out .. code-block:: none ['BiLevel', 'DisciplinaryOpt', 'IDF', 'MDF'] .. GENERATED FROM PYTHON SOURCE LINES 145-149 - :math:`y\_4` corresponds to the :code:`objective_name`. This name must be one of the disciplines outputs, here the ``SobieskiMission`` discipline. The list of all outputs of the disciplines can be obtained by using :meth:`~gemseo.disciplines.utils.get_all_outputs`: .. GENERATED FROM PYTHON SOURCE LINES 149-151 .. code-block:: default get_all_outputs(disciplines) get_all_inputs(disciplines) .. rst-class:: sphx-glr-script-out .. code-block:: none ['y_23', 'x_3', 'c_3', 'y_14', 'y_34', 'c_1', 'c_2', 'c_0', 'y_31', 'y_24', 'c_4', 'x_2', 'y_12', 'x_shared', 'y_21', 'x_1', 'y_32'] .. GENERATED FROM PYTHON SOURCE LINES 152-155 From these :class:`~gemseo.core.discipline.MDODiscipline`, design space, :ref:`MDO formulation ` name and objective function name, we build the scenario: .. GENERATED FROM PYTHON SOURCE LINES 155-162 .. code-block:: default scenario = create_scenario( disciplines, formulation="MDF", maximize_objective=True, objective_name="y_4", design_space=design_space, ) .. GENERATED FROM PYTHON SOURCE LINES 163-177 The range function (:math:`y\_4`) should be maximized. However, optimizers minimize functions by default. Which is why, when creating the scenario, the argument :code:`maximize_objective` shall be set to :code:`True`. Differentiation method ~~~~~~~~~~~~~~~~~~~~~~ We may choose the way derivatives are computed: **Function derivatives.** As analytical disciplinary derivatives are available for the Sobieski test-case, they can be used instead of computing the derivatives with finite-differences or with the complex-step method. The easiest way to set a method is to let the optimizer determine it: .. GENERATED FROM PYTHON SOURCE LINES 177-178 .. code-block:: default scenario.set_differentiation_method() .. GENERATED FROM PYTHON SOURCE LINES 179-204 The default behavior of the optimizer triggers :term:`finite differences`. It corresponds to: .. code:: scenario.set_differentiation_method("finite_differences",1e-7) It it also possible to differentiate functions by means of the :term:`complex step` method: .. code:: scenario.set_differentiation_method("complex_step",1e-30j) Constraints ~~~~~~~~~~~ Similarly to the objective function, the constraints names are a subset of the disciplines' outputs. They can be obtained by using :meth:`~gemseo.disciplines.utils.get_all_outputs`. The formulation has a powerful feature to automatically dispatch the constraints (:math:`g\_1, g\_2, g\_3`) and plug them to the optimizers depending on the formulation. To do that, we use the method :meth:`~gemseo.core.scenario.Scenario.add_constraint`: .. GENERATED FROM PYTHON SOURCE LINES 205-207 .. code-block:: default for constraint in ["g_1", "g_2", "g_3"]: scenario.add_constraint(constraint, "ineq") .. GENERATED FROM PYTHON SOURCE LINES 208-210 Step 3: Apply the exterior penalty and execute the scenario ----------------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 210-213 .. code-block:: default scenario.formulation.opt_problem.apply_exterior_penalty( objective_scale=10.0, scale_inequality=10.0 ) .. GENERATED FROM PYTHON SOURCE LINES 214-216 In this way the L-BFGS-B algorithm can be used to solve the optimization problem. Note that this algorithm is not suited for constrained optimization problems. .. GENERATED FROM PYTHON SOURCE LINES 216-218 .. code-block:: default algo_args = {"max_iter": 10, "algo": "L-BFGS-B"} scenario.execute(algo_args) .. rst-class:: sphx-glr-script-out .. code-block:: none INFO - 16:59:55: INFO - 16:59:55: *** Start MDOScenario execution *** INFO - 16:59:55: MDOScenario INFO - 16:59:55: Disciplines: SobieskiAerodynamics SobieskiMission SobieskiPropulsion SobieskiStructure INFO - 16:59:55: MDO formulation: MDF INFO - 16:59:55: Optimization problem: INFO - 16:59:55: minimize -y_4/10.0+pos_sum_g_1+pos_sum_g_2+pos_sum_g_3(x_1, x_2, x_3, x_shared) = -y_4(x_shared, x_1, x_2, x_3)/10.0+sum(heaviside()***2)+sum(heaviside()***2)+sum(heaviside()***2) INFO - 16:59:55: with respect to x_1, x_2, x_3, x_shared INFO - 16:59:55: over the design space: INFO - 16:59:55: +-------------+-------------+-------+-------------+-------+ INFO - 16:59:55: | name | lower_bound | value | upper_bound | type | INFO - 16:59:55: +-------------+-------------+-------+-------------+-------+ INFO - 16:59:55: | x_shared[0] | 0.01 | 0.05 | 0.09 | float | INFO - 16:59:55: | x_shared[1] | 30000 | 45000 | 60000 | float | INFO - 16:59:55: | x_shared[2] | 1.4 | 1.6 | 1.8 | float | INFO - 16:59:55: | x_shared[3] | 2.5 | 5.5 | 8.5 | float | INFO - 16:59:55: | x_shared[4] | 40 | 55 | 70 | float | INFO - 16:59:55: | x_shared[5] | 500 | 1000 | 1500 | float | INFO - 16:59:55: | x_1[0] | 0.1 | 0.25 | 0.4 | float | INFO - 16:59:55: | x_1[1] | 0.75 | 1 | 1.25 | float | INFO - 16:59:55: | x_2 | 0.75 | 1 | 1.25 | float | INFO - 16:59:55: | x_3 | 0.1 | 0.5 | 1 | float | INFO - 16:59:55: +-------------+-------------+-------+-------------+-------+ INFO - 16:59:55: Solving optimization problem with algorithm L-BFGS-B: INFO - 16:59:55: ... 0%| | 0/10 [00:00 .. GENERATED FROM PYTHON SOURCE LINES 227-232 This solution is almost feasible. The solution can better approximate the original problem solution increasing the value of `objective_scale` and `scale_inequality` parameters. Step 4: Rerun the scenario with increased penalty and objective scaling. ------------------------------------------------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 232-252 .. code-block:: default design_space.set_current_value(x_0) scenario_2 = create_scenario( disciplines, formulation="MDF", maximize_objective=True, objective_name="y_4", design_space=design_space, ) for constraint in ["g_1", "g_2", "g_3"]: scenario_2.add_constraint(constraint, "ineq") scenario_2.set_differentiation_method() scenario_2.formulation.opt_problem.apply_exterior_penalty( objective_scale=1000.0, scale_inequality=1000.0 ) algo_args_2 = {"max_iter": 1000, "algo": "L-BFGS-B"} scenario_2.execute(algo_args_2) scenario_2.post_process("BasicHistory", variable_names=["-y_4"], save=False, show=True) scenario_2.post_process( "BasicHistory", variable_names=["g_1", "g_2", "g_3"], save=False, show=True ) .. rst-class:: sphx-glr-horizontal * .. image-sg:: /examples/exterior_penalty/images/sphx_glr_exterior_penalty_sobieski_002.png :alt: History plot :srcset: /examples/exterior_penalty/images/sphx_glr_exterior_penalty_sobieski_002.png :class: sphx-glr-multi-img * .. image-sg:: /examples/exterior_penalty/images/sphx_glr_exterior_penalty_sobieski_003.png :alt: History plot :srcset: /examples/exterior_penalty/images/sphx_glr_exterior_penalty_sobieski_003.png :class: sphx-glr-multi-img .. rst-class:: sphx-glr-script-out .. code-block:: none INFO - 16:59:57: INFO - 16:59:57: *** Start MDOScenario execution *** INFO - 16:59:57: MDOScenario INFO - 16:59:57: Disciplines: SobieskiAerodynamics SobieskiMission SobieskiPropulsion SobieskiStructure INFO - 16:59:57: MDO formulation: MDF INFO - 16:59:57: Optimization problem: INFO - 16:59:57: minimize -y_4/1000.0+pos_sum_g_1+pos_sum_g_2+pos_sum_g_3(x_1, x_2, x_3, x_shared) = -y_4(x_shared, x_1, x_2, x_3)/1000.0+sum(heaviside()***2)+sum(heaviside()***2)+sum(heaviside()***2) INFO - 16:59:57: with respect to x_1, x_2, x_3, x_shared INFO - 16:59:57: over the design space: INFO - 16:59:57: +-------------+-------------+-------+-------------+-------+ INFO - 16:59:57: | name | lower_bound | value | upper_bound | type | INFO - 16:59:57: +-------------+-------------+-------+-------------+-------+ INFO - 16:59:57: | x_shared[0] | 0.01 | 0.05 | 0.09 | float | INFO - 16:59:57: | x_shared[1] | 30000 | 45000 | 60000 | float | INFO - 16:59:57: | x_shared[2] | 1.4 | 1.6 | 1.8 | float | INFO - 16:59:57: | x_shared[3] | 2.5 | 5.5 | 8.5 | float | INFO - 16:59:57: | x_shared[4] | 40 | 55 | 70 | float | INFO - 16:59:57: | x_shared[5] | 500 | 1000 | 1500 | float | INFO - 16:59:57: | x_1[0] | 0.1 | 0.25 | 0.4 | float | INFO - 16:59:57: | x_1[1] | 0.75 | 1 | 1.25 | float | INFO - 16:59:57: | x_2 | 0.75 | 1 | 1.25 | float | INFO - 16:59:57: | x_3 | 0.1 | 0.5 | 1 | float | INFO - 16:59:57: +-------------+-------------+-------+-------------+-------+ INFO - 16:59:57: Solving optimization problem with algorithm L-BFGS-B: INFO - 16:59:57: ... 0%| | 0/1000 [00:00 .. GENERATED FROM PYTHON SOURCE LINES 253-255 The solution feasibility was improved but this comes with a much higher number of iterations. .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 15.903 seconds) .. _sphx_glr_download_examples_exterior_penalty_exterior_penalty_sobieski.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: exterior_penalty_sobieski.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: exterior_penalty_sobieski.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_