Note
Click here to download the full example code
Scalable problem¶
We want to solve the Aerostructure MDO problem
by means of the MDF
formulation
with a higher dimension for the sweep parameter.
For that, we use the ScalableProblem
class.
from __future__ import division, unicode_literals
from gemseo.api import configure_logger, create_discipline, create_scenario
from gemseo.problems.aerostructure.aerostructure_design_space import (
AerostructureDesignSpace,
)
from gemseo.problems.scalable.data_driven.problem import ScalableProblem
configure_logger()
Out:
<RootLogger root (INFO)>
Define the design problem¶
In a first step, we define the design problem in terms of objective function (to maximize or minimize), design variables (local and global) and constraints (equality and inequality).
design_variables = ["thick_airfoils", "thick_panels", "sweep"]
objective_function = "range"
eq_constraints = ["c_rf"]
ineq_constraints = ["c_lift"]
maximize_objective = True
Create the disciplinary datasets¶
Then, we create the disciplinary AbstractFullCache
datasets
based on a DiagonalDOE
.
disciplines = create_discipline(["Aerodynamics", "Structure", "Mission"])
for discipline in disciplines:
discipline.set_cache_policy(discipline.MEMORY_FULL_CACHE)
design_space = AerostructureDesignSpace()
design_space.filter(discipline.get_input_data_names())
output = next(iter(discipline.get_output_data_names()))
scenario = create_scenario(
discipline, "DisciplinaryOpt", output, design_space, scenario_type="DOE"
)
scenario.execute({"algo": "DiagonalDOE", "n_samples": 10})
Out:
INFO - 14:42:54:
INFO - 14:42:54: *** Start DOE Scenario execution ***
INFO - 14:42:54: DOEScenario
INFO - 14:42:54: Disciplines: Aerodynamics
INFO - 14:42:54: MDOFormulation: DisciplinaryOpt
INFO - 14:42:54: Algorithm: DiagonalDOE
INFO - 14:42:54: Optimization problem:
INFO - 14:42:54: Minimize: drag(thick_airfoils, sweep, displ)
INFO - 14:42:54: With respect to: thick_airfoils, sweep, displ
INFO - 14:42:54: DOE sampling: 0%| | 0/10 [00:00<?, ?it]
INFO - 14:42:54: DOE sampling: 100%|██████████| 10/10 [00:00<00:00, 549.28 it/sec, obj=-320]
INFO - 14:42:54: Optimization result:
INFO - 14:42:54: Objective value = -319.99905478395067
INFO - 14:42:54: The result is feasible.
INFO - 14:42:54: Status: None
INFO - 14:42:54: Optimizer message: None
INFO - 14:42:54: Number of calls to the objective function by the optimizer: 10
INFO - 14:42:54: Design space:
INFO - 14:42:54: +----------------+-------------+-----------+-------------+-------+
INFO - 14:42:54: | name | lower_bound | value | upper_bound | type |
INFO - 14:42:54: +----------------+-------------+-----------+-------------+-------+
INFO - 14:42:54: | thick_airfoils | 5 | (25+0j) | 25 | float |
INFO - 14:42:54: | sweep | 10 | (35+0j) | 35 | float |
INFO - 14:42:54: | displ | -1000 | (1000+0j) | 1000 | float |
INFO - 14:42:54: +----------------+-------------+-----------+-------------+-------+
INFO - 14:42:54: *** DOE Scenario run terminated ***
INFO - 14:42:54:
INFO - 14:42:54: *** Start DOE Scenario execution ***
INFO - 14:42:54: DOEScenario
INFO - 14:42:54: Disciplines: Structure
INFO - 14:42:54: MDOFormulation: DisciplinaryOpt
INFO - 14:42:54: Algorithm: DiagonalDOE
INFO - 14:42:54: Optimization problem:
INFO - 14:42:54: Minimize: mass(thick_panels, sweep, forces)
INFO - 14:42:54: With respect to: thick_panels, sweep, forces
INFO - 14:42:54: DOE sampling: 0%| | 0/10 [00:00<?, ?it]
INFO - 14:42:54: DOE sampling: 100%|██████████| 10/10 [00:00<00:00, 560.17 it/sec, obj=4.02e+5]
INFO - 14:42:54: Optimization result:
INFO - 14:42:54: Objective value = 100.08573388203513
INFO - 14:42:54: The result is feasible.
INFO - 14:42:54: Status: None
INFO - 14:42:54: Optimizer message: None
INFO - 14:42:54: Number of calls to the objective function by the optimizer: 10
INFO - 14:42:54: Design space:
INFO - 14:42:54: +--------------+-------------+------------+-------------+-------+
INFO - 14:42:54: | name | lower_bound | value | upper_bound | type |
INFO - 14:42:54: +--------------+-------------+------------+-------------+-------+
INFO - 14:42:54: | thick_panels | 1 | (1+0j) | 20 | float |
INFO - 14:42:54: | sweep | 10 | (10+0j) | 35 | float |
INFO - 14:42:54: | forces | -1000 | (-1000+0j) | 1000 | float |
INFO - 14:42:54: +--------------+-------------+------------+-------------+-------+
INFO - 14:42:54: *** DOE Scenario run terminated ***
INFO - 14:42:54:
INFO - 14:42:54: *** Start DOE Scenario execution ***
INFO - 14:42:54: DOEScenario
INFO - 14:42:54: Disciplines: Mission
INFO - 14:42:54: MDOFormulation: DisciplinaryOpt
INFO - 14:42:54: Algorithm: DiagonalDOE
INFO - 14:42:54: Optimization problem:
INFO - 14:42:54: Minimize: range(drag, lift, mass, reserve_fact)
INFO - 14:42:54: With respect to: drag, lift, mass, reserve_fact
INFO - 14:42:54: DOE sampling: 0%| | 0/10 [00:00<?, ?it]
INFO - 14:42:54: DOE sampling: 100%|██████████| 10/10 [00:00<00:00, 538.25 it/sec, obj=1600.0]
INFO - 14:42:54: Optimization result:
INFO - 14:42:54: Objective value = 1600.0
INFO - 14:42:54: The result is feasible.
INFO - 14:42:54: Status: None
INFO - 14:42:54: Optimizer message: None
INFO - 14:42:54: Number of calls to the objective function by the optimizer: 10
INFO - 14:42:54: Design space:
INFO - 14:42:54: +--------------+-------------+-------------+-------------+-------+
INFO - 14:42:54: | name | lower_bound | value | upper_bound | type |
INFO - 14:42:54: +--------------+-------------+-------------+-------------+-------+
INFO - 14:42:54: | drag | 100 | (1000+0j) | 1000 | float |
INFO - 14:42:54: | lift | 0.1 | (1+0j) | 1 | float |
INFO - 14:42:54: | mass | 100000 | (500000+0j) | 500000 | float |
INFO - 14:42:54: | reserve_fact | -1000 | (1000+0j) | 1000 | float |
INFO - 14:42:54: +--------------+-------------+-------------+-------------+-------+
INFO - 14:42:54: *** DOE Scenario run terminated ***
Instantiate a scalable problem¶
In a third stage, we instantiate a ScalableProblem
from these disciplinary datasets and from the definition of the MDO problem.
We also increase the dimension of the sweep parameter.
datasets = [discipline.cache.export_to_dataset() for discipline in disciplines]
problem = ScalableProblem(
datasets,
design_variables,
objective_function,
eq_constraints,
ineq_constraints,
maximize_objective,
sizes={"sweep": 2},
)
print(problem)
Out:
/home/docs/checkouts/readthedocs.org/user_builds/gemseo/conda/3.2.2/lib/python3.8/site-packages/gemseo/problems/scalable/data_driven/model.py:150: ComplexWarning: Casting complex values to real discards the imaginary part
data[:, indices] = (value - lower_bound) / (upper_bound - lower_bound)
MDO problem
Disciplines: Aerodynamics, Structure, Mission
Design variables: thick_airfoils, thick_panels, sweep
Objective function: range (to maximize)
Inequality constraints: c_lift
Equality constraints: c_rf
Sizes: sweep (2), thick_airfoils (1), displ (1), drag (1), forces (1), lift (1), thick_panels (1), mass (1), reserve_fact (1), range (1), c_lift (1), c_rf (1)
Note
We could also provide options to the ScalableModel
objects
by means of the constructor of ScalableProblem
,
e.g. fill_factor
in the frame of the ScalableDiagonalModel
.
In this example, we use the standard ones.
Visualize the N2 chart¶
We can see the coupling between disciplines through this N2 chart:
problem.plot_n2_chart(save=False, show=True)
Create an MDO scenario¶
Lastly, we create a MDOScenario
with the MDF
formulation
and start the optimization at equilibrium,
thus ensuring the feasibility of the first iterate.
scenario = problem.create_scenario("MDF", start_at_equilibrium=True)
Out:
INFO - 14:42:55: Build a preliminary MDA to start at equilibrium
Note
We could also provide options for the scalable models to the constructor
of ScalableProblem
, e.g. fill_factor
in the frame of
the ScalableDiagonalModel
.
In this example, we use the standard ones.
Once the scenario is created, we can execute it as any scenario.
Here, we use the NLOPT_SLSQP
optimization algorithm
with no more than 100 iterations.
scenario.execute({"algo": "NLOPT_SLSQP", "max_iter": 100})
Out:
INFO - 14:42:55:
INFO - 14:42:55: *** Start MDO Scenario execution ***
INFO - 14:42:55: MDOScenario
INFO - 14:42:55: Disciplines: sdm_Aerodynamics sdm_Structure sdm_Mission
INFO - 14:42:55: MDOFormulation: MDF
INFO - 14:42:55: Algorithm: NLOPT_SLSQP
INFO - 14:42:55: Optimization problem:
INFO - 14:42:55: Minimize: -range(thick_airfoils, thick_panels, sweep)
INFO - 14:42:55: With respect to: thick_airfoils, thick_panels, sweep
INFO - 14:42:55: Subject to constraints:
INFO - 14:42:55: c_lift(thick_airfoils, thick_panels, sweep) <= [0.74804822]
INFO - 14:42:55: c_rf(thick_airfoils, thick_panels, sweep) == 0.4974338463722028
INFO - 14:42:55: Design space:
INFO - 14:42:55: +----------------+-------------+-------+-------------+-------+
INFO - 14:42:55: | name | lower_bound | value | upper_bound | type |
INFO - 14:42:55: +----------------+-------------+-------+-------------+-------+
INFO - 14:42:55: | thick_airfoils | 0 | 0.5 | 1 | float |
INFO - 14:42:55: | thick_panels | 0 | 0.5 | 1 | float |
INFO - 14:42:55: | sweep | 0 | 0.5 | 1 | float |
INFO - 14:42:55: | sweep | 0 | 0.5 | 1 | float |
INFO - 14:42:55: +----------------+-------------+-------+-------------+-------+
INFO - 14:42:55: Optimization: 0%| | 0/100 [00:00<?, ?it]
WARNING - 14:42:55: MDAJacobi has reached its maximum number of iterations but the normed residual 0.33333333333333337 is still above the tolerance 1e-06.
INFO - 14:42:55: Optimization: 3%|▎ | 3/100 [00:00<00:00, 920.52 it/sec]
WARNING - 14:42:55: MDAJacobi has reached its maximum number of iterations but the normed residual 0.05892556509887897 is still above the tolerance 1e-06.
WARNING - 14:42:55: MDAJacobi has reached its maximum number of iterations but the normed residual 0.11785113019775793 is still above the tolerance 1e-06.
INFO - 14:42:55: Optimization: 6%|▌ | 6/100 [00:00<00:00, 451.26 it/sec]
INFO - 14:42:55: Optimization: 8%|▊ | 8/100 [00:00<00:00, 373.40 it/sec, obj=0.299]
INFO - 14:42:55: Optimization result:
INFO - 14:42:55: Objective value = 0.2985276625156662
INFO - 14:42:55: The result is feasible.
INFO - 14:42:55: Status: None
INFO - 14:42:55: Optimizer message: Successive iterates of the objective function are closer than ftol_rel or ftol_abs. GEMSEO Stopped the driver
INFO - 14:42:55: Number of calls to the objective function by the optimizer: 9
INFO - 14:42:55: Constraints values:
INFO - 14:42:55: c_lift + offset = [-0.49234168]
INFO - 14:42:55: c_rf - 0.4974338463722028 = -7.710498906021712e-14
INFO - 14:42:55: Design space:
INFO - 14:42:55: +----------------+-------------+--------------------+-------------+-------+
INFO - 14:42:55: | name | lower_bound | value | upper_bound | type |
INFO - 14:42:55: +----------------+-------------+--------------------+-------------+-------+
INFO - 14:42:55: | thick_airfoils | 0 | 1 | 1 | float |
INFO - 14:42:55: | thick_panels | 0 | 0.5155052311582397 | 1 | float |
INFO - 14:42:55: | sweep | 0 | 1 | 1 | float |
INFO - 14:42:55: | sweep | 0 | 1 | 1 | float |
INFO - 14:42:55: +----------------+-------------+--------------------+-------------+-------+
INFO - 14:42:55: *** MDO Scenario run terminated in 0:00:00.275749 ***
{'algo': 'NLOPT_SLSQP', 'max_iter': 100}
We can post-process the results.
Here, we use the standard OptHistoryView
.
scenario.post_process("OptHistoryView", save=False, show=True)
Out:
<gemseo.post.opt_history_view.OptHistoryView object at 0x7fcaa4291730>
Total running time of the script: ( 0 minutes 0.964 seconds)