首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用混合分析策略逼近整个问题

用混合分析策略逼近整个问题
EN

Stack Overflow用户
提问于 2021-06-11 19:40:16
回答 1查看 63关注 0票数 0

我有问题,我已经实现了一些成分的分析导数,我使用复杂的步骤,其余的。它们之间有一个循环依赖关系,所以我也使用一个求解器来收敛它们。当我使用NonlinearBlockGS时,它会收敛。但是,当我将NewtonSolver与线性求解器结合使用时,即使迭代次数很高,优化也会失败(迭代限制超过了)。但是我发现,当我使用prob.model.approx_totals()时,它很容易收敛并且工作得很好。我读到approx_totals使用fdcs来查找模型梯度。所以我有两个问题。

  1. 一般来说,当我使用approx_totals()时,我会失去混合分析方法的好处吗?有没有办法用混合分析策略找出整个模型(或群)的导数?(无论如何,在我的例子中,耦合的explicitcomponents使用“复杂步骤”。但我只是好奇。)
  2. 通常(在这个场景中不是这样),Openm道会自动检测混合策略吗?或者我应该如何指定它呢?

我也会感激的,如果你能告诉我一些例子,其中使用混合导数。我自己找不到他们。

编辑:添加示例。我无法在示例代码中再现这个问题。另外,我也不想浪费你的时间在我的代码(有超过30个ExplicitComponents和7个组)。所以我在下面做了一个简单的结构来更好地解释它。其中有7个成分是A to G,只有F and G没有分析衍生物,使用FD

代码语言:javascript
复制
import openmdao.api as om
import numpy as np

class ComponentA_withDerivatives(om.ExplicitComponent):
    def setup(self):
        #setup inputs and outputs
    
    def setup_partials(self):
        #partial declaration

    def compute(self, inputs, outputs):

    def compute_partials(self, inputs, J):
        #Partial definition

class ComponentB_withDerivatives(om.ExplicitComponent):
    .....

class ComponentC_withDerivatives(om.ExplicitComponent):
    ......

class ComponentD_withDerivatives(om.ExplicitComponent):
    ......

class ComponentE_withDerivatives(om.ExplicitComponent):
    ......


class ComponentF(om.ExplicitComponent):
    def setup(self):
        #setup inputs and outputs

        self.declare_partials(of='*', wrt='*', method='fd')

    def compute(self,inputs,outputs):
        # Computation

class ComponentG(om.ExplicitComponent):
    def setup(self):
        #setup inputs and outputs

        self.declare_partials(of='*', wrt='*', method='fd')

    def compute(self,inputs,outputs):
        # Computation 

class GroupAB(om.Group):
    def setup(self):
        self.add_subsystem('A', ComponentA_withDerivatives(), promotes_inputs=['x','y'], promotes_outputs=['z'])
        self.add_subsystem('B', ComponentB_withDerivatives(), promotes_inputs=['x','y','w','u'], promotes_outputs=['k'])

class GroupCD(om.Group):
    def setup(self):
        self.add_subsystem('C', ComponentC_withDerivatives(), .....)
        self.add_subsystem('D', ComponentD_withDerivatives(), ...)


class Final(om.Group):
    def setup(self):
        cycle1 = self.add_subsystem('cycle1', om.Group(), promotes=['*'])
        cycle1.add_subsystem('GroupAB', GroupAB())
        cycle1.add_subsystem('ComponentF', ComponentF())

        cycle1.linear_solver = om.DirectSolver()
        cycle1.nonlinear_solver = om.NewtonSolver(solve_subsystems=True)

        cycle2 = self.add_subsystem('cycle2', om.Group(), promotes=['*'])
        cycle2.add_subsystem('GroupCD', GroupCD())
        cycle2.add_subsystem('ComponentE_withDerivatives', ComponentE_withDerivatives())

        cycle2.linear_solver = om.DirectSolver()
        cycle2.nonlinear_solver = om.NewtonSolver(solve_subsystems=True)

        self.add_subsystem('ComponentG', ComponentG(), promotes_inputs=['a1','a2','a3'], promotes_outputs=['b1'])


prob = om.Problem()
prob.model = Final()

prob.driver = om.pyOptSparseDriver()
prob.driver.options['optimizer'] = 'SNOPT'
prob.driver.options['print_results']= True

## Design Variables

## Costraints

## Objectives

# Setup
prob.setup()

##prob.model.approx_totals(method='fd')

prob.run_model()

prob.run_driver()

这不管用。cycle1不收敛。当我完全删除cycle1或使用NonlinearBlockGS而不是Newton或取消注释prob.model.approx_total(method='FD')时,代码就能工作。( cycle2没有问题。(与牛顿合作)

因此,如果我不使用approx_totals(),我假设Openm道使用混合策略。或者我应该以某种方式手动提及它?当我使用approx_totals()的时候,我会失去我所拥有的分析导数的好处吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-17 01:47:31

您提供的代码示例是不可运行的,因此我不得不做一些猜测。你叫run_model()run_driver()。但是,您需要在示例代码中包含一个优化器,并且您已经在模型层次结构的顶部显示了要调用approx_totals。因此,当您说它不工作时,我假设您的意思是优化器不收敛。

您正确地理解了approx_totals的行为。当您将其设置在模型的顶部时,OpenMDAO将从组级别对相关变量进行FD。在这种情况下,这意味着你也将FD-跨越求解本身。你说这似乎是可行的,但混合分析方法不起作用。

一般来说,当我使用approx_totals()时,我会失去混合分析方法的好处吗?

是。你不再使用混合的方法了。你只是一次又一次的穿越模型。

有没有办法用混合分析策略找出整个模型(或群)的导数?

OpenMDAO是指在不使用approx_totals的情况下,使用混合策略计算总衍生品。问题是,对于你的模型,它似乎不起作用。

通常(在这个场景中不是这样),Openm道会自动检测混合策略吗?

它将“检测”它(它实际上没有检测到任何东西,但是底层的算法将使用混合策略,除非您告诉它不要使用approx_totals。同样,问题不是没有采用混合战略,而是不起作用。

,那么为什么混合策略不起作用呢?

我只能猜测,因为我不能运行密码.所以YMMV。您提到您正在为显式组件的部分使用复杂步骤。复杂步长是一种比FD精确得多的近似方案,但也有其自身的缺陷。并不是所有的计算都是复杂的--安全的。有些可以重写为复杂安全,而另一些则不能。所谓“复杂-安全”,我的意思是,计算正确地处理复杂部分,给出一个导数。

两种常用的复杂安全方法是np.linalg.normnp.abs。双方都乐于接受复数,并给出答案,但这不是正确的答案,当你需要导数。正因为如此,OpenMDAO附带了一个一组安全的自定义函数 --自定义normabs

非cs安全方法通常发生的情况是,复杂的部分以某种方式被抛出,得到0偏导数。错误的部分,错误的总数。

要检查这一点,请确保使用有限差分检查对正在执行复杂步骤的组件调用check_partials。你可能会发现一些不符之处。

您可以使用的修补程序是:

  1. 切换这些组件以使用FD部分。不太准确,但可能会起作用
  2. 纠正计算机中的任何问题都会使代码不安全。如果这是问题所在,或者您可能需要更加小心地在计算中分配和使用numpy数组,请使用OpenMDAO的自定义函数(如果您正在分配自己的数组,那么您需要小心确保它们也很复杂!)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67942714

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档