2017-01-12 1 views
0

일반적으로 최적화 그룹을 사용할 때 문제에 포함시킵니다. 그 후, 나는 그것이 구성 요소 속성입니다 설정할 수 있습니다OpenMDAO 하위 그룹 속성을 설정하는 방법은 무엇입니까?

# import modules, prepare data for Problem setup 
... 

# Initialize problem with my group 
prob = Problem(impl=impl, root=AEPGroup(nTurbines=10,     
             nDirections=5, 
             minSpacing=2)) 

# Configure driver, desvars, and constraints 
prob.driver = pyOptSparseDriver() 
prob.driver.add_desvar('turbineX', lower=np.ones(nTurbs)*min(turbineX), upper=np.ones(nTurbs)*max(turbineX), scaler=1E-2) 
prob.driver.add_objective('obj', scaler=1E-8) 

# run setup() 
prob.setup(check=True) 

# Now I set several specifications 
prob['turbineX'] = turbineX 
.... 

는 아래 내 예제를 참조하십시오 (test_brute_force.py에서 적응). 204 행에서 다른 그룹의 그룹으로 AEPGroup을 실행하고 싶습니다. 하위 그룹 내에 turbineX과 같은 사양을 구성하는 유사한 방법이 있습니까? 당신은 당신은 당신이 방금 계정에 변수 경로 이름을 조정

prob['sellars.sellar0.turbineX'] = turbineX 

로 변수 이름을 설정할 수 있습니다

sellars.add(name, AEPGroup(nTurbines=nTurbines, nDirections=nDirections, 
              differentiable=True, 
              use_rotor_components=False)) 

를 호출 할 때 어떤 변수 승진을 안하고 있기 때문에

from __future__ import print_function 
from florisse.floris import AEPGroup 
import unittest 

from florisse.GeneralWindFarmComponents import calculate_boundary 

from six.moves import range 
from six import iteritems 

import numpy as np 

from openmdao.api import Problem, Group, ParallelGroup, \ 
         Component, IndepVarComp, ExecComp, \ 
         Driver, ScipyOptimizer, SqliteRecorder 

from openmdao.test.sellar import * 
from openmdao.test.util import assert_rel_error 

from openmdao.core.mpi_wrap import MPI 

if MPI: 
    from openmdao.core.petsc_impl import PetscImpl as impl 
else: 
    from openmdao.api import BasicImpl as impl 

# load wind rose data 
windRose = np.loadtxt('./input_files/windrose_amalia_directionally_averaged_speeds.txt') 
indexes = np.where(windRose[:, 1] > 0.1) 
#print ("ypppp indexes are ", indexes) 
indexes = [[8]] 
#print ("ypppp indexes are ", indexes) ; quit() 
windDirections = windRose[indexes[0], 0] 
windSpeeds = windRose[indexes[0], 1] 
windFrequencies = windRose[indexes[0], 2] 
nDirections = len(windDirections) 

# load turbine positions 
locations = np.loadtxt('./input_files/layout_amalia.txt') 
turbineX = locations[:, 0] 
turbineY = locations[:, 1] 

# generate boundary constraint 
boundaryVertices, boundaryNormals = calculate_boundary(locations) 
nVertices = boundaryVertices.shape[0] 

# define turbine size 
rotor_diameter = 126.4 # (m) 

# initialize input variable arrays 
nTurbines = turbineX.size 
rotorDiameter = np.zeros(nTurbines) 
axialInduction = np.zeros(nTurbines) 
Ct = np.zeros(nTurbines) 
Cp = np.zeros(nTurbines) 
generatorEfficiency = np.zeros(nTurbines) 
yaw = np.zeros(nTurbines) 
minSpacing = 2.       # number of rotor diameters 

# define initial values 
for turbI in range(0, nTurbines): 
    rotorDiameter[turbI] = rotor_diameter  # m 
    axialInduction[turbI] = 1.0/3.0 
    Ct[turbI] = 4.0*axialInduction[turbI]*(1.0-axialInduction[turbI]) 
    Cp[turbI] = 0.7737/0.944 * 4.0 * 1.0/3.0 * np.power((1 - 1.0/3.0), 2) 
    generatorEfficiency[turbI] = 0.944 
    yaw[turbI] = 0.  # deg. 

# Define flow properties 
air_density = 1.1716 # kg/m^3 
class Randomize(Component): 
    """ add random uncertainty to params and distribute 

    Args 
    ---- 
    n : number of points to generate for each param 

    params : collection of (name, value, std_dev) specifying the params 
      that are to be randommized. 
    """ 
    def __init__(self, n=0, params=[]): 
     super(Randomize, self).__init__() 

     self.dists = {} 

     for name, value, std_dev in params: 
      # add param 
      self.add_param(name, val=value) 

      # add an output array var to distribute the modified param values 
      if isinstance(value, np.ndarray): 
       shape = (n, value.size) 
      else: 
       shape = (n, 1) 

      # generate a standard normal distribution (size n) for this param 
      self.dists[name] = np.random.normal(0.0, std_dev, n*shape[1]).reshape(shape) 
      #self.dists[name] = std_dev*np.random.normal(0.0, 1.0, n*shape[1]).reshape(shape) 

      self.add_output('dist_'+name, val=np.zeros(shape)) 

    def solve_nonlinear(self, params, unknowns, resids): 
     """ add random uncertainty to params 
     """ 
     for name, dist in iteritems(self.dists): 
      unknowns['dist_'+name] = params[name] + dist 

    def linearize(self, params, unknowns, resids): 
     """ derivatives 
     """ 
     J = {} 
     for u in unknowns: 
      name = u.split('_', 1)[1] 
      for p in params: 
       shape = (unknowns[u].size, params[p].size) 
       if p == name: 
        J[u, p] = np.eye(shape[0], shape[1]) 
       else: 
        J[u, p] = np.zeros(shape) 
     return J 


class Collector(Component): 
    """ collect the inputs and compute the mean of each 

    Args 
    ---- 
    n : number of points to collect for each input 

    names : collection of `Str` specifying the names of the inputs to 
      collect and the resulting outputs. 
    """ 
    def __init__(self, n=10, names=[]): 
     super(Collector, self).__init__() 

     self.names = names 

     # create n params for each input 
     for i in range(n): 
      for name in names: 
       self.add_param('%s_%i' % (name, i), val=0.) 

     # create an output for the mean of each input 
     for name in names: 
      self.add_output(name, val=0.) 

    def solve_nonlinear(self, params, unknowns, resids): 
     """ compute the mean of each input 
     """ 
     inputs = {} 

     for p in params: 
      name = p.split('_', 1)[0] 
      if name not in inputs: 
       inputs[name] = data = [0.0, 0.0] 
      else: 
       data = inputs[name] 
      data[0] += 1 
      data[1] += params[p] 

     for name in self.names: 
      unknowns[name] = inputs[name][1]/inputs[name][0] 

    def linearize(self, params, unknowns, resids): 
     """ derivatives 
     """ 
     J = {} 
     for p in params: 
      name, idx = p.split('_', 1) 
      for u in unknowns: 
       if u == name: 
        J[u, p] = 1 
       else: 
        J[u, p] = 0 
     return J 


class BruteForceSellarProblem(Problem): 
    """ Performs optimization on the AEP problem. 

     Applies a normal distribution to the design vars and runs all of the 
     samples, then collects the values of all of the outputs, calculates 
     the mean of those and stuffs that back into the unknowns vector. 

     This is the brute force version that just stamps out N separate 
     AEP models in a parallel group and sets the input of each 
     one to be one of these random design vars. 

    Args 
    ---- 
    n : number of randomized points to generate for each input value 

    derivs : if True, use user-defined derivatives, else use Finite Difference 
    """ 
    def __init__(self, n=10, derivs=False): 
     super(BruteForceSellarProblem, self).__init__(impl=impl) 

     root = self.root = Group() 
     if not derivs: 
      root.deriv_options['type'] = 'fd' 

     sellars = root.add('sellars', ParallelGroup()) 
     for i in range(n): 
      name = 'sellar%i' % i 
      sellars.add(name, AEPGroup(nTurbines=nTurbines, nDirections=nDirections, 
              differentiable=True, 
              use_rotor_components=False)) 
      #sellars.add(name, SellarDerivatives()) 

      root.connect('dist_air_density', 'sellars.'+name+'.air_density', src_indices=[i]) 
      #root.connect('yaw0', 'sellars.'+name+'.yaw0')#, src_indices=[i]) 
      #root.connect('dist_z', 'sellars.'+name+'.z', src_indices=[i*2, i*2+1]) 

      root.connect('sellars.'+name+'.AEP', 'collect.obj_%i' % i) 
      #root.connect('sellars.'+name+'.con1', 'collect.con1_%i' % i) 
      #root.connect('sellars.'+name+'.con2', 'collect.con2_%i' % i) 

     root.add('indep', IndepVarComp([ 
        ('air_density', 1.0), 
        ('z', np.array([5.0, 2.0])) 
       ]), 
       promotes=['air_density', 'z']) 

     root.add('random', Randomize(n=n, params=[ 
        # name, value, std dev 
        ('air_density', 1.0, 1e-2), 
        ('z', np.array([5.0, 2.0]), 1e-2) 
       ]), 
       promotes=['z', 'dist_air_density', 'dist_z']) 
       #promotes=['x', 'z', 'dist_x', 'dist_z']) 

     root.add('collect', Collector(n=n, names=['obj', 'con1', 'con2']), 
       promotes=['obj', 'con1', 'con2']) 

     # top level driver setup 
     self.driver = ScipyOptimizer() 
     self.driver.options['optimizer'] = 'SLSQP' 
     self.driver.options['tol'] = 1.0e-8 
     self.driver.options['maxiter'] = 50 
     self.driver.options['disp'] = False 

     self.driver.add_desvar('z', lower=np.array([-10.0, 0.0]), 
            upper=np.array([ 10.0, 10.0])) 
     #self.driver.add_desvar('x', lower=0.0, upper=10.0) 

     self.driver.add_objective('obj') 
     self.driver.add_constraint('con1', upper=0.0) 
     self.driver.add_constraint('con2', upper=0.0) 

prob = BruteForceSellarProblem(100, derivs=False) 
prob.setup(check=False) 
prob.run() 
print (prob["obj"]) 

답변

1

추가 학부모 그룹의 존재 여부 및 AEPGroup의 이름이 이제 sellar0 (또는 설정할 필요가있는 색인)인지 확인하십시오.

관련 문제