Array IndexingΒΆ
omtools
supports indexing into Variable
objects for explicit
outputs.
In this example, integer indices are used to concatenate multiple expressions/variables into one variable and extract values from a single variable representing an array.
from openmdao.api import Problem
import numpy as np
import omtools.api as ot
from omtools.api import Group
class ExampleInteger(Group):
def setup(self):
a = self.declare_input('a', val=0)
b = self.declare_input('b', val=1)
c = self.declare_input('c', val=2)
d = self.declare_input('d', val=7.4)
e = self.declare_input('e', val=np.pi)
f = self.declare_input('f', val=9)
g = e + f
x = self.create_output('x', shape=(7, ))
x[0] = a
x[1] = b
x[2] = c
x[3] = d
x[4] = e
x[5] = f
x[6] = g
# Get value from indices
self.register_output('x0', x[0])
self.register_output('x6', x[6])
prob = Problem()
prob.model = ExampleInteger()
prob.setup(force_alloc_complex=True)
prob.run_model()
print('x', prob['x'].shape)
print(prob['x'])
print('x0', prob['x0'].shape)
print(prob['x0'])
print('x6', prob['x6'].shape)
print(prob['x6'])
x (7,)
[ 0. 1. 2. 7.4 3.14159265 9.
12.14159265]
x0 (1,)
[0.]
x6 (1,)
[12.14159265]
Here is the n2 diagram:
omtools
supports specifying ranges as well as individual indices to
slice and concatenate arrays.
from openmdao.api import Problem
import numpy as np
import omtools.api as ot
from omtools.api import Group
class ExampleOneDimensional(Group):
def setup(self):
n = 20
u = self.declare_input('u',
shape=(n, ),
val=np.arange(n).reshape((n, )))
v = self.declare_input('v',
shape=(n - 4, ),
val=np.arange(n - 4).reshape((n - 4, )))
w = self.declare_input('w',
shape=(4, ),
val=16 + np.arange(4).reshape((4, )))
x = self.create_output('x', shape=(n, ))
x[0:n] = 2 * (u + 1)
y = self.create_output('y', shape=(n, ))
y[0:n - 4] = 2 * (v + 1)
y[n - 4:n] = w - 3
# Get value from indices
z = self.create_output('z', shape=(3, ))
z[0:3] = ot.expand(x[2], (3, ))
self.register_output('x0_5', x[0:5])
self.register_output('x3_', x[3:])
self.register_output('x2_4', x[2:4])
prob = Problem()
prob.model = ExampleOneDimensional()
prob.setup(force_alloc_complex=True)
prob.run_model()
print('x', prob['x'].shape)
print(prob['x'])
print('y', prob['y'].shape)
print(prob['y'])
print('z', prob['z'].shape)
print(prob['z'])
print('x0_5', prob['x0_5'].shape)
print(prob['x0_5'])
print('x3_', prob['x3_'].shape)
print(prob['x3_'])
print('x2_4', prob['x2_4'].shape)
print(prob['x2_4'])
x (20,)
[ 2. 4. 6. 8. 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30. 32. 34. 36.
38. 40.]
y (20,)
[ 2. 4. 6. 8. 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30. 32. 13. 14.
15. 16.]
z (3,)
[6. 6. 6.]
x0_5 (5,)
[ 2. 4. 6. 8. 10.]
x3_ (17,)
[ 8. 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30. 32. 34. 36. 38. 40.]
x2_4 (2,)
[6. 8.]
omtools
supports specifying ranges along multiple axes as well as
individual indices and ranges to slice and concatenate arrays.
from openmdao.api import Problem
import numpy as np
import omtools.api as ot
from omtools.api import Group
class ExampleMultidimensional(Group):
def setup(self):
# Works with two dimensional arrays
z = self.declare_input('z',
shape=(2, 3),
val=np.arange(6).reshape((2, 3)))
x = self.create_output('x', shape=(2, 3))
x[0:2, 0:3] = z
# Also works with higher dimensional arrays
p = self.declare_input('p',
shape=(5, 2, 3),
val=np.arange(30).reshape((5, 2, 3)))
q = self.create_output('q', shape=(5, 2, 3))
q[0:5, 0:2, 0:3] = p
# Get value from indices
self.register_output('r', p[0, :, :])
# Assign a vector to a slice
vec = self.create_indep_var(
'vec',
shape=(1, 20),
val=np.arange(20).reshape((1, 20)),
)
s = self.create_output('s', shape=(2, 20))
s[0, :] = vec
s[1, :] = 2 * vec
# negative indices
t = self.create_output('t', shape=(5, 3, 3), val=0)
t[0:5, 0:-1, 0:3] = p
prob = Problem()
prob.model = ExampleMultidimensional()
prob.setup(force_alloc_complex=True)
prob.run_model()
print('x', prob['x'].shape)
print(prob['x'])
print('q', prob['q'].shape)
print(prob['q'])
print('r', prob['r'].shape)
print(prob['r'])
print('s', prob['s'].shape)
print(prob['s'])
print('t', prob['t'].shape)
print(prob['t'])
stop 2
x (2, 3)
[[0. 1. 2.]
[3. 4. 5.]]
q (5, 2, 3)
[[[ 0. 1. 2.]
[ 3. 4. 5.]]
[[ 6. 7. 8.]
[ 9. 10. 11.]]
[[12. 13. 14.]
[15. 16. 17.]]
[[18. 19. 20.]
[21. 22. 23.]]
[[24. 25. 26.]
[27. 28. 29.]]]
r (1, 2, 3)
[[[0. 1. 2.]
[3. 4. 5.]]]
s (2, 20)
[[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
18. 19.]
[ 0. 2. 4. 6. 8. 10. 12. 14. 16. 18. 20. 22. 24. 26. 28. 30. 32. 34.
36. 38.]]
t (5, 3, 3)
[[[ 0. 1. 2.]
[ 3. 4. 5.]
[ 1. 1. 1.]]
[[ 6. 7. 8.]
[ 9. 10. 11.]
[ 1. 1. 1.]]
[[12. 13. 14.]
[15. 16. 17.]
[ 1. 1. 1.]]
[[18. 19. 20.]
[21. 22. 23.]
[ 1. 1. 1.]]
[[24. 25. 26.]
[27. 28. 29.]
[ 1. 1. 1.]]]