2015-12-29 3 views
0

У меня ситуация, когда градиент одного компонента по необходимости вычисляется в другом компоненте. То, что я попытался сделать, - это просто получить градиент от первого компонента и ввода ко второму компоненту. Я установил его как pass_by_obj, чтобы он не влиял на другие вычисления. Любые рекомендации относительно того, будет ли это лучший способ сделать это, будут оценены по достоинству. Тем не менее, я получаю сообщение об ошибке при использовании check_partial_derivatives(). Кажется, что это ошибка для любого вывода, указанного как pass_by_obj. Вот простой пример:Переход градиентов между компонентами; pass_by_obj output

import numpy as np 
from openmdao.api import Group, Problem, Component, ScipyGMRES, ExecComp, IndepVarComp 

class Comp1(Component): 
    def __init__(self): 
     super(Comp1, self).__init__() 
     self.add_param('x', shape=1) 

     self.add_output('y', shape=1) 
     self.add_output('dz_dy', shape=1, pass_by_obj=True) 

    def solve_nonlinear(self, params, unknowns, resids): 

     x = params['x'] 

     unknowns['y'] = 4.0*x + 1.0 
     unknowns['dz_dy'] = 2.0*x 

    def linearize(self, params, unknowns, resids): 

     J = {} 
     J['y', 'x'] = 4.0 
     return J 

class Comp2(Component): 
    def __init__(self): 
     super(Comp2, self).__init__() 
     self.add_param('y', shape=1) 
     self.add_param('dz_dy', shape=1, pass_by_obj=True) 

     self.add_output('z', shape=1) 

    def solve_nonlinear(self, params, unknowns, resids): 
     y = params['y'] 
     unknowns['z'] = y*2.0 

    def linearize(self, params, unknowns, resids): 
     J = {} 
     J['z', 'y'] = params['dz_dy'] 
     return J 

class TestGroup(Group): 
    def __init__(self): 
     super(TestGroup, self).__init__() 
     self.add('x', IndepVarComp('x', 0.0), promotes=['*']) 
     self.add('c1', Comp1(), promotes=['*']) 
     self.add('c2', Comp2(), promotes=['*']) 

p = Problem() 
p.root = TestGroup() 
p.setup(check=False) 

p['x'] = 2.0 

p.run() 

print p['z'] 
print 'gradients' 
test_grad = open('partial_gradients_test.txt', 'w') 
partial = p.check_partial_derivatives(out_stream=test_grad) 

Я получаю следующее сообщение об ошибке:

partial = p.check_partial_derivatives(out_stream=test_grad) 
    File "/usr/local/lib/python2.7/site-packages/openmdao/core/problem.py", line 1699, in check_partial_derivatives 
    dresids._dat[u_name].val[idx] = 1.0 
TypeError: '_ByObjWrapper' object does not support item assignment 

Я спросил прежде о PARAMS проверяется на pass_by_obj в check_partial_derivatives(), и это может быть просто вопрос проверки неизвестные для pass_by_obj.

ответ

0

Ошибка, которую вы получаете, является другой ошибкой, связанной с функцией check_partial_derivatives. Это должно быть достаточно легко исправить, но в то же время вы можете просто удалить настройку pass_by_obj. Поскольку вы вычисляете значение в одном компоненте и передаете его другому, вообще не нужно делать pass_by_obj (и это будет более эффективно, если вы этого не сделаете).

Вы сказали, что сделали это так, чтобы оно «не влияло на другие вычисления», но я не совсем понимаю, что вы подразумеваете под этим. Это не повлияет ни на что, если вы не используете его в методе solve_nonlinear.