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
assembled_jac_type csc [‘csc’, ‘dense’] N/A Linear solver(s) in this group, if using an assembled jacobian, will use this type.
distributed False N/A N/A True if the component has variables that are distributed across multiple processes.
size 1 N/A [‘int’] The size of the linear system.
vec_size 1 N/A [‘int’] Number of linear systems to solve.
vectorize_A False N/A [‘bool’] Set to True to vectorize the A matrix.

Note: Options can be passed as keyword arguments at initialization.

LinearSystemComp Example

import numpy as np

from openmdao.api import Group, Problem, IndepVarComp
from openmdao.api import LinearSystemComp, ScipyKrylov

model = 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])

model.add_subsystem('p1', IndepVarComp('A', A))
model.add_subsystem('p2', IndepVarComp('b', b))

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

model.connect('p1.A', 'lin.A')
model.connect('p2.b', 'lin.b')

prob = Problem(model)
prob.setup()

lingrp.linear_solver = ScipyKrylov()

prob.run_model()

print(prob['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.

import numpy as np

from openmdao.api import Group, Problem, IndepVarComp
from openmdao.api import LinearSystemComp, ScipyKrylov

model = 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]])

model.add_subsystem('p1', IndepVarComp('A', A))
model.add_subsystem('p2', IndepVarComp('b', b))

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

model.connect('p1.A', 'lin.A')
model.connect('p2.b', 'lin.b')

prob = Problem(model)
prob.setup()

lingrp.linear_solver = ScipyKrylov()

prob.run_model()

print(prob['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.

import numpy as np

from openmdao.api import Group, Problem, IndepVarComp
from openmdao.api import LinearSystemComp, ScipyKrylov

model = 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]])

model.add_subsystem('p1', IndepVarComp('A', A))
model.add_subsystem('p2', IndepVarComp('b', b))

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

model.connect('p1.A', 'lin.A')
model.connect('p2.b', 'lin.b')

prob = Problem(model)
prob.setup()

lingrp.linear_solver = ScipyKrylov()

prob.run_model()

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