{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "509d0124",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:52.935820Z",
     "iopub.status.busy": "2026-10-02T14:40:52.935509Z",
     "iopub.status.idle": "2026-10-02T14:40:52.939370Z",
     "shell.execute_reply": "2026-10-02T14:40:52.938917Z"
    },
    "hide_input": true,
    "papermill": {
     "duration": 0.00642,
     "end_time": "2026-10-02T14:40:52.939796+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:52.933376+00:00",
     "status": "completed"
    },
    "tags": [
     "active-ipynb",
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    from openmdao.utils.notebook_utils import notebook_mode  # noqa: F401\n",
    "except ImportError:\n",
    "    !python -m pip install openmdao[notebooks]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ed15d15",
   "metadata": {
    "papermill": {
     "duration": 0.001032,
     "end_time": "2026-10-02T14:40:52.942229+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:52.941197+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "# Revisiting the Beam Problem - Minimizing Stress with KS Constraints and BSplines\n",
    "\n",
    "The following example shows the optimization of a simple beam with rectangular cross section. The beam has been subdivided into\n",
    "elements along the length of the beam, and one end is fixed. The goal is to minimize the volume (and hence the mass of the\n",
    "homogeneous beam) by varying the thickness in each element without exceeding a maximum stress constraint while the beam is\n",
    "subject to multiple load cases, each one being a distributed force load that varies sinusoidally along the span.\n",
    "\n",
    "Constraining the bending stress on each element leads to a more computationally expensive derivative calculation, so we\n",
    "will use the `KSFunction` to reduce the stress vector for each load case to a single scalar value. To do so, we also need\n",
    "to insert an `ExecComp` component that converts the stress into a form where a negative value means it is satisfied, and\n",
    "a positive value means it is violated.\n",
    "\n",
    "The problem presented here is also an example of a multi-point implementation, where we create a separate instance of the\n",
    "parts of the calculation that are impacted by different load cases. This enables our model to take advantage of multiple\n",
    "processors when run in parallel.\n",
    "\n",
    "If we allow the optimizer to vary the thickness of each element, then we have a design variable vector that is as wide as the\n",
    "number of elements in the model. This may perform poorly if we have a large number of elements in the beam. If we assume that\n",
    "the optimal beam thickness is going to have a smooth continuous variation over the length of the beam, then it is a good\n",
    "candidate for using an interpolation component like `SplineComp` to reduce the number of design variables we need.\n",
    "\n",
    "For this example, we have 25 elements, but can reduce that to 5 control points for the optimizer's design variables by\n",
    "including the SplineComp.\n",
    "\n",
    "The code for the top system is this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "1be9f90d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:52.945082Z",
     "iopub.status.busy": "2026-10-02T14:40:52.944835Z",
     "iopub.status.idle": "2026-10-02T14:40:55.594690Z",
     "shell.execute_reply": "2026-10-02T14:40:55.594026Z"
    },
    "papermill": {
     "duration": 2.652057,
     "end_time": "2026-10-02T14:40:55.595343+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:52.943286+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "application/papermill.record/text/html": "<style>pre { line-height: 125%; }\ntd.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\nspan.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\ntd.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\nspan.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n.output_html .hll { background-color: #ffffcc }\n.output_html { background: #f8f8f8; }\n.output_html .c { color: #3D7B7B; font-style: italic } /* Comment */\n.output_html .err { border: 1px solid #F00 } /* Error */\n.output_html .k { color: #008000; font-weight: bold } /* Keyword */\n.output_html .o { color: #666 } /* Operator */\n.output_html .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */\n.output_html .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */\n.output_html .cp { color: #9C6500 } /* Comment.Preproc */\n.output_html .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */\n.output_html .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */\n.output_html .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */\n.output_html .gd { color: #A00000 } /* Generic.Deleted */\n.output_html .ge { font-style: italic } /* Generic.Emph */\n.output_html .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */\n.output_html .gr { color: #E40000 } /* Generic.Error */\n.output_html .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.output_html .gi { color: #008400 } /* Generic.Inserted */\n.output_html .go { color: #717171 } /* Generic.Output */\n.output_html .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.output_html .gs { font-weight: bold } /* Generic.Strong */\n.output_html .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.output_html .gt { color: #04D } /* Generic.Traceback */\n.output_html .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.output_html .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.output_html .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.output_html .kp { color: #008000 } /* Keyword.Pseudo */\n.output_html .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.output_html .kt { color: #B00040 } /* Keyword.Type */\n.output_html .m { color: #666 } /* Literal.Number */\n.output_html .s { color: #BA2121 } /* Literal.String */\n.output_html .na { color: #687822 } /* Name.Attribute */\n.output_html .nb { color: #008000 } /* Name.Builtin */\n.output_html .nc { color: #00F; font-weight: bold } /* Name.Class */\n.output_html .no { color: #800 } /* Name.Constant */\n.output_html .nd { color: #A2F } /* Name.Decorator */\n.output_html .ni { color: #717171; font-weight: bold } /* Name.Entity */\n.output_html .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */\n.output_html .nf { color: #00F } /* Name.Function */\n.output_html .nl { color: #767600 } /* Name.Label */\n.output_html .nn { color: #00F; font-weight: bold } /* Name.Namespace */\n.output_html .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.output_html .nv { color: #19177C } /* Name.Variable */\n.output_html .ow { color: #A2F; font-weight: bold } /* Operator.Word */\n.output_html .w { color: #BBB } /* Text.Whitespace */\n.output_html .mb { color: #666 } /* Literal.Number.Bin */\n.output_html .mf { color: #666 } /* Literal.Number.Float */\n.output_html .mh { color: #666 } /* Literal.Number.Hex */\n.output_html .mi { color: #666 } /* Literal.Number.Integer */\n.output_html .mo { color: #666 } /* Literal.Number.Oct */\n.output_html .sa { color: #BA2121 } /* Literal.String.Affix */\n.output_html .sb { color: #BA2121 } /* Literal.String.Backtick */\n.output_html .sc { color: #BA2121 } /* Literal.String.Char */\n.output_html .dl { color: #BA2121 } /* Literal.String.Delimiter */\n.output_html .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n.output_html .s2 { color: #BA2121 } /* Literal.String.Double */\n.output_html .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */\n.output_html .sh { color: #BA2121 } /* Literal.String.Heredoc */\n.output_html .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */\n.output_html .sx { color: #008000 } /* Literal.String.Other */\n.output_html .sr { color: #A45A77 } /* Literal.String.Regex */\n.output_html .s1 { color: #BA2121 } /* Literal.String.Single */\n.output_html .ss { color: #19177C } /* Literal.String.Symbol */\n.output_html .bp { color: #008000 } /* Name.Builtin.Pseudo */\n.output_html .fm { color: #00F } /* Name.Function.Magic */\n.output_html .vc { color: #19177C } /* Name.Variable.Class */\n.output_html .vg { color: #19177C } /* Name.Variable.Global */\n.output_html .vi { color: #19177C } /* Name.Variable.Instance */\n.output_html .vm { color: #19177C } /* Name.Variable.Magic */\n.output_html .il { color: #666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">LocalStiffnessMatrixComp</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExplicitComponent</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">initialize</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">,</span> <span class=\"n\">types</span><span class=\"o\">=</span><span class=\"nb\">int</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;E&#39;</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;L&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">num_elements</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">E</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;E&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">L</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;L&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;I&#39;</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"n\">num_elements</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_output</span><span class=\"p\">(</span><span class=\"s1\">&#39;K_local&#39;</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"n\">num_elements</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">))</span>\n\n        <span class=\"n\">L0</span> <span class=\"o\">=</span> <span class=\"n\">L</span> <span class=\"o\">/</span> <span class=\"n\">num_elements</span>\n        <span class=\"n\">coeffs</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">empty</span><span class=\"p\">((</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">))</span>\n        <span class=\"n\">coeffs</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"p\">:]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"mi\">6</span> <span class=\"o\">*</span> <span class=\"n\">L0</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"mi\">6</span> <span class=\"o\">*</span> <span class=\"n\">L0</span><span class=\"p\">]</span>\n        <span class=\"n\">coeffs</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"p\">:]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">6</span> <span class=\"o\">*</span> <span class=\"n\">L0</span><span class=\"p\">,</span> <span class=\"mi\">4</span> <span class=\"o\">*</span> <span class=\"n\">L0</span> <span class=\"o\">**</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">6</span> <span class=\"o\">*</span> <span class=\"n\">L0</span><span class=\"p\">,</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">L0</span> <span class=\"o\">**</span> <span class=\"mi\">2</span><span class=\"p\">]</span>\n        <span class=\"n\">coeffs</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"p\">:]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">6</span> <span class=\"o\">*</span> <span class=\"n\">L0</span><span class=\"p\">,</span> <span class=\"mi\">12</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">6</span> <span class=\"o\">*</span> <span class=\"n\">L0</span><span class=\"p\">]</span>\n        <span class=\"n\">coeffs</span><span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"p\">:]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">6</span> <span class=\"o\">*</span> <span class=\"n\">L0</span><span class=\"p\">,</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">L0</span> <span class=\"o\">**</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">6</span> <span class=\"o\">*</span> <span class=\"n\">L0</span><span class=\"p\">,</span> <span class=\"mi\">4</span> <span class=\"o\">*</span> <span class=\"n\">L0</span> <span class=\"o\">**</span> <span class=\"mi\">2</span><span class=\"p\">]</span>\n        <span class=\"n\">coeffs</span> <span class=\"o\">*=</span> <span class=\"n\">E</span> <span class=\"o\">/</span> <span class=\"n\">L0</span> <span class=\"o\">**</span> <span class=\"mi\">3</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">mtx</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">((</span><span class=\"n\">num_elements</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"n\">num_elements</span><span class=\"p\">))</span>\n        <span class=\"k\">for</span> <span class=\"n\">ind</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_elements</span><span class=\"p\">):</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">mtx</span><span class=\"p\">[</span><span class=\"n\">ind</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"p\">:,</span> <span class=\"n\">ind</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">coeffs</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"s1\">&#39;K_local&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;I&#39;</span><span class=\"p\">,</span>\n            <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">mtx</span><span class=\"o\">.</span><span class=\"n\">reshape</span><span class=\"p\">(</span><span class=\"mi\">16</span> <span class=\"o\">*</span> <span class=\"n\">num_elements</span><span class=\"p\">,</span> <span class=\"n\">num_elements</span><span class=\"p\">))</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">outputs</span><span class=\"p\">):</span>\n        <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;K_local&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n        <span class=\"k\">for</span> <span class=\"n\">ind</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">]):</span>\n            <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;K_local&#39;</span><span class=\"p\">][</span><span class=\"n\">ind</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"p\">:]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">mtx</span><span class=\"p\">[</span><span class=\"n\">ind</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"p\">:,</span> <span class=\"n\">ind</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;I&#39;</span><span class=\"p\">][</span><span class=\"n\">ind</span><span class=\"p\">]</span>\n</pre></div>\n",
      "application/papermill.record/text/latex": "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{LocalStiffnessMatrixComp}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{ExplicitComponent}\\PY{p}{)}\\PY{p}{:}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{initialize}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{types}\\PY{o}{=}\\PY{n+nb}{int}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{E}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{L}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{num\\PYZus{}elements} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{E} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{E}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{L} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{L}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{I}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{shape}\\PY{o}{=}\\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}output}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{K\\PYZus{}local}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{shape}\\PY{o}{=}\\PY{p}{(}\\PY{n}{num\\PYZus{}elements}\\PY{p}{,} \\PY{l+m+mi}{4}\\PY{p}{,} \\PY{l+m+mi}{4}\\PY{p}{)}\\PY{p}{)}\n\n        \\PY{n}{L0} \\PY{o}{=} \\PY{n}{L} \\PY{o}{/} \\PY{n}{num\\PYZus{}elements}\n        \\PY{n}{coeffs} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{empty}\\PY{p}{(}\\PY{p}{(}\\PY{l+m+mi}{4}\\PY{p}{,} \\PY{l+m+mi}{4}\\PY{p}{)}\\PY{p}{)}\n        \\PY{n}{coeffs}\\PY{p}{[}\\PY{l+m+mi}{0}\\PY{p}{,} \\PY{p}{:}\\PY{p}{]} \\PY{o}{=} \\PY{p}{[}\\PY{l+m+mi}{12}\\PY{p}{,} \\PY{l+m+mi}{6} \\PY{o}{*} \\PY{n}{L0}\\PY{p}{,} \\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{12}\\PY{p}{,} \\PY{l+m+mi}{6} \\PY{o}{*} \\PY{n}{L0}\\PY{p}{]}\n        \\PY{n}{coeffs}\\PY{p}{[}\\PY{l+m+mi}{1}\\PY{p}{,} \\PY{p}{:}\\PY{p}{]} \\PY{o}{=} \\PY{p}{[}\\PY{l+m+mi}{6} \\PY{o}{*} \\PY{n}{L0}\\PY{p}{,} \\PY{l+m+mi}{4} \\PY{o}{*} \\PY{n}{L0} \\PY{o}{*}\\PY{o}{*} \\PY{l+m+mi}{2}\\PY{p}{,} \\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{6} \\PY{o}{*} \\PY{n}{L0}\\PY{p}{,} \\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{L0} \\PY{o}{*}\\PY{o}{*} \\PY{l+m+mi}{2}\\PY{p}{]}\n        \\PY{n}{coeffs}\\PY{p}{[}\\PY{l+m+mi}{2}\\PY{p}{,} \\PY{p}{:}\\PY{p}{]} \\PY{o}{=} \\PY{p}{[}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{12}\\PY{p}{,} \\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{6} \\PY{o}{*} \\PY{n}{L0}\\PY{p}{,} \\PY{l+m+mi}{12}\\PY{p}{,} \\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{6} \\PY{o}{*} \\PY{n}{L0}\\PY{p}{]}\n        \\PY{n}{coeffs}\\PY{p}{[}\\PY{l+m+mi}{3}\\PY{p}{,} \\PY{p}{:}\\PY{p}{]} \\PY{o}{=} \\PY{p}{[}\\PY{l+m+mi}{6} \\PY{o}{*} \\PY{n}{L0}\\PY{p}{,} \\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{L0} \\PY{o}{*}\\PY{o}{*} \\PY{l+m+mi}{2}\\PY{p}{,} \\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{6} \\PY{o}{*} \\PY{n}{L0}\\PY{p}{,} \\PY{l+m+mi}{4} \\PY{o}{*} \\PY{n}{L0} \\PY{o}{*}\\PY{o}{*} \\PY{l+m+mi}{2}\\PY{p}{]}\n        \\PY{n}{coeffs} \\PY{o}{*}\\PY{o}{=} \\PY{n}{E} \\PY{o}{/} \\PY{n}{L0} \\PY{o}{*}\\PY{o}{*} \\PY{l+m+mi}{3}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{mtx} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{zeros}\\PY{p}{(}\\PY{p}{(}\\PY{n}{num\\PYZus{}elements}\\PY{p}{,} \\PY{l+m+mi}{4}\\PY{p}{,} \\PY{l+m+mi}{4}\\PY{p}{,} \\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\\PY{p}{)}\n        \\PY{k}{for} \\PY{n}{ind} \\PY{o+ow}{in} \\PY{n+nb}{range}\\PY{p}{(}\\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\\PY{p}{:}\n            \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{mtx}\\PY{p}{[}\\PY{n}{ind}\\PY{p}{,} \\PY{p}{:}\\PY{p}{,} \\PY{p}{:}\\PY{p}{,} \\PY{n}{ind}\\PY{p}{]} \\PY{o}{=} \\PY{n}{coeffs}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{K\\PYZus{}local}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{I}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,}\n            \\PY{n}{val}\\PY{o}{=}\\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{mtx}\\PY{o}{.}\\PY{n}{reshape}\\PY{p}{(}\\PY{l+m+mi}{16} \\PY{o}{*} \\PY{n}{num\\PYZus{}elements}\\PY{p}{,} \\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{K\\PYZus{}local}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mi}{0}\n        \\PY{k}{for} \\PY{n}{ind} \\PY{o+ow}{in} \\PY{n+nb}{range}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\\PY{p}{:}\n            \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{K\\PYZus{}local}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{[}\\PY{n}{ind}\\PY{p}{,} \\PY{p}{:}\\PY{p}{,} \\PY{p}{:}\\PY{p}{]} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{mtx}\\PY{p}{[}\\PY{n}{ind}\\PY{p}{,} \\PY{p}{:}\\PY{p}{,} \\PY{p}{:}\\PY{p}{,} \\PY{n}{ind}\\PY{p}{]} \\PY{o}{*} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{I}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{[}\\PY{n}{ind}\\PY{p}{]}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class LocalStiffnessMatrixComp(om.ExplicitComponent):\n\n    def initialize(self):\n        self.options.declare('num_elements', types=int)\n        self.options.declare('E')\n        self.options.declare('L')\n\n    def setup(self):\n        num_elements = self.options['num_elements']\n        E = self.options['E']\n        L = self.options['L']\n\n        self.add_input('I', shape=num_elements)\n        self.add_output('K_local', shape=(num_elements, 4, 4))\n\n        L0 = L / num_elements\n        coeffs = np.empty((4, 4))\n        coeffs[0, :] = [12, 6 * L0, -12, 6 * L0]\n        coeffs[1, :] = [6 * L0, 4 * L0 ** 2, -6 * L0, 2 * L0 ** 2]\n        coeffs[2, :] = [-12, -6 * L0, 12, -6 * L0]\n        coeffs[3, :] = [6 * L0, 2 * L0 ** 2, -6 * L0, 4 * L0 ** 2]\n        coeffs *= E / L0 ** 3\n\n        self.mtx = np.zeros((num_elements, 4, 4, num_elements))\n        for ind in range(num_elements):\n            self.mtx[ind, :, :, ind] = coeffs\n\n        self.declare_partials('K_local', 'I',\n            val=self.mtx.reshape(16 * num_elements, num_elements))\n\n    def compute(self, inputs, outputs):\n        outputs['K_local'] = 0\n        for ind in range(self.options['num_elements']):\n            outputs['K_local'][ind, :, :] = self.mtx[ind, :, :, ind] * inputs['I'][ind]"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src9"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src9\", get_code(\"openmdao.test_suite.test_examples.beam_optimization.components.local_stiffness_matrix_comp.LocalStiffnessMatrixComp\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e97764d",
   "metadata": {
    "papermill": {
     "duration": 0.00166,
     "end_time": "2026-10-02T14:40:55.598860+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:55.597200+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `LocalStiffnessMatrixComp` class definition \n",
    "\n",
    "{glue:}`code_src9`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "2c3a384a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:55.603842Z",
     "iopub.status.busy": "2026-10-02T14:40:55.603681Z",
     "iopub.status.idle": "2026-10-02T14:40:55.625261Z",
     "shell.execute_reply": "2026-10-02T14:40:55.624820Z"
    },
    "papermill": {
     "duration": 0.024191,
     "end_time": "2026-10-02T14:40:55.625786+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:55.601595+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "application/papermill.record/text/html": "<style>pre { line-height: 125%; }\ntd.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\nspan.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\ntd.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\nspan.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n.output_html .hll { background-color: #ffffcc }\n.output_html { background: #f8f8f8; }\n.output_html .c { color: #3D7B7B; font-style: italic } /* Comment */\n.output_html .err { border: 1px solid #F00 } /* Error */\n.output_html .k { color: #008000; font-weight: bold } /* Keyword */\n.output_html .o { color: #666 } /* Operator */\n.output_html .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */\n.output_html .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */\n.output_html .cp { color: #9C6500 } /* Comment.Preproc */\n.output_html .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */\n.output_html .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */\n.output_html .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */\n.output_html .gd { color: #A00000 } /* Generic.Deleted */\n.output_html .ge { font-style: italic } /* Generic.Emph */\n.output_html .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */\n.output_html .gr { color: #E40000 } /* Generic.Error */\n.output_html .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.output_html .gi { color: #008400 } /* Generic.Inserted */\n.output_html .go { color: #717171 } /* Generic.Output */\n.output_html .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.output_html .gs { font-weight: bold } /* Generic.Strong */\n.output_html .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.output_html .gt { color: #04D } /* Generic.Traceback */\n.output_html .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.output_html .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.output_html .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.output_html .kp { color: #008000 } /* Keyword.Pseudo */\n.output_html .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.output_html .kt { color: #B00040 } /* Keyword.Type */\n.output_html .m { color: #666 } /* Literal.Number */\n.output_html .s { color: #BA2121 } /* Literal.String */\n.output_html .na { color: #687822 } /* Name.Attribute */\n.output_html .nb { color: #008000 } /* Name.Builtin */\n.output_html .nc { color: #00F; font-weight: bold } /* Name.Class */\n.output_html .no { color: #800 } /* Name.Constant */\n.output_html .nd { color: #A2F } /* Name.Decorator */\n.output_html .ni { color: #717171; font-weight: bold } /* Name.Entity */\n.output_html .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */\n.output_html .nf { color: #00F } /* Name.Function */\n.output_html .nl { color: #767600 } /* Name.Label */\n.output_html .nn { color: #00F; font-weight: bold } /* Name.Namespace */\n.output_html .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.output_html .nv { color: #19177C } /* Name.Variable */\n.output_html .ow { color: #A2F; font-weight: bold } /* Operator.Word */\n.output_html .w { color: #BBB } /* Text.Whitespace */\n.output_html .mb { color: #666 } /* Literal.Number.Bin */\n.output_html .mf { color: #666 } /* Literal.Number.Float */\n.output_html .mh { color: #666 } /* Literal.Number.Hex */\n.output_html .mi { color: #666 } /* Literal.Number.Integer */\n.output_html .mo { color: #666 } /* Literal.Number.Oct */\n.output_html .sa { color: #BA2121 } /* Literal.String.Affix */\n.output_html .sb { color: #BA2121 } /* Literal.String.Backtick */\n.output_html .sc { color: #BA2121 } /* Literal.String.Char */\n.output_html .dl { color: #BA2121 } /* Literal.String.Delimiter */\n.output_html .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n.output_html .s2 { color: #BA2121 } /* Literal.String.Double */\n.output_html .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */\n.output_html .sh { color: #BA2121 } /* Literal.String.Heredoc */\n.output_html .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */\n.output_html .sx { color: #008000 } /* Literal.String.Other */\n.output_html .sr { color: #A45A77 } /* Literal.String.Regex */\n.output_html .s1 { color: #BA2121 } /* Literal.String.Single */\n.output_html .ss { color: #19177C } /* Literal.String.Symbol */\n.output_html .bp { color: #008000 } /* Name.Builtin.Pseudo */\n.output_html .fm { color: #00F } /* Name.Function.Magic */\n.output_html .vc { color: #19177C } /* Name.Variable.Class */\n.output_html .vg { color: #19177C } /* Name.Variable.Global */\n.output_html .vi { color: #19177C } /* Name.Variable.Instance */\n.output_html .vm { color: #19177C } /* Name.Variable.Magic */\n.output_html .il { color: #666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MultiStatesComp</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ImplicitComponent</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">initialize</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">,</span> <span class=\"n\">types</span><span class=\"o\">=</span><span class=\"nb\">int</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;force_vector&#39;</span><span class=\"p\">,</span> <span class=\"n\">types</span><span class=\"o\">=</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">ndarray</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_rhs&#39;</span><span class=\"p\">,</span> <span class=\"n\">types</span><span class=\"o\">=</span><span class=\"nb\">int</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">num_elements</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">num_nodes</span> <span class=\"o\">=</span> <span class=\"n\">num_elements</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n        <span class=\"n\">size</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">num_nodes</span> <span class=\"o\">+</span> <span class=\"mi\">2</span>\n        <span class=\"n\">num_rhs</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_rhs&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;K_local&#39;</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"n\">num_elements</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">))</span>\n        <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_rhs</span><span class=\"p\">):</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_output</span><span class=\"p\">(</span><span class=\"s1\">&#39;d_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"n\">size</span><span class=\"p\">)</span>\n\n        <span class=\"n\">cols</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"mi\">16</span><span class=\"o\">*</span><span class=\"n\">num_elements</span><span class=\"p\">)</span>\n        <span class=\"n\">rows</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">repeat</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"mi\">4</span><span class=\"p\">)</span>\n        <span class=\"n\">rows</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">rows</span><span class=\"p\">,</span> <span class=\"n\">num_elements</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">repeat</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"n\">num_elements</span><span class=\"p\">),</span> <span class=\"mi\">16</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"mi\">2</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_rhs</span><span class=\"p\">):</span>\n            <span class=\"n\">disp</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;d_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"n\">disp</span><span class=\"p\">,</span> <span class=\"s1\">&#39;K_local&#39;</span><span class=\"p\">,</span> <span class=\"n\">rows</span><span class=\"o\">=</span><span class=\"n\">rows</span><span class=\"p\">,</span> <span class=\"n\">cols</span><span class=\"o\">=</span><span class=\"n\">cols</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"n\">disp</span><span class=\"p\">,</span> <span class=\"n\">disp</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">apply_nonlinear</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">residuals</span><span class=\"p\">):</span>\n        <span class=\"n\">num_rhs</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_rhs&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">K</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assemble_CSC_K</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">)</span>\n        <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_rhs</span><span class=\"p\">):</span>\n            <span class=\"n\">force_vector</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">([</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;force_vector&#39;</span><span class=\"p\">][:,</span> <span class=\"n\">j</span><span class=\"p\">],</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)])</span>\n            <span class=\"n\">residuals</span><span class=\"p\">[</span><span class=\"s1\">&#39;d_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">K</span><span class=\"o\">.</span><span class=\"n\">dot</span><span class=\"p\">(</span><span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;d_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">])</span> <span class=\"o\">-</span> <span class=\"n\">force_vector</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">solve_nonlinear</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">outputs</span><span class=\"p\">):</span>\n        <span class=\"n\">num_rhs</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_rhs&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">K</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assemble_CSC_K</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">lu</span> <span class=\"o\">=</span> <span class=\"n\">splu</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">K</span><span class=\"p\">)</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_rhs</span><span class=\"p\">):</span>\n\n            <span class=\"n\">force_vector</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">concatenate</span><span class=\"p\">([</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;force_vector&#39;</span><span class=\"p\">][:,</span> <span class=\"n\">j</span><span class=\"p\">],</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">)])</span>\n            <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;d_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">lu</span><span class=\"o\">.</span><span class=\"n\">solve</span><span class=\"p\">(</span><span class=\"n\">force_vector</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">linearize</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">outputs</span><span class=\"p\">,</span> <span class=\"n\">jacobian</span><span class=\"p\">):</span>\n        <span class=\"n\">num_rhs</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_rhs&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">num_elements</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">K</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assemble_CSC_K</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">lu</span> <span class=\"o\">=</span> <span class=\"n\">splu</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">K</span><span class=\"p\">)</span>\n\n        <span class=\"n\">i_elem</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"mi\">4</span><span class=\"p\">)</span>\n        <span class=\"n\">i_d</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">i_elem</span><span class=\"p\">,</span> <span class=\"n\">num_elements</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">repeat</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"n\">num_elements</span><span class=\"p\">),</span> <span class=\"mi\">16</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"mi\">2</span>\n\n        <span class=\"n\">K_dense</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">K</span><span class=\"o\">.</span><span class=\"n\">toarray</span><span class=\"p\">()</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_rhs</span><span class=\"p\">):</span>\n            <span class=\"n\">disp</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;d_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span>\n            <span class=\"n\">jacobian</span><span class=\"p\">[</span><span class=\"n\">disp</span><span class=\"p\">,</span> <span class=\"s1\">&#39;K_local&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"n\">disp</span><span class=\"p\">][</span><span class=\"n\">i_d</span><span class=\"p\">]</span>\n            <span class=\"n\">jacobian</span><span class=\"p\">[</span><span class=\"n\">disp</span><span class=\"p\">,</span> <span class=\"n\">disp</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">K_dense</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">solve_linear</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">d_outputs</span><span class=\"p\">,</span> <span class=\"n\">d_residuals</span><span class=\"p\">,</span> <span class=\"n\">mode</span><span class=\"p\">):</span>\n        <span class=\"n\">num_rhs</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_rhs&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_rhs</span><span class=\"p\">):</span>\n            <span class=\"n\">disp</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;d_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span>\n\n            <span class=\"k\">if</span> <span class=\"n\">mode</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;fwd&#39;</span><span class=\"p\">:</span>\n                <span class=\"n\">d_outputs</span><span class=\"p\">[</span><span class=\"n\">disp</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">lu</span><span class=\"o\">.</span><span class=\"n\">solve</span><span class=\"p\">(</span><span class=\"n\">d_residuals</span><span class=\"p\">[</span><span class=\"n\">disp</span><span class=\"p\">])</span>\n            <span class=\"k\">else</span><span class=\"p\">:</span>\n                <span class=\"n\">d_residuals</span><span class=\"p\">[</span><span class=\"n\">disp</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">lu</span><span class=\"o\">.</span><span class=\"n\">solve</span><span class=\"p\">(</span><span class=\"n\">d_outputs</span><span class=\"p\">[</span><span class=\"n\">disp</span><span class=\"p\">])</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">assemble_CSC_K</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Assemble the stiffness matrix in sparse CSC format.</span>\n\n<span class=\"sd\">        Returns</span>\n<span class=\"sd\">        -------</span>\n<span class=\"sd\">        ndarray</span>\n<span class=\"sd\">            Stiffness matrix as dense ndarray.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">num_elements</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">num_nodes</span> <span class=\"o\">=</span> <span class=\"n\">num_elements</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n        <span class=\"n\">num_entry</span> <span class=\"o\">=</span> <span class=\"n\">num_elements</span> <span class=\"o\">*</span> <span class=\"mi\">12</span> <span class=\"o\">+</span> <span class=\"mi\">4</span>\n        <span class=\"n\">ndim</span> <span class=\"o\">=</span> <span class=\"n\">num_entry</span> <span class=\"o\">+</span> <span class=\"mi\">4</span>\n\n        <span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">((</span><span class=\"n\">ndim</span><span class=\"p\">,</span> <span class=\"p\">),</span> <span class=\"n\">dtype</span><span class=\"o\">=</span><span class=\"n\">inputs</span><span class=\"o\">.</span><span class=\"n\">_get_data</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">dtype</span><span class=\"p\">)</span>\n        <span class=\"n\">cols</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">empty</span><span class=\"p\">((</span><span class=\"n\">ndim</span><span class=\"p\">,</span> <span class=\"p\">))</span>\n        <span class=\"n\">rows</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">empty</span><span class=\"p\">((</span><span class=\"n\">ndim</span><span class=\"p\">,</span> <span class=\"p\">))</span>\n\n        <span class=\"c1\"># First element.</span>\n        <span class=\"n\">data</span><span class=\"p\">[:</span><span class=\"mi\">16</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;K_local&#39;</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"p\">:]</span><span class=\"o\">.</span><span class=\"n\">flat</span>\n        <span class=\"n\">cols</span><span class=\"p\">[:</span><span class=\"mi\">16</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"mi\">4</span><span class=\"p\">)</span>\n        <span class=\"n\">rows</span><span class=\"p\">[:</span><span class=\"mi\">16</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">repeat</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"mi\">4</span><span class=\"p\">)</span>\n\n        <span class=\"n\">j</span> <span class=\"o\">=</span> <span class=\"mi\">16</span>\n        <span class=\"k\">for</span> <span class=\"n\">ind</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">num_elements</span><span class=\"p\">):</span>\n            <span class=\"n\">ind1</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">ind</span>\n            <span class=\"n\">K</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;K_local&#39;</span><span class=\"p\">][</span><span class=\"n\">ind</span><span class=\"p\">,</span> <span class=\"p\">:,</span> <span class=\"p\">:]</span>\n\n            <span class=\"c1\"># NW quadrant gets summed with previous connected element.</span>\n            <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"o\">-</span><span class=\"mi\">6</span><span class=\"p\">:</span><span class=\"n\">j</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"p\">]</span> <span class=\"o\">+=</span> <span class=\"n\">K</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"p\">:</span><span class=\"mi\">2</span><span class=\"p\">]</span>\n            <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">:</span><span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">+=</span> <span class=\"n\">K</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"p\">:</span><span class=\"mi\">2</span><span class=\"p\">]</span>\n\n            <span class=\"c1\"># NE quadrant</span>\n            <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">:</span><span class=\"n\">j</span><span class=\"o\">+</span><span class=\"mi\">4</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">K</span><span class=\"p\">[:</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">:]</span><span class=\"o\">.</span><span class=\"n\">flat</span>\n            <span class=\"n\">rows</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">:</span><span class=\"n\">j</span><span class=\"o\">+</span><span class=\"mi\">4</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">ind1</span><span class=\"p\">,</span> <span class=\"n\">ind1</span><span class=\"p\">,</span> <span class=\"n\">ind1</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">ind1</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">])</span>\n            <span class=\"n\">cols</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"p\">:</span><span class=\"n\">j</span><span class=\"o\">+</span><span class=\"mi\">4</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">array</span><span class=\"p\">([</span><span class=\"n\">ind1</span> <span class=\"o\">+</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">ind1</span> <span class=\"o\">+</span> <span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"n\">ind1</span> <span class=\"o\">+</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">ind1</span> <span class=\"o\">+</span> <span class=\"mi\">3</span><span class=\"p\">])</span>\n\n            <span class=\"c1\"># SE and SW quadrants together</span>\n            <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"o\">+</span><span class=\"mi\">4</span><span class=\"p\">:</span><span class=\"n\">j</span><span class=\"o\">+</span><span class=\"mi\">12</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">K</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">:,</span> <span class=\"p\">:]</span><span class=\"o\">.</span><span class=\"n\">flat</span>\n            <span class=\"n\">rows</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"o\">+</span><span class=\"mi\">4</span><span class=\"p\">:</span><span class=\"n\">j</span><span class=\"o\">+</span><span class=\"mi\">12</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">repeat</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"n\">ind1</span> <span class=\"o\">+</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">ind1</span> <span class=\"o\">+</span> <span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"mi\">4</span><span class=\"p\">)</span>\n            <span class=\"n\">cols</span><span class=\"p\">[</span><span class=\"n\">j</span><span class=\"o\">+</span><span class=\"mi\">4</span><span class=\"p\">:</span><span class=\"n\">j</span><span class=\"o\">+</span><span class=\"mi\">12</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">tile</span><span class=\"p\">(</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"n\">ind1</span><span class=\"p\">,</span> <span class=\"n\">ind1</span> <span class=\"o\">+</span> <span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"mi\">2</span><span class=\"p\">)</span>\n\n            <span class=\"n\">j</span> <span class=\"o\">+=</span> <span class=\"mi\">12</span>\n\n        <span class=\"n\">data</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"p\">:]</span> <span class=\"o\">=</span> <span class=\"mf\">1.0</span>\n        <span class=\"n\">rows</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">num_nodes</span>\n        <span class=\"n\">rows</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">3</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">num_nodes</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n        <span class=\"n\">rows</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mf\">0.0</span>\n        <span class=\"n\">rows</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mf\">1.0</span>\n        <span class=\"n\">cols</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mf\">0.0</span>\n        <span class=\"n\">cols</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">3</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mf\">1.0</span>\n        <span class=\"n\">cols</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">num_nodes</span>\n        <span class=\"n\">cols</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">num_nodes</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n\n        <span class=\"n\">n_K</span> <span class=\"o\">=</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">num_nodes</span> <span class=\"o\">+</span> <span class=\"mi\">2</span>\n        <span class=\"k\">return</span> <span class=\"n\">coo_matrix</span><span class=\"p\">((</span><span class=\"n\">data</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"n\">rows</span><span class=\"p\">,</span> <span class=\"n\">cols</span><span class=\"p\">)),</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"p\">(</span><span class=\"n\">n_K</span><span class=\"p\">,</span> <span class=\"n\">n_K</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">tocsc</span><span class=\"p\">()</span>\n</pre></div>\n",
      "application/papermill.record/text/latex": "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{MultiStatesComp}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{ImplicitComponent}\\PY{p}{)}\\PY{p}{:}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{initialize}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{types}\\PY{o}{=}\\PY{n+nb}{int}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{force\\PYZus{}vector}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{types}\\PY{o}{=}\\PY{n}{np}\\PY{o}{.}\\PY{n}{ndarray}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}rhs}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{types}\\PY{o}{=}\\PY{n+nb}{int}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{num\\PYZus{}elements} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{num\\PYZus{}nodes} \\PY{o}{=} \\PY{n}{num\\PYZus{}elements} \\PY{o}{+} \\PY{l+m+mi}{1}\n        \\PY{n}{size} \\PY{o}{=} \\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{num\\PYZus{}nodes} \\PY{o}{+} \\PY{l+m+mi}{2}\n        \\PY{n}{num\\PYZus{}rhs} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}rhs}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{K\\PYZus{}local}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{shape}\\PY{o}{=}\\PY{p}{(}\\PY{n}{num\\PYZus{}elements}\\PY{p}{,} \\PY{l+m+mi}{4}\\PY{p}{,} \\PY{l+m+mi}{4}\\PY{p}{)}\\PY{p}{)}\n        \\PY{k}{for} \\PY{n}{j} \\PY{o+ow}{in} \\PY{n+nb}{range}\\PY{p}{(}\\PY{n}{num\\PYZus{}rhs}\\PY{p}{)}\\PY{p}{:}\n            \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}output}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{,} \\PY{n}{shape}\\PY{o}{=}\\PY{n}{size}\\PY{p}{)}\n\n        \\PY{n}{cols} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{arange}\\PY{p}{(}\\PY{l+m+mi}{16}\\PY{o}{*}\\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\n        \\PY{n}{rows} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{repeat}\\PY{p}{(}\\PY{n}{np}\\PY{o}{.}\\PY{n}{arange}\\PY{p}{(}\\PY{l+m+mi}{4}\\PY{p}{)}\\PY{p}{,} \\PY{l+m+mi}{4}\\PY{p}{)}\n        \\PY{n}{rows} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{tile}\\PY{p}{(}\\PY{n}{rows}\\PY{p}{,} \\PY{n}{num\\PYZus{}elements}\\PY{p}{)} \\PY{o}{+} \\PY{n}{np}\\PY{o}{.}\\PY{n}{repeat}\\PY{p}{(}\\PY{n}{np}\\PY{o}{.}\\PY{n}{arange}\\PY{p}{(}\\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\\PY{p}{,} \\PY{l+m+mi}{16}\\PY{p}{)} \\PY{o}{*} \\PY{l+m+mi}{2}\n\n        \\PY{k}{for} \\PY{n}{j} \\PY{o+ow}{in} \\PY{n+nb}{range}\\PY{p}{(}\\PY{n}{num\\PYZus{}rhs}\\PY{p}{)}\\PY{p}{:}\n            \\PY{n}{disp} \\PY{o}{=} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\n\n            \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{n}{disp}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{K\\PYZus{}local}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{rows}\\PY{o}{=}\\PY{n}{rows}\\PY{p}{,} \\PY{n}{cols}\\PY{o}{=}\\PY{n}{cols}\\PY{p}{)}\n            \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{n}{disp}\\PY{p}{,} \\PY{n}{disp}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{apply\\PYZus{}nonlinear}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{,} \\PY{n}{residuals}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{num\\PYZus{}rhs} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}rhs}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{K} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{assemble\\PYZus{}CSC\\PYZus{}K}\\PY{p}{(}\\PY{n}{inputs}\\PY{p}{)}\n        \\PY{k}{for} \\PY{n}{j} \\PY{o+ow}{in} \\PY{n+nb}{range}\\PY{p}{(}\\PY{n}{num\\PYZus{}rhs}\\PY{p}{)}\\PY{p}{:}\n            \\PY{n}{force\\PYZus{}vector} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{concatenate}\\PY{p}{(}\\PY{p}{[}\\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{force\\PYZus{}vector}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{[}\\PY{p}{:}\\PY{p}{,} \\PY{n}{j}\\PY{p}{]}\\PY{p}{,} \\PY{n}{np}\\PY{o}{.}\\PY{n}{zeros}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\n            \\PY{n}{residuals}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{]} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{K}\\PY{o}{.}\\PY{n}{dot}\\PY{p}{(}\\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{]}\\PY{p}{)} \\PY{o}{\\PYZhy{}} \\PY{n}{force\\PYZus{}vector}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{solve\\PYZus{}nonlinear}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{num\\PYZus{}rhs} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}rhs}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{K} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{assemble\\PYZus{}CSC\\PYZus{}K}\\PY{p}{(}\\PY{n}{inputs}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{lu} \\PY{o}{=} \\PY{n}{splu}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{K}\\PY{p}{)}\n\n        \\PY{k}{for} \\PY{n}{j} \\PY{o+ow}{in} \\PY{n+nb}{range}\\PY{p}{(}\\PY{n}{num\\PYZus{}rhs}\\PY{p}{)}\\PY{p}{:}\n\n            \\PY{n}{force\\PYZus{}vector} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{concatenate}\\PY{p}{(}\\PY{p}{[}\\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{force\\PYZus{}vector}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{[}\\PY{p}{:}\\PY{p}{,} \\PY{n}{j}\\PY{p}{]}\\PY{p}{,} \\PY{n}{np}\\PY{o}{.}\\PY{n}{zeros}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\n            \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{]} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{lu}\\PY{o}{.}\\PY{n}{solve}\\PY{p}{(}\\PY{n}{force\\PYZus{}vector}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{linearize}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{,} \\PY{n}{jacobian}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{num\\PYZus{}rhs} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}rhs}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{num\\PYZus{}elements} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{K} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{assemble\\PYZus{}CSC\\PYZus{}K}\\PY{p}{(}\\PY{n}{inputs}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{lu} \\PY{o}{=} \\PY{n}{splu}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{K}\\PY{p}{)}\n\n        \\PY{n}{i\\PYZus{}elem} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{tile}\\PY{p}{(}\\PY{n}{np}\\PY{o}{.}\\PY{n}{arange}\\PY{p}{(}\\PY{l+m+mi}{4}\\PY{p}{)}\\PY{p}{,} \\PY{l+m+mi}{4}\\PY{p}{)}\n        \\PY{n}{i\\PYZus{}d} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{tile}\\PY{p}{(}\\PY{n}{i\\PYZus{}elem}\\PY{p}{,} \\PY{n}{num\\PYZus{}elements}\\PY{p}{)} \\PY{o}{+} \\PY{n}{np}\\PY{o}{.}\\PY{n}{repeat}\\PY{p}{(}\\PY{n}{np}\\PY{o}{.}\\PY{n}{arange}\\PY{p}{(}\\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\\PY{p}{,} \\PY{l+m+mi}{16}\\PY{p}{)} \\PY{o}{*} \\PY{l+m+mi}{2}\n\n        \\PY{n}{K\\PYZus{}dense} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{K}\\PY{o}{.}\\PY{n}{toarray}\\PY{p}{(}\\PY{p}{)}\n\n        \\PY{k}{for} \\PY{n}{j} \\PY{o+ow}{in} \\PY{n+nb}{range}\\PY{p}{(}\\PY{n}{num\\PYZus{}rhs}\\PY{p}{)}\\PY{p}{:}\n            \\PY{n}{disp} \\PY{o}{=} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\n            \\PY{n}{jacobian}\\PY{p}{[}\\PY{n}{disp}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{K\\PYZus{}local}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{n}{outputs}\\PY{p}{[}\\PY{n}{disp}\\PY{p}{]}\\PY{p}{[}\\PY{n}{i\\PYZus{}d}\\PY{p}{]}\n            \\PY{n}{jacobian}\\PY{p}{[}\\PY{n}{disp}\\PY{p}{,} \\PY{n}{disp}\\PY{p}{]} \\PY{o}{=} \\PY{n}{K\\PYZus{}dense}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{solve\\PYZus{}linear}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{d\\PYZus{}outputs}\\PY{p}{,} \\PY{n}{d\\PYZus{}residuals}\\PY{p}{,} \\PY{n}{mode}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{num\\PYZus{}rhs} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}rhs}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{k}{for} \\PY{n}{j} \\PY{o+ow}{in} \\PY{n+nb}{range}\\PY{p}{(}\\PY{n}{num\\PYZus{}rhs}\\PY{p}{)}\\PY{p}{:}\n            \\PY{n}{disp} \\PY{o}{=} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{d\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\n\n            \\PY{k}{if} \\PY{n}{mode} \\PY{o}{==} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{fwd}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{:}\n                \\PY{n}{d\\PYZus{}outputs}\\PY{p}{[}\\PY{n}{disp}\\PY{p}{]} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{lu}\\PY{o}{.}\\PY{n}{solve}\\PY{p}{(}\\PY{n}{d\\PYZus{}residuals}\\PY{p}{[}\\PY{n}{disp}\\PY{p}{]}\\PY{p}{)}\n            \\PY{k}{else}\\PY{p}{:}\n                \\PY{n}{d\\PYZus{}residuals}\\PY{p}{[}\\PY{n}{disp}\\PY{p}{]} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{lu}\\PY{o}{.}\\PY{n}{solve}\\PY{p}{(}\\PY{n}{d\\PYZus{}outputs}\\PY{p}{[}\\PY{n}{disp}\\PY{p}{]}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{assemble\\PYZus{}CSC\\PYZus{}K}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{)}\\PY{p}{:}\n\\PY{+w}{        }\\PY{l+s+sd}{\\PYZdq{}\\PYZdq{}\\PYZdq{}}\n\\PY{l+s+sd}{        Assemble the stiffness matrix in sparse CSC format.}\n\n\\PY{l+s+sd}{        Returns}\n\\PY{l+s+sd}{        \\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}\\PYZhy{}}\n\\PY{l+s+sd}{        ndarray}\n\\PY{l+s+sd}{            Stiffness matrix as dense ndarray.}\n\\PY{l+s+sd}{        \\PYZdq{}\\PYZdq{}\\PYZdq{}}\n        \\PY{n}{num\\PYZus{}elements} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{num\\PYZus{}nodes} \\PY{o}{=} \\PY{n}{num\\PYZus{}elements} \\PY{o}{+} \\PY{l+m+mi}{1}\n        \\PY{n}{num\\PYZus{}entry} \\PY{o}{=} \\PY{n}{num\\PYZus{}elements} \\PY{o}{*} \\PY{l+m+mi}{12} \\PY{o}{+} \\PY{l+m+mi}{4}\n        \\PY{n}{ndim} \\PY{o}{=} \\PY{n}{num\\PYZus{}entry} \\PY{o}{+} \\PY{l+m+mi}{4}\n\n        \\PY{n}{data} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{zeros}\\PY{p}{(}\\PY{p}{(}\\PY{n}{ndim}\\PY{p}{,} \\PY{p}{)}\\PY{p}{,} \\PY{n}{dtype}\\PY{o}{=}\\PY{n}{inputs}\\PY{o}{.}\\PY{n}{\\PYZus{}get\\PYZus{}data}\\PY{p}{(}\\PY{p}{)}\\PY{o}{.}\\PY{n}{dtype}\\PY{p}{)}\n        \\PY{n}{cols} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{empty}\\PY{p}{(}\\PY{p}{(}\\PY{n}{ndim}\\PY{p}{,} \\PY{p}{)}\\PY{p}{)}\n        \\PY{n}{rows} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{empty}\\PY{p}{(}\\PY{p}{(}\\PY{n}{ndim}\\PY{p}{,} \\PY{p}{)}\\PY{p}{)}\n\n        \\PY{c+c1}{\\PYZsh{} First element.}\n        \\PY{n}{data}\\PY{p}{[}\\PY{p}{:}\\PY{l+m+mi}{16}\\PY{p}{]} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{K\\PYZus{}local}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{[}\\PY{l+m+mi}{0}\\PY{p}{,} \\PY{p}{:}\\PY{p}{,} \\PY{p}{:}\\PY{p}{]}\\PY{o}{.}\\PY{n}{flat}\n        \\PY{n}{cols}\\PY{p}{[}\\PY{p}{:}\\PY{l+m+mi}{16}\\PY{p}{]} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{tile}\\PY{p}{(}\\PY{n}{np}\\PY{o}{.}\\PY{n}{arange}\\PY{p}{(}\\PY{l+m+mi}{4}\\PY{p}{)}\\PY{p}{,} \\PY{l+m+mi}{4}\\PY{p}{)}\n        \\PY{n}{rows}\\PY{p}{[}\\PY{p}{:}\\PY{l+m+mi}{16}\\PY{p}{]} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{repeat}\\PY{p}{(}\\PY{n}{np}\\PY{o}{.}\\PY{n}{arange}\\PY{p}{(}\\PY{l+m+mi}{4}\\PY{p}{)}\\PY{p}{,} \\PY{l+m+mi}{4}\\PY{p}{)}\n\n        \\PY{n}{j} \\PY{o}{=} \\PY{l+m+mi}{16}\n        \\PY{k}{for} \\PY{n}{ind} \\PY{o+ow}{in} \\PY{n+nb}{range}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{,} \\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\\PY{p}{:}\n            \\PY{n}{ind1} \\PY{o}{=} \\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{ind}\n            \\PY{n}{K} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{K\\PYZus{}local}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{[}\\PY{n}{ind}\\PY{p}{,} \\PY{p}{:}\\PY{p}{,} \\PY{p}{:}\\PY{p}{]}\n\n            \\PY{c+c1}{\\PYZsh{} NW quadrant gets summed with previous connected element.}\n            \\PY{n}{data}\\PY{p}{[}\\PY{n}{j}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{6}\\PY{p}{:}\\PY{n}{j}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{4}\\PY{p}{]} \\PY{o}{+}\\PY{o}{=} \\PY{n}{K}\\PY{p}{[}\\PY{l+m+mi}{0}\\PY{p}{,} \\PY{p}{:}\\PY{l+m+mi}{2}\\PY{p}{]}\n            \\PY{n}{data}\\PY{p}{[}\\PY{n}{j}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{2}\\PY{p}{:}\\PY{n}{j}\\PY{p}{]} \\PY{o}{+}\\PY{o}{=} \\PY{n}{K}\\PY{p}{[}\\PY{l+m+mi}{1}\\PY{p}{,} \\PY{p}{:}\\PY{l+m+mi}{2}\\PY{p}{]}\n\n            \\PY{c+c1}{\\PYZsh{} NE quadrant}\n            \\PY{n}{data}\\PY{p}{[}\\PY{n}{j}\\PY{p}{:}\\PY{n}{j}\\PY{o}{+}\\PY{l+m+mi}{4}\\PY{p}{]} \\PY{o}{=} \\PY{n}{K}\\PY{p}{[}\\PY{p}{:}\\PY{l+m+mi}{2}\\PY{p}{,} \\PY{l+m+mi}{2}\\PY{p}{:}\\PY{p}{]}\\PY{o}{.}\\PY{n}{flat}\n            \\PY{n}{rows}\\PY{p}{[}\\PY{n}{j}\\PY{p}{:}\\PY{n}{j}\\PY{o}{+}\\PY{l+m+mi}{4}\\PY{p}{]} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{array}\\PY{p}{(}\\PY{p}{[}\\PY{n}{ind1}\\PY{p}{,} \\PY{n}{ind1}\\PY{p}{,} \\PY{n}{ind1} \\PY{o}{+} \\PY{l+m+mi}{1}\\PY{p}{,} \\PY{n}{ind1} \\PY{o}{+} \\PY{l+m+mi}{1}\\PY{p}{]}\\PY{p}{)}\n            \\PY{n}{cols}\\PY{p}{[}\\PY{n}{j}\\PY{p}{:}\\PY{n}{j}\\PY{o}{+}\\PY{l+m+mi}{4}\\PY{p}{]} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{array}\\PY{p}{(}\\PY{p}{[}\\PY{n}{ind1} \\PY{o}{+} \\PY{l+m+mi}{2}\\PY{p}{,} \\PY{n}{ind1} \\PY{o}{+} \\PY{l+m+mi}{3}\\PY{p}{,} \\PY{n}{ind1} \\PY{o}{+} \\PY{l+m+mi}{2}\\PY{p}{,} \\PY{n}{ind1} \\PY{o}{+} \\PY{l+m+mi}{3}\\PY{p}{]}\\PY{p}{)}\n\n            \\PY{c+c1}{\\PYZsh{} SE and SW quadrants together}\n            \\PY{n}{data}\\PY{p}{[}\\PY{n}{j}\\PY{o}{+}\\PY{l+m+mi}{4}\\PY{p}{:}\\PY{n}{j}\\PY{o}{+}\\PY{l+m+mi}{12}\\PY{p}{]} \\PY{o}{=} \\PY{n}{K}\\PY{p}{[}\\PY{l+m+mi}{2}\\PY{p}{:}\\PY{p}{,} \\PY{p}{:}\\PY{p}{]}\\PY{o}{.}\\PY{n}{flat}\n            \\PY{n}{rows}\\PY{p}{[}\\PY{n}{j}\\PY{o}{+}\\PY{l+m+mi}{4}\\PY{p}{:}\\PY{n}{j}\\PY{o}{+}\\PY{l+m+mi}{12}\\PY{p}{]} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{repeat}\\PY{p}{(}\\PY{n}{np}\\PY{o}{.}\\PY{n}{arange}\\PY{p}{(}\\PY{n}{ind1} \\PY{o}{+} \\PY{l+m+mi}{2}\\PY{p}{,} \\PY{n}{ind1} \\PY{o}{+} \\PY{l+m+mi}{4}\\PY{p}{)}\\PY{p}{,} \\PY{l+m+mi}{4}\\PY{p}{)}\n            \\PY{n}{cols}\\PY{p}{[}\\PY{n}{j}\\PY{o}{+}\\PY{l+m+mi}{4}\\PY{p}{:}\\PY{n}{j}\\PY{o}{+}\\PY{l+m+mi}{12}\\PY{p}{]} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{tile}\\PY{p}{(}\\PY{n}{np}\\PY{o}{.}\\PY{n}{arange}\\PY{p}{(}\\PY{n}{ind1}\\PY{p}{,} \\PY{n}{ind1} \\PY{o}{+} \\PY{l+m+mi}{4}\\PY{p}{)}\\PY{p}{,} \\PY{l+m+mi}{2}\\PY{p}{)}\n\n            \\PY{n}{j} \\PY{o}{+}\\PY{o}{=} \\PY{l+m+mi}{12}\n\n        \\PY{n}{data}\\PY{p}{[}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{4}\\PY{p}{:}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mf}{1.0}\n        \\PY{n}{rows}\\PY{p}{[}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{4}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{num\\PYZus{}nodes}\n        \\PY{n}{rows}\\PY{p}{[}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{3}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{num\\PYZus{}nodes} \\PY{o}{+} \\PY{l+m+mi}{1}\n        \\PY{n}{rows}\\PY{p}{[}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{2}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mf}{0.0}\n        \\PY{n}{rows}\\PY{p}{[}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{1}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mf}{1.0}\n        \\PY{n}{cols}\\PY{p}{[}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{4}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mf}{0.0}\n        \\PY{n}{cols}\\PY{p}{[}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{3}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mf}{1.0}\n        \\PY{n}{cols}\\PY{p}{[}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{2}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{num\\PYZus{}nodes}\n        \\PY{n}{cols}\\PY{p}{[}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{1}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{num\\PYZus{}nodes} \\PY{o}{+} \\PY{l+m+mi}{1}\n\n        \\PY{n}{n\\PYZus{}K} \\PY{o}{=} \\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{num\\PYZus{}nodes} \\PY{o}{+} \\PY{l+m+mi}{2}\n        \\PY{k}{return} \\PY{n}{coo\\PYZus{}matrix}\\PY{p}{(}\\PY{p}{(}\\PY{n}{data}\\PY{p}{,} \\PY{p}{(}\\PY{n}{rows}\\PY{p}{,} \\PY{n}{cols}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{shape}\\PY{o}{=}\\PY{p}{(}\\PY{n}{n\\PYZus{}K}\\PY{p}{,} \\PY{n}{n\\PYZus{}K}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{tocsc}\\PY{p}{(}\\PY{p}{)}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class MultiStatesComp(om.ImplicitComponent):\n\n    def initialize(self):\n        self.options.declare('num_elements', types=int)\n        self.options.declare('force_vector', types=np.ndarray)\n        self.options.declare('num_rhs', types=int)\n\n    def setup(self):\n        num_elements = self.options['num_elements']\n        num_nodes = num_elements + 1\n        size = 2 * num_nodes + 2\n        num_rhs = self.options['num_rhs']\n\n        self.add_input('K_local', shape=(num_elements, 4, 4))\n        for j in range(num_rhs):\n            self.add_output('d_%d' % j, shape=size)\n\n        cols = np.arange(16*num_elements)\n        rows = np.repeat(np.arange(4), 4)\n        rows = np.tile(rows, num_elements) + np.repeat(np.arange(num_elements), 16) * 2\n\n        for j in range(num_rhs):\n            disp = 'd_%d' % j\n\n            self.declare_partials(disp, 'K_local', rows=rows, cols=cols)\n            self.declare_partials(disp, disp)\n\n    def apply_nonlinear(self, inputs, outputs, residuals):\n        num_rhs = self.options['num_rhs']\n\n        self.K = self.assemble_CSC_K(inputs)\n        for j in range(num_rhs):\n            force_vector = np.concatenate([self.options['force_vector'][:, j], np.zeros(2)])\n            residuals['d_%d' % j] = self.K.dot(outputs['d_%d' % j]) - force_vector\n\n    def solve_nonlinear(self, inputs, outputs):\n        num_rhs = self.options['num_rhs']\n\n        self.K = self.assemble_CSC_K(inputs)\n        self.lu = splu(self.K)\n\n        for j in range(num_rhs):\n\n            force_vector = np.concatenate([self.options['force_vector'][:, j], np.zeros(2)])\n            outputs['d_%d' % j] = self.lu.solve(force_vector)\n\n    def linearize(self, inputs, outputs, jacobian):\n        num_rhs = self.options['num_rhs']\n        num_elements = self.options['num_elements']\n\n        self.K = self.assemble_CSC_K(inputs)\n        self.lu = splu(self.K)\n\n        i_elem = np.tile(np.arange(4), 4)\n        i_d = np.tile(i_elem, num_elements) + np.repeat(np.arange(num_elements), 16) * 2\n\n        K_dense = self.K.toarray()\n\n        for j in range(num_rhs):\n            disp = 'd_%d' % j\n            jacobian[disp, 'K_local'] = outputs[disp][i_d]\n            jacobian[disp, disp] = K_dense\n\n    def solve_linear(self, d_outputs, d_residuals, mode):\n        num_rhs = self.options['num_rhs']\n\n        for j in range(num_rhs):\n            disp = 'd_%d' % j\n\n            if mode == 'fwd':\n                d_outputs[disp] = self.lu.solve(d_residuals[disp])\n            else:\n                d_residuals[disp] = self.lu.solve(d_outputs[disp])\n\n    def assemble_CSC_K(self, inputs):\n        \"\"\"\n        Assemble the stiffness matrix in sparse CSC format.\n\n        Returns\n        -------\n        ndarray\n            Stiffness matrix as dense ndarray.\n        \"\"\"\n        num_elements = self.options['num_elements']\n        num_nodes = num_elements + 1\n        num_entry = num_elements * 12 + 4\n        ndim = num_entry + 4\n\n        data = np.zeros((ndim, ), dtype=inputs._get_data().dtype)\n        cols = np.empty((ndim, ))\n        rows = np.empty((ndim, ))\n\n        # First element.\n        data[:16] = inputs['K_local'][0, :, :].flat\n        cols[:16] = np.tile(np.arange(4), 4)\n        rows[:16] = np.repeat(np.arange(4), 4)\n\n        j = 16\n        for ind in range(1, num_elements):\n            ind1 = 2 * ind\n            K = inputs['K_local'][ind, :, :]\n\n            # NW quadrant gets summed with previous connected element.\n            data[j-6:j-4] += K[0, :2]\n            data[j-2:j] += K[1, :2]\n\n            # NE quadrant\n            data[j:j+4] = K[:2, 2:].flat\n            rows[j:j+4] = np.array([ind1, ind1, ind1 + 1, ind1 + 1])\n            cols[j:j+4] = np.array([ind1 + 2, ind1 + 3, ind1 + 2, ind1 + 3])\n\n            # SE and SW quadrants together\n            data[j+4:j+12] = K[2:, :].flat\n            rows[j+4:j+12] = np.repeat(np.arange(ind1 + 2, ind1 + 4), 4)\n            cols[j+4:j+12] = np.tile(np.arange(ind1, ind1 + 4), 2)\n\n            j += 12\n\n        data[-4:] = 1.0\n        rows[-4] = 2 * num_nodes\n        rows[-3] = 2 * num_nodes + 1\n        rows[-2] = 0.0\n        rows[-1] = 1.0\n        cols[-4] = 0.0\n        cols[-3] = 1.0\n        cols[-2] = 2 * num_nodes\n        cols[-1] = 2 * num_nodes + 1\n\n        n_K = 2 * num_nodes + 2\n        return coo_matrix((data, (rows, cols)), shape=(n_K, n_K)).tocsc()"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src10"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src10\", get_code(\"openmdao.test_suite.test_examples.beam_optimization.components.multi_states_comp.MultiStatesComp\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f7c1fca",
   "metadata": {
    "papermill": {
     "duration": 0.001831,
     "end_time": "2026-10-02T14:40:55.629968+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:55.628137+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `MultiStatesComp` class definition \n",
    "\n",
    "{glue:}`code_src10`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "3abf53d4",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:55.634450Z",
     "iopub.status.busy": "2026-10-02T14:40:55.634322Z",
     "iopub.status.idle": "2026-10-02T14:40:55.640996Z",
     "shell.execute_reply": "2026-10-02T14:40:55.640361Z"
    },
    "papermill": {
     "duration": 0.009531,
     "end_time": "2026-10-02T14:40:55.641426+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:55.631895+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "application/papermill.record/text/html": "<style>pre { line-height: 125%; }\ntd.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\nspan.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\ntd.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\nspan.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n.output_html .hll { background-color: #ffffcc }\n.output_html { background: #f8f8f8; }\n.output_html .c { color: #3D7B7B; font-style: italic } /* Comment */\n.output_html .err { border: 1px solid #F00 } /* Error */\n.output_html .k { color: #008000; font-weight: bold } /* Keyword */\n.output_html .o { color: #666 } /* Operator */\n.output_html .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */\n.output_html .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */\n.output_html .cp { color: #9C6500 } /* Comment.Preproc */\n.output_html .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */\n.output_html .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */\n.output_html .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */\n.output_html .gd { color: #A00000 } /* Generic.Deleted */\n.output_html .ge { font-style: italic } /* Generic.Emph */\n.output_html .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */\n.output_html .gr { color: #E40000 } /* Generic.Error */\n.output_html .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.output_html .gi { color: #008400 } /* Generic.Inserted */\n.output_html .go { color: #717171 } /* Generic.Output */\n.output_html .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.output_html .gs { font-weight: bold } /* Generic.Strong */\n.output_html .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.output_html .gt { color: #04D } /* Generic.Traceback */\n.output_html .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.output_html .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.output_html .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.output_html .kp { color: #008000 } /* Keyword.Pseudo */\n.output_html .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.output_html .kt { color: #B00040 } /* Keyword.Type */\n.output_html .m { color: #666 } /* Literal.Number */\n.output_html .s { color: #BA2121 } /* Literal.String */\n.output_html .na { color: #687822 } /* Name.Attribute */\n.output_html .nb { color: #008000 } /* Name.Builtin */\n.output_html .nc { color: #00F; font-weight: bold } /* Name.Class */\n.output_html .no { color: #800 } /* Name.Constant */\n.output_html .nd { color: #A2F } /* Name.Decorator */\n.output_html .ni { color: #717171; font-weight: bold } /* Name.Entity */\n.output_html .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */\n.output_html .nf { color: #00F } /* Name.Function */\n.output_html .nl { color: #767600 } /* Name.Label */\n.output_html .nn { color: #00F; font-weight: bold } /* Name.Namespace */\n.output_html .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.output_html .nv { color: #19177C } /* Name.Variable */\n.output_html .ow { color: #A2F; font-weight: bold } /* Operator.Word */\n.output_html .w { color: #BBB } /* Text.Whitespace */\n.output_html .mb { color: #666 } /* Literal.Number.Bin */\n.output_html .mf { color: #666 } /* Literal.Number.Float */\n.output_html .mh { color: #666 } /* Literal.Number.Hex */\n.output_html .mi { color: #666 } /* Literal.Number.Integer */\n.output_html .mo { color: #666 } /* Literal.Number.Oct */\n.output_html .sa { color: #BA2121 } /* Literal.String.Affix */\n.output_html .sb { color: #BA2121 } /* Literal.String.Backtick */\n.output_html .sc { color: #BA2121 } /* Literal.String.Char */\n.output_html .dl { color: #BA2121 } /* Literal.String.Delimiter */\n.output_html .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n.output_html .s2 { color: #BA2121 } /* Literal.String.Double */\n.output_html .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */\n.output_html .sh { color: #BA2121 } /* Literal.String.Heredoc */\n.output_html .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */\n.output_html .sx { color: #008000 } /* Literal.String.Other */\n.output_html .sr { color: #A45A77 } /* Literal.String.Regex */\n.output_html .s1 { color: #BA2121 } /* Literal.String.Single */\n.output_html .ss { color: #19177C } /* Literal.String.Symbol */\n.output_html .bp { color: #008000 } /* Name.Builtin.Pseudo */\n.output_html .fm { color: #00F } /* Name.Function.Magic */\n.output_html .vc { color: #19177C } /* Name.Variable.Class */\n.output_html .vg { color: #19177C } /* Name.Variable.Global */\n.output_html .vi { color: #19177C } /* Name.Variable.Instance */\n.output_html .vm { color: #19177C } /* Name.Variable.Magic */\n.output_html .il { color: #666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MomentOfInertiaComp</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExplicitComponent</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">initialize</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">,</span> <span class=\"n\">types</span><span class=\"o\">=</span><span class=\"nb\">int</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;b&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">num_elements</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;h&#39;</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"n\">num_elements</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_output</span><span class=\"p\">(</span><span class=\"s1\">&#39;I&#39;</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"n\">num_elements</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup_partials</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">rows</span> <span class=\"o\">=</span> <span class=\"n\">cols</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">arange</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">])</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"s1\">&#39;I&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;h&#39;</span><span class=\"p\">,</span> <span class=\"n\">rows</span><span class=\"o\">=</span><span class=\"n\">rows</span><span class=\"p\">,</span> <span class=\"n\">cols</span><span class=\"o\">=</span><span class=\"n\">cols</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">outputs</span><span class=\"p\">):</span>\n        <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;I&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mf\">1.</span><span class=\"o\">/</span><span class=\"mf\">12.</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;b&#39;</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;h&#39;</span><span class=\"p\">]</span> <span class=\"o\">**</span> <span class=\"mi\">3</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute_partials</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">partials</span><span class=\"p\">):</span>\n        <span class=\"n\">partials</span><span class=\"p\">[</span><span class=\"s1\">&#39;I&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;h&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mf\">1.</span><span class=\"o\">/</span><span class=\"mf\">4.</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;b&#39;</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;h&#39;</span><span class=\"p\">]</span> <span class=\"o\">**</span> <span class=\"mi\">2</span>\n</pre></div>\n",
      "application/papermill.record/text/latex": "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{MomentOfInertiaComp}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{ExplicitComponent}\\PY{p}{)}\\PY{p}{:}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{initialize}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{types}\\PY{o}{=}\\PY{n+nb}{int}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{b}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{num\\PYZus{}elements} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{shape}\\PY{o}{=}\\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}output}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{I}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{shape}\\PY{o}{=}\\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup\\PYZus{}partials}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{rows} \\PY{o}{=} \\PY{n}{cols} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{arange}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{I}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{rows}\\PY{o}{=}\\PY{n}{rows}\\PY{p}{,} \\PY{n}{cols}\\PY{o}{=}\\PY{n}{cols}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{I}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mf}{1.}\\PY{o}{/}\\PY{l+m+mf}{12.} \\PY{o}{*} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{b}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{*} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{*}\\PY{o}{*} \\PY{l+m+mi}{3}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute\\PYZus{}partials}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{partials}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{partials}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{I}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{l+m+mf}{1.}\\PY{o}{/}\\PY{l+m+mf}{4.} \\PY{o}{*} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{b}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{*} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{*}\\PY{o}{*} \\PY{l+m+mi}{2}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class MomentOfInertiaComp(om.ExplicitComponent):\n\n    def initialize(self):\n        self.options.declare('num_elements', types=int)\n        self.options.declare('b')\n\n    def setup(self):\n        num_elements = self.options['num_elements']\n\n        self.add_input('h', shape=num_elements)\n        self.add_output('I', shape=num_elements)\n\n    def setup_partials(self):\n        rows = cols = np.arange(self.options['num_elements'])\n        self.declare_partials('I', 'h', rows=rows, cols=cols)\n\n    def compute(self, inputs, outputs):\n        outputs['I'] = 1./12. * self.options['b'] * inputs['h'] ** 3\n\n    def compute_partials(self, inputs, partials):\n        partials['I', 'h'] = 1./4. * self.options['b'] * inputs['h'] ** 2"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src11"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src11\", get_code(\"openmdao.test_suite.test_examples.beam_optimization.components.moment_comp.MomentOfInertiaComp\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7190aa42",
   "metadata": {
    "papermill": {
     "duration": 0.001535,
     "end_time": "2026-10-02T14:40:55.644447+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:55.642912+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `MomentOfInertiaComp` class definition \n",
    "\n",
    "{glue:}`code_src11`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "1a1b148f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:55.648244Z",
     "iopub.status.busy": "2026-10-02T14:40:55.648076Z",
     "iopub.status.idle": "2026-10-02T14:40:55.664610Z",
     "shell.execute_reply": "2026-10-02T14:40:55.664031Z"
    },
    "papermill": {
     "duration": 0.019286,
     "end_time": "2026-10-02T14:40:55.665232+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:55.645946+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "application/papermill.record/text/html": "<style>pre { line-height: 125%; }\ntd.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\nspan.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\ntd.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\nspan.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n.output_html .hll { background-color: #ffffcc }\n.output_html { background: #f8f8f8; }\n.output_html .c { color: #3D7B7B; font-style: italic } /* Comment */\n.output_html .err { border: 1px solid #F00 } /* Error */\n.output_html .k { color: #008000; font-weight: bold } /* Keyword */\n.output_html .o { color: #666 } /* Operator */\n.output_html .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */\n.output_html .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */\n.output_html .cp { color: #9C6500 } /* Comment.Preproc */\n.output_html .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */\n.output_html .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */\n.output_html .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */\n.output_html .gd { color: #A00000 } /* Generic.Deleted */\n.output_html .ge { font-style: italic } /* Generic.Emph */\n.output_html .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */\n.output_html .gr { color: #E40000 } /* Generic.Error */\n.output_html .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.output_html .gi { color: #008400 } /* Generic.Inserted */\n.output_html .go { color: #717171 } /* Generic.Output */\n.output_html .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.output_html .gs { font-weight: bold } /* Generic.Strong */\n.output_html .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.output_html .gt { color: #04D } /* Generic.Traceback */\n.output_html .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.output_html .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.output_html .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.output_html .kp { color: #008000 } /* Keyword.Pseudo */\n.output_html .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.output_html .kt { color: #B00040 } /* Keyword.Type */\n.output_html .m { color: #666 } /* Literal.Number */\n.output_html .s { color: #BA2121 } /* Literal.String */\n.output_html .na { color: #687822 } /* Name.Attribute */\n.output_html .nb { color: #008000 } /* Name.Builtin */\n.output_html .nc { color: #00F; font-weight: bold } /* Name.Class */\n.output_html .no { color: #800 } /* Name.Constant */\n.output_html .nd { color: #A2F } /* Name.Decorator */\n.output_html .ni { color: #717171; font-weight: bold } /* Name.Entity */\n.output_html .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */\n.output_html .nf { color: #00F } /* Name.Function */\n.output_html .nl { color: #767600 } /* Name.Label */\n.output_html .nn { color: #00F; font-weight: bold } /* Name.Namespace */\n.output_html .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.output_html .nv { color: #19177C } /* Name.Variable */\n.output_html .ow { color: #A2F; font-weight: bold } /* Operator.Word */\n.output_html .w { color: #BBB } /* Text.Whitespace */\n.output_html .mb { color: #666 } /* Literal.Number.Bin */\n.output_html .mf { color: #666 } /* Literal.Number.Float */\n.output_html .mh { color: #666 } /* Literal.Number.Hex */\n.output_html .mi { color: #666 } /* Literal.Number.Integer */\n.output_html .mo { color: #666 } /* Literal.Number.Oct */\n.output_html .sa { color: #BA2121 } /* Literal.String.Affix */\n.output_html .sb { color: #BA2121 } /* Literal.String.Backtick */\n.output_html .sc { color: #BA2121 } /* Literal.String.Char */\n.output_html .dl { color: #BA2121 } /* Literal.String.Delimiter */\n.output_html .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n.output_html .s2 { color: #BA2121 } /* Literal.String.Double */\n.output_html .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */\n.output_html .sh { color: #BA2121 } /* Literal.String.Heredoc */\n.output_html .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */\n.output_html .sx { color: #008000 } /* Literal.String.Other */\n.output_html .sr { color: #A45A77 } /* Literal.String.Regex */\n.output_html .s1 { color: #BA2121 } /* Literal.String.Single */\n.output_html .ss { color: #19177C } /* Literal.String.Symbol */\n.output_html .bp { color: #008000 } /* Name.Builtin.Pseudo */\n.output_html .fm { color: #00F } /* Name.Function.Magic */\n.output_html .vc { color: #19177C } /* Name.Variable.Class */\n.output_html .vg { color: #19177C } /* Name.Variable.Global */\n.output_html .vi { color: #19177C } /* Name.Variable.Instance */\n.output_html .vm { color: #19177C } /* Name.Variable.Magic */\n.output_html .il { color: #666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MultiStressComp</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExplicitComponent</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">initialize</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">,</span> <span class=\"n\">types</span><span class=\"o\">=</span><span class=\"nb\">int</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_rhs&#39;</span><span class=\"p\">,</span> <span class=\"n\">types</span><span class=\"o\">=</span><span class=\"nb\">int</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;E&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">num_elements</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">num_nodes</span> <span class=\"o\">=</span> <span class=\"n\">num_elements</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n        <span class=\"n\">num_rhs</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_rhs&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;h&#39;</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"n\">num_elements</span><span class=\"p\">)</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_rhs</span><span class=\"p\">):</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;displacements_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"n\">num_nodes</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_output</span><span class=\"p\">(</span><span class=\"s1\">&#39;stress_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"n\">num_elements</span><span class=\"p\">)</span>\n\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"n\">of</span><span class=\"o\">=</span><span class=\"s1\">&#39;stress_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">,</span> <span class=\"n\">wrt</span><span class=\"o\">=</span><span class=\"s1\">&#39;displacements_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">)</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"n\">of</span><span class=\"o\">=</span><span class=\"s1\">&#39;stress_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">,</span> <span class=\"n\">wrt</span><span class=\"o\">=</span><span class=\"s1\">&#39;h&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">outputs</span><span class=\"p\">):</span>\n        <span class=\"n\">num_rhs</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_rhs&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">tk</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;h&#39;</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"mf\">0.5</span>\n        <span class=\"n\">E</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;E&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_rhs</span><span class=\"p\">):</span>\n            <span class=\"n\">ang</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;displacements_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">::</span><span class=\"mi\">2</span><span class=\"p\">]</span>\n            <span class=\"n\">d_ang</span> <span class=\"o\">=</span> <span class=\"n\">ang</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"o\">-</span> <span class=\"n\">ang</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n            <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;stress_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">tk</span> <span class=\"o\">*</span> <span class=\"n\">E</span> <span class=\"o\">*</span> <span class=\"n\">d_ang</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute_partials</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">partials</span><span class=\"p\">):</span>\n        <span class=\"n\">num_elements</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">num_nodes</span> <span class=\"o\">=</span> <span class=\"n\">num_elements</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\n        <span class=\"n\">num_states</span> <span class=\"o\">=</span> <span class=\"n\">num_nodes</span> <span class=\"o\">*</span> <span class=\"mi\">2</span>\n        <span class=\"n\">num_rhs</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_rhs&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">tk</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;h&#39;</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"mf\">0.5</span>\n        <span class=\"n\">E</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;E&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"n\">num_rhs</span><span class=\"p\">):</span>\n            <span class=\"n\">ang</span> <span class=\"o\">=</span> <span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;displacements_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">][</span><span class=\"mi\">1</span><span class=\"p\">::</span><span class=\"mi\">2</span><span class=\"p\">]</span>\n            <span class=\"n\">d_ang</span> <span class=\"o\">=</span> <span class=\"n\">ang</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"o\">-</span> <span class=\"n\">ang</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n            <span class=\"n\">partials</span><span class=\"p\">[</span><span class=\"s1\">&#39;stress_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">,</span> <span class=\"s1\">&#39;h&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">diag</span><span class=\"p\">(</span><span class=\"mf\">0.5</span> <span class=\"o\">*</span> <span class=\"n\">E</span> <span class=\"o\">*</span> <span class=\"n\">d_ang</span><span class=\"p\">)</span>\n\n            <span class=\"n\">J</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">zeros</span><span class=\"p\">((</span><span class=\"n\">num_elements</span><span class=\"p\">,</span> <span class=\"n\">num_states</span><span class=\"p\">))</span>\n            <span class=\"n\">J</span><span class=\"p\">[:,</span> <span class=\"mi\">1</span><span class=\"p\">:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">:</span><span class=\"mi\">2</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">diag</span><span class=\"p\">(</span><span class=\"n\">tk</span> <span class=\"o\">*</span> <span class=\"n\">E</span><span class=\"p\">)</span>\n            <span class=\"n\">J</span><span class=\"p\">[:,</span> <span class=\"mi\">3</span><span class=\"p\">::</span><span class=\"mi\">2</span><span class=\"p\">]</span> <span class=\"o\">+=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">diag</span><span class=\"p\">(</span><span class=\"n\">tk</span> <span class=\"o\">*</span> <span class=\"n\">E</span><span class=\"p\">)</span>\n            <span class=\"n\">partials</span><span class=\"p\">[</span><span class=\"s1\">&#39;stress_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">,</span> <span class=\"s1\">&#39;displacements_</span><span class=\"si\">%d</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"n\">j</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">J</span>\n</pre></div>\n",
      "application/papermill.record/text/latex": "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{MultiStressComp}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{ExplicitComponent}\\PY{p}{)}\\PY{p}{:}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{initialize}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{types}\\PY{o}{=}\\PY{n+nb}{int}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}rhs}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{types}\\PY{o}{=}\\PY{n+nb}{int}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{E}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{num\\PYZus{}elements} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{num\\PYZus{}nodes} \\PY{o}{=} \\PY{n}{num\\PYZus{}elements} \\PY{o}{+} \\PY{l+m+mi}{1}\n        \\PY{n}{num\\PYZus{}rhs} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}rhs}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{shape}\\PY{o}{=}\\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\n\n        \\PY{k}{for} \\PY{n}{j} \\PY{o+ow}{in} \\PY{n+nb}{range}\\PY{p}{(}\\PY{n}{num\\PYZus{}rhs}\\PY{p}{)}\\PY{p}{:}\n            \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{displacements\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{,} \\PY{n}{shape}\\PY{o}{=}\\PY{l+m+mi}{2} \\PY{o}{*} \\PY{n}{num\\PYZus{}nodes}\\PY{p}{)}\n            \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}output}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{stress\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{,} \\PY{n}{shape}\\PY{o}{=}\\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\n\n            \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{n}{of}\\PY{o}{=}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{stress\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{,} \\PY{n}{wrt}\\PY{o}{=}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{displacements\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{)}\n            \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{n}{of}\\PY{o}{=}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{stress\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{,} \\PY{n}{wrt}\\PY{o}{=}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{num\\PYZus{}rhs} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}rhs}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{tk} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{*} \\PY{l+m+mf}{0.5}\n        \\PY{n}{E} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{E}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{k}{for} \\PY{n}{j} \\PY{o+ow}{in} \\PY{n+nb}{range}\\PY{p}{(}\\PY{n}{num\\PYZus{}rhs}\\PY{p}{)}\\PY{p}{:}\n            \\PY{n}{ang} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{displacements\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{]}\\PY{p}{[}\\PY{l+m+mi}{1}\\PY{p}{:}\\PY{p}{:}\\PY{l+m+mi}{2}\\PY{p}{]}\n            \\PY{n}{d\\PYZus{}ang} \\PY{o}{=} \\PY{n}{ang}\\PY{p}{[}\\PY{l+m+mi}{1}\\PY{p}{:}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{ang}\\PY{p}{[}\\PY{l+m+mi}{0}\\PY{p}{:}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{1}\\PY{p}{]}\n            \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{stress\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{]} \\PY{o}{=} \\PY{n}{tk} \\PY{o}{*} \\PY{n}{E} \\PY{o}{*} \\PY{n}{d\\PYZus{}ang}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute\\PYZus{}partials}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{partials}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{num\\PYZus{}elements} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{num\\PYZus{}nodes} \\PY{o}{=} \\PY{n}{num\\PYZus{}elements} \\PY{o}{+} \\PY{l+m+mi}{1}\n        \\PY{n}{num\\PYZus{}states} \\PY{o}{=} \\PY{n}{num\\PYZus{}nodes} \\PY{o}{*} \\PY{l+m+mi}{2}\n        \\PY{n}{num\\PYZus{}rhs} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}rhs}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{tk} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{*} \\PY{l+m+mf}{0.5}\n        \\PY{n}{E} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{E}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{k}{for} \\PY{n}{j} \\PY{o+ow}{in} \\PY{n+nb}{range}\\PY{p}{(}\\PY{n}{num\\PYZus{}rhs}\\PY{p}{)}\\PY{p}{:}\n            \\PY{n}{ang} \\PY{o}{=} \\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{displacements\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{]}\\PY{p}{[}\\PY{l+m+mi}{1}\\PY{p}{:}\\PY{p}{:}\\PY{l+m+mi}{2}\\PY{p}{]}\n            \\PY{n}{d\\PYZus{}ang} \\PY{o}{=} \\PY{n}{ang}\\PY{p}{[}\\PY{l+m+mi}{1}\\PY{p}{:}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{ang}\\PY{p}{[}\\PY{l+m+mi}{0}\\PY{p}{:}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{1}\\PY{p}{]}\n            \\PY{n}{partials}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{stress\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{diag}\\PY{p}{(}\\PY{l+m+mf}{0.5} \\PY{o}{*} \\PY{n}{E} \\PY{o}{*} \\PY{n}{d\\PYZus{}ang}\\PY{p}{)}\n\n            \\PY{n}{J} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{zeros}\\PY{p}{(}\\PY{p}{(}\\PY{n}{num\\PYZus{}elements}\\PY{p}{,} \\PY{n}{num\\PYZus{}states}\\PY{p}{)}\\PY{p}{)}\n            \\PY{n}{J}\\PY{p}{[}\\PY{p}{:}\\PY{p}{,} \\PY{l+m+mi}{1}\\PY{p}{:}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{1}\\PY{p}{:}\\PY{l+m+mi}{2}\\PY{p}{]} \\PY{o}{=} \\PY{o}{\\PYZhy{}}\\PY{n}{np}\\PY{o}{.}\\PY{n}{diag}\\PY{p}{(}\\PY{n}{tk} \\PY{o}{*} \\PY{n}{E}\\PY{p}{)}\n            \\PY{n}{J}\\PY{p}{[}\\PY{p}{:}\\PY{p}{,} \\PY{l+m+mi}{3}\\PY{p}{:}\\PY{p}{:}\\PY{l+m+mi}{2}\\PY{p}{]} \\PY{o}{+}\\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{diag}\\PY{p}{(}\\PY{n}{tk} \\PY{o}{*} \\PY{n}{E}\\PY{p}{)}\n            \\PY{n}{partials}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{stress\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{displacements\\PYZus{}}\\PY{l+s+si}{\\PYZpc{}d}\\PY{l+s+s1}{\\PYZsq{}} \\PY{o}{\\PYZpc{}} \\PY{n}{j}\\PY{p}{]} \\PY{o}{=} \\PY{n}{J}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class MultiStressComp(om.ExplicitComponent):\n\n    def initialize(self):\n        self.options.declare('num_elements', types=int)\n        self.options.declare('num_rhs', types=int)\n        self.options.declare('E')\n\n    def setup(self):\n        num_elements = self.options['num_elements']\n        num_nodes = num_elements + 1\n        num_rhs = self.options['num_rhs']\n\n        self.add_input('h', shape=num_elements)\n\n        for j in range(num_rhs):\n            self.add_input('displacements_%d' % j, shape=2 * num_nodes)\n            self.add_output('stress_%d' % j, shape=num_elements)\n\n            self.declare_partials(of='stress_%d' % j, wrt='displacements_%d' % j)\n            self.declare_partials(of='stress_%d' % j, wrt='h')\n\n    def compute(self, inputs, outputs):\n        num_rhs = self.options['num_rhs']\n        tk = inputs['h'] * 0.5\n        E = self.options['E']\n\n        for j in range(num_rhs):\n            ang = inputs['displacements_%d' % j][1::2]\n            d_ang = ang[1:] - ang[0:-1]\n            outputs['stress_%d' % j] = tk * E * d_ang\n\n    def compute_partials(self, inputs, partials):\n        num_elements = self.options['num_elements']\n        num_nodes = num_elements + 1\n        num_states = num_nodes * 2\n        num_rhs = self.options['num_rhs']\n        tk = inputs['h'] * 0.5\n        E = self.options['E']\n\n        for j in range(num_rhs):\n            ang = inputs['displacements_%d' % j][1::2]\n            d_ang = ang[1:] - ang[0:-1]\n            partials['stress_%d' % j, 'h'] = np.diag(0.5 * E * d_ang)\n\n            J = np.zeros((num_elements, num_states))\n            J[:, 1:-1:2] = -np.diag(tk * E)\n            J[:, 3::2] += np.diag(tk * E)\n            partials['stress_%d' % j, 'displacements_%d' % j] = J"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src12"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src12\", get_code(\"openmdao.test_suite.test_examples.beam_optimization.components.multi_stress_comp.MultiStressComp\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "262485eb",
   "metadata": {
    "papermill": {
     "duration": 0.001668,
     "end_time": "2026-10-02T14:40:55.668549+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:55.666881+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `MultiStressComp` class definition \n",
    "\n",
    "{glue:}`code_src12`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "af1f14df",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:55.679064Z",
     "iopub.status.busy": "2026-10-02T14:40:55.678933Z",
     "iopub.status.idle": "2026-10-02T14:40:55.685450Z",
     "shell.execute_reply": "2026-10-02T14:40:55.684976Z"
    },
    "papermill": {
     "duration": 0.016021,
     "end_time": "2026-10-02T14:40:55.686095+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:55.670074+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "application/papermill.record/text/html": "<style>pre { line-height: 125%; }\ntd.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\nspan.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\ntd.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\nspan.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n.output_html .hll { background-color: #ffffcc }\n.output_html { background: #f8f8f8; }\n.output_html .c { color: #3D7B7B; font-style: italic } /* Comment */\n.output_html .err { border: 1px solid #F00 } /* Error */\n.output_html .k { color: #008000; font-weight: bold } /* Keyword */\n.output_html .o { color: #666 } /* Operator */\n.output_html .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */\n.output_html .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */\n.output_html .cp { color: #9C6500 } /* Comment.Preproc */\n.output_html .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */\n.output_html .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */\n.output_html .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */\n.output_html .gd { color: #A00000 } /* Generic.Deleted */\n.output_html .ge { font-style: italic } /* Generic.Emph */\n.output_html .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */\n.output_html .gr { color: #E40000 } /* Generic.Error */\n.output_html .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.output_html .gi { color: #008400 } /* Generic.Inserted */\n.output_html .go { color: #717171 } /* Generic.Output */\n.output_html .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.output_html .gs { font-weight: bold } /* Generic.Strong */\n.output_html .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.output_html .gt { color: #04D } /* Generic.Traceback */\n.output_html .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.output_html .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.output_html .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.output_html .kp { color: #008000 } /* Keyword.Pseudo */\n.output_html .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.output_html .kt { color: #B00040 } /* Keyword.Type */\n.output_html .m { color: #666 } /* Literal.Number */\n.output_html .s { color: #BA2121 } /* Literal.String */\n.output_html .na { color: #687822 } /* Name.Attribute */\n.output_html .nb { color: #008000 } /* Name.Builtin */\n.output_html .nc { color: #00F; font-weight: bold } /* Name.Class */\n.output_html .no { color: #800 } /* Name.Constant */\n.output_html .nd { color: #A2F } /* Name.Decorator */\n.output_html .ni { color: #717171; font-weight: bold } /* Name.Entity */\n.output_html .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */\n.output_html .nf { color: #00F } /* Name.Function */\n.output_html .nl { color: #767600 } /* Name.Label */\n.output_html .nn { color: #00F; font-weight: bold } /* Name.Namespace */\n.output_html .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.output_html .nv { color: #19177C } /* Name.Variable */\n.output_html .ow { color: #A2F; font-weight: bold } /* Operator.Word */\n.output_html .w { color: #BBB } /* Text.Whitespace */\n.output_html .mb { color: #666 } /* Literal.Number.Bin */\n.output_html .mf { color: #666 } /* Literal.Number.Float */\n.output_html .mh { color: #666 } /* Literal.Number.Hex */\n.output_html .mi { color: #666 } /* Literal.Number.Integer */\n.output_html .mo { color: #666 } /* Literal.Number.Oct */\n.output_html .sa { color: #BA2121 } /* Literal.String.Affix */\n.output_html .sb { color: #BA2121 } /* Literal.String.Backtick */\n.output_html .sc { color: #BA2121 } /* Literal.String.Char */\n.output_html .dl { color: #BA2121 } /* Literal.String.Delimiter */\n.output_html .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n.output_html .s2 { color: #BA2121 } /* Literal.String.Double */\n.output_html .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */\n.output_html .sh { color: #BA2121 } /* Literal.String.Heredoc */\n.output_html .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */\n.output_html .sx { color: #008000 } /* Literal.String.Other */\n.output_html .sr { color: #A45A77 } /* Literal.String.Regex */\n.output_html .s1 { color: #BA2121 } /* Literal.String.Single */\n.output_html .ss { color: #19177C } /* Literal.String.Symbol */\n.output_html .bp { color: #008000 } /* Name.Builtin.Pseudo */\n.output_html .fm { color: #00F } /* Name.Function.Magic */\n.output_html .vc { color: #19177C } /* Name.Variable.Class */\n.output_html .vg { color: #19177C } /* Name.Variable.Global */\n.output_html .vi { color: #19177C } /* Name.Variable.Instance */\n.output_html .vm { color: #19177C } /* Name.Variable.Magic */\n.output_html .il { color: #666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">VolumeComp</span><span class=\"p\">(</span><span class=\"n\">om</span><span class=\"o\">.</span><span class=\"n\">ExplicitComponent</span><span class=\"p\">):</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">initialize</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">,</span> <span class=\"n\">types</span><span class=\"o\">=</span><span class=\"nb\">int</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;b&#39;</span><span class=\"p\">,</span> <span class=\"n\">default</span><span class=\"o\">=</span><span class=\"mf\">1.</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"o\">.</span><span class=\"n\">declare</span><span class=\"p\">(</span><span class=\"s1\">&#39;L&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">num_elements</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">b</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;b&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">L</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;L&#39;</span><span class=\"p\">]</span>\n        <span class=\"n\">L0</span> <span class=\"o\">=</span> <span class=\"n\">L</span> <span class=\"o\">/</span> <span class=\"n\">num_elements</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_input</span><span class=\"p\">(</span><span class=\"s1\">&#39;h&#39;</span><span class=\"p\">,</span> <span class=\"n\">shape</span><span class=\"o\">=</span><span class=\"n\">num_elements</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_output</span><span class=\"p\">(</span><span class=\"s1\">&#39;volume&#39;</span><span class=\"p\">)</span>\n\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">declare_partials</span><span class=\"p\">(</span><span class=\"s1\">&#39;volume&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;h&#39;</span><span class=\"p\">,</span> <span class=\"n\">val</span><span class=\"o\">=</span><span class=\"n\">b</span> <span class=\"o\">*</span> <span class=\"n\">L0</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">compute</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">inputs</span><span class=\"p\">,</span> <span class=\"n\">outputs</span><span class=\"p\">):</span>\n        <span class=\"n\">L0</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;L&#39;</span><span class=\"p\">]</span> <span class=\"o\">/</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;num_elements&#39;</span><span class=\"p\">]</span>\n\n        <span class=\"n\">outputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;volume&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">np</span><span class=\"o\">.</span><span class=\"n\">sum</span><span class=\"p\">(</span><span class=\"n\">inputs</span><span class=\"p\">[</span><span class=\"s1\">&#39;h&#39;</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">options</span><span class=\"p\">[</span><span class=\"s1\">&#39;b&#39;</span><span class=\"p\">]</span> <span class=\"o\">*</span> <span class=\"n\">L0</span><span class=\"p\">)</span>\n</pre></div>\n",
      "application/papermill.record/text/latex": "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n\\PY{k}{class}\\PY{+w}{ }\\PY{n+nc}{VolumeComp}\\PY{p}{(}\\PY{n}{om}\\PY{o}{.}\\PY{n}{ExplicitComponent}\\PY{p}{)}\\PY{p}{:}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{initialize}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{types}\\PY{o}{=}\\PY{n+nb}{int}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{b}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{default}\\PY{o}{=}\\PY{l+m+mf}{1.}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{o}{.}\\PY{n}{declare}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{L}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{setup}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{num\\PYZus{}elements} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{b} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{b}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{L} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{L}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n        \\PY{n}{L0} \\PY{o}{=} \\PY{n}{L} \\PY{o}{/} \\PY{n}{num\\PYZus{}elements}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}input}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{shape}\\PY{o}{=}\\PY{n}{num\\PYZus{}elements}\\PY{p}{)}\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{add\\PYZus{}output}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{volume}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n\n        \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{declare\\PYZus{}partials}\\PY{p}{(}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{volume}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{,} \\PY{n}{val}\\PY{o}{=}\\PY{n}{b} \\PY{o}{*} \\PY{n}{L0}\\PY{p}{)}\n\n    \\PY{k}{def}\\PY{+w}{ }\\PY{n+nf}{compute}\\PY{p}{(}\\PY{n+nb+bp}{self}\\PY{p}{,} \\PY{n}{inputs}\\PY{p}{,} \\PY{n}{outputs}\\PY{p}{)}\\PY{p}{:}\n        \\PY{n}{L0} \\PY{o}{=} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{L}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{/} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{num\\PYZus{}elements}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]}\n\n        \\PY{n}{outputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{volume}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{=} \\PY{n}{np}\\PY{o}{.}\\PY{n}{sum}\\PY{p}{(}\\PY{n}{inputs}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{h}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{*} \\PY{n+nb+bp}{self}\\PY{o}{.}\\PY{n}{options}\\PY{p}{[}\\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{b}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{]} \\PY{o}{*} \\PY{n}{L0}\\PY{p}{)}\n\\end{Verbatim}\n",
      "application/papermill.record/text/plain": "class VolumeComp(om.ExplicitComponent):\n\n    def initialize(self):\n        self.options.declare('num_elements', types=int)\n        self.options.declare('b', default=1.)\n        self.options.declare('L')\n\n    def setup(self):\n        num_elements = self.options['num_elements']\n        b = self.options['b']\n        L = self.options['L']\n        L0 = L / num_elements\n\n        self.add_input('h', shape=num_elements)\n        self.add_output('volume')\n\n        self.declare_partials('volume', 'h', val=b * L0)\n\n    def compute(self, inputs, outputs):\n        L0 = self.options['L'] / self.options['num_elements']\n\n        outputs['volume'] = np.sum(inputs['h'] * self.options['b'] * L0)"
     },
     "metadata": {
      "scrapbook": {
       "mime_prefix": "application/papermill.record/",
       "name": "code_src13"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from openmdao.utils.notebook_utils import get_code\n",
    "from myst_nb import glue\n",
    "glue(\"code_src13\", get_code(\"openmdao.test_suite.test_examples.beam_optimization.components.volume_comp.VolumeComp\"), display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c784780",
   "metadata": {
    "papermill": {
     "duration": 0.001659,
     "end_time": "2026-10-02T14:40:55.689488+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:55.687829+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    ":::{dropdown} `VolumeComp` class definition \n",
    "\n",
    "{glue:}`code_src13`\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "70c18bca",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:55.693889Z",
     "iopub.status.busy": "2026-10-02T14:40:55.693560Z",
     "iopub.status.idle": "2026-10-02T14:40:55.700802Z",
     "shell.execute_reply": "2026-10-02T14:40:55.700165Z"
    },
    "papermill": {
     "duration": 0.010118,
     "end_time": "2026-10-02T14:40:55.701250+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:55.691132+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "This is a multipoint implementation of the beam optimization problem.\n",
    "\n",
    "This version minimizes volume while satisfying a max bending stress constraint in each element\n",
    "for each loadcase.\n",
    "\"\"\"\n",
    "import numpy as np\n",
    "import openmdao.api as om\n",
    "\n",
    "from openmdao.test_suite.test_examples.beam_optimization.components.local_stiffness_matrix_comp import LocalStiffnessMatrixComp\n",
    "from openmdao.test_suite.test_examples.beam_optimization.components.moment_comp import MomentOfInertiaComp\n",
    "from openmdao.test_suite.test_examples.beam_optimization.components.multi_stress_comp import MultiStressComp\n",
    "from openmdao.test_suite.test_examples.beam_optimization.components.volume_comp import VolumeComp\n",
    "from openmdao.utils.spline_distributions import sine_distribution\n",
    "\n",
    "\n",
    "def divide_cases(ncases, nprocs):\n",
    "    \"\"\"\n",
    "    Divide up load cases among available procs.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    ncases : int\n",
    "        Number of load cases.\n",
    "    nprocs : int\n",
    "        Number of processors.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    list of list of int\n",
    "        Integer case numbers for each proc.\n",
    "    \"\"\"\n",
    "    data = []\n",
    "    for j in range(nprocs):\n",
    "        data.append([])\n",
    "\n",
    "    wrap = 0\n",
    "    for j in range(ncases):\n",
    "        idx = j - wrap\n",
    "        if idx >= nprocs:\n",
    "            idx = 0\n",
    "            wrap = j\n",
    "\n",
    "        data[idx].append(j)\n",
    "\n",
    "    return data\n",
    "\n",
    "\n",
    "class MultipointBeamGroup(om.Group):\n",
    "    \"\"\"\n",
    "    System setup for minimization of volume (i.e., mass) subject to KS aggregated bending stress constraints.\n",
    "    \"\"\"\n",
    "\n",
    "    def initialize(self):\n",
    "        self.options.declare('E')\n",
    "        self.options.declare('L')\n",
    "        self.options.declare('b')\n",
    "        self.options.declare('volume')\n",
    "        self.options.declare('max_bending')\n",
    "        self.options.declare('num_elements', 5)\n",
    "        self.options.declare('num_cp', 50)\n",
    "        self.options.declare('num_load_cases', 1)\n",
    "        self.options.declare('parallel_derivs', False, types=bool, allow_none=True)\n",
    "        self.options.declare('ks_add_constraint', default=False, types=bool)\n",
    "\n",
    "    def setup(self):\n",
    "        E = self.options['E']\n",
    "        L = self.options['L']\n",
    "        b = self.options['b']\n",
    "        # volume = self.options['volume']\n",
    "        max_bending = self.options['max_bending']\n",
    "        num_elements = self.options['num_elements']\n",
    "        num_nodes = num_elements + 1\n",
    "        num_cp = self.options['num_cp']\n",
    "        num_load_cases = self.options['num_load_cases']\n",
    "        parallel_derivs = self.options['parallel_derivs']\n",
    "\n",
    "        x_interp = sine_distribution(num_elements)\n",
    "        comp = om.SplineComp(method='bsplines', num_cp=num_cp, x_interp_val=x_interp)\n",
    "        comp.add_spline(y_cp_name='h_cp', y_interp_name='h')\n",
    "        self.add_subsystem('interp', comp)\n",
    "\n",
    "        I_comp = MomentOfInertiaComp(num_elements=num_elements, b=b)\n",
    "        self.add_subsystem('I_comp', I_comp)\n",
    "\n",
    "        comp = LocalStiffnessMatrixComp(num_elements=num_elements, E=E, L=L)\n",
    "        self.add_subsystem('local_stiffness_matrix_comp', comp)\n",
    "\n",
    "        # Parallel Subsystem for load cases.\n",
    "        par = self.add_subsystem('parallel', om.ParallelGroup())\n",
    "\n",
    "        # Determine how to split cases up over the available procs.\n",
    "        nprocs = self.comm.size\n",
    "        divide = divide_cases(num_load_cases, nprocs)\n",
    "\n",
    "        for j, this_proc in enumerate(divide):\n",
    "            num_rhs = len(this_proc)\n",
    "\n",
    "            name = 'sub_%d' % j\n",
    "            sub = par.add_subsystem(name, om.Group())\n",
    "\n",
    "            # Load is a sinusoidal distributed force of varying spatial frequency.\n",
    "            force_vector = np.zeros((2 * num_nodes, num_rhs))\n",
    "            for i, k in enumerate(this_proc):\n",
    "\n",
    "                end = 1.5 * np.pi\n",
    "                if num_load_cases > 1:\n",
    "                    end += k * 0.5 * np.pi / (num_load_cases - 1)\n",
    "\n",
    "                x = np.linspace(0, end, num_nodes)\n",
    "                f = - np.sin(x)\n",
    "                force_vector[0:-1:2, i] = f\n",
    "\n",
    "            comp = MultiStatesComp(num_elements=num_elements, force_vector=force_vector,\n",
    "                                   num_rhs=num_rhs)\n",
    "            sub.add_subsystem('states_comp', comp)\n",
    "\n",
    "            comp = MultiStressComp(num_elements=num_elements, E=E, num_rhs=num_rhs)\n",
    "            sub.add_subsystem('stress_comp', comp)\n",
    "\n",
    "            self.connect('local_stiffness_matrix_comp.K_local',\n",
    "                         'parallel.%s.states_comp.K_local' % name)\n",
    "\n",
    "            for k in range(num_rhs):\n",
    "                sub.connect('states_comp.d_%d' % k,\n",
    "                            'stress_comp.displacements_%d' % k,\n",
    "                            src_indices=np.arange(2 *num_nodes))\n",
    "\n",
    "                if parallel_derivs:\n",
    "                    color = 'red_%d' % k\n",
    "                else:\n",
    "                    color = None\n",
    "\n",
    "                comp = om.KSComp(width=num_elements, upper=max_bending,\n",
    "                                 add_constraint=self.options['ks_add_constraint'],\n",
    "                                 parallel_deriv_color=color)\n",
    "\n",
    "                sub.add_subsystem('KS_%d' % k, comp)\n",
    "\n",
    "                sub.connect('stress_comp.stress_%d' % k,\n",
    "                            'KS_%d.g' % k)\n",
    "\n",
    "                if not self.options['ks_add_constraint']:\n",
    "                    sub.add_constraint('KS_%d.KS' % k, upper=0.0,\n",
    "                                       parallel_deriv_color=color)\n",
    "\n",
    "        comp = VolumeComp(num_elements=num_elements, b=b, L=L)\n",
    "        self.add_subsystem('volume_comp', comp)\n",
    "\n",
    "        self.connect('interp.h', 'I_comp.h')\n",
    "        self.connect('interp.h', 'volume_comp.h')\n",
    "        self.connect('I_comp.I', 'local_stiffness_matrix_comp.I')\n",
    "\n",
    "        self.add_design_var('interp.h_cp', lower=1e-2, upper=10.)\n",
    "        self.add_objective('volume_comp.volume')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "86512de2",
   "metadata": {
    "papermill": {
     "duration": 0.002268,
     "end_time": "2026-10-02T14:40:55.705896+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:55.703628+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "Next we run the model, and choose `ScipyOptimizeDriver` SLSQP to be our optimizer. At the conclusion of optimization, we print out the design variable, which is the thickness for each element."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a43fa51f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:55.714501Z",
     "iopub.status.busy": "2026-10-02T14:40:55.714381Z",
     "iopub.status.idle": "2026-10-02T14:40:57.143595Z",
     "shell.execute_reply": "2026-10-02T14:40:57.142960Z"
    },
    "papermill": {
     "duration": 1.433516,
     "end_time": "2026-10-02T14:40:57.144195+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:55.710679+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952056.918893] [runnervm8df0l:6134 :0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x5647bfc73d40 failed to create UD QP TX wr:256 sge:6 inl:64 resp:0 RX wr:4096 sge:1 resp:0 failed: Operation not supported\n",
      "[1790952056.919167] [runnervm8df0l:6134 :0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[runnervm8df0l:06134] pml_ucx.c:313  Error: Failed to create UCP worker\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Optimization terminated successfully    (Exit mode 0)\n",
      "            Current function value: 0.03494890159973937\n",
      "            Iterations: 35\n",
      "            Function evaluations: 71\n",
      "            Gradient evaluations: 35\n",
      "Optimization Complete\n",
      "-----------------------------------\n",
      "[0.45632322 0.45612552 0.45543324 0.45397058 0.45134629 0.44714397\n",
      " 0.4410258  0.43283139 0.42265378 0.41087801 0.3981731  0.3854358\n",
      " 0.37369202 0.36342186 0.35289066 0.34008776 0.32362887 0.30300358\n",
      " 0.27867837 0.25204063 0.22519409 0.20063906 0.18088818 0.16807857\n",
      " 0.16364105]\n"
     ]
    }
   ],
   "source": [
    "from openmdao.test_suite.test_examples.beam_optimization.components.multi_states_comp import MultiStatesComp\n",
    "\n",
    "E = 1.\n",
    "L = 1.\n",
    "b = 0.1\n",
    "volume = 0.01\n",
    "max_bending = 100.0\n",
    "\n",
    "num_cp = 5\n",
    "num_elements = 25\n",
    "num_load_cases = 2\n",
    "\n",
    "model = MultipointBeamGroup(E=E, L=L, b=b, volume=volume, max_bending = max_bending,\n",
    "                            num_elements=num_elements, num_cp=num_cp,\n",
    "                            num_load_cases=num_load_cases)\n",
    "\n",
    "prob = om.Problem(model=model)\n",
    "\n",
    "prob.driver = om.ScipyOptimizeDriver()\n",
    "prob.driver.options['optimizer'] = 'SLSQP'\n",
    "prob.driver.options['tol'] = 1e-9\n",
    "prob.driver.options['disp'] = True\n",
    "\n",
    "prob.setup(mode='rev')\n",
    "\n",
    "prob.run_driver()\n",
    "\n",
    "print(prob['interp.h'][0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "7cef62c7",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:40:57.149408Z",
     "iopub.status.busy": "2026-10-02T14:40:57.149088Z",
     "iopub.status.idle": "2026-10-02T14:40:57.153175Z",
     "shell.execute_reply": "2026-10-02T14:40:57.152653Z"
    },
    "papermill": {
     "duration": 0.007469,
     "end_time": "2026-10-02T14:40:57.153949+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:40:57.146480+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(1.0467586563622177e-08)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from openmdao.utils.assert_utils import assert_near_equal\n",
    "\n",
    "assert_near_equal(prob['interp.h'][0],\n",
    "                 [ 0.45632323,  0.45612552,  0.45543324,  0.45397058,  0.45134629,  0.44714397,\n",
    "                   0.4410258,   0.43283139,  0.42265378,  0.41087801,  0.3981731,   0.3854358,\n",
    "                   0.37369202,  0.36342186,  0.35289066,  0.34008777,  0.32362887,  0.30300358,\n",
    "                   0.27867837,  0.25204063,  0.22519409,  0.20063906,  0.18088818,  0.16807856,\n",
    "                   0.16364104], 1e-4)"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "interpreter": {
   "hash": "c3e5a3598b81f1f111a5814b7aa7b9fddabe1e30fc374c51323a6f1030ed4ad3"
  },
  "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.13.14"
  },
  "papermill": {
   "default_parameters": {},
   "duration": 5.717756,
   "end_time": "2026-10-02T14:40:57.971864+00:00",
   "environment_variables": {},
   "exception": null,
   "input_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/examples/beam_optimization_example_part_2.ipynb",
   "output_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/examples/beam_optimization_example_part_2.ipynb",
   "parameters": {},
   "start_time": "2026-10-02T14:40:52.254108+00:00",
   "version": "2.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}