forked from watertap-org/watertap-reflo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request watertap-org#96 from zacharybinger/pv_surrogates
Adding PV Surrogate
- Loading branch information
Showing
3 changed files
with
193 additions
and
0 deletions.
There are no files selected for viewing
Binary file added
BIN
+3.87 KB
src/watertap_contrib/reflo/solar_models/surrogate/pv/data/dataset.pkl
Binary file not shown.
1 change: 1 addition & 0 deletions
1
src/watertap_contrib/reflo/solar_models/surrogate/pv/pv_surrogate.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"model_encoding": {"annual_energy": {"attr": {"x_data_columns": ["design_size"], "x_data": [[0.707070707070707], [0.030303030303030304], [0.3131313131313131], [0.1919191919191919], [0.3535353535353535], [0.9191919191919191], [0.7474747474747474], [0.10101010101010101], [0.7676767676767676], [0.1414141414141414], [0.797979797979798], [0.2525252525252525], [0.7171717171717171], [0.6666666666666666], [0.7575757575757576], [0.06060606060606061], [0.3838383838383838], [0.3636363636363636], [0.9292929292929293], [0.40404040404040403], [0.4242424242424242], [0.1313131313131313], [0.050505050505050504], [0.5656565656565656], [0.8282828282828283], [0.0], [0.0101010101010101], [0.5252525252525252], [0.1616161616161616], [0.0808080808080808], [0.0707070707070707], [1.0], [0.24242424242424243], [0.7777777777777778], [0.9898989898989898], [0.9797979797979798], [0.8989898989898989], [0.8383838383838385], [0.5454545454545454], [0.4949494949494949], [0.7272727272727272], [0.2121212121212121], [0.696969696969697], [0.9595959595959596], [0.47474747474747475], [0.505050505050505], [0.6363636363636364], [0.1818181818181818], [0.7373737373737373], [0.8686868686868686], [0.5757575757575758], [0.23232323232323232], [0.2727272727272727], [0.6767676767676768], [0.3232323232323232], [0.5555555555555556], [0.8181818181818181], [0.46464646464646464], [0.5151515151515151], [0.0909090909090909], [0.606060606060606], [0.8080808080808081], [0.3939393939393939], [0.5353535353535354], [0.8888888888888888], [0.3434343434343434], [0.1111111111111111], [0.2222222222222222], [0.41414141414141414], [0.8787878787878787], [0.7878787878787878], [0.20202020202020202], [0.3333333333333333], [0.2626262626262626], [0.6262626262626262], [0.48484848484848486], [0.4444444444444444], [0.9090909090909091], [0.12121212121212122], [0.9393939393939393]], "centres": [[0.707070707070707], [0.030303030303030304], [0.3131313131313131], [0.1919191919191919], [0.3535353535353535], [0.9191919191919191], [0.7474747474747474], [0.10101010101010101], [0.7676767676767676], [0.1414141414141414], [0.797979797979798], [0.2525252525252525], [0.7171717171717171], [0.6666666666666666], [0.7575757575757576], [0.06060606060606061], [0.3838383838383838], [0.3636363636363636], [0.9292929292929293], [0.40404040404040403], [0.4242424242424242], [0.1313131313131313], [0.050505050505050504], [0.5656565656565656], [0.8282828282828283], [0.0], [0.0101010101010101], [0.5252525252525252], [0.1616161616161616], [0.0808080808080808], [0.0707070707070707], [1.0], [0.24242424242424243], [0.7777777777777778], [0.9898989898989898], [0.9797979797979798], [0.8989898989898989], [0.8383838383838385], [0.5454545454545454], [0.4949494949494949], [0.7272727272727272], [0.2121212121212121], [0.696969696969697], [0.9595959595959596], [0.47474747474747475], [0.505050505050505], [0.6363636363636364], [0.1818181818181818], [0.7373737373737373], [0.8686868686868686], [0.5757575757575758], [0.23232323232323232], [0.2727272727272727], [0.6767676767676768], [0.3232323232323232], [0.5555555555555556], [0.8181818181818181], [0.46464646464646464], [0.5151515151515151], [0.0909090909090909], [0.606060606060606], [0.8080808080808081], [0.3939393939393939], [0.5353535353535354], [0.8888888888888888], [0.3434343434343434], [0.1111111111111111], [0.2222222222222222], [0.41414141414141414], [0.8787878787878787], [0.7878787878787878], [0.20202020202020202], [0.3333333333333333], [0.2626262626262626], [0.6262626262626262], [0.48484848484848486], [0.4444444444444444], [0.9090909090909091], [0.12121212121212122], [0.9393939393939393]], "basis_function": "gaussian", "weights": [[7.557659474608954], [-13.580571363857871], [-0.0013114429384586401], [8.936002747402199], [18.562123829644406], [-5.191113421969931], [-15.230376695184532], [7.228545765899071], [-24.055019284009177], [-9.217174556850296], [-2.195791781767184], [20.469328475786824], [0.6792154013965046], [-10.825834495968593], [-17.389650103203167], [-20.321918088309758], [6.118492608606175], [12.88368118994913], [-3.0478884089607163], [-0.6826250540143519], [-7.544862441187433], [-3.732126722628891], [-15.647040309176646], [4.822599111117597], [-15.729523441979836], [-5.8719127886574825], [-6.301883643344354], [20.570473820982443], [-15.495274638637056], [12.252416945399546], [-19.714832850237144], [42.85383465425548], [-10.430752108819433], [-30.637398890896293], [40.70707259204937], [39.34781702843975], [1.1216636804674636], [-16.798930011224], [12.809819515798154], [-2.570614328273223], [-1.605159066948545], [2.149278554663397], [-26.83174891267845], [-2.4552845378748316], [4.701073110270954], [-8.56970857808119], [4.925748128294799], [14.592126194759658], [-8.436272208135051], [-27.631664374486718], [-1.5443324243206007], [-4.714176599261009], [13.663103518265416], [-13.088172614239738], [-5.679703028239601], [6.552610227088735], [-9.871294108343136], [10.57416181471126], [-10.026225160992908], [12.108300760472048], [-16.412098956221598], [-8.409007852547802], [5.006987513850618], [19.005955647524388], [0.33982090665085707], [24.233254239854432], [2.0473554274076378], [-3.5733766860075775], [-6.393512371443649], [4.525621414701163], [4.157110718064359], [7.824619262700253], [-11.362762508499145], [19.385104925517226], [11.620692711258016], [3.3777877848806384], [17.624797227188537], [-2.25965603471559], [1.5298592178987747], [-4.958699834096478]], "sigma": 0.5, "regularization_parameter": 1e-05, "rmse": 0.0001448967594405131, "R2": 0.9999997565062678, "x_data_min": [[10.0]], "x_data_max": [[10000.0]], "y_data_min": [25279.514640115292], "y_data_max": [22646995.556103665]}, "map": {"x_data_columns": "list", "x_data": "numpy", "centres": "numpy", "basis_function": "str", "weights": "numpy", "sigma": "str", "regularization_parameter": "str", "rmse": "str", "R2": "str", "x_data_min": "numpy", "x_data_max": "numpy", "y_data_min": "numpy", "y_data_max": "numpy"}}, "land_req": {"attr": {"x_data_columns": ["design_size"], "x_data": [[0.707070707070707], [0.030303030303030304], [0.3131313131313131], [0.1919191919191919], [0.3535353535353535], [0.9191919191919191], [0.7474747474747474], [0.10101010101010101], [0.7676767676767676], [0.1414141414141414], [0.797979797979798], [0.2525252525252525], [0.7171717171717171], [0.6666666666666666], [0.7575757575757576], [0.06060606060606061], [0.3838383838383838], [0.3636363636363636], [0.9292929292929293], [0.40404040404040403], [0.4242424242424242], [0.1313131313131313], [0.050505050505050504], [0.5656565656565656], [0.8282828282828283], [0.0], [0.0101010101010101], [0.5252525252525252], [0.1616161616161616], [0.0808080808080808], [0.0707070707070707], [1.0], [0.24242424242424243], [0.7777777777777778], [0.9898989898989898], [0.9797979797979798], [0.8989898989898989], [0.8383838383838385], [0.5454545454545454], [0.4949494949494949], [0.7272727272727272], [0.2121212121212121], [0.696969696969697], [0.9595959595959596], [0.47474747474747475], [0.505050505050505], [0.6363636363636364], [0.1818181818181818], [0.7373737373737373], [0.8686868686868686], [0.5757575757575758], [0.23232323232323232], [0.2727272727272727], [0.6767676767676768], [0.3232323232323232], [0.5555555555555556], [0.8181818181818181], [0.46464646464646464], [0.5151515151515151], [0.0909090909090909], [0.606060606060606], [0.8080808080808081], [0.3939393939393939], [0.5353535353535354], [0.8888888888888888], [0.3434343434343434], [0.1111111111111111], [0.2222222222222222], [0.41414141414141414], [0.8787878787878787], [0.7878787878787878], [0.20202020202020202], [0.3333333333333333], [0.2626262626262626], [0.6262626262626262], [0.48484848484848486], [0.4444444444444444], [0.9090909090909091], [0.12121212121212122], [0.9393939393939393]], "centres": [[0.707070707070707], [0.030303030303030304], [0.3131313131313131], [0.1919191919191919], [0.3535353535353535], [0.9191919191919191], [0.7474747474747474], [0.10101010101010101], [0.7676767676767676], [0.1414141414141414], [0.797979797979798], [0.2525252525252525], [0.7171717171717171], [0.6666666666666666], [0.7575757575757576], [0.06060606060606061], [0.3838383838383838], [0.3636363636363636], [0.9292929292929293], [0.40404040404040403], [0.4242424242424242], [0.1313131313131313], [0.050505050505050504], [0.5656565656565656], [0.8282828282828283], [0.0], [0.0101010101010101], [0.5252525252525252], [0.1616161616161616], [0.0808080808080808], [0.0707070707070707], [1.0], [0.24242424242424243], [0.7777777777777778], [0.9898989898989898], [0.9797979797979798], [0.8989898989898989], [0.8383838383838385], [0.5454545454545454], [0.4949494949494949], [0.7272727272727272], [0.2121212121212121], [0.696969696969697], [0.9595959595959596], [0.47474747474747475], [0.505050505050505], [0.6363636363636364], [0.1818181818181818], [0.7373737373737373], [0.8686868686868686], [0.5757575757575758], [0.23232323232323232], [0.2727272727272727], [0.6767676767676768], [0.3232323232323232], [0.5555555555555556], [0.8181818181818181], [0.46464646464646464], [0.5151515151515151], [0.0909090909090909], [0.606060606060606], [0.8080808080808081], [0.3939393939393939], [0.5353535353535354], [0.8888888888888888], [0.3434343434343434], [0.1111111111111111], [0.2222222222222222], [0.41414141414141414], [0.8787878787878787], [0.7878787878787878], [0.20202020202020202], [0.3333333333333333], [0.2626262626262626], [0.6262626262626262], [0.48484848484848486], [0.4444444444444444], [0.9090909090909091], [0.12121212121212122], [0.9393939393939393]], "basis_function": "gaussian", "weights": [[6.792046620499605], [-11.110192082516278], [-2.0406721779836516], [9.93113909945987], [18.91813089864445], [-3.1621413279572153], [-14.1464730396292], [6.821469805936886], [-24.337877641683008], [-7.606911239882265], [-1.6700856515781197], [22.588612776744412], [1.5211659695851267], [-9.424810870048532], [-19.27732283450314], [-18.175506377403053], [6.703716028812778], [14.849478497795644], [-4.000514174644195], [-1.4725485577473592], [-9.705113204217923], [-3.851089868188865], [-15.582507593302125], [3.3394781197421253], [-14.964698909934668], [-6.54669623938662], [-7.74771009828919], [21.83157445094548], [-15.338622949222554], [13.29062836783578], [-20.97720156388914], [44.48873911341434], [-10.549790048340583], [-29.311747901549097], [40.746509438729845], [37.79353684918169], [-0.05496240284264786], [-19.00587227028882], [12.696414615042158], [-2.1090222747916414], [-3.733678928885638], [1.7810202127184311], [-25.189752109447], [-3.1912112834033906], [6.541124050898361], [-6.4997234800575825], [6.087258191302681], [13.966627910210264], [-8.960558433485858], [-29.60454174381448], [-1.4244211148943577], [-6.432284578940198], [14.355707000700932], [-14.660829509084579], [-6.122575912697357], [8.04623641877697], [-10.712619473211817], [10.806788899448293], [-10.937962718540803], [10.131555798956015], [-16.05674630426074], [-6.273549302983156], [2.620947481449548], [17.291041404932912], [2.1418782141263364], [22.987295586875916], [3.3773014811231405], [-2.320498261588], [-5.580088462902495], [4.722055860962428], [3.07646791602383], [5.866944546540253], [-10.198740998042922], [18.470366468149223], [11.174753322302422], [2.2369223538407823], [19.23605612938627], [-1.8347135514923139], [-0.18512921195178933], [-4.311587726107973]], "sigma": 0.5, "regularization_parameter": 1e-05, "rmse": 0.00014527506200332678, "R2": 0.9999997552228744, "x_data_min": [[10.0]], "x_data_max": [[10000.0]], "y_data_min": [0.07254508590000001], "y_data_max": [64.97621527110002]}, "map": {"x_data_columns": "list", "x_data": "numpy", "centres": "numpy", "basis_function": "str", "weights": "numpy", "sigma": "str", "regularization_parameter": "str", "rmse": "str", "R2": "str", "x_data_min": "numpy", "x_data_max": "numpy", "y_data_min": "numpy", "y_data_max": "numpy"}}}, "input_labels": ["design_size"], "output_labels": ["annual_energy", "land_req"], "input_bounds": {"design_size": [1, 200000]}, "surrogate_type": "rbf"} |
192 changes: 192 additions & 0 deletions
192
src/watertap_contrib/reflo/solar_models/surrogate/pv/pv_surrogate.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
############################################################################### | ||
# WaterTAP Copyright (c) 2021, The Regents of the University of California, | ||
# through Lawrence Berkeley National Laboratory, Oak Ridge National | ||
# Laboratory, National Renewable Energy Laboratory, and National Energy | ||
# Technology Laboratory (subject to receipt of any required approvals from | ||
# the U.S. Dept. of Energy). All rights reserved. | ||
# | ||
# Please see the files COPYRIGHT.md and LICENSE.md for full copyright and license | ||
# information, respectively. These files are also available online at the URL | ||
# "https://github.com/watertap-org/watertap/" | ||
# | ||
############################################################################### | ||
|
||
import os | ||
import sys | ||
import re | ||
import time | ||
import pandas as pd | ||
import numpy as np | ||
from pathlib import Path | ||
from io import StringIO | ||
import matplotlib.pyplot as plt | ||
|
||
from pyomo.environ import ConcreteModel, Var, Constraint, units as pyunits, value, Param | ||
|
||
from idaes.core import FlowsheetBlock | ||
from idaes.core import declare_process_block_class | ||
from idaes.core.surrogate.surrogate_block import SurrogateBlock | ||
from idaes.core.surrogate.pysmo_surrogate import PysmoRBFTrainer, PysmoSurrogate | ||
from idaes.core.surrogate.sampling.data_utils import split_training_validation | ||
|
||
from watertap_contrib.reflo.core import SolarEnergyBaseData | ||
|
||
__author__ = "Zachary Binger, Matthew Boyd, Kurban Sitterley" | ||
|
||
|
||
@declare_process_block_class("PVSurrogate") | ||
class PVSurrogateData(SolarEnergyBaseData): | ||
""" | ||
Surrogate model for PV. | ||
""" | ||
|
||
CONFIG = SolarEnergyBaseData.CONFIG() | ||
|
||
def build(self): | ||
super().build() | ||
|
||
self._tech_type = "PV" | ||
self.surrogate_file = os.path.join( | ||
os.path.dirname(__file__), "pv_surrogate.json" | ||
) | ||
|
||
self.design_size = Var( | ||
initialize=1000, | ||
bounds=[1, 200000], | ||
units=pyunits.kW, | ||
doc="PV design size in kW", | ||
) | ||
|
||
self.annual_energy = Var( | ||
initialize=1, | ||
units=pyunits.kWh, | ||
doc="Annual energy produced by the plant in kWh", | ||
) | ||
|
||
self.land_req = Var( | ||
initialize=7e7, | ||
units=pyunits.acre, | ||
doc="Land area required by the plant in acres", | ||
) | ||
|
||
self.surrogate_inputs = [self.design_size] | ||
self.surrogate_outputs = [self.annual_energy, self.land_req] | ||
|
||
self.input_labels = ["design_size"] | ||
self.output_labels = ["annual_energy", "land_req"] | ||
|
||
self.electricity_constraint = Constraint( | ||
expr=self.annual_energy | ||
== -1 | ||
* self.electricity | ||
* pyunits.convert(1 * pyunits.year, to_units=pyunits.hour) | ||
) | ||
|
||
def load_surrogate(self): | ||
print("Loading surrogate file...") | ||
self.surrogate_file = os.path.join( | ||
os.path.dirname(__file__), "pv_surrogate.json" | ||
) | ||
|
||
if os.path.exists(self.surrogate_file): | ||
stream = StringIO() | ||
oldstdout = sys.stdout | ||
sys.stdout = stream | ||
|
||
self.surrogate_blk = SurrogateBlock(concrete=True) | ||
self.surrogate = PysmoSurrogate.load_from_file(self.surrogate_file) | ||
self.surrogate_blk.build_model( | ||
self.surrogate, | ||
input_vars=self.surrogate_inputs, | ||
output_vars=self.surrogate_outputs, | ||
) | ||
|
||
# Revert back to standard output | ||
sys.stdout = oldstdout | ||
|
||
def get_training_validation(self): | ||
self.dataset_filename = os.path.join( | ||
os.path.dirname(__file__), "data/dataset.pkl" | ||
) | ||
print("Loading Training Data...\n") | ||
time_start = time.process_time() | ||
pkl_data = pd.read_pickle(self.dataset_filename) | ||
data = pkl_data.sample(n=int(len(pkl_data))) # FIX default this to 100% of data | ||
self.data_training, self.data_validation = split_training_validation( | ||
data, self.training_fraction, seed=len(data) | ||
) | ||
time_stop = time.process_time() | ||
print("Data Loading Time:", time_stop - time_start, "\n") | ||
|
||
def create_surrogate( | ||
self, | ||
save=False, | ||
): | ||
self.sample_fraction = 0.1 # fraction of the generated data to train with. More flexible than n_samples. | ||
self.training_fraction = 0.8 | ||
|
||
self.get_training_validation() | ||
time_start = time.process_time() | ||
# Capture long output | ||
stream = StringIO() | ||
oldstdout = sys.stdout | ||
sys.stdout = stream | ||
|
||
# Create PySMO trainer object | ||
trainer = PysmoRBFTrainer( | ||
input_labels=self.input_labels, | ||
output_labels=self.output_labels, | ||
training_dataframe=self.data_training, | ||
) | ||
|
||
# Set PySMO options | ||
trainer.config.basis_function = "gaussian" # default = gaussian | ||
trainer.config.solution_method = "algebraic" # default = algebraic | ||
trainer.config.regularization = True # default = True | ||
|
||
# Train surrogate | ||
rbf_train = trainer.train_surrogate() | ||
|
||
# Remove autogenerated 'solution.pickle' file | ||
try: | ||
os.remove("solution.pickle") | ||
except FileNotFoundError: | ||
pass | ||
except Exception as e: | ||
raise e | ||
# Create callable surrogate object | ||
xmin, xmax = [self.design_size.bounds[0]], [self.design_size.bounds[1]] | ||
input_bounds = { | ||
self.input_labels[i]: (xmin[i], xmax[i]) | ||
for i in range(len(self.input_labels)) | ||
} | ||
rbf_surr = PysmoSurrogate( | ||
rbf_train, self.input_labels, self.output_labels, input_bounds | ||
) | ||
|
||
# Save model to JSON | ||
if (self.surrogate_file is not None) and (save is True): | ||
print(f"Writing surrogate model to {self.surrogate_file}") | ||
model = rbf_surr.save_to_file(self.surrogate_file, overwrite=True) | ||
|
||
# Revert back to standard output | ||
sys.stdout = oldstdout | ||
|
||
time_stop = time.process_time() | ||
print("Model Training Time:", time_stop - time_start, "\n") | ||
|
||
return rbf_surr | ||
|
||
|
||
if __name__ == "__main__": | ||
m = ConcreteModel() | ||
m.fs = FlowsheetBlock(dynamic=False) | ||
m.fs.pv = PVSurrogate() | ||
m.fs.pv.create_surrogate(save=False) | ||
|
||
m.fs.pv.load_surrogate() | ||
|
||
results = m.fs.pv.surrogate.evaluate_surrogate( | ||
m.fs.pv.data_validation[m.fs.pv.input_labels] | ||
) | ||
print(results) |