Skip to content

Commit

Permalink
Merge pull request #40 from chrislupp/develop
Browse files Browse the repository at this point in the history
Version 0.6.0
  • Loading branch information
chrislupp authored Mar 14, 2024
2 parents d109372 + ad7b5a3 commit 3a4d837
Show file tree
Hide file tree
Showing 21 changed files with 1,679 additions and 216 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
doxer.*
*.html
.idea/
examples/reports/
**/reports/
Expand Down
99 changes: 73 additions & 26 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,62 @@
# Change Log

## Version 0.6.0

### Features

- Added a mechanism for the server to provide a list of available options
(with associated types).
- Created a general implementation of the explicit discipline client for
OpenMDAO. The client creates an OpenMDAO ExplicitComponent which can
be added to any OpenMDAO model.

### Bug Fixes

- None


## Version 0.5.3

- [fix] Added missing function arguments to explicit discipline.
### Features

- None

### Bug Fixes

- Added missing function arguments to explicit discipline.


## Version 0.5.2

- [fix] Lowered the dependency versions (they were far too stringent and new)
- [fix] Change PyPI deployment to source only. It is not practical to distribute
### Features

- None

### Bug Fixes

- Lowered the dependency versions (they were far too stringent and new)
- Change PyPI deployment to source only. It is not practical to distribute
a platform-specific wheel. The wheel must be platform-specific, because gRPC
has C underpinnings.


## Version 0.5.1

- [feature] Transitioned away from setuptools and setup.py to a pyproject.toml
### Features

- Transitioned away from setuptools and setup.py to a pyproject.toml
and poetry-based package.
- [feature] gRPC and protobuf stubs are now automatically compiled during
installation.
- [feature] Added test coverage report generation that is uploaded to
coveralls.
- [feature] Added action to upload to PyPI when a release is published.
- gRPC and protobuf stubs are now automatically compiled during
installation.
- Added test coverage report generation that is uploaded to coveralls.
- Added action to upload to PyPI when a release is published.

### Bug Fixes

- Lowered the dependency versions (they were far too stringent and new)
- Change PyPI deployment to source only. It is not practical to distribute
a platform-specific wheel. The wheel must be platform-specific, because gRPC
has C underpinnings.


## Version 0.5.0
Expand All @@ -31,7 +66,13 @@

## Version 0.4.0

- [doc] General documentation updates.
### Features

- General documentation updates.

### Bug Fixes

- None


## Version 0.3.0
Expand All @@ -40,24 +81,30 @@ This release is one of the biggest changes to the code to date. It contains a
fundamental reorganization and adds a number of features. Notably, it adds
unit and integration testing of almost all the code.

- [feature] Reorganized codebase to reduce code duplication. The clients and
servers now use base classes.
- [feature] Protobuf/gRPC files are now generated at build time and not commited
### Features

- Reorganized codebase to reduce code duplication. The clients and servers now
use base classes.
- Protobuf/gRPC files are now generated at build time and not committed
to the repository. This requires grpc-tools and protoletariat to be installed.
See the readme for details.
- [feature] Added a change log file to the repository.
- [feature] Updated API and logic to conform with newer Philote definition.
- [feature] Added unit testing suite.
- [feature] Added integration test suite (based on examples).
- [feature] Completed implicit discipline functionality and testing.
- [fix] Fixed unit tests for GetVariableDefinitions and GetPartialsDefinitions.
- [fix] Added edge case handling for partials of variables that are scalar.
- [fix] Corrected the preallocate_inputs function for the implicit case to
resolve variable copy issues.
- [fix] Fixed typo in discrete input parsing.
- [fix] Moved to setup.py, as setuptools is still in beta for pyproject.toml.
- [doc] Added jupyter book for documentation.
- [doc] Added a quick start guide.
- Added a change log file to the repository.
- Updated API and logic to conform with newer Philote definition.
- Added unit testing suite.
- Added integration test suite (based on examples).
- Completed implicit discipline functionality and testing.
- Fixed unit tests for GetVariableDefinitions and GetPartialsDefinitions.
- Added edge case handling for partials of variables that are scalar.
-

### Bug Fixes

- Corrected the preallocate_inputs function for the implicit case to resolve
variable copy issues.
- Fixed typo in discrete input parsing.
- Moved to setup.py, as setuptools is still in beta for pyproject.toml.
- Added jupyter book for documentation.
- Added a quick start guide.


## Version 0.2.1
Expand Down
6 changes: 4 additions & 2 deletions philote_mdo/examples/rosenbrock.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ class Rosenbrock(pmdo.ExplicitDiscipline):
"""
Explicit discipline implementation of the Rosenbrock function.
"""
def initialize(self):
self.add_option('dimension', 'int')

def initialize(self, options):
self.dimension = options["dimension"]
def set_options(self, options):
self.dimension = int(options["dimension"])

def setup(self):
self.add_input("x", shape=(self.dimension,), units="")
Expand Down
77 changes: 75 additions & 2 deletions philote_mdo/general/discipline.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,38 @@ def __init__(self):
# flag that indicates the discipline is implicit
self._is_implicit = False

# dictionary of available discipline options (with types)
self.options_list = {}

# create the available options and run any other initialization
self.initialize()

def add_option(self, name, type):
"""
Adds an option definition to the discipline.
Parameters
----------
name : string
the name of the option being added
type : string
the data type of the option. acceptable types are 'bool', 'int',
'float'
"""
self.options_list[name] = type

def add_input(self, name, shape=(1,), units=""):
"""
Define a continuous input.
Parameters
----------
name : string
the name of the input variable
shape : tuple
the shape of the input variable
units : string
the unit definition for the input variable
"""
meta = data.VariableMetaData()
meta.type = data.VariableType.kInput
Expand All @@ -64,6 +93,15 @@ def add_input(self, name, shape=(1,), units=""):
def add_output(self, name, shape=(1,), units=""):
"""
Defines a continuous output.
Parameters
----------
name : string
the name of the output variable
shape : tuple
the shape of the output variable
units : string
the unit definition for the output variable
"""
out_meta = data.VariableMetaData()
out_meta.type = data.VariableType.kOutput
Expand All @@ -87,21 +125,56 @@ def declare_partials(self, func, var):
"""
self._partials_meta += [data.PartialsMetaData(name=func, subname=var)]

def initialize(self, options):
def initialize(self):
"""
Sets up the available options.
This function is called when the server is first started. It does not
set options, but instead defines what option names (and types) are
available. The set_options function is used to actually set the option
values instead.
"""
pass

def set_options(self, options):
"""
Sets the option values for the discipline.
Parameters
----------
options : DisciplineOptions
options data structure (generated from the Philote MDO standard)
that is used to set the discipline options. This data structure
is received from the client and passed to this function.
"""
pass

def setup(self):
"""
Sets up the discipline inputs and outputs.
This function is called when the client invokes the Setup RPC. This
function should be used to define inputs and outputs of the analysis
discipline.
"""
pass

def setup_partials(self):
"""
Sets up the discipline partials.
This function is called when the client invokes the Setup RPC. This
function should be used to define partial derivatives of the analysis
discipline.
"""
pass

def configure(self):
pass

def _clear_data(self):
"""
Clears all meta data of the discipline.
Clears all metadata of the discipline.
This function is invoked from the Setup function of the server.
"""
Expand Down
32 changes: 26 additions & 6 deletions philote_mdo/general/discipline_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
# therein. The DoD does not exercise any editorial, security, or other
# control over the information you may find at these locations.
import numpy as np
from google.protobuf.empty_pb2 import Empty
from google.protobuf.struct_pb2 import Struct
import google.protobuf.empty_pb2 as empty
import philote_mdo.generated.data_pb2 as data
import philote_mdo.generated.disciplines_pb2_grpc as disc
import philote_mdo.utils as utils
Expand Down Expand Up @@ -62,11 +61,14 @@ def __init__(self, channel):
self._var_meta = []
self._partials_meta = []

# list of available options
self.options_list = {}

def get_discipline_info(self):
"""
Gets the discipline properties from the analysis server.
"""
response = self._disc_stub.GetInfo(Empty())
response = self._disc_stub.GetInfo(empty.Empty())
self._is_continuous = response[0].continuous
self._is_differentiable = response[0].differentiable
self._provides_gradients = response[0].provides_gradients
Expand All @@ -77,6 +79,24 @@ def send_stream_options(self):
"""
self._disc_stub.SetStreamOptions(self._stream_options)

def get_available_options(self):
"""
Gets the available options for the analysis discipline.
"""
opts = self._disc_stub.GetAvailableOptions(empty.Empty())

for name, val in zip(opts.options, opts.type):
type_str = None
if val == data.kBool:
type_str = "bool"
if val == data.kInt:
type_str = "int"
if val == data.kDouble:
type_str = "float"
if val == data.kString:
type_str = "str"
self.options_list[name] = type_str

def send_options(self, options):
"""
Sends the discipline options to the analysis server.
Expand All @@ -98,20 +118,20 @@ def run_setup(self):
"""
Runs the setup function on the analysis server.
"""
self._disc_stub.Setup(Empty())
self._disc_stub.Setup(empty.Empty())

def get_variable_definitions(self):
"""
Requests the input and output metadata from the server.
"""
for message in self._disc_stub.GetVariableDefinitions(Empty()):
for message in self._disc_stub.GetVariableDefinitions(empty.Empty()):
self._var_meta += [message]

def get_partials_definitions(self):
"""
Requests metadata information on the partials from the analysis server.
"""
for message in self._disc_stub.GetPartialDefinitions(Empty()):
for message in self._disc_stub.GetPartialDefinitions(empty.Empty()):
if message.name not in self._partials_meta:
self._partials_meta += [message]

Expand Down
29 changes: 28 additions & 1 deletion philote_mdo/general/discipline_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,39 @@ def SetStreamOptions(self, request, context):
self._stream_opts = request
return Empty()

def GetAvailableOptions(self, request, context):
"""
RPC that gets the names and types of all available discipline options.
"""
opts_dict = self._discipline.options_list
opts = data.OptionsList()

for name, val in opts_dict.items():
opts.options.append(name)

# assign the correct data type
if val == 'bool':
type = data.kBool
elif val == 'int':
type = data.kInt
elif val == 'float':
type = data.kDouble
elif val == 'str':
type = data.kString
else:
raise ValueError("Invalid value for discipline option '{}'".format(name))

opts.type.append(type)

return opts

def SetOptions(self, request, context):
"""
RPC that sets the discipline options.
"""
options = request.options
self._discipline.initialize(options)
self._discipline.set_options(options)
return Empty()

def Setup(self, request, context):
"""
Expand Down
2 changes: 1 addition & 1 deletion philote_mdo/openmdao/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@
from .explicit import RemoteExplicitComponent
from .implicit import RemoteImplicitComponent

from .group import OpenMdaoSubProblem
# from .group import OpenMdaoSubProblem
Loading

0 comments on commit 3a4d837

Please sign in to comment.