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 |
---|---|---|---|---|
always_opt | False | [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. |
assembled_jac_type | csc | ['csc', 'dense'] | N/A | Linear solver(s) in this group or implicit component, if using an assembled jacobian, will use this type. |
derivs_method | N/A | ['jax', 'cs', 'fd', None] | N/A | The method to use for computing derivatives |
distributed | False | [True, False] | ['bool'] | If True, set all variables in this component as distributed across multiple processes |
run_root_only | False | [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. |
size | 1 | N/A | ['int'] | The size of the linear system. |
use_jit | True | [True, False] | ['bool'] | If True, attempt to use jit on compute_primal, assuming jax or some other AD package is active. |
vec_size | 1 | N/A | ['int'] | Number of linear systems to solve. |
vectorize_A | False | [True, False] | ['bool'] | Set to True to vectorize the A matrix. |
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 ]]