Source code for openmdao.examples.implicit

# Simple implicit component example. Component solves itself.

from __future__ import print_function
import numpy as np

from openmdao.api import Component, Group, Problem, ScipyGMRES

[docs]class SimpleImplicitComp(Component): """ A Simple Implicit Component with an additional output equation. f(x,z) = xz + z - 4 y = x + 2z Sol: when x = 0.5, z = 2.666 Coupled derivs: y = x + 8/(x+1) dy_dx = 1 - 8/(x+1)**2 = -2.5555555555555554 z = 4/(x+1) dz_dx = -4/(x+1)**2 = -1.7777777777777777 """ def __init__(self): super(SimpleImplicitComp, self).__init__() # Params self.add_param('x', 0.5) # Unknowns self.add_output('y', 0.0) # States self.add_state('z', 0.0) self.maxiter = 25 self.atol = 1.0e-12
[docs] def solve_nonlinear(self, params, unknowns, resids): """ Simple iterative solve. (Babylonian method).""" x = params['x'] z = unknowns['z'] znew = z itercount = 0 eps = 1.0e99 while itercount < self.maxiter and abs(eps) > self.atol: z = znew znew = 4.0 - x*z eps = x*znew + znew - 4.0 itercount += 1 # Our State unknowns['z'] = znew # Our Output unknowns['y'] = x + 2.0*znew
[docs] def apply_nonlinear(self, params, unknowns, resids): """ Don't solve; just calculate the residual.""" x = params['x'] z = unknowns['z'] resids['z'] = x*z + z - 4.0 # Output equations need to evaluate a residual just like an explicit comp. resids['y'] = x + 2.0*z - unknowns['y']
[docs] def linearize(self, params, unknowns, resids): """Analytical derivatives.""" J = {} # Output equation J[('y', 'x')] = np.array([1.0]) J[('y', 'z')] = np.array([2.0]) # State equation J[('z', 'z')] = np.array([params['x'] + 1.0]) J[('z', 'x')] = np.array([unknowns['z']]) return J
if __name__ == '__main__': top = Problem() root = top.root = Group() root.add('comp', SimpleImplicitComp()) root.ln_solver = ScipyGMRES() top.setup() top.run() print('Solution: x = %f, z = %f, y = %f' % (top['comp.x'], top['comp.z'], top['comp.y']))