【发布时间】:2021-07-07 21:04:47
【问题描述】:
我有一些几何图形,我已在上游参数化到网格预处理器中,该预处理器为我运行的外部代码生成输入。其输出是由其输入定义的几何图形,调用我的外部求解器,然后从 CSV 文件中提取输出。我已经让它运行了,但在优化方面肯定没有最小化函数的价值。事实上,它的尝试值都稍微偏离了起点。
我有 5 个影响几何形状的设计变量,并设置在不同的范围内,我们称它们为 a、b、c、d 和 e。每个变量的标称起始值为 0.1。从我保存的文件的历史记录中可以清楚地看到,例如试过了
a | b | c | d | e
------------------
0.100001 0.1 0.1 0.1 0.1
0.1 0.100001 0.1 0.1 0.1
0.1 0.1 0.100001 0.1 0.1
0.1 0.1 0.1 0.100001 0.1
0.1 0.1 0.1 0.1 0.100001
0.1 0.1 0.1 0.1 0.1
它以某种方式确定原始起始值是最佳的,这非常奇怪,因为在我的例子中,我们可以依次查看每个返回值 (fout)。然后我意识到我需要将我的返回值缩放到更接近 1 的值,我已经完成了一些比较,现在我得到了以下结果
Inequality constraints incompatible (Exit mode 4)
Current function value: [0.90320516]
Iterations: 3
Function evaluations: 2
Gradient evaluations: 2
Optimization FAILED.
Inequality constraints incompatible
-----------------------------------
Optimal pfc_thickness: [0.1]
Optimal conductor radius: [0.10000001]
Optimal conductor thickness: [0.1]
Optimal cut height: [0.1]
Optimal cut width: [0.3745392]
Objective value: [0.90320516]
有没有尝试过类似方法并可以提供反馈/提示的好心人?
我的完整代码如下所示。
from openmdao.api import Problem, Group, ExternalCodeComp, IndepVarComp, ScipyOptimizeDriver
import sys
import os
from make_geometry import *
file = open("data.txt", "w")
class ExternalCode(ExternalCodeComp):
def setup(self):
self.iteration = 0
self.add_input('pfc_thickness', val = 0.0)
self.add_input('conductor_radius', val = 0.0)
self.add_input('conductor_thickness', val = 0.0)
self.add_input('conductor_origin_x', val = 0.0)
self.add_input('conductor_origin_y', val = 0.0)
self.add_input('cut_height', val = 0.0)
self.add_input('cut_width', val = 0.0)
self.add_output('fout', val=0.0)
problem_name = "mdao"
self.geometry_instance = build_geometry(problem_name)
self.input_file = 'input-thermal.i'
self.output_file = 'input-thermal_csv.csv'
self.options['external_input_files'] = [self.input_file]
self.options['external_output_files'] = [self.output_file]
#os.environ['LD_LIBRARY_PATH'] = '/usr/lib64/mpich/lib:/usr/lib64'
self.options['command'] = ['/home/adavis/opt/moose/modules/combined/combined-opt','-i','input-thermal.i']
def setup_partials(self):
# this external code does not provide derivatives, use finite difference
self.declare_partials(of='*', wrt='*', method='fd')
def __read_csv(self,filename):
import csv
with open(filename) as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
line_count = 0
for row in csv_reader:
data = row
return data[1] # this is the maxtemp
def compute(self, inputs, outputs):
self.iteration = self.iteration + 1
# set the variables
print(inputs)
pfc_thickness = inputs['pfc_thickness'][0]
conductor_radius = inputs['conductor_radius'][0]
conductor_thickness = inputs['conductor_thickness'][0]
#conductor_origin_x = inputs['conductor_origin_x']
#conductor_origin_y = inputs['conductor_origin_y']
cut_height = inputs['cut_height'][0]
cut_width = inputs['cut_width'][0]
# set the geometry instance
self.geometry_instance.pfc_thickness = pfc_thickness
self.geometry_instance.conductor_radius = conductor_radius
self.geometry_instance.conductor_thickness = conductor_thickness
self.geometry_instance.conductor_origin_x = 5.0
self.geometry_instance.conductor_origin_y = 5.0
self.geometry_instance.cut_height = cut_height
self.geometry_instance.cut_width = cut_width
if os.path.isfile('mdao.e'):
os.remove('mdao.e')
if os.path.isfile('mdao.e'):
os.remove('input-thermal_csv.csv')
# build the file
self.geometry_instance.build_all()
# test to make sure mesh exists
if not os.path.isfile('mdao.e'):
print('meshing failed')
sys.exit(1)
filename = '%s_%s_%s_%s_%s.cub' % (pfc_thickness,conductor_radius,conductor_thickness,cut_height,cut_width)
os.system('cp mdao.cub %s' % (filename))
# the parent compute function actually runs the external code
super().compute(inputs, outputs)
# get the output
f_xy = self.__read_csv(self.output_file)
file.write('%s %s\n' % (self.iteration, f_xy))
# set the output data in f_out
outputs['fout'] = f_xy
if __name__ == "__main__":
prob = Problem()
# Create and connect inputs
prob.model.add_subsystem('p', ExternalCode())
prob.driver = ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'
prob.model.add_design_var('p.pfc_thickness', lower=0.1, upper = 2)
prob.model.add_design_var('p.conductor_radius', lower=0.1, upper = 3.5)
prob.model.add_design_var('p.conductor_thickness', lower=0.1, upper = 1.0)
prob.model.add_design_var('p.cut_height', lower=0.1, upper = 1.5)
prob.model.add_design_var('p.cut_width', lower=0.1, upper = 3.0)
prob.model.add_objective('p.fout')
prob.driver.options['tol'] = 1e-9
prob.driver.options['disp'] = True
prob.model.approx_totals()
# run the ExternalCodeComp Component
prob.setup()
prob.set_solver_print(level=2)
# Set input values
prob.set_val('p.pfc_thickness', 0.1)
prob.set_val('p.conductor_radius', 0.1)
prob.set_val('p.conductor_thickness', 0.1)
prob.set_val('p.cut_height', 0.1)
prob.set_val('p.cut_width', 0.1)
prob.run_driver()
print('Optimal pfc_thickness: ', prob.get_val('p.pfc_thickness'))
print('Optimal conductor radius: ', prob.get_val('p.conductor_radius'))
print('Optimal conductor thickness: ', prob.get_val('p.conductor_thickness'))
print('Optimal cut height: ', prob.get_val('p.cut_height'))
print('Optimal cut width: ', prob.get_val('p.cut_width'))
print('Objective value: ', prob.get_val('p.fout'))
file.close()
【问题讨论】:
标签: openmdao