VectorMagnitudeComp#

VectorMagnitudeComp computes the magnitude (L2 norm) of a single input of some given length. It may be vectorized to provide the result at one or more points simultaneously.

\[ \lvert a_i \rvert = \sqrt{\bar{a}_i \cdot \bar{a}_i} \]

VectorMagnitudeComp Options#

The default vec_size is 1, providing the magnitude of \(a\) at a singlepoint. The length of \(a\) is provided by option length.

Other options for VectorMagnitudeComp allow the user to rename the input variable \(a\) and the output \(a\_mag\), as well as specifying their units.

OptionDefaultAcceptable ValuesAcceptable TypesDescription
always_optFalse[True, False]['bool']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.
derivs_methodN/A['jax', 'cs', 'fd', None]N/AThe method to use for computing derivatives
distributedFalse[True, False]['bool']If True, set all variables in this component as distributed across multiple processes
in_nameaN/A['str']The variable name for input vector.
length3N/A['int']The length of the input vector at each point
mag_namea_magN/A['str']The variable name for output vector magnitude.
run_root_onlyFalse[True, False]['bool']If True, call compute, compute_partials, linearize, apply_linear, apply_nonlinear, and compute_jacvec_product only on rank 0 and broadcast the results to the other ranks.
unitsN/AN/A['str']The units of the input vector.
use_jitTrue[True, False]['bool']If True, attempt to use jit on compute_primal, assuming jax or some other AD package is active.
vec_size1N/A['int']The number of points at which the vector magnitude is computed

VectorMagnitudeComp Constructor#

The call signature for the VectorMagnitudeComp constructor is:

VectorMagnitudeComp.__init__(**kwargs)[source]

Initialize the Vector Magnitude component.

VectorMagnitudeComp Usage#

There are often situations when numerous magnitudes need to be computed, essentially in parallel. You can reduce the number of components required by having one VectorMagnitudeComp perform multiple operations. This is also convenient when the different operations have common inputs.

The add_magnitude method is used to create additional magnitude calculations after instantiation.

VectorMagnitudeComp.add_magnitude(mag_name, in_name, units=None, vec_size=1, length=3)[source]

Add a new output magnitude to the vector magnitude component.

Parameters:
mag_namestr

The name of the output vector magnitude.

in_namestr

The name of the input vector.

unitsstr or None

The units of the input vector.

vec_sizeint

The number of points at which the dot vector product should be computed simultaneously. The shape of the output is (vec_size,).

lengthint

The length of the vectors a and b. Their shapes are (vec_size, length).

VectorMagnitudeComp Example#

In the following example VectorMagnitudeComp is used to compute the radius vector magnitude 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.

import numpy as np
import openmdao.api as om

n = 100

p = om.Problem()

comp = om.VectorMagnitudeComp(vec_size=n, length=3,
                              in_name='r', mag_name='r_mag', units='km')

p.model.add_subsystem(name='vec_mag_comp', subsys=comp,
                      promotes_inputs=[('r', 'pos')])

p.setup()

p.set_val('pos', 1.0 + np.random.rand(n, 3))

p.run_model()

# Verify the results against numpy.dot in a for loop.
expected = []
for i in range(n):
    a_i = p.get_val('pos')[i, :]
    expected.append(np.sqrt(np.dot(a_i, a_i)))

    actual_i = p.get_val('vec_mag_comp.r_mag')[i]
    rel_error = np.abs(expected[i] - actual_i)/actual_i
    assert rel_error < 1e-9, f"Relative error: {rel_error}"

print(p.get_val('vec_mag_comp.r_mag'))
[2.83110138 2.9379222  2.65718898 2.62409394 3.01323021 3.38360942
 2.55412889 2.41945636 2.35688086 2.5639024  2.76858905 2.58789971
 2.37967122 2.43830235 2.73279418 2.12406852 2.25077709 2.05757856
 2.89324747 2.8708736  2.82506964 2.93764203 2.43209613 2.6309755
 2.73671349 2.72799923 2.95834979 2.94647501 3.03786893 2.74777194
 2.82749894 2.75411076 2.8807654  2.54965302 2.72269804 2.22637367
 2.94360161 2.82118796 2.52262402 3.21541363 1.93661441 2.59978773
 2.43823309 2.37812993 2.58546561 2.64111564 2.00476581 2.41556316
 2.30231214 2.9339408  2.2088402  2.64005016 2.82887054 2.73325733
 2.34016847 2.87138236 2.75171085 2.11685398 2.51828981 2.80889947
 2.96928267 2.14182939 2.536292   2.31102643 2.91521909 3.0499047
 3.25791248 2.20996788 2.06961158 2.50831466 2.50776149 2.88823597
 2.63592488 2.01325394 2.33909477 2.34829147 2.64824405 2.08684603
 2.27089687 2.79467693 2.26335458 2.80948326 2.46671941 2.12303916
 2.39555382 2.43224933 2.9010863  2.91978433 3.00164892 2.89269997
 2.23142593 2.48771701 2.7617498  2.57656754 2.34586735 2.87526147
 2.40480431 2.43690625 2.22649783 2.55183931]

VectorMagnitudeComp Example with Multiple Magnitudes#

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.

import numpy as np

n = 100

p = om.Problem()

comp = om.VectorMagnitudeComp(vec_size=n, length=3,
                              in_name='r', mag_name='r_mag', units='km')

comp.add_magnitude(vec_size=n, length=3,
                   in_name='b', mag_name='b_mag', units='ft')

p.model.add_subsystem(name='vec_mag_comp', subsys=comp,
                      promotes_inputs=['r', 'b'])

p.setup()

p.set_val('r', 1.0 + np.random.rand(n, 3))
p.set_val('b', 1.0 + np.random.rand(n, 3))

p.run_model()

# Verify the results against numpy.dot in a for loop.
expected_r = []
expected_b = []
for i in range(n):
    a_i = p.get_val('r')[i, :]
    expected_r.append(np.sqrt(np.dot(a_i, a_i)))

    actual_i = p.get_val('vec_mag_comp.r_mag')[i]
    rel_error = np.abs(expected_r[i] - actual_i)/actual_i
    assert rel_error < 1e-9, f"Relative error: {rel_error}"

    b_i = p.get_val('b')[i, :]
    expected_b.append(np.sqrt(np.dot(b_i, b_i)))

    actual_i = p.get_val('vec_mag_comp.b_mag')[i]
    rel_error = np.abs(expected_b[i] - actual_i)/actual_i
    assert rel_error < 1e-9, f"Relative error: {rel_error}"

print(p.get_val('vec_mag_comp.r_mag'))
[2.42503712 2.85586474 2.73020517 2.64853556 2.60173105 3.00260917
 2.3734975  2.86075767 3.31117679 2.59370624 2.5323972  2.55496094
 2.02705196 2.30156321 2.67983007 2.52559542 2.68334974 3.11243831
 2.99321311 2.32515209 2.79480381 2.92979219 2.95050062 3.16186563
 2.11344266 2.54319756 2.30579912 2.72128503 2.87891927 3.03224801
 2.73246874 2.28659557 2.48591888 2.67252019 2.31219859 2.76155548
 2.67004314 2.81010341 2.81847986 2.46807357 2.56131761 2.94158976
 2.88533273 2.58531223 2.86200374 2.41235689 3.07629724 2.5341389
 2.53873988 2.63892903 2.29038591 2.94475478 2.65514439 2.28860643
 2.66824802 2.15783519 2.28727922 2.59026714 2.76616993 2.0757434
 3.0009915  2.40909464 2.70725107 3.07997189 2.49600655 2.40497639
 2.92411768 2.52530916 2.71659909 2.42596812 3.30486258 2.69762643
 2.56403077 2.09619472 3.10165733 2.79850275 2.57536584 2.00566192
 2.7805766  2.35023074 2.3673903  2.57261685 2.70531415 2.41779872
 2.27904478 2.70000424 2.40929206 2.98512228 2.93121726 2.45797882
 3.00520755 2.87441746 1.95324277 2.71004151 2.68624969 2.49010093
 2.50097755 2.54180373 2.72360544 2.46950025]
print(p.get_val('vec_mag_comp.b_mag'))
[2.39444234 2.63903409 2.31297613 2.82473647 2.6294979  2.70196635
 3.05943061 2.81432883 2.66515946 2.75910411 2.68031641 2.59285867
 2.76891859 2.54646209 2.61439497 2.72768409 3.09719148 2.29011861
 2.47493831 2.13404969 3.20764415 2.87184157 2.56776424 2.61173705
 2.41917386 2.67188173 2.3315059  2.70904505 2.67566412 3.07556616
 2.26354955 2.77013639 2.47285791 1.95380702 2.96792245 2.91231843
 2.4890491  2.46381199 2.77938198 2.45024335 2.30149681 2.84119327
 2.33023634 2.65071589 2.14069774 2.98912156 2.53038224 2.26264344
 3.03588981 2.19960048 2.78353517 2.73903908 2.33081861 2.38390386
 2.56231506 2.35680351 3.2478947  2.50374885 2.5483527  2.75385244
 2.8974776  2.2638447  2.4426737  2.3748311  2.80555778 2.54674151
 2.6319942  2.44503375 2.52680209 2.57727701 3.16040463 2.59637421
 2.8162821  2.32463537 2.7198841  2.29845742 2.42762288 2.54079476
 3.07062415 3.18071491 2.42280192 2.36934865 2.45596508 2.60067059
 2.31091678 2.92016835 2.27931081 2.72393685 2.90468105 2.15517408
 2.34389673 2.50996719 2.82977239 2.88973933 2.60745248 2.91277197
 2.62379155 2.55519585 2.7654492  2.7766804 ]