Skip to content

Commit

Permalink
Merge 70c03ea into 8669d56
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith Marsteller committed Jul 28, 2017
2 parents 8669d56 + 70c03ea commit 1b4a320
Show file tree
Hide file tree
Showing 49 changed files with 4,576 additions and 304 deletions.
3 changes: 3 additions & 0 deletions openmdao/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
# System-Building Tools
from openmdao.utils.options_dictionary import OptionsDictionary

# Recorders
from openmdao.recorders.sqlite_recorder import SqliteRecorder

# set up tracing or memory profiling if env vars are set.
import os
if os.environ.get('OPENMDAO_TRACE'):
Expand Down
10 changes: 5 additions & 5 deletions openmdao/code_review/test_lint_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ def test_attributes(self):
if not found_in_pc:
new_failures.append('Member `{0}` not documented in Attributes section of own class or parent class docstrings'.format(v))
else:
if(print_info): print(" Documented member `%s`" % (v))
else: #no init section
if(len(classdoc_matches) == 0): # no Attributes section
if(print_info): print(' Skipping Class `%s`... missing Attributes and init' % (class_name))
else: # one Attributes section
if print_info: print(" Documented member `%s`" % (v))
else: # no init section
if len(classdoc_matches) == 0: # no Attributes section
if print_info: print(' Skipping Class `%s`... missing Attributes and init' % (class_name))
else: # one Attributes section
new_failures.append('Attributes section in docstring but no __init__ function')
if new_failures:
key = '{0}/{1}:{2}'.format(dir_name, file_name, class_name)
Expand Down
2 changes: 1 addition & 1 deletion openmdao/components/meta_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import numpy as np
from copy import deepcopy

from openmdao.api import ExplicitComponent
from openmdao.core.explicitcomponent import ExplicitComponent
from openmdao.surrogate_models.surrogate_model import SurrogateModel
from openmdao.utils.class_util import overrides_method

Expand Down
131 changes: 121 additions & 10 deletions openmdao/core/driver.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"""Define a base class for all Drivers in OpenMDAO."""

from six import iteritems

import numpy as np

from openmdao.utils.record_util import create_local_meta
from openmdao.utils.options_dictionary import OptionsDictionary
from openmdao.recorders.recording_manager import RecordingManager
from openmdao.recorders.recording_iteration_stack import Recording


class Driver(object):
Expand All @@ -15,6 +17,10 @@ class Driver(object):
----------
fail : bool
Reports whether the driver ran successfully.
iter_count : int
Keep track of iterations for case recording.
metadata : list
List of metadata
options : <OptionsDictionary>
Dictionary with general pyoptsparse options.
_problem : <Problem>
Expand All @@ -29,12 +35,18 @@ class Driver(object):
Contains all objective info.
_responses : dict
Contains all response info.
_rec_mgr : <RecordingManager>
Object that manages all recorders added to this driver.
_model_viewer_data : dict
Structure of model, used to make n2 diagram.
"""

def __init__(self):
"""
Initialize the driver.
"""
self._rec_mgr = RecordingManager()

self._problem = None
self._designvars = None
self._cons = None
Expand All @@ -53,11 +65,32 @@ def __init__(self):
self.supports.declare('gradients', type_=bool, default=False)
self.supports.declare('active_set', type_=bool, default=False)

self.iter_count = 0
self.metadata = None
self._model_viewer_data = None

# TODO, support these in Openmdao blue
self.supports.declare('integer_design_vars', type_=bool, default=False)

self.fail = False

def add_recorder(self, recorder):
"""
Add a recorder to the driver.
Parameters
----------
recorder : BaseRecorder
A recorder instance.
"""
self._rec_mgr.append(recorder)

def cleanup(self):
"""
Clean up resources prior to exit.
"""
self._rec_mgr.close()

def _setup_driver(self, problem):
"""
Prepare the driver for execution.
Expand All @@ -79,20 +112,42 @@ def _setup_driver(self, problem):
self._objs = model.get_objectives(recurse=True)
self._cons = model.get_constraints(recurse=True)

def get_design_var_values(self):
self._rec_mgr.startup(self)
if (self._rec_mgr._recorders):
from openmdao.devtools.problem_viewer.problem_viewer import _get_viewer_data
self._model_viewer_data = _get_viewer_data(problem)
self._rec_mgr.record_metadata(self)

def get_design_var_values(self, filter=None):
"""
Return the design variable values.
This is called to gather the initial design variable state.
Parameters
----------
filter : list
List of desvar names used by recorders.
Returns
-------
dict
Dictionary containing values of each design variable.
"""
designvars = {}

if filter:
# pull out designvars of those names into filtered dict.
for inc in filter:
designvars[inc] = self._designvars[inc]

else:
# use all the designvars
designvars = self._designvars

vec = self._problem.model._outputs._views_flat
dv_dict = {}
for name, meta in iteritems(self._designvars):
for name, meta in iteritems(designvars):
scaler = meta['scaler']
adder = meta['adder']
indices = meta['indices']
Expand Down Expand Up @@ -138,10 +193,15 @@ def set_design_var(self, name, value):
if adder is not None:
desvar[indices] -= adder

def get_response_values(self):
def get_response_values(self, filter=None):
"""
Return response values.
Parameters
----------
filter : list
List of response names used by recorders.
Returns
-------
dict
Expand All @@ -150,18 +210,34 @@ def get_response_values(self):
# TODO: finish this method when we have a driver that requires it.
pass

def get_objective_values(self):
def get_objective_values(self, filter=None):
"""
Return objective values.
Parameters
----------
filter : list
List of objective names used by recorders.
Returns
-------
dict
Dictionary containing values of each objective.
"""
objectives = {}

if filter:
# pull out objectives of those names into filtered dict.
for inc in filter:
objectives[inc] = self._objs[inc]

else:
# use all the objectives
objectives = self._objs

vec = self._problem.model._outputs._views_flat
obj_dict = {}
for name, meta in iteritems(self._objs):
for name, meta in iteritems(objectives):
scaler = meta['scaler']
adder = meta['adder']
indices = meta['indices']
Expand All @@ -180,7 +256,7 @@ def get_objective_values(self):

return obj_dict

def get_constraint_values(self, ctype='all', lintype='all'):
def get_constraint_values(self, ctype='all', lintype='all', filter=None):
"""
Return constraint values.
Expand All @@ -194,15 +270,29 @@ def get_constraint_values(self, ctype='all', lintype='all'):
Default is 'all'. Optionally return just the linear constraints
with 'linear' or the nonlinear constraints with 'nonlinear'.
filter : list
List of objective names used by recorders.
Returns
-------
dict
Dictionary containing values of each constraint.
"""
constraints = {}

if filter is not None:
# pull out objectives of those names into filtered dict.
for inc in filter:
constraints[inc] = self._cons[inc]

else:
# use all the objectives
constraints = self._cons

vec = self._problem.model._outputs._views_flat
con_dict = {}

for name, meta in iteritems(self._cons):
for name, meta in iteritems(constraints):

if lintype == 'linear' and meta['linear'] is False:
continue
Expand Down Expand Up @@ -234,7 +324,6 @@ def get_constraint_values(self, ctype='all', lintype='all'):
# TODO: Need to get the allgathered values? Like:
# cons[name] = self._get_distrib_var(name, meta, 'constraint')
con_dict[name] = val

return con_dict

def run(self):
Expand All @@ -249,7 +338,11 @@ def run(self):
boolean
Failure flag; True if failed to converge, False is successful.
"""
return self._problem.model._solve_nonlinear()
with Recording(self._get_name(), self.iter_count, self) as rec:
failure_flag = self._problem.model._solve_nonlinear()

self.iter_count += 1
return failure_flag

def _compute_total_derivs(self, of=None, wrt=None, return_format='flat_dict',
global_names=True):
Expand Down Expand Up @@ -376,3 +469,21 @@ def get_req_procs(self, model):
max_procs can be None, indicating all available procs can be used.
"""
return model.get_req_procs()

def record_iteration(self):
"""
Record an iteration of the current Driver.
"""
metadata = create_local_meta(self._get_name())
self._rec_mgr.record_iteration(self, metadata)

def _get_name(self):
"""
Get name of current Driver.
Returns
-------
str
Name of current Driver.
"""
return "Driver"

0 comments on commit 1b4a320

Please sign in to comment.