{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "a61d4fd0",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:45.581367Z",
     "iopub.status.busy": "2026-10-02T14:41:45.581185Z",
     "iopub.status.idle": "2026-10-02T14:41:45.585262Z",
     "shell.execute_reply": "2026-10-02T14:41:45.584511Z"
    },
    "papermill": {
     "duration": 0.006442,
     "end_time": "2026-10-02T14:41:45.585755+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:45.579313+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "active-ipynb",
     "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": "8d2b93f3",
   "metadata": {
    "papermill": {
     "duration": 0.001186,
     "end_time": "2026-10-02T14:41:45.588446+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:45.587260+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "# VectorMagnitudeComp\n",
    "\n",
    "`VectorMagnitudeComp` computes the magnitude (L2 norm) of a single input of some given length.\n",
    "It may be vectorized to provide the result at one or more points simultaneously.\n",
    "\n",
    "$$\n",
    "    \\lvert a_i \\rvert = \\sqrt{\\bar{a}_i \\cdot \\bar{a}_i}\n",
    "$$\n",
    "\n",
    "## VectorMagnitudeComp Options\n",
    "\n",
    "The default `vec_size` is 1, providing the magnitude of $a$ at a singlepoint.  The length of $a$ is provided by option `length`.\n",
    "\n",
    "Other options for VectorMagnitudeComp allow the user to rename the input variable $a$ and the output $a\\_mag$, as well as specifying their units."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "24182ec7",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:45.591435Z",
     "iopub.status.busy": "2026-10-02T14:41:45.591300Z",
     "iopub.status.idle": "2026-10-02T14:41:46.784017Z",
     "shell.execute_reply": "2026-10-02T14:41:46.783255Z"
    },
    "papermill": {
     "duration": 1.19487,
     "end_time": "2026-10-02T14:41:46.784514+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:45.589644+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<!DOCTYPE html>\n",
       "<html lang=\"en\">\n",
       "<head>\n",
       "    <style>\n",
       "        h2 {\n",
       "            text-align: center;\n",
       "        }\n",
       "    </style>\n",
       "</head>\n",
       "<body>\n",
       "    <h2></h2>\n",
       "        <table style=\"border: 1px solid #999; border-collapse: collapse;\">\n",
       "        <tr><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Option</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Default</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Acceptable Values</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Acceptable Types</th><th style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; background-color: #E9E9E9; text-align: left;\">Description</th></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">always_opt</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">False</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[True, False]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;bool&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">If True, force nonlinear operations on this component to be included in the optimization loop even if this component is not relevant to the design variables and responses.</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">default_shape</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">(1,)</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;tuple&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">Default shape for variables that do not set val to a non-scalar value or set shape, shape_by_conn, copy_shape, or compute_shape. Default is (1,).</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">derivs_method</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;jax&#x27;, &#x27;cs&#x27;, &#x27;fd&#x27;, None]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">The method to use for computing derivatives</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">distributed</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">False</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[True, False]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;bool&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">If True, set all variables in this component as distributed across multiple processes</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">in_name</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">a</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;str&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">The variable name for input vector.</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">length</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">3</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;int&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">The length of the input vector at each point</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">mag_name</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">a_mag</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;str&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">The variable name for output vector magnitude.</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">run_root_only</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">False</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[True, False]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;bool&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">If True, call compute, compute_partials, linearize, apply_linear, apply_nonlinear, solve_linear, solve_nonlinear, and compute_jacvec_product only on rank 0 and broadcast the results to the other ranks.</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">units</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;str&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">The units of the input vector.</td></tr>\n",
       "       <tr style=\"background-color: #F3F3F3;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">use_jit</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">True</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[True, False]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;bool&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">If True, attempt to use jit on compute_primal, assuming jax or some other AD package capable of jitting is active.</td></tr>\n",
       "       <tr style=\"background-color: ghostwhite;\"><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">vec_size</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">1</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">N/A</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">[&#x27;int&#x27;]</td><td style=\"border: 1px solid #999; border-collapse: collapse; padding: 5px; text-align: left;\">The number of points at which the vector magnitude is computed</td></tr>\n",
       "    </table>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import openmdao.api as om\n",
    "om.show_options_table(\"openmdao.components.vector_magnitude_comp.VectorMagnitudeComp\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ae67fa9",
   "metadata": {
    "papermill": {
     "duration": 0.001053,
     "end_time": "2026-10-02T14:41:46.786878+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:46.785825+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## VectorMagnitudeComp Constructor\n",
    "\n",
    "The call signature for the `VectorMagnitudeComp` constructor is:\n",
    "\n",
    "```{eval-rst}\n",
    "    .. automethod:: openmdao.components.vector_magnitude_comp.VectorMagnitudeComp.__init__\n",
    "        :noindex:\n",
    "```\n",
    "\n",
    "## VectorMagnitudeComp Usage\n",
    "\n",
    "There are often situations when numerous magnitudes need to be computed, essentially in parallel.\n",
    "You can reduce the number of components required by having one `VectorMagnitudeComp` perform multiple operations.\n",
    "This is also convenient when the different operations have common inputs.\n",
    "\n",
    "The `add_magnitude` method is used to create additional magnitude calculations after instantiation.\n",
    "\n",
    "```{eval-rst}\n",
    "    .. automethod:: openmdao.components.vector_magnitude_comp.VectorMagnitudeComp.add_magnitude\n",
    "       :noindex:\n",
    "```\n",
    "\n",
    "## VectorMagnitudeComp Example\n",
    "\n",
    "In the following example VectorMagnitudeComp is used to compute the radius vector magnitude\n",
    "given a radius 3-vector at 100 points simultaneously. Note the use of `in_name` and `mag_name` to assign names to the inputs and outputs. Units are assigned using `units`.  The units of the output magnitude are the same as those for the input."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "54da8a72",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:46.789553Z",
     "iopub.status.busy": "2026-10-02T14:41:46.789293Z",
     "iopub.status.idle": "2026-10-02T14:41:47.991513Z",
     "shell.execute_reply": "2026-10-02T14:41:47.990632Z"
    },
    "papermill": {
     "duration": 1.205118,
     "end_time": "2026-10-02T14:41:47.992897+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:46.787779+00:00",
     "status": "completed"
    },
    "tags": [
     "allow-assert"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1790952107.975225] [runnervm8df0l:6833 :0]        ib_iface.c:1269 UCX  ERROR mana_0: iface 0x5638e7e518f0 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",
      "[1790952107.975476] [runnervm8df0l:6833 :0]      ucp_worker.c:1412 UCX  ERROR uct_iface_open(ud_verbs/mana_0:1) failed: Input/output error\n",
      "[2.85750531 2.50174892 2.9155433  2.4823593  2.75900087 2.54721839\n",
      " 2.65788028 2.55844324 2.57807811 2.58960972 2.75723465 2.01360044\n",
      " 2.61203375 2.41654486 2.43476906 2.65317025 2.26166137 2.062405\n",
      " 2.6176164  2.58273795 2.60516257 2.29868961 2.41221897 2.76593447\n",
      " 2.61583202 2.3208024  2.37716736 3.0854658  2.35906415 2.73900957\n",
      " 2.72436912 2.91516313 2.39813078 2.92079569 3.06919622 2.89698033\n",
      " 2.71236004 2.5786449  1.81112453 2.62062092 2.68481822 1.92651602\n",
      " 2.61526281 2.93331478 2.43387968 2.56269571 3.00352941 2.91792402\n",
      " 2.54916631 3.06822165 2.69448613 2.78274325 2.52322206 2.8988186\n",
      " 2.54131714 2.58739168 2.77786575 2.9947228  2.53623928 2.39182134\n",
      " 3.16377517 2.68640272 2.94467724 2.14113781 2.61543108 2.79727583\n",
      " 2.2461479  2.50412708 2.34574704 2.65378687 2.55950639 2.65955213\n",
      " 2.39464601 2.39544872 2.02763116 2.70984679 2.66352621 3.07833642\n",
      " 3.12885213 2.49176721 2.94116838 2.32141479 3.03835872 3.16834085\n",
      " 2.61251647 2.61968055 2.4901345  2.79433088 3.12724637 2.2906506\n",
      " 2.56365899 2.09319289 2.11784028 2.57540421 2.44545707 2.54641595\n",
      " 2.8340948  2.38880222 2.57454853 2.53027228]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[runnervm8df0l:06833] pml_ucx.c:313  Error: Failed to create UCP worker\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import openmdao.api as om\n",
    "\n",
    "n = 100\n",
    "\n",
    "p = om.Problem()\n",
    "\n",
    "comp = om.VectorMagnitudeComp(vec_size=n, length=3,\n",
    "                              in_name='r', mag_name='r_mag', units='km')\n",
    "\n",
    "p.model.add_subsystem(name='vec_mag_comp', subsys=comp,\n",
    "                      promotes_inputs=[('r', 'pos')])\n",
    "\n",
    "p.setup()\n",
    "\n",
    "p.set_val('pos', 1.0 + np.random.rand(n, 3))\n",
    "\n",
    "p.run_model()\n",
    "\n",
    "# Verify the results against numpy.dot in a for loop.\n",
    "expected = []\n",
    "for i in range(n):\n",
    "    a_i = p.get_val('pos')[i, :]\n",
    "    expected.append(np.sqrt(np.dot(a_i, a_i)))\n",
    "\n",
    "    actual_i = p.get_val('vec_mag_comp.r_mag')[i]\n",
    "    rel_error = np.abs(expected[i] - actual_i)/actual_i\n",
    "    assert rel_error < 1e-9, f\"Relative error: {rel_error}\"\n",
    "\n",
    "print(p.get_val('vec_mag_comp.r_mag'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "5ce8983c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:47.997211Z",
     "iopub.status.busy": "2026-10-02T14:41:47.997017Z",
     "iopub.status.idle": "2026-10-02T14:41:48.002972Z",
     "shell.execute_reply": "2026-10-02T14:41:48.002378Z"
    },
    "papermill": {
     "duration": 0.00879,
     "end_time": "2026-10-02T14:41:48.003577+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:47.994787+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(6.39103915647494e-17)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from openmdao.utils.assert_utils import assert_near_equal\n",
    "\n",
    "assert_near_equal(p.get_val('vec_mag_comp.r_mag'), np.array(expected))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b7bdf3d0",
   "metadata": {
    "papermill": {
     "duration": 0.001412,
     "end_time": "2026-10-02T14:41:48.006583+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:48.005171+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "source": [
    "## VectorMagnitudeComp Example with Multiple Magnitudes\n",
    "\n",
    "Note that, when defining multiple magnitudes, an input name in one call to `add_magnitude` may not be an output name in another call, and vice-versa."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "16a89cbf",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:48.010631Z",
     "iopub.status.busy": "2026-10-02T14:41:48.010335Z",
     "iopub.status.idle": "2026-10-02T14:41:48.023265Z",
     "shell.execute_reply": "2026-10-02T14:41:48.022723Z"
    },
    "papermill": {
     "duration": 0.016099,
     "end_time": "2026-10-02T14:41:48.024196+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:48.008097+00:00",
     "status": "completed"
    },
    "tags": [
     "allow_assert",
     "allow-assert"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2.94150942 2.38802442 2.96474423 2.96286864 2.93145956 2.37448568\n",
      " 2.66785445 2.68592757 3.10231324 2.20774032 3.16150831 2.67801845\n",
      " 2.35493889 2.5985426  2.84452695 2.57568393 2.51946056 2.6647638\n",
      " 3.38597844 2.83227089 2.79968191 2.55079835 2.36219258 2.97108226\n",
      " 2.62820447 2.7167298  2.56024763 3.12091922 3.05983716 2.3234788\n",
      " 2.98862055 2.64280412 2.73181378 3.04230545 2.27539892 2.40971498\n",
      " 2.81553032 2.38948478 2.48920531 2.33116376 2.81311334 2.39810696\n",
      " 2.7248686  2.86901389 2.66077466 2.48756816 2.40714374 3.34147257\n",
      " 3.02391174 2.70898673 2.59132995 2.86814649 2.45636438 2.20620658\n",
      " 3.14969345 2.59150227 2.43011744 2.79858915 2.36109504 2.70070795\n",
      " 2.79226762 3.08132426 3.08391196 3.10197039 3.20265938 2.50312371\n",
      " 2.13317725 2.91630068 2.8580269  2.14833487 2.40334094 2.72428637\n",
      " 2.92856938 2.60907714 2.296835   2.6070284  2.27316886 2.69177432\n",
      " 2.84323958 2.59094559 2.87381609 2.26458576 2.37670461 2.5978017\n",
      " 2.3109162  3.09358817 2.52866379 2.30601876 2.47865764 2.40813802\n",
      " 2.7931841  2.64195744 2.48969502 2.94986017 2.57442048 2.28693572\n",
      " 2.78809911 3.15379439 2.11473169 2.61203502]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "n = 100\n",
    "\n",
    "p = om.Problem()\n",
    "\n",
    "comp = om.VectorMagnitudeComp(vec_size=n, length=3,\n",
    "                              in_name='r', mag_name='r_mag', units='km')\n",
    "\n",
    "comp.add_magnitude(vec_size=n, length=3,\n",
    "                   in_name='b', mag_name='b_mag', units='ft')\n",
    "\n",
    "p.model.add_subsystem(name='vec_mag_comp', subsys=comp,\n",
    "                      promotes_inputs=['r', 'b'])\n",
    "\n",
    "p.setup()\n",
    "\n",
    "p.set_val('r', 1.0 + np.random.rand(n, 3))\n",
    "p.set_val('b', 1.0 + np.random.rand(n, 3))\n",
    "\n",
    "p.run_model()\n",
    "\n",
    "# Verify the results against numpy.dot in a for loop.\n",
    "expected_r = []\n",
    "expected_b = []\n",
    "for i in range(n):\n",
    "    a_i = p.get_val('r')[i, :]\n",
    "    expected_r.append(np.sqrt(np.dot(a_i, a_i)))\n",
    "\n",
    "    actual_i = p.get_val('vec_mag_comp.r_mag')[i]\n",
    "    rel_error = np.abs(expected_r[i] - actual_i)/actual_i\n",
    "    assert rel_error < 1e-9, f\"Relative error: {rel_error}\"\n",
    "\n",
    "    b_i = p.get_val('b')[i, :]\n",
    "    expected_b.append(np.sqrt(np.dot(b_i, b_i)))\n",
    "\n",
    "    actual_i = p.get_val('vec_mag_comp.b_mag')[i]\n",
    "    rel_error = np.abs(expected_b[i] - actual_i)/actual_i\n",
    "    assert rel_error < 1e-9, f\"Relative error: {rel_error}\"\n",
    "\n",
    "print(p.get_val('vec_mag_comp.r_mag'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "6815465e",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:48.028588Z",
     "iopub.status.busy": "2026-10-02T14:41:48.028395Z",
     "iopub.status.idle": "2026-10-02T14:41:48.033207Z",
     "shell.execute_reply": "2026-10-02T14:41:48.032590Z"
    },
    "papermill": {
     "duration": 0.007731,
     "end_time": "2026-10-02T14:41:48.033901+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:48.026170+00:00",
     "status": "completed"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2.96069145 3.13130979 2.46960323 2.24185923 3.14236443 2.7162824\n",
      " 2.67084699 2.65208076 2.23138507 2.96495719 2.21283452 2.96075738\n",
      " 2.7791782  2.45658923 2.32385805 2.61976552 3.07065177 3.02596357\n",
      " 2.81495593 2.79496595 2.69827459 2.17279619 3.12760617 2.52198103\n",
      " 2.69469765 2.1651186  2.44447024 2.82418528 2.79381759 2.24740186\n",
      " 2.04800647 2.45960075 2.73787187 2.78086296 2.73710427 2.18965073\n",
      " 2.40401628 2.7300819  3.05246641 2.66080812 2.20449301 2.68046025\n",
      " 2.15475355 2.22855567 2.38393625 2.49604276 2.69421345 2.52955125\n",
      " 2.50563237 2.71117168 2.22085459 2.29111274 2.65386564 2.74080244\n",
      " 2.79412452 2.61396614 2.38182512 2.46355725 1.91068459 2.02098145\n",
      " 2.23456152 2.55308248 2.45104384 2.28304056 2.69883242 2.69168668\n",
      " 2.77406375 2.96496458 2.08479141 2.60693208 2.51590045 2.83919379\n",
      " 2.47032324 2.8424662  2.59189145 2.75896828 2.90934579 2.99116046\n",
      " 2.65137125 1.9195302  2.84364137 2.46645639 2.12549131 3.08559738\n",
      " 2.86335082 2.64536696 2.27241003 2.32738122 2.77713957 2.85329487\n",
      " 2.24610566 1.93326468 2.37727492 2.34248477 2.95801972 2.09113215\n",
      " 2.73661374 2.64484663 3.0714567  2.33691541]\n"
     ]
    }
   ],
   "source": [
    "print(p.get_val('vec_mag_comp.b_mag'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "95216bda",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-02T14:41:48.038366Z",
     "iopub.status.busy": "2026-10-02T14:41:48.038188Z",
     "iopub.status.idle": "2026-10-02T14:41:48.041784Z",
     "shell.execute_reply": "2026-10-02T14:41:48.041148Z"
    },
    "papermill": {
     "duration": 0.00768,
     "end_time": "2026-10-02T14:41:48.043063+00:00",
     "exception": false,
     "start_time": "2026-10-02T14:41:48.035383+00:00",
     "status": "completed"
    },
    "tags": [
     "remove-input",
     "remove-output"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(6.060962970202032e-17)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "assert_near_equal(p.get_val('vec_mag_comp.r_mag'), np.array(expected_r))\n",
    "assert_near_equal(p.get_val('vec_mag_comp.b_mag'), np.array(expected_b))"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "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"
  },
  "orphan": true,
  "papermill": {
   "default_parameters": {},
   "duration": 3.745256,
   "end_time": "2026-10-02T14:41:48.660288+00:00",
   "environment_variables": {},
   "exception": null,
   "input_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/features/building_blocks/components/vector_magnitude_comp.ipynb",
   "output_path": "/home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/_executed_book/features/building_blocks/components/vector_magnitude_comp.ipynb",
   "parameters": {},
   "start_time": "2026-10-02T14:41:44.915032+00:00",
   "version": "2.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}