Skip to content

Commit

Permalink
Merge pull request watertap-org#96 from zacharybinger/pv_surrogates
Browse files Browse the repository at this point in the history
Adding PV Surrogate
  • Loading branch information
zacharybinger authored Jan 10, 2024
2 parents 845f8e7 + 9bb4030 commit 4575aa7
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 0 deletions.
Binary file not shown.
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 src/watertap_contrib/reflo/solar_models/surrogate/pv/pv_surrogate.py
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)

0 comments on commit 4575aa7

Please sign in to comment.