在问题中定义未用作输入的变量,并且等于先前的 input/output
Define variable in problem which is not used as input, and equals a previous input/output
我想定义一个变量,根据某些选项,该变量将等于以前的输出(好像以前的输出有两个名称)或者将是新组件的输出。
一个简单的解决方案是在未实现定义值的组件时省略值的定义,但出于 readability/traceability 原因我更希望定义它(以简化 if 语句代码,并将其作为时间序列输出提供)。
问题是,当使用connect语句时,如果后续条件没有导致变量被用作另一个组件的输入,它会提供一个错误,提示它尝试连接但变量不存在.
我用一种 link 语句(下面的 LinkVarComp 波纹管)进行了临时修复,它创建了一个输出等于输入的显式组件(以及一些额外的东西,如缩放和移位,这可能是对线性方程有用),但我担心这会增加不必要的 computations/design variables/constraints.
是否有 easier/better 解决方法? (也许通过允许变量有多个名称?)最好的做法是让一个变量的名称与之前的 output/input 相同?
一个简单的例子:
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 中,您不能让同一个变量使用两个不同的名称。那是不允许的。
您提出的解决方案实际上是创建一个单独的组件来保存输出的副本。这样可行。您可以使用 ExecComp 以更少的代码获得相同的效果:
import numpy as np
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.add_subsystem('ycomp', om.ExecComp("y=x", shape=(3,2)), promotes=['*'])
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['x'])
print(p['y'])
一般来说,我自己可能不会真正这样做。好像有点浪费相反,我会修改我的 post-processing 脚本来寻找 y
,如果它没有找到它然后抓取 x
。
我想定义一个变量,根据某些选项,该变量将等于以前的输出(好像以前的输出有两个名称)或者将是新组件的输出。
一个简单的解决方案是在未实现定义值的组件时省略值的定义,但出于 readability/traceability 原因我更希望定义它(以简化 if 语句代码,并将其作为时间序列输出提供)。
问题是,当使用connect语句时,如果后续条件没有导致变量被用作另一个组件的输入,它会提供一个错误,提示它尝试连接但变量不存在.
我用一种 link 语句(下面的 LinkVarComp 波纹管)进行了临时修复,它创建了一个输出等于输入的显式组件(以及一些额外的东西,如缩放和移位,这可能是对线性方程有用),但我担心这会增加不必要的 computations/design variables/constraints.
是否有 easier/better 解决方法? (也许通过允许变量有多个名称?)最好的做法是让一个变量的名称与之前的 output/input 相同?
一个简单的例子:
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 中,您不能让同一个变量使用两个不同的名称。那是不允许的。
您提出的解决方案实际上是创建一个单独的组件来保存输出的副本。这样可行。您可以使用 ExecComp 以更少的代码获得相同的效果:
import numpy as np
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.add_subsystem('ycomp', om.ExecComp("y=x", shape=(3,2)), promotes=['*'])
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['x'])
print(p['y'])
一般来说,我自己可能不会真正这样做。好像有点浪费相反,我会修改我的 post-processing 脚本来寻找 y
,如果它没有找到它然后抓取 x
。