Skip to content

Commit

Permalink
Merge pull request #1 from FlanFlanagan/master
Browse files Browse the repository at this point in the history
initial pr
  • Loading branch information
scopatz authored Mar 19, 2018
2 parents dec0603 + 17807ee commit aff100d
Show file tree
Hide file tree
Showing 7 changed files with 738 additions and 102 deletions.
108 changes: 7 additions & 101 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,101 +1,7 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# dotenv
.env

# virtualenv
.venv
venv/
ENV/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
*.h5
*.json
*.sqlite
*.txt
*.pyc
build
d3ploy/__pycache__
119 changes: 118 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,119 @@
# d3ploy
A collection of Cyclus manager archetypes for demand driven deployment
A collection of Cyclus manager archetypes for demand driven deployment. It operates using
global calls within a Cyclus simulation so that all agents within the simulation
can communicate. The goal of this package is to provide three types of mathematical
basis for determining supply and demand of commodities within Cyclus; Non-optimizing (NO)
deterministing optimization (DO), and Stochastic optimization (SO).

Dependencies
============
**statsmodels**: Python package for statistical analysis
**arch**: Python package for conditional heteroskidasticity models.

Non-Optimizing Methods
======================
There are two methods currently being considered for the NO models. Autoregressive
moving average (ARMA), and autoregressive conditional heteroskedasticity (ARCH).

ARMA
----
The autoregressive moving average method takes a time series and uses an
auto regressive term and a moving average term.

ARCH
----
Currently a work in progress

Deterministic Optimization
==========================
Currently a work in progress

Stochastic Optimization
=======================
Currently a work in progress


NO Instutition
==============
This represents the Non-Optimizing instition, included in this are the ARMA
and ARCH methods. Additionally a simple moving average calculation is included
with this archetype. The user chooses the method as part of the institution
input.

The institution works by using the chosen method to predict supply and
demand for given commodities. Each timestep the institution calculates a prediction
on the supply and demand for the next time step. If the demand exceeds the
supply it deploys facilities to ensure supply exceeds demand. Predictions are not
performed if the method chosen by the institution is 'moving average'. In this instance
the institution will schedule facilities for deployment only if there is a
deficit in the current time step.

Required Inputs
---------------
- **demand_commod**: This is the commodity that is demanded of the institution.
Facilities outside of this insitution need this commodity and request it from
facilities inside of this institution. **NOTE** If 'power' is used as the
**demand_commod**, the institution will calculate the demand using an exponential
growth curve and a grow rate of 2% by default. This growth rate is an optional
input.
- **supply_commod**: This is the commodity that facilities inside of this institution
supply.
- **prototypes**: A oneOrMore of the prototypes available for the institution to deploy
to meet the demand for the demanded commodity.
- **initial_demand**: This sets the initial demand of the demand commodity. If the
initial facilities at start up does not meet this demand the first time step will
see a undersupply.
- **calc_method**: This is the method used to calculate the supply and demand.
Current available options are 'ARMA' and 'MA' for autoregressive moving average
and moving average.

Optional Inputs
---------------
- **growth_rate**: The growth rate used to calculate power if power is the
**demand_commod**. Default: 0.02 (2%).
- **record**: A boolean flag used to set if an institution will dump a record
of its supply and demand values to a .txt file. The name of the file is the
**demand_commod**. Default: False.
- **supply_std_dev**: The number of standard deviations off of the predicted supply
value to use as the predicted value. For example if the predicted value is 10
with a standard deviation of 2, +1 will result in a predicted value of 12 and
-1 will result in a predicted value of 8. Default: 0
- **demand_std_dev**: The number of standard deviations off of the predicted demand
value to use as the predicted value. For example if the predicted value is 10
with a standard deviation of 2, +1 will result in a predicted value of 12 and
-1 will result in a predicted value of 8. Default: 0
- **steps**: This is the number of time steps forward the supply and demand will
be predicted. Default: 1.
- **back_steps**: This input is for the ARCH methods. It provides the user with
the ability to set the number of timesteps back from the current time step
to use for prediction. If this is set to '0', all values in the time series
are used. Default: 5.

Demand Fac
==========
This facility is a test facility for D3ploy. It generates a random amount of
supply and demand for commodities, and then reports these using the
**RecordTimeSeries** functions inside of Cyclus.Thus providing a supply and
demand to the institutions.

Amount of commodity demanded and supplied can be determined randomly through
their minimum and maximum values. If for instance you'd like variability in
the production rate of your supply you can set these minimum and maximum
values to reflect that.

Required Inputs
---------------
- **demand_commod**: This is the commodity that the facility demands in order to
operate.
- **demand_rate_min**: Minimum amount of the demanded commodity needed.
- **demand_rate_max**: Maximum amount of the demanded commodity needed.
- **supply_commod**: The commodity that the facility supplies.
- **supply_rate_min**: Minimum rate of production of the supplied commodity.
- **supply_rate_max**: Maximum rate of production of the supplied commodity.

Optional Inputs
---------------
- **demand_ts**: The amount of time steps between demanding material. For
example a reactor may only demand material every 18 months.
- **supply_ts**: The amount of time steps between supplying material.

98 changes: 98 additions & 0 deletions d3ploy/demand_fac.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"""
This is a mock facility used to demonstrate and test the capabilities
of the deploy instutitions in d3ploy. It produces a fixed (or random)
amount of psuedo material per time step (the production can also be
set to every nth time step by the user).
"""

import random
import numpy as np
import scipy as sp

from cyclus.agents import Facility
from cyclus import lib
import cyclus.typesystem as ts


class DemandFac(Facility):
"""
This institution deploys facilities based on demand curves using
Non Optimizing (NO) methods.
"""

demand_rate_min = ts.Double(
doc="The minimum rate at which this facility produces it's commodity. ",
tooltip="The minimum rate at which this facility produces its product.",
uilabel="Min Production"
)

demand_rate_max = ts.Double(
doc="The maximum rate at which this facility produces it's commodity.",
tooltip="The maximum rate at which this facility produces its product.",
uilabel="Max Production"
)

demand_ts = ts.Int(
doc="The number of timesteps between demand calls by the agent",
tooltip="The number of timesteps between demand calls by the agent",
uilabel="Demand Timestep",
default=1
)

supply_rate_max = ts.Double(
doc="The maximum rate at which this facility produces it's commodity.",
tooltip="The maximum rate at which this facility produces its product.",
uilabel="Max Production"
)

supply_rate_min = ts.Double(
doc="The maximum rate at which this facility produces it's commodity.",
tooltip="The maximum rate at which this facility produces its product.",
uilabel="Max Production"
)

supply_ts = ts.Int(
doc="The number of timesteps between supply calls by the agent",
tooltip="The number of timesteps between supply calls by the agent",
uilabel="Supply Timestep",
default=1
)

supply_commod = ts.String(
doc="The commodity supplied by this facility.",
tooltip="Supplied Commodity",
uilabel="Supplied Commodity"
)

demand_commod = ts.String(
doc="The commodity demanded by this facility.",
tooltip="Commodity demanded",
uilabel="Commodity Demanded"
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.demand_t = -2
self.supply_t = -2

def tick(self):
"""
This method defines the tick behavior for this archetype. The demand and supply
rates are calculated, and those are recorded in time series.
"""
self.demand_t += 1
self.supply_t += 1
supply_rate = random.uniform(self.supply_rate_min, self.supply_rate_max)
demand_rate = random.uniform(self.demand_rate_min, self.demand_rate_max)
if self.supply_t == -1 or self.supply_t == self.supply_ts:
lib.record_time_series(self.supply_commod, self, supply_rate)
self.supply_t = 0
else:
lib.record_time_series(self.supply_commod, self, 0.)
if self.demand_t == -1 or self.demand_t == self.demand_ts:
lib.record_time_series(self.demand_commod, self, demand_rate)
self.demand_t = 0
else:
lib.record_time_series(self.demand_commod, self, 0.)


Loading

0 comments on commit aff100d

Please sign in to comment.