我刚刚完成了阅读器和记录器的教程。我想知道是否有一种方法可以计算每个学科被调用的次数。下面我在 Sellar 问题中使用全局变量来计算这个。更好的方法是什么?另外,如果问题没有解决者,建议的方式会改变吗?
import numpy as np
import time
import openmdao.api as om
tic = time.perf_counter()
dc1 = 0
dc2 = 0
class SellarDis1(om.ExplicitComponent):
def setup(self):
self.add_input('z', val=np.zeros(2))
self.add_input('x', val=0.)
self.add_input('y2', val=1.0)
self.add_output('y1', val=1.0)
self.declare_partials('*', '*', method='fd')
def compute(self, inputs, outputs):
global dc1
dc1+=1
z1 = inputs['z'][0]
z2 = inputs['z'][1]
x1 = inputs['x']
y2 = inputs['y2']
outputs['y1'] = z1**2 + z2 + x1 - 0.2*y2
class SellarDis2(om.ExplicitComponent):
def setup(self):
self.add_input('z', val=np.zeros(2))
self.add_input('y1', val=1.0)
self.add_output('y2', val=1.0)
self.declare_partials('*', '*',method='fd')
def compute(self, inputs, outputs):
global dc2
dc2 +=1
z1 = inputs['z'][0]
z2 = inputs['z'][1]
y1 = inputs['y1']
if y1.real < 0.0:
y1 *= -1
outputs['y2'] = y1**.5 + z1 + z2
class SellarMDF(om.Group):
def setup(self):
indeps = self.add_subsystem('indeps', om.IndepVarComp(), promotes=['*'])
indeps.add_output('x', 1.0)
indeps.add_output('z', np.array([5.0, 2.0]))
cycle = self.add_subsystem('cycle', om.Group(), promotes=['*'])
cycle.add_subsystem('d1', SellarDis1(), promotes_inputs=['x', 'z', 'y2'],
promotes_outputs=['y1'])
cycle.add_subsystem('d2', SellarDis2(), promotes_inputs=['z', 'y1'],
promotes_outputs=['y2'])
cycle.linear_solver = om.ScipyKrylov()
cycle.nonlinear_solver = om.NewtonSolver(solve_subsystems=False)
self.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)',
z=np.array([0.0, 0.0]), x=0.0, y1=0.0, y2=0.0),
promotes=['x', 'z', 'y1', 'y2', 'obj'])
self.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1'])
self.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2'])
prob = om.Problem()
prob.model = SellarMDF()
driver = prob.driver = om.ScipyOptimizer()
prob.driver.options['optimizer'] = 'SLSQP'
prob.model.add_design_var('x', lower=0, upper=10)
prob.model.add_design_var('z', lower=0, upper=10)
prob.model.add_objective('obj')
prob.model.add_constraint('con1', upper=0)
prob.model.add_constraint('con2', upper=0)
prob.setup()
prob.set_solver_print(level=0)
prob.run_driver()
print('minimum found at')
print(prob['x'][0])
print(prob['z'])
print('Coupling Variables')
print(prob['y1'][0])
print(prob['y2'][0])
print('minumum objective')
print(prob['obj'][0])
toc = time.perf_counter()
print(f"You waited {toc - tic:0.4f} seconds")
print("Function Calls")
print('SellarDis1 : ', dc1)
print('SellarDis2 : ', dc2)
Run Code Online (Sandbox Code Playgroud)
编辑:我所说的更好是指“openmdao”方式,例如使用录音机或其他东西。
所有 OpenMDAO 系统(组件和组的总称)都具有该iter_count属性。这是 的文档页面System,所有组件和组都从中继承。iter_count是对每个方法的调用总数compute(),而iter_count_without_approx是对方法的调用次数compute(),不包括由于梯度近似而导致的调用次数。此方法适用于任何求解器层次结构或驱动程序设置。
因此,示例脚本的最后两行将是:
print('SellarDis1 : ', prob.model.cycle.d1.iter_count)
print('SellarDis2 : ', prob.model.cycle.d2.iter_count)
Run Code Online (Sandbox Code Playgroud)
正如您所建议的,这不使用录音机。如果您更喜欢使用记录器的解决方案,我们可以找到一个可行的方法。这里有很大的灵活性,要开始使用,您可以查看有关案例阅读的特定文档页面,这可以帮助对案例进行后处理以获得呼叫总数。
如果有任何不清楚的地方,请告诉我!
| 归档时间: |
|
| 查看次数: |
301 次 |
| 最近记录: |