Expressing Cyclic Relationships with Explicit OutputsΒΆ
We can also define a value in terms of itself. In the example below, consider three fixed point iterations. Each of these fixed point iterations is declared within its own subsystem so that a solver may be assigned to it. Note that variables are not rpomoted so that we can use the same name to refer to different variables, depending on which subsystem they belong to.
from openmdao.api import Problem
from openmdao.api import ScipyKrylov, NewtonSolver, NonlinearBlockGS
from omtools.api import Group, ImplicitComponent
import omtools.api as ot
import numpy as np
class ExampleCycles(Group):
def setup(self):
# x == (3 + x - 2 * x**2)**(1 / 4)
group = Group()
x = group.create_output('x')
x.define((3 + x - 2 * x**2)**(1 / 4))
group.nonlinear_solver = NonlinearBlockGS(maxiter=100)
self.add_subsystem('cycle_1', group)
# x == ((x + 3 - x**4) / 2)**(1 / 4)
group = Group()
x = group.create_output('x')
x.define(((x + 3 - x**4) / 2)**(1 / 4))
group.nonlinear_solver = NonlinearBlockGS(maxiter=100)
self.add_subsystem('cycle_2', group)
# x == 0.5 * x
group = Group()
x = group.create_output('x')
x.define(0.5 * x)
group.nonlinear_solver = NonlinearBlockGS(maxiter=100)
self.add_subsystem('cycle_3', group)
prob = Problem()
prob.model = ExampleCycles()
prob.setup(force_alloc_complex=True)
prob.run_model()
print('cycle_1.x', prob['cycle_1.x'].shape)
print(prob['cycle_1.x'])
print('cycle_2.x', prob['cycle_2.x'].shape)
print(prob['cycle_2.x'])
print('cycle_3.x', prob['cycle_3.x'].shape)
print(prob['cycle_3.x'])
=======
cycle_1
=======
NL: NLBGS Converged in 48 iterations
=======
cycle_2
=======
NL: NLBGS Converged in 26 iterations
=======
cycle_3
=======
NL: NLBGS Converged in 34 iterations
cycle_1.x (1,)
[1.12412303]
cycle_2.x (1,)
[1.07989607]
cycle_3.x (1,)
[5.82076609e-11]