Оптимизатор не использует объявленные частичные данные? - PullRequest
0 голосов
/ 05 августа 2020

Я использую OpenMDAO для оптимизации CFD. Вычислительная геометрия, построение сетки и выполнение решателя обрабатываются отдельным python скриптом, который принимает обновленный дизайн. За одно выполнение сценарий найдет силы, а также производные посредством сопряженного анализа. Моя проблема в том, что OpenMDAO, похоже, использует только производные, которые я указал, часть времени, а не для каждой итерации. Ниже приведен пример кода, который я использую:

import os
import argparse
import numpy as np
from matplotlib import pyplot as plt
import csv
import f90nml
import socket
import sys
import pickle

# Import OpenMDAO module - currently tested against version 2.8.0
from openmdao.api import Problem, Group, IndepVarComp, ExplicitComponent, ScipyOptimizeDriver
import openmdao.api as om

class FUN3DExternalCodeComp(om.ExternalCodeComp):

    def setup(self):

        # Design Variables
        self.add_input('alpha', val=0.0)
        self.add_input('TE1', val=0.0)
        self.add_input('TE2', val=0.0)
        self.add_input('TE3', val=0.0)
        self.add_input('TE4', val=0.0)
        self.add_input('TE5', val=0.0)
        self.add_input('TE6', val=0.0)

        self.add_output('CD', val=0.0)
        self.add_output('CL', val=0.0)
        self.add_output('CY', val=0.0)
        self.add_output('CMx', val=0.0)
        self.add_output('CMy', val=0.0)
        self.add_output('CMz', val=0.0)

        self.input_file = 'designVar.in'
        self.output_file = 'fun3dResponse.out'
        self.derivs_file = 'fun3dDerivs.out'

        # providing these is optional; the component will verify that any input
        # files exist before execution and that the output files exist after.
        self.options['external_input_files'] = [self.input_file]
        self.options['external_output_files'] = [self.output_file, self.derivs_file]

        self.options['command'] = [
            # sys.executable, 'runFun3DsensPA_Euler.py',
            sys.executable, 'function.py',
            self.input_file, self.output_file, self.derivs_file]

        # this external code does provide derivatives
        self.declare_partials(of='*', wrt='*')

    def compute(self, inputs, outputs):

        alpha = inputs['alpha']
        TE1 = inputs['TE1']
        TE2 = inputs['TE2']
        TE3 = inputs['TE3']
        TE4 = inputs['TE4']
        TE5 = inputs['TE5']
        TE6 = inputs['TE6']

        # generate the input file for the paraboloid external code
        with open(self.input_file, 'w') as input_file:
            input_file.write('%.16f\n%.16f\n%.16f\n%.16f\n%.16f\n%.16f\n%.16f\n' % (alpha, TE1, TE2, TE3, TE4, TE5, TE6))

        # the parent compute function actually runs the external code
        super(FUN3DExternalCodeComp, self).compute(inputs, outputs)

        # parse the output file from the external code and set the value of f_xy
        with open(os.path.join(self.output_file), 'r') as output_file:

            outputs['CL'] = float(output_file.readline())
            outputs['CD'] = float(output_file.readline())
            outputs['CY'] = float(output_file.readline())
            outputs['CMx'] = float(output_file.readline())
            outputs['CMy'] = float(output_file.readline())
            outputs['CMz'] = float(output_file.readline())

            print('OUTPUTS', outputs)

    def compute_partials(self, inputs, partials):

        # parse the derivs file from the external code and set partials
        with open(os.path.join(self.derivs_file), 'r') as derivs_file:

            partials['CL', 'alpha'] = float(derivs_file.readline())
            partials['CL', 'TE1'] = float(derivs_file.readline())
            partials['CL', 'TE2'] = float(derivs_file.readline())
            partials['CL', 'TE3'] = float(derivs_file.readline())
            partials['CL', 'TE4'] = float(derivs_file.readline())
            partials['CL', 'TE5'] = float(derivs_file.readline())
            partials['CL', 'TE6'] = float(derivs_file.readline())

            partials['CD', 'alpha'] = float(derivs_file.readline())
            partials['CD', 'TE1'] = float(derivs_file.readline())
            partials['CD', 'TE2'] = float(derivs_file.readline())
            partials['CD', 'TE3'] = float(derivs_file.readline())
            partials['CD', 'TE4'] = float(derivs_file.readline())
            partials['CD', 'TE5'] = float(derivs_file.readline())
            partials['CD', 'TE6'] = float(derivs_file.readline())

            partials['CY', 'alpha'] = float(derivs_file.readline())
            partials['CY', 'TE1'] = float(derivs_file.readline())
            partials['CY', 'TE2'] = float(derivs_file.readline())
            partials['CY', 'TE3'] = float(derivs_file.readline())
            partials['CY', 'TE4'] = float(derivs_file.readline())
            partials['CY', 'TE5'] = float(derivs_file.readline())
            partials['CY', 'TE6'] = float(derivs_file.readline())

            # Rolling moment partials
            partials['CMx', 'alpha'] = float(derivs_file.readline())
            partials['CMx', 'TE1'] = float(derivs_file.readline())
            partials['CMx', 'TE2'] = float(derivs_file.readline())
            partials['CMx', 'TE3'] = float(derivs_file.readline())
            partials['CMx', 'TE4'] = float(derivs_file.readline())
            partials['CMx', 'TE5'] = float(derivs_file.readline())
            partials['CMx', 'TE6'] = float(derivs_file.readline())

            # Pitching moment partials
            partials['CMy', 'alpha'] = float(derivs_file.readline())
            partials['CMy', 'TE1'] = float(derivs_file.readline())
            partials['CMy', 'TE2'] = float(derivs_file.readline())
            partials['CMy', 'TE3'] = float(derivs_file.readline())
            partials['CMy', 'TE4'] = float(derivs_file.readline())
            partials['CMy', 'TE5'] = float(derivs_file.readline())
            partials['CMy', 'TE6'] = float(derivs_file.readline())

            # Yaw moment partials
            partials['CMz', 'alpha'] = float(derivs_file.readline())
            partials['CMz', 'TE1'] = float(derivs_file.readline())
            partials['CMz', 'TE2'] = float(derivs_file.readline())
            partials['CMz', 'TE3'] = float(derivs_file.readline())
            partials['CMz', 'TE4'] = float(derivs_file.readline())
            partials['CMz', 'TE5'] = float(derivs_file.readline())
            partials['CMz', 'TE6'] = float(derivs_file.readline())

            print('PARTIALS', partials)

# Initialize OpenMDAO Problem
prob = om.Problem()
model = prob.model

# create and connect inputs
model.add_subsystem('p', FUN3DExternalCodeComp())

# Add Design variables
prob.model.add_design_var('p.alpha', lower = 1.0, upper = 10)
prob.model.add_design_var('p.TE1',   lower = 1.0, upper = 10)
prob.model.add_design_var('p.TE2',   lower = 1.0, upper = 10)
prob.model.add_design_var('p.TE3',   lower = 1.0, upper = 10)
prob.model.add_design_var('p.TE4',   lower = 1.0, upper = 10)
prob.model.add_design_var('p.TE5',   lower = 1.0, upper = 10)
prob.model.add_design_var('p.TE6',   lower = 1.0, upper = 10)

# Lift constraint
prob.model.add_constraint('p.CL',  lower = 10, upper = 120)
prob.model.add_constraint('p.CY',  lower = 20, upper = 250)
prob.model.add_constraint('p.CMx', lower = 20, upper = 250)
prob.model.add_constraint('p.CMy', lower = 20, upper = 250)
prob.model.add_constraint('p.CMz', lower = 20, upper = 250)

# Minimize Drag
prob.model.add_objective('p.CD')

prob.driver = om.pyOptSparseDriver(optimizer='SLSQP')
prob.driver.options['print_results'] = True
prob.driver.options['debug_print'] = ['desvars','ln_cons','nl_cons','objs','totals']

# prob.driver = om.ScipyOptimizeDriver()
# prob.driver.options['optimizer'] = 'SLSQP'
# prob.driver.options['tol'] = 1e-5
# prob.driver.options['disp'] = True
# prob.driver.options['maxiter'] = 20 # Maximum number of solver iterations
# prob.driver.options['debug_print'] = ['desvars','ln_cons','nl_cons','objs','totals']

prob.driver.recording_options['record_objectives'] = True
prob.driver.recording_options['record_constraints'] = True
prob.driver.recording_options['record_desvars'] = True
prob.driver.recording_options['record_derivatives'] = True

recorder = om.SqliteRecorder('results.sql')
prob.driver.add_recorder(recorder)

prob.set_solver_print(level=0)

prob.setup()

# Set input values
prob.set_val('p.alpha', 3.0)
prob.set_val('p.TE1', 1.0)
prob.set_val('p.TE2', 2.0)
prob.set_val('p.TE3', 3.0)
prob.set_val('p.TE4', 4.0)
prob.set_val('p.TE5', 5.0)
prob.set_val('p.TE6', 6.0)

prob.run_driver()
Exception: '_auto_ivc.v0'
====================================================================== Traceback (most recent call last):
  File "/Users/deslicjp/Documents/Software/OpenMDAO/openmdao/drivers/pyoptsparse_driver.py", line 593, in _gradfunc
    sens_dict = self._compute_totals(of=self._quantities,
  File "/Users/deslicjp/Documents/Software/OpenMDAO/openmdao/core/driver.py", line 849, in _compute_totals
    totals = total_jac.compute_totals()
  File "/Users/deslicjp/Documents/Software/OpenMDAO/openmdao/core/total_jac.py", line 1414, in compute_totals
    self._print_derivatives()
  File "/Users/deslicjp/Documents/Software/OpenMDAO/openmdao/core/total_jac.py", line 1629, in _print_derivatives
    pprint.pprint({(of, wrt): J[of][wrt]})
KeyError: '_auto_ivc.v0'
 ======================================================================
capi_return is NULL
Call-back cb_slgrad_in_slsqp__user__routines failed.
Traceback (most recent call last):

ОБНОВЛЕНИЕ: 08-07-2020 15: 32

Любое понимание приветствуется!

Спасибо, Джо sh

...