2017-09-06 96 views
0

我試圖用OpenMDAO解決簡單的隱式方程。該公式如下所示,
X * Z + Z - 4 = 0
Y = X + 2 * Z如何在OpenMDAO中求解方程組?

的解決方案是Z = 2.666667,Y = 5.833333對於x = 0.5。

對於這種情況,我已經使用其在下面示出的代碼,

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'])) 

我寫基於Solving an Implicit Relationship with a Newton Solver方法的代碼。 要運行這個代碼,我得到了這樣一個解決方案,

############################################## 
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_nonlinear & apply_nonlinear。

回答

1

看來,當你添加一個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 

我同意你不應該添加這個工作,它可能是一個錯誤。我已經證實,我們最新的OpenMDAO開發版本已修復此問題。

+0

謝謝,Kenneth。這對我們非常有用。但是我用[OpenMDAO]的最新開發版本(https://github.com/OpenMDAO/OpenMDAO)嘗試了這些。這也重複了同樣的錯誤。如果不添加IndepVarComp變量,我無法運行問題。 –

+0

我認爲摩爾博士意味着尚未發佈的2.x版本,而您可能使用的是1.7.x版本? – kmarsteller