From 9944c51525ccd19579efe6ac8a666d1afffc278e Mon Sep 17 00:00:00 2001 From: Christian Doh Dinga <cdohdinga@tudelft.nl> Date: Sun, 23 Jun 2024 20:28:11 +0200 Subject: [PATCH] implement ADMM subroutine: update and solve optimization problems --- .../implement_admm_subroutine.py | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 src/demoses_distibuted_optimization/implement_admm_subroutine.py diff --git a/src/demoses_distibuted_optimization/implement_admm_subroutine.py b/src/demoses_distibuted_optimization/implement_admm_subroutine.py new file mode 100644 index 0000000..6864eb2 --- /dev/null +++ b/src/demoses_distibuted_optimization/implement_admm_subroutine.py @@ -0,0 +1,136 @@ +import timeit +import numpy as np +import pyomo.environ as pyo +from typing import Dict +from solve_consumer_agent import solve_consumer_agent +from solve_generator_agent import solve_generator_agent + + +def implement_admm_subroutine( + agent: str, + agents: Dict, + primal_var_and_λ_EOM: Dict, + admm_parameters: Dict, + EOM: Dict, + model: pyo.ConcreteModel, + data: Dict, +) -> Dict: + """This function implements the first step of ADMM which is the admm_subroutine. + + admm_subroutine obtains the latest values of ADMM paramters (λ_EOM, g_bar, Ï_EOM) from the previous optimization round, + and updates them to new_λ_EOM, new_g_bar, and new_Ï_EOM respectively. Next, it then calls the solve_generator_agent and + solve_consumer_agent functions, which instantiates new optimization problems for each agents by updating ADMM paramters + to their new values. Finally, it runs all optimization problems again and appends results to the respective dictionaries. + """ + # Initialize total run time + total_time = 0 + start_time = timeit.default_timer() + # Get current ADMM parameters and update to latest values for next optimization round (common to all agents) + new_λ_EOM = primal_var_and_λ_EOM['λ']['EOM'][-1] + new_g_bar = primal_var_and_λ_EOM['g'][agent][-1] - (1 / (EOM['nAgents'] + 1)) * admm_parameters['Imbalances']['EOM'][-1] + new_Ï_EOM = admm_parameters['Ï']['EOM'][-1] + + # Prepare updated data in right format for instantiating agent optimization problems + instance_data = { + None: { + 'λ_EOM': dict(enumerate(new_λ_EOM)), # Convert time-indexed parameters to dict for declaration in pyomo + 'g_bar': dict(enumerate(new_g_bar)), + 'Ï_EOM': {None: new_Ï_EOM}, + } + } + update_time = timeit.default_timer() - start_time + total_time += update_time + start_time = timeit.default_timer() + # Instantiate and solve agent new optimization problems + if agent in agents['Gen']: + # print(f'############ solve optimization problem for generator agent {agent} in subroutine: start #################') + instance_model = solve_generator_agent(model=model, data=data, instance_data=instance_data) + # print(f'############ solve optimization problem for generator agent {agent} in subroutine: done ##################') + elif agent in agents['Cons']: + # print(f'############ solve optimization problem for consumer agent {agent} in subroutine: start ##################') + instance_model = solve_consumer_agent(model=model, data=data, instance_data=instance_data) + # print(f'############ solve optimization problem for consumer agent {agent} in subroutine: done ###################') + else: + print(f'Agent {agent} is not part of the game') + return 0 + + solve_time = timeit.default_timer() - start_time + total_time += solve_time + + # Query results + start_time = timeit.default_timer() + optimal_decision_variable = np.array([pyo.value(instance_model.var_g[t]) for t in instance_model.time]) # get values of decision variables + primal_var_and_λ_EOM['g'][agent].append(optimal_decision_variable) + query_time = timeit.default_timer() - start_time + total_time += query_time + # print(f'################ print primal decision variables for agent {agent} in subroutine: start #####################') + # print(optimal_decision_variable) + # print(f'################ print primal decision variables for agent {agent} in subroutine: done ######################') + + # Record the total time in the TO dictionary + TO = dict() + TO['total_time'] = TO.get('total_time', 0) + total_time + return TO + + +# # Example usage +# import yaml +# import pandas as pd +# from define_EOM_parameters import define_EOM_parameters +# from define_common_parameters import define_common_parameters +# from define_consumer_parameters import define_consumer_parameters +# from define_generator_parameters import define_generator_parameters +# from define_results import define_results + + +# def read_config(config_file): +# with open(config_file, 'r') as file: +# config = yaml.safe_load(file) +# return config +# data = read_config('config.yaml') +# ts = pd.read_csv('timeseries.csv', delimiter=';') +# scenario_number = 1 +# scenario_overview_row = pd.read_csv('overview_scenarios.csv', delimiter=';').iloc[scenario_number-1, :] + +# agents = {} +# agents['Gen'] = [id for id in data['Generators'].keys()] +# agents['Cons'] = [id for id in data['Consumers'].keys()] +# agents['eom'] = agents['Gen'] + agents['Cons'] + +# generator_agent = agents['Gen'][0] +# generator_agent_model = define_common_parameters(agent=generator_agent, data=data) +# define_generator_parameters(agent=generator_agent, model=generator_agent_model, data=data, ts=ts) + +# consumer_agent = agents['Cons'][0] +# consumer_agent_model = define_common_parameters(agent=consumer_agent, data=data) +# define_consumer_parameters(agent=consumer_agent, model=consumer_agent_model, data=data, ts=ts) + +# EOM = define_EOM_parameters(ts=ts) +# EOM["nAgents"] = len(agents['eom']) + +# primal_var_and_λ_EOM, admm_parameters = define_results(data=data, agents=agents) + +# TO_generator_agent = implement_admm_subroutine( +# agent=generator_agent, +# agents=agents, +# primal_var_and_λ_EOM=primal_var_and_λ_EOM, +# admm_parameters=admm_parameters, +# EOM=EOM, +# model=generator_agent_model, +# data=data, +# ) + +# print(TO_generator_agent) + +# print() + +# TO_consumer_agent = implement_admm_subroutine( +# agent=consumer_agent, +# agents=agents, +# primal_var_and_λ_EOM=primal_var_and_λ_EOM, +# admm_parameters=admm_parameters, +# EOM=EOM, +# model=consumer_agent_model, +# data=data, +# ) +# print(TO_consumer_agent) -- GitLab