LinearSystemComp

The LinearSystemComp solves the linear system Ax = b where A and b are inputs, and x is the output.

LinearSystemComp Options

Option Default Acceptable Values Acceptable Types Description Deprecation
assembled_jac_typecsc ['csc', 'dense'] N/A Linear solver(s) in this group or implicit component, if using an assembled jacobian, will use this type. N/A
distributed False [True, False] ['bool'] True if ALL variables in this component are distributed across multiple processes. The 'distributed' option has been deprecated. Individual inputs and outputs should be set as distributed instead, using calls to add_input() or add_output().
run_root_only False [True, False] ['bool'] If True, call compute/compute_partials/linearize/apply_linear/apply_nonlinear/compute_jacvec_product only on rank 0 and broadcast the results to the other ranks.N/A
size 1 N/A ['int'] The size of the linear system. N/A
vec_size 1 N/A ['int'] Number of linear systems to solve. N/A
vectorize_A False [True, False] ['bool'] Set to True to vectorize the A matrix. N/A

LinearSystemComp Constructor

The call signature for the LinearSystemComp constructor is:

LinearSystemComp.__init__(**kwargs)[source]

Intialize the LinearSystemComp component.

LinearSystemComp Example

import numpy as np
import openmdao.api as om

model = om.Group()

A = np.array([[5.0, -3.0, 2.0], [1.0, 7.0, -4.0], [1.0, 0.0, 8.0]])
b = np.array([1.0, 2.0, -3.0])

lingrp = model.add_subsystem('lingrp', om.Group(), promotes=['*'])
lingrp.add_subsystem('lin', om.LinearSystemComp(size=3))

prob = om.Problem(model)
prob.setup()

prob.set_val('lin.A', A)
prob.set_val('lin.b', b)

lingrp.linear_solver = om.ScipyKrylov()

prob.run_model()

print(prob.get_val('lin.x'))
[ 0.36423841 -0.00662252 -0.4205298 ]

This component can also be vectorized to either solve a single linear system with multiple right hand sides, or to solve multiple independent linear systems.

You can solve multiple right hand sides by setting the “vec_size” argument, giving it the number of right hand sides. When you do this, the LinearSystemComp creates an input for “b” such that each row of b is solved independently.

model = om.Group()

A = np.array([[5.0, -3.0, 2.0], [1.0, 7.0, -4.0], [1.0, 0.0, 8.0]])
b = np.array([[2.0, -3.0, 4.0], [1.0, 0.0, -1.0]])

lingrp = model.add_subsystem('lingrp', om.Group(), promotes=['*'])
lingrp.add_subsystem('lin', om.LinearSystemComp(size=3, vec_size=2))

prob = om.Problem(model)
prob.setup()

prob.set_val('lin.A', A)
prob.set_val('lin.b', b)

lingrp.linear_solver = om.ScipyKrylov()

prob.run_model()

print(prob.get_val('lin.x'))
[[ 0.10596026 -0.16556291  0.48675497]
 [ 0.19205298 -0.11258278 -0.14900662]]

To solve multiple linear systems, you just need to set the “vectorize_A” option or argument to True. The A matrix is now a 3-dimensional matrix where the first dimension is the number of linear systems to solve.

model = om.Group()

A = np.array([[[5.0, -3.0, 2.0], [1.0, 7.0, -4.0], [1.0, 0.0, 8.0]],
              [[2.0, 3.0, 4.0], [1.0, -1.0, -2.0], [3.0, 2.0, -2.0]]])
b = np.array([[-5.0, 2.0, 3.0], [-1.0, 1.0, -3.0]])

lingrp = model.add_subsystem('lingrp', om.Group(), promotes=['*'])
lingrp.add_subsystem('lin', om.LinearSystemComp(size=3, vec_size=2, vectorize_A=True))

prob = om.Problem(model)
prob.setup()

prob.set_val('lin.A', A)
prob.set_val('lin.b', b)

lingrp.linear_solver = om.ScipyKrylov()

prob.run_model()

print(prob.get_val('lin.x'))
[[-0.78807947  0.66887417  0.47350993]
 [ 0.7        -1.8         0.75      ]]