Source code for gemseo.formulations.bilevel_test_helper

# -*- coding: utf-8 -*-
# Copyright 2021 IRT Saint Exupéry, https://www.irt-saintexupery.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License version 3 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

"""Provide base test class stub for testing bilevel also for |g| plugins."""
from __future__ import division, unicode_literals

import unittest
from copy import deepcopy

from gemseo.core.mdo_scenario import MDOScenario
from gemseo.problems.sobieski.wrappers import (
    SobieskiAerodynamics,
    SobieskiMission,
    SobieskiProblem,
    SobieskiPropulsion,
    SobieskiStructure,
)


[docs]def build_system_scenario(disciplines, **options): """ :param disciplines: """ # Maximize range (Breguet) ds = SobieskiProblem().read_design_space() # Add a coupling to DV but bielevel filters it sc_system = MDOScenario( disciplines, formulation="BiLevel", objective_name="y_4", design_space=ds.filter(["x_shared", "y_14"]), maximize_objective=True, **options ) assert sc_system.formulation.opt_problem.design_space.variables_names == [ "x_shared" ] sc_system.set_differentiation_method("finite_differences", step=1e-6) return sc_system
[docs]class TestBilevelFormulationBase(unittest.TestCase): """Helper class for testing bilevel formulations."""
[docs] @classmethod def setUpClass(cls): cls.propulsion = SobieskiPropulsion() cls.aerodynamics = SobieskiAerodynamics() cls.struct = SobieskiStructure() cls.mission = SobieskiMission()
[docs] def build_scenarios(self): """""" ds = SobieskiProblem().read_design_space() sc_prop = MDOScenario( disciplines=[self.propulsion], formulation="DisciplinaryOpt", objective_name="y_34", design_space=deepcopy(ds).filter("x_3"), name="PropulsionScenario", ) # Maximize L/D sc_aero = MDOScenario( disciplines=[self.aerodynamics], formulation="DisciplinaryOpt", objective_name="y_24", design_space=deepcopy(ds).filter("x_2"), name="AerodynamicsScenario", maximize_objective=True, ) # Maximize log(aircraft total weight / (aircraft total weight - fuel # weight)) sc_str = MDOScenario( disciplines=[self.struct], formulation="DisciplinaryOpt", objective_name="y_11", design_space=deepcopy(ds).filter("x_1"), name="StructureScenario", maximize_objective=True, ) return sc_str, sc_aero, sc_prop
[docs] def build_bilevel(self, **options): """""" sub_scenarios = self.build_scenarios() sub_disciplines = list(sub_scenarios) + [self.mission] for sc in sub_scenarios: sc.default_inputs = {"max_iter": 5, "algo": "SLSQP"} system_scenario = build_system_scenario(sub_disciplines, **options) return system_scenario