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)