Source code for openmdao.test_suite.components.implicit_newton_linesearch

"""Components used mainly for testing Newton and line searches."""
from math import exp

import numpy as np
import unittest

import openmdao.api as om


[docs]class ImplCompOneState(om.ImplicitComponent): """ A Simple Implicit Component R(x,y) = 0.5y^2 + 2y + exp(-16y^2) + 2exp(-5y) - x Solution: x = 1.2278849186466743 y = 0.3968459 """
[docs] def setup(self): self.add_input('x', 1.2278849186466743) self.add_output('y', val=1.0) self.declare_partials(of='*', wrt='*')
[docs] def apply_nonlinear(self, inputs, outputs, resids): """ Don't solve; just calculate the residual. """ x = inputs['x'] y = outputs['y'] resids['y'] = 0.5*y*y + 2.0*y + exp(-16.0*y*y) + 2.0*exp(-5.0*y) - x
[docs] def linearize(self, inputs, outputs, J): """ Analytical derivatives. """ y = outputs['y'] # State equation J[('y', 'x')] = -1.0 J[('y', 'y')] = y + 2.0 - 32.0*y*exp(-16.0*y*y) - 10.0*exp(-5.0*y)
[docs]class ImplCompTwoStates(om.ImplicitComponent): """ 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 Sol: when x = 2.0, z = 1.333 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 """
[docs] def setup(self): self.add_input('x', 0.5) self.add_output('y', 0.0) self.add_output('z', 2.0, lower=1.5, upper=2.5) self.maxiter = 10 self.atol = 1.0e-12 self.declare_partials(of='*', wrt='*')
[docs] def apply_nonlinear(self, inputs, outputs, residuals): """ Don't solve; just calculate the residual. """ x = inputs['x'] y = outputs['y'] z = outputs['z'] residuals['y'] = y - x - 2.0*z residuals['z'] = x*z + z - 4.0
[docs] def linearize(self, inputs, outputs, jac): """ Analytical derivatives. """ # Output equation jac[('y', 'x')] = -1.0 jac[('y', 'y')] = 1.0 jac[('y', 'z')] = -2.0 # State equation jac[('z', 'z')] = inputs['x'] + 1.0 jac[('z', 'x')] = outputs['z']
[docs]class ImplCompTwoStatesArrays(om.ImplicitComponent): """ 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 Sol: when x = 2.0, z = 1.333 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 """
[docs] def setup(self): self.add_input('x', np.zeros((3, 1))) self.add_output('y', np.zeros((3, 1))) self.add_output('z', 2.0*np.ones((3, 1)), lower=1.5, upper=np.array([2.6, 2.5, 2.65]).reshape((3,1))) self.maxiter = 10 self.atol = 1.0e-12 self.declare_partials(of='*', wrt='*')
[docs] def apply_nonlinear(self, inputs, outputs, residuals): """ Don't solve; just calculate the residual. """ x = inputs['x'] y = outputs['y'] z = outputs['z'] residuals['y'] = y - x - 2.0*z residuals['z'] = x*z + z - 4.0
[docs] def linearize(self, inputs, outputs, jac): """ Analytical derivatives. """ # Output equation jac[('y', 'x')] = -np.diag(np.array([1.0, 1.0, 1.0])) jac[('y', 'y')] = np.diag(np.array([1.0, 1.0, 1.0])) jac[('y', 'z')] = -np.diag(np.array([2.0, 2.0, 2.0])) # State equation jac[('z', 'z')] = (inputs['x'] + 1.0) * np.eye(3) jac[('z', 'x')] = outputs['z'] * np.eye(3)