{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "8FaMeOrwYSgB"
   },
   "source": [
    "# Aerospace Design via Quasiconvex Optimization \n",
    "\n",
    "Consider a triangle, or a wedge, located within a hypersonic flow. A standard aerospace design optimization problem is to design the wedge to maximize the lift-to-drag ratio (L/D) (or conversely minimize the D/L ratio), subject to certain geometric constraints. In this example, the wedge is known to have a constant hypotenuse, and our job is to choose its width and height.\n",
    "\n",
    "The drag-to-lift ratio is given by\n",
    "\n",
    "$$\n",
    "\\frac{\\mathrm{D}}{\\mathrm{L}} = \\frac{\\mathrm{c_d}}{\\mathrm{c_l}},\n",
    "$$\n",
    "\n",
    "where $\\mathrm{c_d}$ and $\\mathrm{c_l}$ are drag and lift coefficients, respectively, that are obtained by integrating the projection of the pressure coefficient in directions parallel to, and perpendicular to, the body.\n",
    "\n",
    "It turns out that the the drag-to-lift ratio is a quasilinear function, as we'll now show. We will assume the pressure coefficient is given by the Newtonian sine-squared law for whetted areas of the body,\n",
    "\n",
    "$$\n",
    "\\mathrm{c_p} = 2(\\hat{v}\\cdot\\hat{n})^2\n",
    "$$\n",
    "\n",
    "and elsewhere $\\mathrm{c_p} = 0$. Here, $\\hat{v}$ is the free stream direction, which for simplicity we will assume is parallel to the body so that, $\\hat{v} = \\langle 1, 0 \\rangle$, and $\\hat{n}$ is the local unit normal. For a wedge defined by width $\\Delta x$, and height $\\Delta y$, \n",
    "\n",
    "$$\n",
    "\\hat{n} = \\langle -\\Delta y/s,-\\Delta x/s \\rangle\n",
    "$$\n",
    "\n",
    "where $s$ is the hypotenuse length. Therefore,\n",
    "\n",
    "$$\n",
    "\\mathrm{c_p} = 2((1)(-\\Delta y/s)+(0)(-\\Delta x/s))^2 = \\frac{2 \\Delta y^2}{s^2}\n",
    "$$\n",
    "\n",
    "The lift and drag coefficients are given by\n",
    "\n",
    "$$\n",
    "\\begin{align*}\n",
    "\\mathrm{c_d} &= \\frac{1}{c}\\int_0^s -\\mathrm{c_p}\\hat{n}_x \\mathrm{d}s \\\\\n",
    "\\mathrm{c_l} &= \\frac{1}{c}\\int_0^s -\\mathrm{c_p}\\hat{n}_y \\mathrm{d}s\n",
    "\\end{align*}\n",
    "$$\n",
    "\n",
    "Where $c$ is the reference chord length of the body. Given that $\\hat{n}$, and therefore $\\mathrm{c_p}$ are constant over the whetted surface of the body,\n",
    "\n",
    "$$\n",
    "\\begin{align*}\n",
    "\\mathrm{c_d} &= -\\frac{s}{c}\\mathrm{c_p}\\hat{n}_x = \\frac{s}{c}\\frac{2 \\Delta y^2}{s^2}\\frac{\\Delta y}{s} \\\\\n",
    "\\mathrm{c_l} &= -\\frac{s}{c}\\mathrm{c_p}\\hat{n}_y = \\frac{s}{c}\\frac{2 \\Delta y^2}{s^2}\\frac{\\Delta x}{s}\n",
    "\\end{align*}\n",
    "$$\n",
    "\n",
    "Assuming $s=1$, so that $\\Delta y = \\sqrt{1-\\Delta x^2}$, plugging in the above into the equation for $D/L$, we obtain \n",
    "\n",
    "$$\n",
    "\\frac{\\mathrm{D}}{\\mathrm{L}} = \\frac{\\Delta y}{\\Delta x} = \\frac{\\sqrt{1-\\Delta x^2}}{\\Delta x} = \\sqrt{\\frac{1}{\\Delta x^2}-1}.\n",
    "$$\n",
    "\n",
    "This function is representable as a DQCP, quasilinear function. We plot it below, and then we write it using DQCP.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 283
    },
    "colab_type": "code",
    "id": "1Sx2TUDOXwQ7",
    "outputId": "993dfb1c-3f01-499e-8282-28a72de83a2a"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f571d7bfdd8>]"
      ]
     },
     "execution_count": 1,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\nXUQkQvx/bSsPbQxMiD8AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "tags": []
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "import matplotlib\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import math\n",
    "\n",
    "x = np.linspace(.25,1,num=201)\n",
    "obj = []\n",
    "for i in range(len(x)):\n",
    "    obj.append(math.sqrt(1/x[i]**2-1))\n",
    "\n",
    "plt.plot(x,obj)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 34
    },
    "colab_type": "code",
    "id": "yXdP_PXeXyJI",
    "outputId": "aecdeea8-cf8b-4c95-f88b-206415d70df3"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This objective function is QUASILINEAR\n"
     ]
    }
   ],
   "source": [
    "import cvxpy as cp\n",
    "\n",
    "x = cp.Variable(pos=True)\n",
    "obj = cp.sqrt(cp.inv_pos(cp.square(x))-1)\n",
    "print(\"This objective function is\", obj.curvature)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "N_wi4BJuYRKh"
   },
   "source": [
    "Minimizing this objective function subject to constraints representing payload requirements is a standard aerospace design problem. In this case we will consider the constraint that the wedge must be able to contain a rectangle of given length and width internally along its hypotenuse. This is representable as a convex constraint."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 34
    },
    "colab_type": "code",
    "id": "wrXBd8faStXs",
    "outputId": "3dbe0fcf-cb39-4109-f8ba-e5c3d8a0cd14"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Inequality(Expression(CONVEX, UNKNOWN, ()))]\n"
     ]
    }
   ],
   "source": [
    "a = .05 # USER INPUT: height of rectangle, should be at most b\n",
    "b = .65 # USER INPUT: width of rectangle\n",
    "constraint = [a*cp.inv_pos(x)-(1-b)*cp.sqrt(1-cp.square(x))<=0]\n",
    "print(constraint)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 734
    },
    "colab_type": "code",
    "id": "43nliP73StzN",
    "outputId": "1e3a3170-cb98-4c70-949e-9c2ded0d0de8"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "********************************************************************************\n",
      "Preparing to bisect problem\n",
      "\n",
      "minimize 0.0\n",
      "subject to 0.05 * var30766 + -0.35 * var30793 <= 0.0\n",
      "           SOC(reshape(var30747 + var30766, (1,)), Vstack(reshape(var30747 + -var30766, (1, 1)), reshape(2.0 * 1.0, (1, 1))))\n",
      "           SOC(reshape(var30779 + 1.0, (1,)), Vstack(reshape(var30779 + -1.0, (1, 1)), reshape(2.0 * var30747, (1, 1))))\n",
      "           SOC(reshape(1.0 + -var30779 + 1.0, (1,)), Vstack(reshape(1.0 + -var30779 + -1.0, (1, 1)), reshape(2.0 * var30793, (1, 1))))\n",
      "           power(power(power(param30811, 2) + --1.0, -1), 1/2) <= var30747\n",
      "\n",
      "Finding interval for bisection ...\n",
      "initial lower bound: 0.000000\n",
      "initial upper bound: 1.000000\n",
      "\n",
      "(iteration 0) lower bound: 0.000000\n",
      "(iteration 0) upper bound: 1.000000\n",
      "(iteration 0) query point: 0.500000 \n",
      "(iteration 0) query was feasible. Solution(status=optimal, opt_val=0.0, primal_vars={30766: array(1.28425055), 30793: array(0.32048066), 30747: 0.9203698369509382, 30779: array(0.86287821)}, dual_vars={30764: 1.184352986830617e-10, 30775: array([ 7.68139086e-12, -9.11799720e-13, -6.85059567e-12]), 30788: array([ 6.73308751e-11,  7.50722737e-12, -6.55220021e-11]), 30802: array([ 4.04979217e-11,  3.43109122e-11, -1.68754271e-11]), 30835: 1.4165742899966837e-10}, attr={'solve_time': 6.0109e-05, 'setup_time': 4.4997e-05, 'num_iters': 7}))\n",
      "\n",
      "(iteration 5) lower bound: 0.125000\n",
      "(iteration 5) upper bound: 0.156250\n",
      "(iteration 5) query point: 0.140625 \n",
      "(iteration 5) query was infeasible.\n",
      "\n",
      "(iteration 10) lower bound: 0.145508\n",
      "(iteration 10) upper bound: 0.146484\n",
      "(iteration 10) query point: 0.145996 \n",
      "(iteration 10) query was feasible. Solution(status=optimal, opt_val=0.0, primal_vars={30766: array(1.01067238), 30793: array(0.14440604), 30747: 0.9895144829793, 30779: array(0.97914383)}, dual_vars={30764: 1.2610785752467482e-05, 30775: array([ 6.37367039e-07,  6.73702792e-09, -6.37322961e-07]), 30788: array([ 1.50627898e-05,  1.58286953e-07, -1.50619494e-05]), 30802: array([ 7.77053008e-06,  7.45051237e-06, -2.20683981e-06]), 30835: 2.948014872712083e-05}, attr={'solve_time': 0.000114922, 'setup_time': 3.6457e-05, 'num_iters': 10}))\n",
      "\n",
      "(iteration 15) lower bound: 0.145874\n",
      "(iteration 15) upper bound: 0.145905\n",
      "(iteration 15) query point: 0.145889 \n",
      "(iteration 15) query was infeasible.\n",
      "\n",
      "Bisection completed, with lower bound 0.145897 and upper bound 0.1458979\n",
      "********************************************************************************\n",
      "\n",
      "Final L/D Ratio =  6.854107648695203\n",
      "Final width of wedge =  0.9895238539767502\n",
      "Final height of wedge =  0.14436946495363565\n"
     ]
    }
   ],
   "source": [
    "prob = cp.Problem(cp.Minimize(obj), constraint)\n",
    "prob.solve(qcp=True, verbose=True)\n",
    "print('Final L/D Ratio = ', 1/obj.value)\n",
    "print('Final width of wedge = ', x.value)\n",
    "print('Final height of wedge = ', math.sqrt(1-x.value**2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "mapH_CrHuKVU"
   },
   "source": [
    "Once the solution has been found, we can create a plot to verify that the rectangle is inscribed within the wedge."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 333
    },
    "colab_type": "code",
    "id": "fxfYRD7Jga2R",
    "outputId": "fea6812f-ab04-4879-a1a4-69e84f515736"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-0.04947620645689951,\n",
       " 1.0390003355948896,\n",
       " -0.15158793820131744,\n",
       " 0.0072184732476817896)"
      ]
     },
     "execution_count": 72,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\nqzewjQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "tags": []
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "y = math.sqrt(1-x.value**2)\n",
    "lambda1 = a*x.value/y\n",
    "lambda2 = a*x.value**2/y+a*y\n",
    "lambda3 = a*x.value-y*(a*x.value/y-b)\n",
    "\n",
    "plt.plot([0,x.value],[0,0],'b.-')\n",
    "plt.plot([0,x.value],[0,-y],'b.-')\n",
    "plt.plot([x.value,x.value],[0,-y],'b.-')\n",
    "\n",
    "pt1 = [lambda1*x.value,-lambda1*y]\n",
    "pt2 = [(lambda1+b)*x.value,-(lambda1+b)*y]\n",
    "pt3 = [(lambda1+b)*x.value+a*y,-(lambda1+b)*y+a*x.value]\n",
    "pt4 = [lambda1*x.value+a*y,-lambda1*y+a*x.value]\n",
    "\n",
    "plt.plot([pt1[0],pt2[0]],[pt1[1],pt2[1]],'r.-')\n",
    "plt.plot([pt2[0],pt3[0]],[pt2[1],pt3[1]],'r.-')\n",
    "plt.plot([pt3[0],pt4[0]],[pt3[1],pt4[1]],'r.-')\n",
    "plt.plot([pt4[0],pt1[0]],[pt4[1],pt1[1]],'r.-')\n",
    "\n",
    "plt.axis('equal')"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "QuasiconvexAerospaceShapeDesignExample.ipynb",
   "provenance": []
  },
  "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.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
