Python 如何在DAO中求解方程组?

Python 如何在DAO中求解方程组?,python,openmdao,Python,Openmdao,我试图用OpenMDAO解这个简单的隐式方程。方程式如下所示, x*z+z-4=0 y=x+2*z 对于x=0.5,溶液为z=2.666667,y=5.833333 对于本例,我使用了如下所示的代码 from __future__ import print_function from openmdao.api import Component, Group, Problem, Newton, ScipyGMRES class SimpleEquationSystem(Component):

我试图用OpenMDAO解这个简单的隐式方程。方程式如下所示,
x*z+z-4=0
y=x+2*z

对于x=0.5,溶液为z=2.666667,y=5.833333

对于本例,我使用了如下所示的代码

from __future__ import print_function

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

class SimpleEquationSystem(Component):
    """Solve the Equation 
            x*z + z - 4 = 0
            y = x + 2*z

       Solution: z = 2.666667, y = 5.833333 for x = 0.5
    """

    def __init__(self):
        super(SimpleEquationSystem, self).__init__()


        self.add_param('x', 0.5)
        self.add_state('y', 0.0)
        self.add_state('z', 0.0)
        self.iter=0

    def solve_nonlinear(self, params, unknowns, resids):
        """This component does no calculation on its own. It mainly holds the
        initial value of the state. An OpenMDAO solver outside of this
        component varies it to drive the residual to zero."""
        pass

    def apply_nonlinear(self, params, unknowns, resids):
        """ Report the residual """
        self.iter+=1
        x=params['x']
        y = unknowns['y']
        z = unknowns['z']


        resids['y'] = x*z + z - 4
        resids['z'] = x + 2*z - y

        print('y_%d' % self.iter,'=%f' %resids['y'], 'z_%d' % self.iter, '=%f' %resids['z'])
        print('x' ,'=%f' %x, 'y', '=%f' %y, 'z', '=%f' %z)

top = Problem()
root = top.root = Group()
root.add('comp', SimpleEquationSystem())


# Tell these components to finite difference
root.comp.deriv_options['type'] = 'fd'
root.comp.deriv_options['form'] = 'central'
root.comp.deriv_options['step_size'] = 1.0e-4
root.nl_solver = Newton()
root.ln_solver = ScipyGMRES()

top.setup()
top.print_all_convergence(level=1, depth=2)
top.run()
print('Solution x=%.2f, y=%.2f, z=%.2f' % (top['comp.x'], top['comp.y'], top['comp.z']))
我写了一个基于方法的代码。 为了运行这个代码,我得到了这样的解决方案

##############################################
Setup: Checking root problem for potential issues...

No recorders have been specified, so no data will be saved.

The following parameters have no associated unknowns:
comp.x

The following components have no connections:
comp

Setup: Check of root problem complete.
##############################################

y_1 =-4.000000 z_1 =0.500000
x =0.500000 y =0.000000 z =0.000000
y_2 =-4.000000 z_2 =0.499900
x =0.500000 y =0.000100 z =0.000000
y_3 =-4.000000 z_3 =0.500100
x =0.500000 y =-0.000100 z =0.000000
y_4 =-3.999850 z_4 =0.500200
x =0.500000 y =0.000000 z =0.000100
y_5 =-4.000150 z_5 =0.499800
x =0.500000 y =0.000000 z =-0.000100
   [root] LN: GMRES   1 | 0 0
   [root] LN: GMRES   1 | Converged in 1 iterations
y_6 =-inf z_6 =-inf
x =0.500000 y =inf z =-inf
y_7 =-inf z_7 =-inf
x =0.500000 y =inf z =-inf
y_8 =-inf z_8 =-inf
x =0.500000 y =inf z =-inf
y_9 =-inf z_9 =-inf
x =0.500000 y =inf z =-inf
y_10 =-inf z_10 =-inf
x =0.500000 y =inf z =-inf
   [root] LN: GMRES   1000 | nan nan
   [root] LN: GMRES   1000 | Converged in 1000 iterations
y_11 =nan z_11 =nan
x =0.500000 y =nan z =nan
[root] NL: NEWTON   2 | nan nan (nan)
[root] NL: NEWTON   2 | FAILED to converge after 2 iterations
Solution x=0.50, y=nan, z=nan
C:\ProgramData\Anaconda3\Anaconda3\lib\site-packages\openmdao\core\system.py:750: RuntimeWarning: invalid value encountered in subtract
  resultvec.vec[:] -= cache2

你知道,如何用各自的迭代来解决这个问题吗?。告诉我,在这种情况下,如何构造solve_Nonal&apply_Nonal。

当您为自变量添加Indepvarcomp时,问题似乎就解决了:

root.add('p1', IndepVarComp('x', 0.5))
root.add('comp', SimpleEquationSystem())
root.connect('p1.x', 'comp.x')
然后它迅速收敛

[root] NL: NEWTON   1 | 2.73692411e-11 6.7894731e-12 (6.41396046825)
[root] NL: NEWTON   1 | Converged in 1 iterations

我同意你不应该为了这个工作而添加这个,这可能是一个bug。我已经验证了这个问题已经在我们最新的OpenMDAO开发版本中修复。

谢谢,Kenneth。这对我们很有用。但我用你的最新开发版本的试过了。这也重复了同样的错误。如果不添加IndepVarComp变量,我无法运行一个问题。我想摩尔博士指的是尚未发布的2.x版本,而不是您可能使用的1.7.x版本?