{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Scalable problem\n\nWe want to solve the Aerostructure MDO problem\nby means of the :class:`.MDF` formulation\nwith a higher dimension for the sweep parameter.\nFor that, we use the :class:`.ScalableProblem` class.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from __future__ import division, unicode_literals\n\nfrom gemseo.api import configure_logger, create_discipline, create_scenario\nfrom gemseo.problems.aerostructure.aerostructure_design_space import (\n    AerostructureDesignSpace,\n)\nfrom gemseo.problems.scalable.data_driven.problem import ScalableProblem\n\nconfigure_logger()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Define the design problem\nIn a first step, we define the design problem in terms of\nobjective function (to maximize or minimize),\ndesign variables (local and global)\nand constraints (equality and inequality).\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "design_variables = [\"thick_airfoils\", \"thick_panels\", \"sweep\"]\nobjective_function = \"range\"\neq_constraints = [\"c_rf\"]\nineq_constraints = [\"c_lift\"]\nmaximize_objective = True"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Create the disciplinary datasets\nThen, we create the disciplinary :class:`.AbstractFullCache` datasets\nbased on a :class:`.DiagonalDOE`.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "disciplines = create_discipline([\"Aerodynamics\", \"Structure\", \"Mission\"])\nfor discipline in disciplines:\n    discipline.set_cache_policy(discipline.MEMORY_FULL_CACHE)\n    design_space = AerostructureDesignSpace()\n    design_space.filter(discipline.get_input_data_names())\n    output = next(iter(discipline.get_output_data_names()))\n    scenario = create_scenario(\n        discipline, \"DisciplinaryOpt\", output, design_space, scenario_type=\"DOE\"\n    )\n    scenario.execute({\"algo\": \"DiagonalDOE\", \"n_samples\": 10})"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Instantiate a scalable problem\nIn a third stage, we instantiate a :class:`.ScalableProblem`\nfrom these disciplinary datasets and from the definition of the MDO problem.\nWe also increase the dimension of the sweep parameter.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "datasets = [discipline.cache.export_to_dataset() for discipline in disciplines]\nproblem = ScalableProblem(\n    datasets,\n    design_variables,\n    objective_function,\n    eq_constraints,\n    ineq_constraints,\n    maximize_objective,\n    sizes={\"sweep\": 2},\n)\nprint(problem)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "<div class=\"alert alert-info\"><h4>Note</h4><p>We could also provide options to the :class:`.ScalableModel` objects\n   by means of the constructor of :class:`.ScalableProblem`,\n   e.g. :code:`fill_factor` in the frame of the :class:`.ScalableDiagonalModel`.\n   In this example, we use the standard ones.</p></div>\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Visualize the N2 chart\nWe can see the coupling between disciplines through this N2 chart:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "problem.plot_n2_chart(save=False, show=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Create an MDO scenario\nLastly, we create a :class:`.MDOScenario` with the :class:`.MDF` formulation\nand start the optimization at equilibrium,\nthus ensuring the feasibility of the first iterate.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "scenario = problem.create_scenario(\"MDF\", start_at_equilibrium=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "<div class=\"alert alert-info\"><h4>Note</h4><p>We could also provide options for the scalable models to the constructor\n   of :class:`.ScalableProblem`, e.g. :code:`fill_factor` in the frame of\n   the :class:`.ScalableDiagonalModel`.\n   In this example, we use the standard ones.</p></div>\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Once the scenario is created, we can execute it as any scenario.\nHere, we use the :code:`NLOPT_SLSQP` optimization algorithm\nwith no more than 100 iterations.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "scenario.execute({\"algo\": \"NLOPT_SLSQP\", \"max_iter\": 100})"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We can post-process the results.\nHere, we use the standard :class:`.OptHistoryView`.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "scenario.post_process(\"OptHistoryView\", save=False, show=True)"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.8.12"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}