【发布时间】:2021-08-17 12:53:18
【问题描述】:
我想定义一个变量,根据某些选项,该变量将等于先前的输出(就好像先前的输出有两个名称一样)或者将是新组件的输出。
一个简单的解决方案是在定义它的组件未实现时省略值的定义,但出于可读性/可追溯性的原因,我更愿意对其进行定义(以简化代码中的 if 语句,并将其作为时间序列输出提供)。
问题是在使用connect语句时,如果后续条件没有导致变量被用作另一个组件的输入,它会提供一个错误,指出它试图连接但变量不存在。
我使用一种链接语句 (LinkVarComp bellow) 进行了时间修复,它创建了一个输出等于输入的显式组件(以及一些其他的东西,如缩放和移位,这可能对线性方程有用),但我担心这会增加不必要的计算/设计变量/约束。
是否有更简单/更好的解决方法? (也许通过允许变量有多个名称?)最好的做法是让一个具有不同名称的变量等于先前的输出/输入?
一个简单的例子:
import openmdao.api as om
model = om.Group()
model.add_subsystem('xcomp',subsys=om.IndepVarComp(name='x',val=np.zeros((3,2))),promotes_outputs=['*'])
model.connect('x','y')
p = om.Problem(model)
p.setup(force_alloc_complex=True)
p.set_val('x', np.array([[1.0 ,3],[10 ,-5],[0,3.1]]))
p.run_model()
因错误而崩溃
NameError: <model> <class Group>: Attempted to connect from 'x' to 'y', but 'y' doesn't exist.
虽然这在使用以下 LinkVarComp 组件时有效(但我想添加新的变量和计算)
import openmdao.api as om
import numpy as np
from math import prod
class LinkVarComp(om.ExplicitComponent):
"""
Component containing
"""
def initialize(self):
"""
Declare component options.
"""
self.options.declare('shape', types=(int,tuple),default=1)
self.options.declare('scale', types=int,default=1)
self.options.declare('shift', types=float,default=0.)
self.options.declare('input_default', types=float,default=0.)
self.options.declare('input_name', types=str,default='x')
self.options.declare('output_name', types=str,default='y')
self.options.declare('output_default', types=float,default=0.)
self.options.declare('input_units', types=(str,None),default=None)
self.options.declare('output_units', types=(str,None),default=None)
def setup(self):
self.add_input(name=self.options['input_name'],val=self.options['input_default'],shape=self.options['shape'],units=self.options['input_units'])
self.add_output(name=self.options['output_name'],val=self.options['output_default'],shape=self.options['shape'],units=self.options['output_units'])
if type(self.options['shape']) == int:
n = self.options['shape']
else:
n =prod( self.options['shape'])
ar = np.arange(n)
self.declare_partials(of=self.options['output_name'] , wrt=self.options['input_name'], rows=ar, cols=ar,val=self.options['scale'])
def compute(self, inputs, outputs):
outputs[self.options['output_name']] = self.options['scale']*inputs[self.options['input_name']] + self.options['shift']
model = om.Group()
model.add_subsystem('xcomp',subsys=om.IndepVarComp(name='x',val=np.zeros((3,2))),promotes_outputs=['*'])
model.add_subsystem('link', LinkVarComp(shape=(3,2)),
promotes_inputs=['*'],
promotes_outputs=['*'])
p = om.Problem(model)
p.setup(force_alloc_complex=True)
p.set_val('x', np.array([[1.0 ,3],[10 ,-5],[0,3.1]]))
p.run_model()
print(p['y'])
输出预期:
[[ 1. 3. ]
[10. -5. ]
[ 0. 3.1]]
【问题讨论】:
标签: openmdao