EDIT: Nevermind. The driver was being repeatedly executed by OpenMDAO, and I was not seeing that.

I have a an assembly which generates Monte Carlo simulation output to a text file using a custom driver. I am using an assembly to read this file and return the average simulated objective. When I run this code, the outer_opt CONMIN driver only executes my rosenSA assembly once. When I run the same code multiple time in ipython, the rosenSA assembly is only run during the first execution of the code. I have theorized that OPenMDAO/CONMIN's dependency tree is not seeing a connection between rosenSA and the set objective (associated with the get_dak_output component which is run during each iteration), and is not running the rosenSA assembly because of this. I tried adding the force_execute flag to several objects in this code associated with rosenSA, but this hasn't helped. How can I force my rosenSA assembly to execute during each driver iteration? Any insight as to how I can approach this problem would be greatly appreciated.

from dakota_driver.driver import pydakdriver
from pyopt_driver.pyopt_driver import pyOptDriver
from openmdao.main.api import Component, Assembly
from openmdao.lib.drivers.api import SLSQPdriver, CONMINdriver, Genetic, COBYLAdriver, NEWSUMTdriver
from openmdao.lib.datatypes.api import Float

# Design order of execution 
# =========================
# outer_opt
#  -> rosenSA
#       - DAKOTA Monte Carlo sampling of rose assembly
#  -> get_dak_output

dacout = 'dakota.out'

class get_dak_output(Component):
    mean_f = Float(0.0, iotype='out', desc='p50 cost of energy output from dakota')
    x1 = Float(-888, iotype = 'in')

    def execute(self):
       nam ='rose.f'

       # read data
       with open(dacout) as dak:
         daklines = dak.readlines()
       vals = {}
       for n, line in enumerate(daklines):
         if n<49 or n > len(daklines)-45: pass
         else:
           split_line = line.split()
           if len(split_line)==2:
               if split_line[1] not in vals: vals[split_line[1]] = [float(split_line[0])]
               else:vals[split_line[1]].append(float(split_line[0]))

       # Get mean value
       self.objective_vals = vals[nam]
       self.mean_f = sum(self.objective_vals)/len(self.objective_vals)
       print "GET_DAK X1 f", self.x1, self.mean_f

class rosen(Component):
    x1 = Float(0.0, iotype='in', desc = 'The variable x1' )
    x2 = Float(0.0, iotype='in', desc = 'The variable x2' )
    f = Float(0.0, iotype='out', desc='F(x,y)')

    def execute(self):
        x1 = self.x1
        x2 = self.x2
        self.f = (1-x1)**2 + 100*(x2-x1**2)**2
        print 'X1 X2', x1,x2

class rosenSA(Assembly):
    def configure(self):
        self.add('rose', rosen())
        self.add('x1', Float(-999, iotype = 'in'))
        self.connect('x1', 'rose.x1')

        driver_obj = pydakdriver()
        driver_obj.UQ()
        self.driver = self.add('driver',driver_obj)
        self.driver.stdout = dacout
        self.driver.stderr = 'dakota.err'
        self.driver.sample_type = 'random'
        self.driver.seed = 20
        self.driver.samples = 15
        self.driver.add_special_distribution('rose.x2', "normal", mean = .1, std_dev = 0.000000001)
        self.driver.add_objective('x1')
        self.driver.add_objective('rose.f')

class outer_opt(Assembly):
    def configure(self):
        self.add('driver',CONMINdriver())

        self.add('roseSA',rosenSA())
        self.add('dakBak', get_dak_output())

        self.driver.workflow.add('roseSA')
        self.driver.workflow.add('dakBak')
        self.add('x1',Float(0.4, iotype = 'in'))
        self.driver.add_parameter('x1', low = -6, high = 6)
        self.connect('x1', ['roseSA.x1', 'dakBak.x1'])
        self.driver.add_objective('dakBak.mean_f')

top = outer_opt()
top.run()
print top.x1

Here is the output of the code. As you can see, the rosenSA is executed initially then never again.

X1 X2 0.4 0.100000001689
X1 X2 0.4 0.0999999996911
X1 X2 0.4 0.100000000448
X1 X2 0.4 0.100000000223
X1 X2 0.4 0.100000001667
X1 X2 0.4 0.100000000309
X1 X2 0.4 0.100000001649
X1 X2 0.4 0.100000000359
X1 X2 0.4 0.100000000501
X1 X2 0.4 0.100000001269
X1 X2 0.4 0.1000000009
X1 X2 0.4 0.100000000046
X1 X2 0.4 0.100000001235
X1 X2 0.4 0.100000001213
X1 X2 0.4 0.0999999981995
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.400001 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.400001 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.400001 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
GET_DAK X1 f 0.4 0.719999992482
0.4

asked 28 Jan '16, 12:44

kilojoules's gravatar image

kilojoules
31110

edited 28 Jan '16, 19:54


You set force_execute on rosenA assembly itself? You will likely have to set it to rosenA itself, and all of its children to get around the lazy evaluation.

link

answered 28 Jan '16, 13:36

admin's gravatar image

admin ♦♦
203313

Thank you for your response. I tried setting roseSA to force execute like this:

class outer_opt(Assembly):
    def configure(self):
        self.add('driver',CONMINdriver())
        self.add('roseSA',rosenSA())
        self.roseSA.force_execute = True
       .....

This didn't effect the output. I also noticed that top.roseSA.force_execute has no default value while top.roseSA.force_fd is false by default. Setting roseSA.force_fd to true also does not effect the output.

I also tried setting rosenSA itself to force_execute:

class rosenSA(Assembly):
    def configure(self):
        self.force_execute = True
        ......

This also did not effect the output.

I've tried adding the force_execute flag in objects across the code, but this does not seem to have an effect.

(28 Jan '16, 13:41) kilojoules kilojoules's gravatar image

Here is my current code, with force_execute flags everywhere I could think to put them. This still results in a single iteration through rosenSA (the output is identical to before).

from dakota_driver.driver import pydakdriver
from pyopt_driver.pyopt_driver import pyOptDriver
from openmdao.main.api import Component, Assembly
from openmdao.lib.drivers.api import SLSQPdriver, CONMINdriver, Genetic, COBYLAdriver, NEWSUMTdriver
from openmdao.lib.datatypes.api import Float

dacout = 'dakota.out'

class get_dak_output(Component):
    force_execute = True
    mean_f = Float(0.0, iotype='out', desc='p50 cost of energy output from dakota')
    x1 = Float(-888, iotype = 'in')

    def execute(self):
       nam ='rose.f'

       # read data
       with open(dacout) as dak:
         daklines = dak.readlines()
       vals = {}
       for n, line in enumerate(daklines):
         if n<49 or n > len(daklines)-45: pass
         else:
           split_line = line.split()
           if len(split_line)==2:
               if split_line[1] not in vals: vals[split_line[1]] = [float(split_line[0])]
               else:vals[split_line[1]].append(float(split_line[0]))

       # Get mean value
       self.objective_vals = vals[nam]
       self.mean_f = sum(self.objective_vals)/len(self.objective_vals)
       print "GET_DAK X1 f", self.x1, self.mean_f

class rosen(Component):
    force_execute = True
    x1 = Float(0.0, iotype='in', desc = 'The variable x1' )
    x2 = Float(0.0, iotype='in', desc = 'The variable x2' )
    f = Float(0.0, iotype='out', desc='F(x,y)')

    def execute(self):
        x1 = self.x1
        x2 = self.x2
        self.f = (1-x1)**2 + 100*(x2-x1**2)**2
        print 'X1 X2', x1,x2

class rosenSA(Assembly):
    def configure(self):
        self.force_execute = True
        self.add('rose', rosen())
        self.rose.force_execute = True
        self.add('x1', Float(-999, iotype = 'in'))
        self.connect('x1', 'rose.x1')

        driver_obj = pydakdriver()
        driver_obj.UQ()
        self.driver = self.add('driver',driver_obj)
        self.driver.force_execute = True
        self.driver.stdout = dacout
        self.driver.stderr = 'dakota.err'
        self.driver.sample_type = 'random'
        self.driver.seed = 20
        self.driver.samples = 15
        self.driver.add_special_distribution('rose.x2', "normal", mean = .1, std_dev = 0.000000001)
        self.driver.add_objective('x1')
        self.driver.add_objective('rose.f')
        self.driver.force_execute = True ## doesn't help

class outer_opt(Assembly):
    def configure(self):
        self.force_execute = True
        self.add('driver',CONMINdriver())
        #self.add('driver',pyOptDriver())
        #self.driver.optimizer = 'CONMIN'

        self.add('roseSA',rosenSA())
        self.roseSA.force_execute = True
        self.add('dakBak', get_dak_output())
        self.dakBak.force_execute = True

        self.driver.workflow.add('roseSA')
        self.driver.workflow.add('dakBak')
        self.add('x1',Float(0.4, iotype = 'in'))
        self.driver.add_parameter('x1', low = -6, high = 6)
        self.connect('x1', ['roseSA.x1', 'dakBak.x1'])
        self.driver.add_objective('dakBak.mean_f')
        self.driver.force_execute = True ## doesn't help

top = outer_opt()
top.run()
print top.x1
(28 Jan '16, 15:07) kilojoules kilojoules's gravatar image

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×27
×6
×5
×1

Asked: 28 Jan '16, 12:44

Seen: 950 times

Last updated: 28 Jan '16, 19:54

powered by OSQA