diff --git a/examples/run_pomato_fbmc.py b/examples/run_pomato_fbmc.py new file mode 100644 index 0000000..1f2775b --- /dev/null +++ b/examples/run_pomato_fbmc.py @@ -0,0 +1,45 @@ +"""IEEE Test Case.""" +from pathlib import Path +import numpy as np +import pandas as pd +import pomato + + +mato = pomato.POMATO(wdir=self.wdir, options_file="profiles/nrel118.json") +mato.load_data('data_input/nrel_118_original.zip') + +mato.options["model_horizon"] = [0, 168] +mato.options["redispatch"]["include"] = False +mato.options["redispatch"]["zones"] = list(mato.data.zones.index) +mato.options["infeasibility"]["electricity"]["bound"] = 200 +mato.options["infeasibility"]["electricity"]["cost"] = 1000 +mato.options["redispatch"]["cost"] = 20 + +# %% Nodal Basecase +mato.data.results = {} +mato.options["type"] = "opf" +mato.create_grid_representation() +mato.update_market_model_data() +mato.run_market_model() +result_name = next(r for r in list(mato.data.results)) +basecase = mato.data.results[result_name] + +mato.options["fbmc"]["minram"] = 0.2 +mato.options["fbmc"]["lodf_sensitivity"] = 0.1 +mato.options["fbmc"]["cne_sensitivity"] = 0.2 +fb_parameters = mato.create_flowbased_parameters(basecase) +fbmc_domain = pomato.visualization.FBDomainPlots(mato.data, fb_parameters) +fbmc_domain.generate_flowbased_domains(("R1", "R2"), ["R1", "R3"], timesteps=["t0001"]) +mato.visualization.create_fb_domain_plot(fbmc_domain.fbmc_plots[0], show_plot=False) + +# %% FBMC market clearing +mato.options["redispatch"]["include"] = True +mato.options["redispatch"]["zones"] = list(mato.data.zones.index) +mato.create_grid_representation(flowbased_parameters=fb_parameters) +mato.update_market_model_data() +mato.run_market_model() +mato.visualization.create_generation_overview(list(mato.data.results.values()), show_plot=False) +mato._join_julia_instances() + +# Join all subprocesses. +mato._join_julia_instances() diff --git a/examples/run_pomato_ieee.py b/examples/run_pomato_ieee.py index f873242..90ee471 100644 --- a/examples/run_pomato_ieee.py +++ b/examples/run_pomato_ieee.py @@ -6,9 +6,11 @@ # Init POMATO with the options file and the dataset wdir = Path("/examples/") # Change to local copy of examples folder + mato = pomato.POMATO(wdir=wdir, options_file="profiles/ieee118.json") mato.load_data('data_input/pglib_opf_case118_ieee.m') + # %% Access the data from the main pomato instance in the data object. nodes = mato.data.nodes lines = mato.grid.lines @@ -17,9 +19,9 @@ plants = mato.data.plants # %% Run uniform pricing -mato.options["type"] = "dispatch" +mato.options["type"] = "uniform" mato.create_grid_representation() -mato.run_market_model() +mato.run_market_model(update_data=True) # Obtain the market result by name and its instance dispatch_result_name = mato.market_model.result_folders[0].name @@ -32,9 +34,9 @@ print("Number of overloaded lines N-1 (Dispatch): ", len(df3)) # %% Run nodal-prcing market clearing -mato.options["type"] = "nodal" +mato.options["type"] = "opf" mato.create_grid_representation() -mato.run_market_model() +mato.run_market_model(update_data=True) # Obtain the market result by name and its instance nodal_result_name = mato.market_model.result_folders[0].name @@ -48,12 +50,11 @@ print("Number of overloaded lines N-1 (nodal): ", len(df3)) # Create geoplot for nodal result, including price layer and saving it as .html -mato.visualization.create_geo_plot(nodal_result, - show_prices=True, - filepath=mato.wdir.joinpath("geoplot_nodal.html")) +mato.visualization.create_geo_plot( + nodal_result, show_prices=True, filepath=mato.wdir.joinpath("geoplot_nodal.html")) # %% Rerun the model as SCOPF -mato.options["type"] = "cbco_nodal" +mato.options["type"] = "scopf" mato.options["grid"]["redundancy_removal_option"] = "conditional_redundancy_removal" # Optionally set a line rating factors # mato.options["grid"]["short_term_rating_factor"] = 1 @@ -61,10 +62,7 @@ # SCOPF requires to presolve the network with the RedundancyRemoval Algorithm mato.create_grid_representation() - -# Update the model data -mato.update_market_model_data() -mato.run_market_model() +mato.run_market_model(update_data=True) # Check for overloaded lines (Should be none for N-0 and N-1) scopf_result_name = mato.market_model.result_folders[0].name @@ -77,9 +75,11 @@ print("Number of overloaded lines N-1 (SCOPF): ", len(df3)) # Create geoplot for scopf result, including price layer and saving it as .html -mato.visualization.create_geo_plot(scopf_result, - show_prices=True, - filepath=mato.wdir.joinpath("geoplot_scopf.html")) +mato.visualization.create_geo_plot( + scopf_result, show_prices=True, + filepath=mato.wdir.joinpath("geoplot_scopf.html") +) # Join all subprocesses. mato._join_julia_instances() + diff --git a/pomato/data/worker.py b/pomato/data/worker.py index 9e62961..892ce9f 100644 --- a/pomato/data/worker.py +++ b/pomato/data/worker.py @@ -440,17 +440,18 @@ def process_matpower_case(self, casefile, m_type): ### Make ieee case ready for the market model self.data.nodes["name"] = ["n" + str(int(idx)) for idx in self.data.nodes.index] self.data.nodes.rename(columns={"baseKV": "voltage"}, inplace=True) - self.data.nodes.set_index("name", drop=False, inplace=True) + self.data.nodes = self.data.nodes.set_index("name", drop=False).rename_axis(index="index") + self.data.nodes.zone = ["z" + str(int(idx)) for idx in self.data.nodes.zone] self.data.lines.node_i = ["n" + str(int(idx)) for idx in self.data.lines.node_i] self.data.lines.node_j = ["n" + str(int(idx)) for idx in self.data.lines.node_j] self.data.lines["voltage"] = self.data.nodes.loc[self.data.lines.node_i, "voltage"].values self.data.lines["technology"] = "ac" - condition_tranformer = (self.data.nodes.loc[self.data.lines.node_i, "voltage"].values + condition_transformer = (self.data.nodes.loc[self.data.lines.node_i, "voltage"].values != self.data.nodes.loc[self.data.lines.node_j, "voltage"].values) - self.data.lines.loc[condition_tranformer, "technology"] = "transformer" + self.data.lines.loc[condition_transformer, "technology"] = "transformer" self.data.zones = pd.DataFrame(index=set(self.data.nodes.zone.values)) self.data.plants.node = ["n" + str(int(idx)) for idx in self.data.plants.node] diff --git a/pomato/market_model/market_model.py b/pomato/market_model/market_model.py index a6e4bcf..131db7e 100644 --- a/pomato/market_model/market_model.py +++ b/pomato/market_model/market_model.py @@ -4,7 +4,7 @@ the market model written in julia. This is done by saving the relevant data as csv, run the model in a threaded julia program which provides the results in folder as csv files. -The Modes is initionaled empty and then filled with data seperately. This makes it +The model is initialized empty and then filled with data separately. This makes it easy to change the data and rerun without re-initializing everything again. """ @@ -107,6 +107,10 @@ def run(self): if not self.julia_model: self.julia_model = tools.JuliaDaemon(self.logger, self.wdir, self.package_dir, "market_model", self.options["solver"]["name"]) + elif not self.julia_model.julia_daemon.isAlive(): + self.logger.info("Joining previous market model thread.") + self.julia_model.join() + self.julia_model = tools.JuliaDaemon(self.logger, self.wdir, self.package_dir, "market_model", self.options["solver"]["name"]) self.logger.info("Start-Time: %s", t_start.strftime("%H:%M:%S"))