diff --git a/00_use-case/auxfuns/mpc_data.m b/00_use-case/auxfuns/mpc_data.m index 2dde7f7..349491a 100644 --- a/00_use-case/auxfuns/mpc_data.m +++ b/00_use-case/auxfuns/mpc_data.m @@ -152,5 +152,16 @@ 2 4 64 10; 2 5 837 8; ]; + elseif strcmp(casefile, '18') + + mpc.trans = ext2int(loadcase('case9')); + mpc.dist = { ext2int(loadcase('case9'))}; + % region 1 - region 2 + mpc.connection_array = [ + % region 1 - region 2 + 1 2 2 1 + + ]; end + end \ No newline at end of file diff --git a/00_use-case/getting_started_opf.m b/00_use-case/getting_started_opf.m index dd854aa..e65fb92 100644 --- a/00_use-case/getting_started_opf.m +++ b/00_use-case/getting_started_opf.m @@ -14,16 +14,35 @@ mpc.fields_to_merge = {'bus', 'gen', 'branch', 'gencost'}; mpc_temp = loadcase('case5'); -mpc_temp.gencost(:, 4) = 3; -mpc_temp.gencost(:, 6:7) = rand(); -%mpc.fields_to_merge = {'bus', 'gen', 'branch'}; -mpc.trans = mpc_temp; -mpc.dist = { mpc_temp; - mpc_temp - }; +% mpc_temp.gencost(:, 4) = 3; +% mpc_temp.gencost(:, 6:7) = rand(); + +% remove limits in casefile +% generator limits +% upper bounds -mpc.connection_array = [ 1 2 1 5; - 2 3 4 1]; +% line flow limits +% upper bounds +% mpc_temp.branch(:, 6) = 0; + +%mpc.fields_to_merge = {'bus', 'gen', 'branch'}; +% mpc.trans = mpc_temp; +% mpc.dist = { mpc_temp; +% mpc_temp +% }; +% +% mpc.connection_array = [ 1 2 1 5; +% 2 3 4 1]; +% + + mpc.trans = ext2int(loadcase('case9')); + mpc.dist = { ext2int(loadcase('case9'))}; + % region 1 - region 2 + mpc.connection_array = [ + % region 1 - region 2 + 1 2 2 1 + + ]; % compatibility tests % Opf data is provided ?? @@ -90,16 +109,86 @@ %% setup distributed opf % start values from pf +%% solve pf + + mpc_split = run_case_file_splitter(mpc_merge, conn, names); + problem_type = 'feasibility'; + % generate distributed problem + problem = generate_distributed_pf_for_aladin(mpc_split, names, problem_type); + problem.solver = 'fmincon'; + + + opts = struct('maxiter',50, 'solveQP','quadprog'); + opts.reg ='false'; + opts.rho0= 1e2; + % + % % opts.regParam = 1e-12; + % [xsol_aladin, xsol_stack_aladin, mpc_sol_aladin, logg] = solve_distributed_problem_with_aladin(mpc_split, problem, names, opts); + %% +% comparison_aladin = compare_results(xval, xsol_aladin) +% violation = compare_constraints_violation(problem, logg); + %% +% [a,b,c] = compare_power_flow_between_regions(mpc_sol_aladin, mpc_merge.connections, mpc_split.regions, conn(:,1:2)); + %% +% deviation = deviation_violation_iter_plot(mpc_split, xval, logg, names, xsol_aladin); + + +%% solve opf problem + + + % generate distributed problem problem = generate_distributed_opf_for_aladin(mpc_split, names, 'feasibility'); + +% +% option = AladinOption; +% option.iter_max = 15; +% option.tol = 1e-8; +% option.mu0 = 1e3; +% option.rho0 = 1e2; +% option.nlp = NLPoption; +% option.nlp.solver = 'casadi'; +% option.nlp.iter_display = true; +% option.nlp.active_set = true; +% option.qp = QPoption; +% % option.qp.regularization_hess = true; +% % option.qp.solver = 'lsqminnorm'; +% % option.qp.solver = 'lsqlin'; +% option.qp.solver = 'casadi'; +% +% +% +% +% for i = 1 : length(problem.AA) +% local_funs = originalFuns(problem.locFuns.ffi{i}, [], [], problem.AA{i}, [], [], problem.locFuns.ggi{i}, [], problem.locFuns.hhi{i}, []); +% nlps(i) = localNLP(local_funs,option.nlp,problem.llbx{i},problem.uubx{i}); +% end +% [xopt,logg] = run_aladin_algorithm(nlps,problem.zz0,problem.lam0,horzcat(problem.AA(:)),problem.b,option); +% +% +% +% +% for i = 1:Nregion +% +% local_funs = originalFuns(fi{i}, [], [], AA{i}, [], [], con_eq{i}, [], con_ineq{i}, []); +% +% nlps(i) = localNLP(local_funs,option.nlp,lbx{i},ubx{i}); +% +% end +% +% [xopt,logg] = run_aladin_algorithm(nlps,x0,lam0,A,b,option); + + + problem.solver = 'fmincon'; % [xval, xval_stacked] = validate_distributed_problem_formulation(problem, mpc_split, names); % solve distributed ALADIN -opts = struct('maxiter',50); +opts = struct('maxiter',50, 'solveQP','quadprog'); opts.reg ='false'; opts.rho0= 1e2; +opts.maxiter = 50; [xsol_aladin, xsol_stack_aladin, mpc_sol_aladin, logg] = solve_distributed_problem_with_aladin(mpc_split, problem, names, opts); \ No newline at end of file diff --git a/00_use-case/mini_example.m b/00_use-case/mini_example.m new file mode 100644 index 0000000..ceb942f --- /dev/null +++ b/00_use-case/mini_example.m @@ -0,0 +1,34 @@ +mpc = loadcase('case3_personalized'); +results_pf = runpf('case3_personalized'); +results_opf = runopf('case3_personalized'); + +[f, df, d2f] = opf_costfcn(results_opf.x, results_opf.om); +[h, g, dh, dg] = opf_consfcn(results_opf.x, results_opf.om); + +names = generate_name_struct(); +mpc.fields_to_merge = {'bus', 'gen', 'branch', 'gencost'}; + +mpc_temp = loadcase('case3_personalized'); +mpc.trans = mpc_temp; +mpc.dist = { mpc_temp;}; + +mpc.connection_array = [ 1 2 3 3]; + +fields_to_merge = mpc.fields_to_merge; +connection_array = mpc.connection_array; + + +trafo_params.r = 0; +trafo_params.x = 0.00623; +trafo_params.b = 0; +trafo_params.ratio = 0.985; +trafo_params.angle = 0; + +conn = build_connection_table(connection_array, trafo_params); +Nconnections = height(conn); + +%% main +% case-file-generator +mpc_merge = run_case_file_generator(mpc.trans, mpc.dist, conn, fields_to_merge, names); +mpc_split = run_case_file_splitter(mpc_merge, conn, names); + diff --git a/00_use-case/mpc_merge.m b/00_use-case/mpc_merge.m index 9fb853c..28bfbe4 100644 --- a/00_use-case/mpc_merge.m +++ b/00_use-case/mpc_merge.m @@ -20,12 +20,12 @@ 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; - 10 1 0 0 0 0 1 1.1 0 230 1 1.1 0.9; - 11 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 11 2 0 0 0 0 1 1 0 230 1 1.1 0.9; 12 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 13 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 14 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; - 15 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 15 1 0 0 0 0 1 1 0 230 1 1.1 0.9; ]; %% generator data @@ -35,39 +35,40 @@ 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; - 5 466.51 0 450 -450 1.1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; + 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 11 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 11 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 13 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 14 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; - 15 466.51 0 450 -450 1.1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; ]; %% branch data % fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax mpc.branch = [ - 1 2 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 1 2 0.00281 0.0281 0.00712 0 0 0 0 0 1 -360 360; 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; - 4 5 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; - 6 7 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 4 5 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 6 7 0.00281 0.0281 0.00712 0 0 0 0 0 1 -360 360; 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; - 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 9 10 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; - 11 12 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 11 12 0.00281 0.0281 0.00712 0 0 0 0 0 1 -360 360; 11 14 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; 11 15 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; 12 13 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; 13 14 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; - 14 15 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; - 9 11 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 14 15 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 6 15 0 0.00623 0 0 0 0 0.985 0 1 0 0; ]; %%----- OPF Data -----%% @@ -84,7 +85,8 @@ 2 0 0 2 15 0; 2 0 0 2 30 0; 2 0 0 2 40 0; + 2 0 0 2 14 0; + 2 0 0 2 15 0; 2 0 0 2 30 0; 2 0 0 2 40 0; - 2 0 0 2 10 0; ]; diff --git a/00_use-case/mpc_merge_split.m b/00_use-case/mpc_merge_split.m index d911eeb..47dc320 100644 --- a/00_use-case/mpc_merge_split.m +++ b/00_use-case/mpc_merge_split.m @@ -20,12 +20,12 @@ 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; - 10 1 0 0 0 0 1 1.1 0 230 1 1.1 0.9; - 11 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 11 2 0 0 0 0 1 1 0 230 1 1.1 0.9; 12 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 13 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 14 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; - 15 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 15 1 0 0 0 0 1 1 0 230 1 1.1 0.9; ]; %% generator data @@ -35,39 +35,40 @@ 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; - 5 466.51 0 450 -450 1.1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; + 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 11 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 11 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 13 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 14 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; - 15 466.51 0 450 -450 1.1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; ]; %% branch data % fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax mpc.branch = [ - 1 2 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 1 2 0.00281 0.0281 0.00712 0 0 0 0 0 1 -360 360; 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; - 4 5 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; - 6 7 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 4 5 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 6 7 0.00281 0.0281 0.00712 0 0 0 0 0 1 -360 360; 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; - 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 9 10 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; - 11 12 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 11 12 0.00281 0.0281 0.00712 0 0 0 0 0 1 -360 360; 11 14 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; 11 15 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; 12 13 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; 13 14 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; - 14 15 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; - 9 11 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 14 15 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 6 15 0 0.00623 0 0 0 0 0.985 0 1 0 0; ]; %%----- OPF Data -----%% @@ -84,7 +85,8 @@ 2 0 0 2 15 0; 2 0 0 2 30 0; 2 0 0 2 40 0; + 2 0 0 2 14 0; + 2 0 0 2 15 0; 2 0 0 2 30 0; 2 0 0 2 40 0; - 2 0 0 2 10 0; ]; diff --git a/00_use-case/test_functions.m b/00_use-case/test_functions.m new file mode 100644 index 0000000..9e22208 --- /dev/null +++ b/00_use-case/test_functions.m @@ -0,0 +1,37 @@ +results_pf = runpf('case3_personalized'); +results_opf = runopf('case3_personalized'); + +[f, df, d2f] = opf_costfcn(results_opf.x, results_opf.om); + +mpc = loadcase('case3_personalized'); +names = generate_name_struct(); + +[mpc_opf, om, local_buses_to_remove, mpopt] = prepare_case_file(mpc, names); + + + + + +[constraint_function, ~] = build_local_constraint_function(mpc_opf, om, mpopt); +%% cost function + cost gradient +[cost, grad_cost, hess_cost] = build_local_cost_function(om); +%% equalities + Jacobian +eq = @(x)get_eq_cons(x, constraint_function, inds); +eq_jac = @(x)get_eq_cons_jacobian(x, constraint_function, inds); +%% inequalities + Jacobian +[ineq, ineq_jac] = build_local_inequalities(constraint_function); + +pf = eq(results_opf.x); +h = ineq(results_opf.x); + +%% equalities +function g = get_eq_cons(x, gh_fcn, inds) + [~,g,~,~] = gh_fcn(x); + % remove power flow equations for all copy buses + g(inds) = []; +end + +function dg = get_eq_cons_jacobian(x, gh_fcn, inds) + [~,~,~,dg] = gh_fcn(x); + dg(:, inds) = []; +end diff --git a/00_use-case/test_merged_5bus_systems.m b/00_use-case/test_merged_5bus_systems.m new file mode 100644 index 0000000..5ed4267 --- /dev/null +++ b/00_use-case/test_merged_5bus_systems.m @@ -0,0 +1,207 @@ + +clc +clear +close all + +% branch idx +[F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ... +TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ... +ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch; +% gen idx + +names = generate_name_struct(); +mpc.fields_to_merge = {'bus', 'gen', 'branch', 'gencost'}; + +mpc_temp = loadcase('case5'); + +% mpc_temp.branch(:, RATE_A) = 0; +% mpc_temp.branch(:, RATE_B) = 0; +% mpc_temp.branch(:, RATE_C) = 0; + +mpc.trans = mpc_temp; +mpc.dist = { mpc_temp}; + +mpc.connection_array = [ 1 2 1 5]; +% + mpc.trans = mpc_temp; + mpc.dist = { mpc_temp; + mpc_temp + }; + + mpc.connection_array = [ 1 2 1 5; + 2 3 1 5]; + + +% +% mpc.trans = ext2int(loadcase('case9')); +% mpc.dist = { ext2int(loadcase('case9'))}; +% % region 1 - region 2 +% mpc.connection_array = [ +% % region 1 - region 2 +% 1 2 2 1 +% +% ]; + +% +% +% mpc.trans = ext2int(loadcase('case9')); +% mpc.dist = { ext2int(loadcase('case9')); +% ext2int(loadcase('case9')); +% ext2int(loadcase('case9'))}; +% % region 1 - region 2 +% mpc.connection_array = [ +% % region 1 - region 2 +% 1 2 2 1 +% 1 3 1 1 +% 1 4 3 1 +% +% ]; + +% connected a from generator to a to generator with much higher Pmax +%% + +% [mpc_trans,mpc_dist] = gen_shift_key(mpc, gsk); % P = P * 0.2 +fields_to_merge = mpc.fields_to_merge; +connection_array = mpc.connection_array; + + +trafo_params.r = 0; +trafo_params.x = 0.00623; +trafo_params.b = 0; +trafo_params.ratio = 0.985; +trafo_params.angle = 0; + +conn = build_connection_table(connection_array, trafo_params); +Nconnections = height(conn); + +%% main +% case-file-generator +mpc_merge = run_case_file_generator(mpc.trans, mpc.dist, conn, fields_to_merge, names); +mpc_split = run_case_file_splitter(mpc_merge, conn, names); + +split_file_1 = mpc_split.split_case_files{1, 1}; +split_file_2 = mpc_split.split_case_files{2, 1}; + +runopf(mpc_merge); + +problem = generate_distributed_opf_for_aladin(mpc_split, names, 'feasibility'); + +mpopt = mpoption('out.lim.all', 2, 'opf.return_raw_der', 1); +result_opf = runopf(mpc_merge, mpopt); +% [f, df, d2f] = opf_costfcn(result_opf.x, result_opf.om); +% [h, g, dh, dg] = opf_consfcn(result_opf.x, result_opf.om); +% +% x = result_opf.x; +% x1 = vertcat(x(1:5), x(10), x(11:15), x(20), x(21:25), x(30:34)); +% x1_test = get_local_variable_from_global_objective_variable(x, 1, mpc_split, names); +% x2 = vertcat(x(6:10), x(1), x(16:20), x(11), x(26:29), x(35:38)); +% x2_test = get_local_variable_from_global_objective_variable(x, 2, mpc_split, names); +% x3_test = get_local_variable_from_global_objective_variable(x, 3, mpc_split, names); +% +% fx1 = problem.locFuns.ffi{1}(x1_test); +% fx2 = problem.locFuns.ffi{2}(x2_test); +% fx3 = problem.locFuns.ffi{3}(x3_test); +% +% diff_f = result_opf.f - (fx1 + fx2 + fx3); +% +% gx1 = problem.locFuns.ggi{1}(x1_test); +% gx2 = problem.locFuns.ggi{2}(x2_test); +% gx3 = problem.locFuns.ggi{3}(x3_test); +% +% hx1 = problem.locFuns.hhi{1}(x1_test); +% hx2 = problem.locFuns.hhi{2}(x2_test); +% hx3 = problem.locFuns.hhi{3}(x3_test); +% +% consensus = problem.AA{1}*x1_test + problem.AA{2}*x2_test + problem.AA{3}*x3_test; +%% ALADIN-alpha +% +% problem.solver = 'fmincon'; +% % [xval, xval_stacked] = validate_distributed_problem_formulation(problem, mpc_split, names); +% +% % solve distributed ALADIN +% +% opts = struct('maxiter',50, 'solveQP','ipopt'); +% opts.reg ='false'; +% opts.rho0= 1e2; +% opts.maxiter = 20; +% [xsol_aladin, xsol_stack_aladin, mpc_sol_aladin, logg] = solve_distributed_problem_with_aladin(mpc_split, problem, names, opts); +%% ALADIN-OOP +option = AladinOption; +option.iter_max = 20; +option.tol = 1e-8; +option.mu0 = 1e4; +option.rho0 = 1e2; +option.nlp = NLPoption; +option.nlp.solver = 'fmincon'; +option.nlp.iter_display = true; +option.nlp.active_set = true; +option.qp = QPoption; +% option.qp.regularization_hess = true; +% option.qp.solver = 'lsqminnorm'; +% option.qp.solver = 'lsqlin'; +option.qp.solver = 'casadi'; + + + + +for i = 1 : length(problem.AA) + local_funs = originalFuns(problem.locFuns.ffi{i}, problem.sens.gg{i}, problem.sens.HH{i}, problem.AA{i}, [], [], problem.locFuns.ggi{i}, problem.sens.JJac_eq{i}, problem.locFuns.hhi{i}, problem.sens.JJac_ineq{i}); + nlps(i) = localNLP(local_funs,option.nlp,problem.llbx{i},problem.uubx{i}); +end + +[xopt,logg] = run_aladin_algorithm(nlps,problem.zz0,problem.lam0,horzcat(problem.AA{:}),problem.b,option); +%% validation + +% compare ALADIN_Alex with ALADIN_OOP +%diff_aladin_alpha_oop = xopt - xsol_aladin; + +% compare ALADIN_Alex with run_opf solution +n_regions = size(mpc_merge.regions, 2); +x = cell(n_regions, 1); +x_ref = []; +for i = 1 : n_regions + x{i, 1} = get_local_variable_from_global_objective_variable(result_opf.x, i, mpc_split, names); + x_ref = vertcat(x_ref, x{i, 1}); +end +% diff_aladin_alpha_runopf = x_ref - xsol_aladin; + +% compare ALADIN_OOP with run_opf solution +diff_aladin_oop_runopf = x_ref - xopt; + + +%% validation old +opts = mpoption; +% fix deviation +opts.opf.violation = 1e-8; +mpc_merge = runopf(mpc_merge,opts); +% initialize local NLP problem by extracting data from rapidPF problem +Nregion = n_regions; +baseMVA = 100; +nlps(Nregion,1) = localNLP; +mpc_split = run_case_file_splitter(mpc_merge, conn, names); +mpc = mpc_split; +GEN_BUS = 1; +VA = 9; +VM =8; +PG=2; +QG=3; +for i = 1:Nregion + mpc_local = mpc_split.split_case_files{i}; + gen_idx = ismember(mpc_local.regions,mpc_local.gen(:,GEN_BUS)); + gen_bus_entries = find(gen_idx); % entries of bus data + + gen_bus_global = mpc_local.bus(gen_bus_entries,GEN_BUS); + gencost_idx_global = find(ismember(mpc.gen(:,GEN_BUS), gen_bus_global)); + Vang_opt = mpc_local.bus(:,VA)/180*pi; + Vmag_opt = mpc_local.bus(:,VM); +% gencost haven't been splitted - complicated - need to be simplified + Pg_opt = mpc.gen(gencost_idx_global,PG)/baseMVA; + Qg_opt = mpc.gen(gencost_idx_global,QG)/baseMVA; + xsol{i} = stack_state(Vang_opt,Vmag_opt,Pg_opt,Qg_opt); +end +XOPT = vertcat(xsol{:}); +logg.plot_distance(XOPT); +dx = xopt-XOPT +dx_norm = norm(dx,inf) + +% [xsol_aladin, xsol_stack_aladin, mpc_sol_aladin, logg] = solve_distributed_problem_with_aladin(mpc_split, problem, names, opts); \ No newline at end of file diff --git a/00_use-case/testscript.m b/00_use-case/testscript.m new file mode 100644 index 0000000..607114e --- /dev/null +++ b/00_use-case/testscript.m @@ -0,0 +1,80 @@ +mpc = loadcase('case3_personalized'); +results_pf = runpf('case3_personalized'); +results_opf = runopf('case3_personalized'); + +[f, df, d2f] = opf_costfcn(results_opf.x, results_opf.om); +[h, g, dh, dg] = opf_consfcn(results_opf.x, results_opf.om); + + +%%%%%%%%%%%%%% + +mpc = loadcase('case5'); +results_pf = runpf('case5'); +results_opf = runopf('case5'); + +[f, df, d2f] = opf_costfcn(results_opf.x, results_opf.om); +[g, h, dg, dh] = opf_consfcn(results_opf.x, results_opf.om); + +%%%%%%%%%%%%%%% + +%% setup +names = generate_name_struct(); +mpc.fields_to_merge = {'bus', 'gen', 'branch', 'gencost'}; + +mpc_temp = loadcase('case5'); + +mpc.trans = mpc_temp; +mpc.dist = { mpc_temp}; + +mpc.connection_array = [ 1 2 1 5]; + + +% connected a from generator to a to generator with much higher Pmax +%% + +% [mpc_trans,mpc_dist] = gen_shift_key(mpc, gsk); % P = P * 0.2 +fields_to_merge = mpc.fields_to_merge; +connection_array = mpc.connection_array; + + +trafo_params.r = 0; +trafo_params.x = 0.00623; +trafo_params.b = 0; +trafo_params.ratio = 0.985; +trafo_params.angle = 0; + +conn = build_connection_table(connection_array, trafo_params); +Nconnections = height(conn); + +%% main +% case-file-generator +mpc_merge = run_case_file_generator(mpc.trans, mpc.dist, conn, fields_to_merge, names); +mpc_split = run_case_file_splitter(mpc_merge, conn, names); + +split_file_1 = mpc_split.split_case_files{1, 1}; +split_file_2 = mpc_split.split_case_files{2, 1}; + +problem = generate_distributed_opf_for_aladin(mpc_split, names, 'feasibility'); + +mpopt = mpoption('out.lim.all', 2, 'opf.return_raw_der', 1); +result_opf = runopf(mpc_merge, mpopt); +[f, df, d2f] = opf_costfcn(result_opf.x, results_simple.om); +[h, g, dh, dg] = opf_consfcn(results_opf.x, results_simple.om); + +x = result_opf.x; +x1 = vertcat(x(1:5), x(10), x(11:15), x(20), x(21:25), x(30:34)); +x2 = vertcat(x(1), x(6:10), x(11), x(16:20), x(26:29), x(35:38)); + +fx1 = problem.locFuns.ffi{1}(x1); +fx2 = problem.locFuns.ffi{2}(x2); + +diff_f = result_opf.f - (fx1 + fx2); + +gx1 = problem.locFuns.ggi{1}(x1); +gx2 = problem.locFuns.ggi{2}(x2); + +mpopt = mpoption('out.lim.all', 2, 'opf.return_raw_der', 1); +results_simple = runopf('case5', mpopt); + +[f, df, d2f] = opf_costfcn(results_simple.x, results_simple.om); +[h, g, dh, dg] = opf_consfcn(results_simple.x, results_simple.om); diff --git a/01_generator/mpc_merge.m b/01_generator/mpc_merge.m new file mode 100644 index 0000000..eb5c13a --- /dev/null +++ b/01_generator/mpc_merge.m @@ -0,0 +1,90 @@ +function mpc = mpc_merge +%MPC_MERGE + +%% MATPOWER Case Format : Version 2 +mpc.version = '2'; + +%%----- Power Flow Data -----%% +%% system MVA base +mpc.baseMVA = 100; + +%% bus data +% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin +mpc.bus = [ + 1 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 2 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 3 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 4 3 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 5 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 6 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 11 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 12 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 13 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 14 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 15 2 0 0 0 0 1 1 0 230 1 1.1 0.9; +]; + +%% generator data +% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf +mpc.gen = [ + 1 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; + 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 13 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 14 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 15 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; +]; + +%% branch data +% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax +mpc.branch = [ + 1 2 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 4 5 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 6 7 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 11 12 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 11 14 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 11 15 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 12 13 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 13 14 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 14 15 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 9 11 0 0.00623 0 0 0 0 0.985 0 1 0 0; +]; + +%%----- OPF Data -----%% +%% generator cost data +% 1 startup shutdown n x1 y1 ... xn yn +% 2 startup shutdown n c(n-1) ... c0 +mpc.gencost = [ + 2 0 0 3 14 0.278498219 0.278498219; + 2 0 0 3 15 0.278498219 0.278498219; + 2 0 0 3 30 0.278498219 0.278498219; + 2 0 0 3 40 0.278498219 0.278498219; + 2 0 0 3 10 0.278498219 0.278498219; + 2 0 0 3 14 0.278498219 0.278498219; + 2 0 0 3 15 0.278498219 0.278498219; + 2 0 0 3 30 0.278498219 0.278498219; + 2 0 0 3 40 0.278498219 0.278498219; + 2 0 0 3 30 0.278498219 0.278498219; + 2 0 0 3 40 0.278498219 0.278498219; + 2 0 0 3 10 0.278498219 0.278498219; +]; diff --git a/01_generator/mpc_merge_split.m b/01_generator/mpc_merge_split.m new file mode 100644 index 0000000..6c6319d --- /dev/null +++ b/01_generator/mpc_merge_split.m @@ -0,0 +1,90 @@ +function mpc = mpc_merge_split +%MPC_MERGE_SPLIT + +%% MATPOWER Case Format : Version 2 +mpc.version = '2'; + +%%----- Power Flow Data -----%% +%% system MVA base +mpc.baseMVA = 100; + +%% bus data +% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin +mpc.bus = [ + 1 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 2 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 3 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 4 3 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 5 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 6 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 11 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 12 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 13 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 14 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 15 2 0 0 0 0 1 1 0 230 1 1.1 0.9; +]; + +%% generator data +% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf +mpc.gen = [ + 1 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; + 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 13 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 14 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 15 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; +]; + +%% branch data +% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax +mpc.branch = [ + 1 2 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 4 5 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 6 7 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 11 12 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 11 14 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 11 15 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 12 13 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 13 14 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 14 15 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 9 11 0 0.00623 0 0 0 0 0.985 0 1 0 0; +]; + +%%----- OPF Data -----%% +%% generator cost data +% 1 startup shutdown n x1 y1 ... xn yn +% 2 startup shutdown n c(n-1) ... c0 +mpc.gencost = [ + 2 0 0 3 14 0.278498219 0.278498219; + 2 0 0 3 15 0.278498219 0.278498219; + 2 0 0 3 30 0.278498219 0.278498219; + 2 0 0 3 40 0.278498219 0.278498219; + 2 0 0 3 10 0.278498219 0.278498219; + 2 0 0 3 14 0.278498219 0.278498219; + 2 0 0 3 15 0.278498219 0.278498219; + 2 0 0 3 30 0.278498219 0.278498219; + 2 0 0 3 40 0.278498219 0.278498219; + 2 0 0 3 30 0.278498219 0.278498219; + 2 0 0 3 40 0.278498219 0.278498219; + 2 0 0 3 10 0.278498219 0.278498219; +]; diff --git a/02_splitter/mpc_merge.m b/02_splitter/mpc_merge.m new file mode 100644 index 0000000..00aa94c --- /dev/null +++ b/02_splitter/mpc_merge.m @@ -0,0 +1,72 @@ +function mpc = mpc_merge +%MPC_MERGE + +%% MATPOWER Case Format : Version 2 +mpc.version = '2'; + +%%----- Power Flow Data -----%% +%% system MVA base +mpc.baseMVA = 100; + +%% bus data +% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin +mpc.bus = [ + 1 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 2 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 3 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 4 3 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 5 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 6 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; +]; + +%% generator data +% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf +mpc.gen = [ + 1 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; + 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; +]; + +%% branch data +% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax +mpc.branch = [ + 1 2 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 4 5 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 6 7 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; +]; + +%%----- OPF Data -----%% +%% generator cost data +% 1 startup shutdown n x1 y1 ... xn yn +% 2 startup shutdown n c(n-1) ... c0 +mpc.gencost = [ + 2 0 0 2 14 0; + 2 0 0 2 15 0; + 2 0 0 2 30 0; + 2 0 0 2 40 0; + 2 0 0 2 10 0; + 2 0 0 2 14 0; + 2 0 0 2 15 0; + 2 0 0 2 30 0; + 2 0 0 2 40 0; +]; diff --git a/02_splitter/mpc_merge_split.m b/02_splitter/mpc_merge_split.m new file mode 100644 index 0000000..303a74f --- /dev/null +++ b/02_splitter/mpc_merge_split.m @@ -0,0 +1,72 @@ +function mpc = mpc_merge_split +%MPC_MERGE_SPLIT + +%% MATPOWER Case Format : Version 2 +mpc.version = '2'; + +%%----- Power Flow Data -----%% +%% system MVA base +mpc.baseMVA = 100; + +%% bus data +% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin +mpc.bus = [ + 1 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 2 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 3 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 4 3 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 5 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 6 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; +]; + +%% generator data +% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf +mpc.gen = [ + 1 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; + 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; +]; + +%% branch data +% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax +mpc.branch = [ + 1 2 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 4 5 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 6 7 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; +]; + +%%----- OPF Data -----%% +%% generator cost data +% 1 startup shutdown n x1 y1 ... xn yn +% 2 startup shutdown n c(n-1) ... c0 +mpc.gencost = [ + 2 0 0 2 14 0; + 2 0 0 2 15 0; + 2 0 0 2 30 0; + 2 0 0 2 40 0; + 2 0 0 2 10 0; + 2 0 0 2 14 0; + 2 0 0 2 15 0; + 2 0 0 2 30 0; + 2 0 0 2 40 0; +]; diff --git a/03_parser/auxfuns/create_consensus_matrices_opf.m b/03_parser/auxfuns/create_consensus_matrices_opf.m index 36038eb..54c91e1 100644 --- a/03_parser/auxfuns/create_consensus_matrices_opf.m +++ b/03_parser/auxfuns/create_consensus_matrices_opf.m @@ -1,21 +1,18 @@ function A = create_consensus_matrices_opf(tab, number_of_buses_in_region, number_of_generators_in_region) % create_consensus_matrices_opf % -% `copy the declaration of the function in here (leave the ticks unchanged)` +% `A = create_consensus_matrices_opf(tab, number_of_buses_in_region, number_of_generators_in_region)` % -% _describe what the function does in the following line_ +% _creates optimal power flow consensus matrix for distributed optization_ % -% # Markdown formatting is supported -% Equations are possible to, e.g $a^2 + b^2 = c^2$. -% So are lists: -% - item 1 -% - item 2 -% ```matlab -% function y = square(x) -% x^2 -% end -% ``` -% See also: [run_case_file_splitter](run_case_file_splitter.md) +% INPUT: +% - $\texttt{tab}$ connection table +% - $\texttt{number\_of\_buses\_in\_region}$ +% - $\texttt{number\_of\_generators\_in\_region}$ +% +% OUTPUT: +% - $\texttt{A}$ cell with consensus matrices + assert(istable(tab), 'expecting tab to be a table.'); assert(mod(height(tab), 2) == 0, 'inconsistent number of consensus restrictions.') assert(numel(number_of_buses_in_region) == numel(number_of_generators_in_region), 'inconsistent dimensions'); diff --git a/03_parser/auxfuns/create_state_mp.m b/03_parser/auxfuns/create_state_mp.m index 7e234ab..80d0c43 100644 --- a/03_parser/auxfuns/create_state_mp.m +++ b/03_parser/auxfuns/create_state_mp.m @@ -1,21 +1,21 @@ function [vang, vmag, pg, qg] = create_state_mp(postfix, Nbus, Ngen) % create_state % -% `copy the declaration of the function in here (leave the ticks unchanged)` +% `[vang, vmag, pg, qg] = create_state_mp(postfix, Nbus, Ngen)` % -% _describe what the function does in the following line_ +% _gives an abstract representation of the optimization variable used in MATPOWER_ % -% # Markdown formatting is supported -% Equations are possible to, e.g $a^2 + b^2 = c^2$. -% So are lists: -% - item 1 -% - item 2 -% ```matlab -% function y = square(x) -% x^2 -% end -% ``` -% See also: [run_case_file_splitter](run_case_file_splitter.md) +% Input +% - $\ŧexttt{postfix}$ either $\textt{core}$ or $\texttt{copy}$ postfix +% for symbolic variable +% - $\texttt{Nbus}$ number of $\texttt{postfix}$ - buses in splitted +% system +% - $\texttt{Ngen}$ number of generators in splitted system +% +% Output +% - $\texttt{[vang, vm, Pq, Qg]}$ symbolic voltage entries for Nbus bus entries +% and real and reactive power entries for Ngen generators + vang = sym(strcat('Va_', postfix, '_'), [Nbus 1], 'real'); vmag = sym(strcat('Vm_', postfix, '_'), [Nbus 1], 'real'); pg = sym(strcat('Pg_', postfix, '_'), [Ngen 1], 'real'); diff --git a/03_parser/auxfuns/modelfuns/build_local_opf.m b/03_parser/auxfuns/modelfuns/build_local_opf.m index fc5081e..4621c6d 100644 --- a/03_parser/auxfuns/modelfuns/build_local_opf.m +++ b/03_parser/auxfuns/modelfuns/build_local_opf.m @@ -1,42 +1,53 @@ function [cost, ineq, eq, x0, grad_cost, eq_jac, ineq_jac, lagrangian_hessian, state, dims, lb, ub] = build_local_opf(mpc, names, postfix) % build_local_opf % -% `copy the declaration of the function in here (leave the ticks unchanged)` +% `[cost, ineq, eq, x0, grad_cost, eq_jac, ineq_jac, lagrangian_hessian, state, dims, lb, ub] = build_local_opf(mpc, names, postfix)` % -% _describe what the function does in the following line_ +% _extracts the local functions and information needed for opf_ % -% # Markdown formatting is supported -% Equations are possible to, e.g $a^2 + b^2 = c^2$. -% So are lists: -% - item 1 -% - item 2 -% ```matlab -% function y = square(x) -% x^2 -% end -% ``` -% See also: [run_case_file_splitter](run_case_file_splitter.md) +% INPUT: +% - $\texttt{mpc}$ splitted full casefile +% - $\texttt{names}$ struct of names corresponding to the fields +% of mpc +% - $\ŧexttt{postfix}$ index of subsystem +% OUTPUT: +% - $\texttt{cost}$ scalar local cost function +% - $\texttt{ineq}$ vector of equality constraint functions +% - $\texttt{eq}$ vector of inequality constraint functions +% - $\texttt{x0}$ intial condition of x +% - $\texttt{grad_cost}$ gradient of cost function +% - $\texttt{eq_jac}$ jacobian of eqality contraints +% - $\texttt{ineq_jac}$ jacobian of inequality constraints +% - $\texttt{lagrangian_hessian}$ hesisan of reduced lagrange +% function +% - $\texttt{state}$ representation of objective ariable +% - $\texttt{dims}$ struct of local dimensions +% - $\texttt{lb}$ lower bound of x +% - $\texttt{ub}$ upper bond of x %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% The following code (implicitly) assumes that the copy buses are %%% always at the end of the bus numbering. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% preparation [mpc_opf, om, local_buses_to_remove, mpopt] = prepare_case_file(mpc, names); - [constraint_function, ~] = build_local_constraint_function(mpc_opf, om, mpopt); + [constraint_function, Lxx] = build_local_constraint_function(mpc_opf, om, mpopt); %% cost function + cost gradient [cost, grad_cost, hess_cost] = build_local_cost_function(om); %% equalities + Jacobian - [eq, eq_jac] = build_local_equalities(constraint_function, local_buses_to_remove); + total_number_of_nodes = length(mpc.connections_with_aux_nodes); + [eq, eq_jac] = build_local_equalities(constraint_function, local_buses_to_remove, total_number_of_nodes); %% inequalities + Jacobian [ineq, ineq_jac] = build_local_inequalities(constraint_function); %% symbolic state state = build_local_state(mpc_opf, names, postfix); %% hessian of Lagrangian - [~, ~, lagrangian_hessian] = build_local_lagrangian_function(cost, grad_cost, eq, eq_jac, ineq, ineq_jac); + [~, ~, lagrangian_hessian] = build_local_lagrangian_function(cost, grad_cost, eq, eq_jac, ineq, ineq_jac, state); %% initial conditions x0 = build_local_initial_conditions(om); %% lower and upper bounds [lb, ub] = build_local_bounds(om); %% dimensions of state, equalities, inequalities - dims = build_local_dimensions(mpc_opf, eq, ineq); + dims = build_local_dimensions(mpc_opf, eq, ineq, local_buses_to_remove); + %% for testing + dims.ineq = []; end diff --git a/03_parser/auxfuns/modelfuns/mpc_merge.m b/03_parser/auxfuns/modelfuns/mpc_merge.m index 00aa94c..330a5f2 100644 --- a/03_parser/auxfuns/modelfuns/mpc_merge.m +++ b/03_parser/auxfuns/modelfuns/mpc_merge.m @@ -21,6 +21,11 @@ 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 11 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 12 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 13 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 14 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 15 2 0 0 0 0 1 1 0 230 1 1.1 0.9; ]; %% generator data @@ -35,6 +40,9 @@ 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 13 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 14 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 15 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; ]; %% branch data @@ -53,6 +61,13 @@ 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 11 12 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 11 14 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 11 15 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 12 13 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 13 14 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 14 15 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 9 11 0 0.00623 0 0 0 0 0.985 0 1 0 0; ]; %%----- OPF Data -----%% @@ -60,13 +75,16 @@ % 1 startup shutdown n x1 y1 ... xn yn % 2 startup shutdown n c(n-1) ... c0 mpc.gencost = [ - 2 0 0 2 14 0; - 2 0 0 2 15 0; - 2 0 0 2 30 0; - 2 0 0 2 40 0; - 2 0 0 2 10 0; - 2 0 0 2 14 0; - 2 0 0 2 15 0; - 2 0 0 2 30 0; - 2 0 0 2 40 0; + 2 0 0 3 14 0.157613082 0.157613082; + 2 0 0 3 15 0.157613082 0.157613082; + 2 0 0 3 30 0.157613082 0.157613082; + 2 0 0 3 40 0.157613082 0.157613082; + 2 0 0 3 10 0.157613082 0.157613082; + 2 0 0 3 14 0.157613082 0.157613082; + 2 0 0 3 15 0.157613082 0.157613082; + 2 0 0 3 30 0.157613082 0.157613082; + 2 0 0 3 40 0.157613082 0.157613082; + 2 0 0 3 30 0.157613082 0.157613082; + 2 0 0 3 40 0.157613082 0.157613082; + 2 0 0 3 10 0.157613082 0.157613082; ]; diff --git a/03_parser/auxfuns/modelfuns/mpc_merge_split.m b/03_parser/auxfuns/modelfuns/mpc_merge_split.m index 303a74f..6b47d6a 100644 --- a/03_parser/auxfuns/modelfuns/mpc_merge_split.m +++ b/03_parser/auxfuns/modelfuns/mpc_merge_split.m @@ -21,6 +21,11 @@ 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 11 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 12 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 13 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 14 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 15 2 0 0 0 0 1 1 0 230 1 1.1 0.9; ]; %% generator data @@ -35,6 +40,9 @@ 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 13 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 14 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 15 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; ]; %% branch data @@ -53,6 +61,13 @@ 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 11 12 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 11 14 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 11 15 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 12 13 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 13 14 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 14 15 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 9 11 0 0.00623 0 0 0 0 0.985 0 1 0 0; ]; %%----- OPF Data -----%% @@ -60,13 +75,16 @@ % 1 startup shutdown n x1 y1 ... xn yn % 2 startup shutdown n c(n-1) ... c0 mpc.gencost = [ - 2 0 0 2 14 0; - 2 0 0 2 15 0; - 2 0 0 2 30 0; - 2 0 0 2 40 0; - 2 0 0 2 10 0; - 2 0 0 2 14 0; - 2 0 0 2 15 0; - 2 0 0 2 30 0; - 2 0 0 2 40 0; + 2 0 0 3 14 0.157613082 0.157613082; + 2 0 0 3 15 0.157613082 0.157613082; + 2 0 0 3 30 0.157613082 0.157613082; + 2 0 0 3 40 0.157613082 0.157613082; + 2 0 0 3 10 0.157613082 0.157613082; + 2 0 0 3 14 0.157613082 0.157613082; + 2 0 0 3 15 0.157613082 0.157613082; + 2 0 0 3 30 0.157613082 0.157613082; + 2 0 0 3 40 0.157613082 0.157613082; + 2 0 0 3 30 0.157613082 0.157613082; + 2 0 0 3 40 0.157613082 0.157613082; + 2 0 0 3 10 0.157613082 0.157613082; ]; diff --git a/03_parser/auxfuns/mpc_merge.m b/03_parser/auxfuns/mpc_merge.m new file mode 100644 index 0000000..7fa34d0 --- /dev/null +++ b/03_parser/auxfuns/mpc_merge.m @@ -0,0 +1,92 @@ +function mpc = mpc_merge +%MPC_MERGE + +%% MATPOWER Case Format : Version 2 +mpc.version = '2'; + +%%----- Power Flow Data -----%% +%% system MVA base +mpc.baseMVA = 100; + +%% bus data +% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin +mpc.bus = [ + 1 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 2 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 3 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 4 3 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 5 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 6 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 11 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 12 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 13 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 14 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 15 1 0 0 0 0 1 1 0 230 1 1.1 0.9; +]; + +%% generator data +% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf +mpc.gen = [ + 1 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; + 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 11 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 11 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 13 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 14 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; +]; + +%% branch data +% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax +mpc.branch = [ + 1 2 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 4 5 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 6 7 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 11 12 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 11 14 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 11 15 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 12 13 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 13 14 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 14 15 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 6 15 0 0.00623 0 0 0 0 0.985 0 1 0 0; +]; + +%%----- OPF Data -----%% +%% generator cost data +% 1 startup shutdown n x1 y1 ... xn yn +% 2 startup shutdown n c(n-1) ... c0 +mpc.gencost = [ + 2 0 0 2 14 0; + 2 0 0 2 15 0; + 2 0 0 2 30 0; + 2 0 0 2 40 0; + 2 0 0 2 10 0; + 2 0 0 2 14 0; + 2 0 0 2 15 0; + 2 0 0 2 30 0; + 2 0 0 2 40 0; + 2 0 0 2 14 0; + 2 0 0 2 15 0; + 2 0 0 2 30 0; + 2 0 0 2 40 0; +]; diff --git a/03_parser/auxfuns/mpc_merge_split.m b/03_parser/auxfuns/mpc_merge_split.m new file mode 100644 index 0000000..209b807 --- /dev/null +++ b/03_parser/auxfuns/mpc_merge_split.m @@ -0,0 +1,92 @@ +function mpc = mpc_merge_split +%MPC_MERGE_SPLIT + +%% MATPOWER Case Format : Version 2 +mpc.version = '2'; + +%%----- Power Flow Data -----%% +%% system MVA base +mpc.baseMVA = 100; + +%% bus data +% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin +mpc.bus = [ + 1 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 2 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 3 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 4 3 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 5 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 6 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 11 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 12 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 13 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 14 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 15 1 0 0 0 0 1 1 0 230 1 1.1 0.9; +]; + +%% generator data +% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf +mpc.gen = [ + 1 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; + 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 11 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 11 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 13 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 14 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; +]; + +%% branch data +% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax +mpc.branch = [ + 1 2 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 4 5 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 6 7 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 11 12 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 11 14 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 11 15 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 12 13 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 13 14 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 14 15 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 6 15 0 0.00623 0 0 0 0 0.985 0 1 0 0; +]; + +%%----- OPF Data -----%% +%% generator cost data +% 1 startup shutdown n x1 y1 ... xn yn +% 2 startup shutdown n c(n-1) ... c0 +mpc.gencost = [ + 2 0 0 2 14 0; + 2 0 0 2 15 0; + 2 0 0 2 30 0; + 2 0 0 2 40 0; + 2 0 0 2 10 0; + 2 0 0 2 14 0; + 2 0 0 2 15 0; + 2 0 0 2 30 0; + 2 0 0 2 40 0; + 2 0 0 2 14 0; + 2 0 0 2 15 0; + 2 0 0 2 30 0; + 2 0 0 2 40 0; +]; diff --git a/03_parser/generate_distributed_opf.m b/03_parser/generate_distributed_opf.m index 2a455da..569d90b 100644 --- a/03_parser/generate_distributed_opf.m +++ b/03_parser/generate_distributed_opf.m @@ -1,24 +1,31 @@ -function problem = generate_distributed_opf(mpc, names, problem_type) +function problem = generate_distributed_opf(mpc, names, ~) % generate_distributed_opf % -% `copy the declaration of the function in here (leave the ticks unchanged)` +% `problem = generate_distributed_opf(mpc, names, ~)` % -% _describe what the function does in the following line_ +% _extracts the information from the splitted case files to run a distributed optimization with ALADIN_ % -% # Markdown formatting is supported -% Equations are possible to, e.g $a^2 + b^2 = c^2$. -% So are lists: -% - item 1 -% - item 2 -% ```matlab -% function y = square(x) -% x^2 -% end -% ``` -% See also: [run_case_file_splitter](run_case_file_splitter.md) - % extract Data from casefile +% INPUT: +% - $\texttt{mpc}$ struct with splitted case files +% - $\texttt{names}$ struct containing the names of the fields of +% $\texttt{mpc} +% Output: +% - $\texttt{problem}$ struct with the following fields +% - $\texttt{locFuns}$ struct with fields of cells for local costs, +% equality constraints, inequality constraints and dimensions +% - $\texttt{sens}$ struct with fields of cells for gradient of costs, +% jacobian of equality and inequality and the Hessian of the +% Lagrangian +% - $\texttt{zz0}$ cell of initial conditions +% - $\texttt{AA}$ cell of consensus matrices +% - $\texttt{state}$ cell that contans the local states +% - $\texttt{llbx}$ cell that contains the local lower bounds +% - $\texttt{uubx}$ cell that cotains the local upper bounds + + +% extract Data from casefile [N_regions, N_buses_in_regions, N_copy_buses_in_regions, ~] = get_relevant_information(mpc, names); - [costs, inequalities, equalities, xx0, grads, Jacs, Hessians, states, dims, lbs, ubs] = deal(cell(N_regions,1)); + [costs, inequalities, equalities, xx0, grads, Jacs, Jacs_eq, Jacs_ineq, Hessians, states, dims, lbs, ubs] = deal(cell(N_regions,1)); connection_table = mpc.(names.consensus); % set up the Ai's @@ -28,8 +35,16 @@ fprintf('Creating power flow problem for system %i...', i); [cost, inequality, equality, x0, grad, eq_jac, ineq_jac, Hessian, state, dim, lb, ub] = build_local_opf(mpc.(names.split){i}, names, num2str(i)); % combine Jacobians of inequalities and equalities in single Jacobian + % test i problem are the inqalitites Jac = @(x)[eq_jac(x), ineq_jac(x)]'; - [costs{i}, inequalities{i}, equalities{i}, xx0{i}, grads{i}, Jacs{i}, Hessians{i}, states{i}, dims{i}, lbs{i}, ubs{i}] = deal(cost, inequality, equality, x0, grad, Jac, Hessian, state, dim, lb, ub); + Jac_eq = @(x)eq_jac(x)'; + Jac_ineq = @(x)ineq_jac(x)'; +% %% only for testing +% Jac = @(x) [eq_jac(x)']; +% inequality = @(x) []; +% cost = @(x) 0; + %% + [costs{i}, inequalities{i}, equalities{i}, xx0{i}, grads{i}, Jacs{i}, Jacs_eq{i}, Jacs_ineq{i}, Hessians{i}, states{i}, dims{i}, lbs{i}, ubs{i}] = deal(cost, inequality, equality, x0, grad, Jac, Jac_eq, Jac_ineq, Hessian, state, dim, lb, ub); fprintf('done.\n') end @@ -44,6 +59,8 @@ problem.sens.gg = grads; problem.sens.JJac = Jacs; + problem.sens.JJac_eq = Jacs_eq; + problem.sens.JJac_ineq = Jacs_ineq; problem.sens.HH = Hessians; problem.zz0 = xx0; diff --git a/03_parser/mpc_merge.m b/03_parser/mpc_merge.m index 00aa94c..06ce239 100644 --- a/03_parser/mpc_merge.m +++ b/03_parser/mpc_merge.m @@ -40,18 +40,18 @@ %% branch data % fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax mpc.branch = [ - 1 2 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 1 2 0.00281 0.0281 0.00712 0 0 0 0 0 1 -360 360; 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; - 4 5 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; - 6 7 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 4 5 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 6 7 0.00281 0.0281 0.00712 0 0 0 0 0 1 -360 360; 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; - 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 9 10 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; ]; diff --git a/03_parser/mpc_merge_split.m b/03_parser/mpc_merge_split.m index 303a74f..39f565b 100644 --- a/03_parser/mpc_merge_split.m +++ b/03_parser/mpc_merge_split.m @@ -9,50 +9,50 @@ mpc.baseMVA = 100; %% bus data -% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin +% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin lam_P lam_Q mu_Vmax mu_Vmin mpc.bus = [ - 1 2 0 0 0 0 1 1 0 230 1 1.1 0.9; - 2 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; - 3 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; - 4 3 400 131.47 0 0 1 1 0 230 1 1.1 0.9; - 5 2 0 0 0 0 1 1 0 230 1 1.1 0.9; - 6 2 0 0 0 0 1 1 0 230 1 1.1 0.9; - 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; - 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; - 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; - 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 1 2 0 0 0 0 1 1.08492247 2.09607558 230 1 1.1 0.9 29.8339 0.0000 0.0000 0.0000; + 2 1 300 98.61 0 0 1 1.07444025 -0.161333044 230 1 1.1 0.9 30.0757 0.0430 0.0000 0.0000; + 3 2 300 98.61 0 0 1 1.08358895 0.513085573 230 1 1.1 0.9 30.0000 0.0000 0.0000 0.0000; + 4 3 400 131.47 0 0 1 1.08262907 0 230 1 1.1 0.9 30.0534 0.0000 0.0000 0.0000; + 5 2 0 0 0 0 1 1.08791679 3.25443171 230 1 1.1 0.9 29.7135 0.0000 0.0000 0.0000; + 6 2 0 0 0 0 1 1.0982527 0.992065913 230 1 1.1 0.9 29.8648 0.0000 0.0000 0.0000; + 7 1 300 98.61 0 0 1 1.08797688 -1.02594578 230 1 1.1 0.9 30.0812 0.0416 0.0000 0.0000; + 8 2 300 98.61 0 0 1 1.09699403 -0.29719505 230 1 1.1 0.9 30.0000 0.0000 0.0000 0.0000; + 9 2 400 131.47 0 0 1 1.09479564 -1.24884322 230 1 1.1 0.9 30.0995 0.0000 0.0000 0.0000; + 10 1 0 0 0 0 1 1.1 1.28086191 230 1 1.1 0.9 29.8337 -0.0108 320.3592 0.0000; ]; %% generator data -% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf +% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf mu_Pmax mu_Pmin mu_Qmax mu_Qmin mpc.gen = [ - 1 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; - 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; - 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; - 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; - 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; - 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; - 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; - 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; - 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 1 40 3.43105871 30 -30 1.08492247 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0 15.8339 0.0000 0.0000 0.0000; + 1 170 35.5624823 127.5 -127.5 1.08492247 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0 14.8339 0.0000 0.0000 0.0000; + 3 470.177037 176.3076 390 -390 1.08358895 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 0.0000; + 4 4.27028697e-08 148.49222 150 -150 1.08262907 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 9.9466 0.0000 0.0000; + 5 600 18.1841424 450 -450 1.08791679 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0 19.7135 0.0000 0.0000 0.0000; + 6 40 1.75262358 30 -30 1.0982527 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0 15.8648 0.0000 0.0000 0.0000; + 6 170 3.10464255 127.5 -127.5 1.0982527 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0 14.8648 0.0000 0.0000 0.0000; + 8 515.674602 176.684679 390 -390 1.09699403 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 0.0000 0.0000 0.0000; + 9 4.29015966e-08 138.064008 150 -150 1.09479564 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0 0.0000 9.9005 0.0000 0.0000; ]; %% branch data -% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax +% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax Pf Qf Pt Qt mu_Sf mu_St mu_angmin mu_angmax mpc.branch = [ - 1 2 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; - 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; - 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; - 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; - 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; - 4 5 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; - 6 7 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; - 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; - 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; - 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; - 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; - 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; - 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 1 2 0.00281 0.0281 0.00712 0 0 0 0 0 1 -360 360 166.1071 26.6607 -165.4309 -20.7287 0.0000 0.0000 0.0000 0.0000; + 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360 140.9835 -3.7157 -140.4698 8.0791 0.0000 0.0000 0.0000 0.0000; + 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360 -373.7856 -11.4518 374.5457 15.3639 0.0000 0.0000 0.0000 0.0000; + 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360 -134.5691 -77.8813 134.7937 77.9712 0.0000 0.0000 0.0000 0.0000; + 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360 35.3834 -0.2736 -35.3517 -0.2004 0.0000 0.0000 0.0000 0.0000; + 4 5 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360 -224.1785 9.1435 225.4543 2.8203 0.0000 0.0000 0.0000 0.0000; + 6 7 0.00281 0.0281 0.00712 0 0 0 0 0 1 -360 360 152.4912 27.1204 -151.9318 -22.3770 0.0000 0.0000 0.0000 0.0000; + 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360 154.6558 -0.3485 -154.0530 5.5857 0.0000 0.0000 0.0000 0.0000; + 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360 -97.1470 -21.9147 97.1992 18.6603 0.0000 0.0000 0.0000 0.0000; + 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360 -148.0682 -76.2330 148.3198 76.5380 0.0000 0.0000 0.0000 0.0000; + 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360 67.3548 1.5367 -67.2428 -1.2255 0.0000 0.0000 0.0000 0.0000; + 9 10 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360 -178.7043 2.2338 179.4958 4.8696 0.0000 0.0000 0.0000 0.0000; + 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0 276.6950 27.5002 -276.6950 -23.5298 0.0000 0.0000 0.0000 0.0000; ]; %%----- OPF Data -----%% diff --git a/03_parser/solvefuns/solve_distributed_problem_with_aladin.m b/03_parser/solvefuns/solve_distributed_problem_with_aladin.m index 1feee97..6eb7830 100644 --- a/03_parser/solvefuns/solve_distributed_problem_with_aladin.m +++ b/03_parser/solvefuns/solve_distributed_problem_with_aladin.m @@ -21,15 +21,17 @@ end sol = run_ALADINnew(problem, opts); xsol = vertcat(sol.xxOpt{:}); - [xsol, xsol_stacked] = deal_solution(xsol, mpc, names); - - %% numerical solution back to matpower casefile - timers = sol.timers; - iter = sol.iter.i - 1; % number of iteration - elapsed_time = timers.totTime - timers.setupT; - alg = 'ALADIN'; + xsol_stacked = 0; + mpc_sol = 0; +% [xsol, xsol_stacked] = deal_solution(xsol, mpc, names); +% +% %% numerical solution back to matpower casefile +% timers = sol.timers; +% iter = sol.iter.i - 1; % number of iteration +% elapsed_time = timers.totTime - timers.setupT; +% alg = 'ALADIN'; logg.X = sol.iter.logg.Y; logg.iter = sol.iter.i - 1; logg.cons_violations = sol.iter.logg.consViol; - mpc_sol = back_to_mpc(mpc, xsol, elapsed_time, iter, alg); +% mpc_sol = back_to_mpc(mpc, xsol, elapsed_time, iter, alg); end \ No newline at end of file diff --git a/05_UI_test/mpc_merge.m b/05_UI_test/mpc_merge.m index d675ba9..6c751a3 100644 --- a/05_UI_test/mpc_merge.m +++ b/05_UI_test/mpc_merge.m @@ -11,151 +11,80 @@ %% bus data % bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin mpc.bus = [ - 1 3 0 0 0 0 1 1.06 0 0 1 1.06 0.94; - 2 2 21.7 12.7 0 0 1 1.045 -4.98 0 1 1.06 0.94; - 3 2 94.2 19 0 0 1 1.01 -12.72 0 1 1.06 0.94; - 4 1 47.8 -3.9 0 0 1 1.019 -10.33 0 1 1.06 0.94; - 5 1 7.6 1.6 0 0 1 1.02 -8.78 0 1 1.06 0.94; - 6 2 11.2 7.5 0 0 1 1.07 -14.22 0 1 1.06 0.94; - 7 1 0 0 0 0 1 1.062 -13.37 0 1 1.06 0.94; - 8 2 0 0 0 0 1 1.09 -13.36 0 1 1.06 0.94; - 9 1 29.5 16.6 0 19 1 1.056 -14.94 0 1 1.06 0.94; - 10 1 9 5.8 0 0 1 1.051 -15.1 0 1 1.06 0.94; - 11 1 3.5 1.8 0 0 1 1.057 -14.79 0 1 1.06 0.94; - 12 1 6.1 1.6 0 0 1 1.055 -15.07 0 1 1.06 0.94; - 13 1 13.5 5.8 0 0 1 1.05 -15.16 0 1 1.06 0.94; - 14 1 14.9 5 0 0 1 1.036 -16.04 0 1 1.06 0.94; - 15 1 0 0 0 0 1 1 0 135 1 1.05 0.95; - 16 2 21.7 12.7 0 0 1 1 0 135 1 1.1 0.95; - 17 1 2.4 1.2 0 0 1 1 0 135 1 1.05 0.95; - 18 1 7.6 1.6 0 0 1 1 0 135 1 1.05 0.95; - 19 1 0 0 0 0.19 1 1 0 135 1 1.05 0.95; - 20 1 0 0 0 0 1 1 0 135 1 1.05 0.95; - 21 1 22.8 10.9 0 0 1 1 0 135 1 1.05 0.95; - 22 1 30 30 0 0 1 1 0 135 1 1.05 0.95; - 23 1 0 0 0 0 1 1 0 135 1 1.05 0.95; - 24 1 5.8 2 0 0 3 1 0 135 1 1.05 0.95; - 25 1 0 0 0 0 1 1 0 135 1 1.05 0.95; - 26 1 11.2 7.5 0 0 2 1 0 135 1 1.05 0.95; - 27 2 0 0 0 0 2 1 0 135 1 1.1 0.95; - 28 1 6.2 1.6 0 0 2 1 0 135 1 1.05 0.95; - 29 1 8.2 2.5 0 0 2 1 0 135 1 1.05 0.95; - 30 1 3.5 1.8 0 0 2 1 0 135 1 1.05 0.95; - 31 1 9 5.8 0 0 2 1 0 135 1 1.05 0.95; - 32 1 3.2 0.9 0 0 2 1 0 135 1 1.05 0.95; - 33 1 9.5 3.4 0 0 2 1 0 135 1 1.05 0.95; - 34 1 2.2 0.7 0 0 2 1 0 135 1 1.05 0.95; - 35 1 17.5 11.2 0 0 3 1 0 135 1 1.05 0.95; - 36 2 0 0 0 0 3 1 0 135 1 1.1 0.95; - 37 2 3.2 1.6 0 0 2 1 0 135 1 1.1 0.95; - 38 1 8.7 6.7 0 0.04 3 1 0 135 1 1.05 0.95; - 39 1 0 0 0 0 3 1 0 135 1 1.05 0.95; - 40 1 3.5 2.3 0 0 3 1 0 135 1 1.05 0.95; - 41 2 0 0 0 0 3 1 0 135 1 1.1 0.95; - 42 1 0 0 0 0 1 1 0 135 1 1.05 0.95; - 43 1 2.4 0.9 0 0 3 1 0 135 1 1.05 0.95; - 44 1 10.6 1.9 0 0 3 1 0 135 1 1.05 0.95; - 45 1 0 0 0 0 1 1.04 0 345 1 1.1 0.9; - 46 2 0 0 0 0 1 1 0 345 1 1.1 0.9; - 47 1 0 0 0 0 1 1.025 0 345 1 1.1 0.9; - 48 1 0 0 0 0 1 1 0 345 1 1.1 0.9; - 49 1 90 30 0 0 1 1 0 345 1 1.1 0.9; - 50 1 0 0 0 0 1 1 0 345 1 1.1 0.9; - 51 1 100 35 0 0 1 1 0 345 1 1.1 0.9; - 52 1 0 0 0 0 1 1 0 345 1 1.1 0.9; - 53 1 125 50 0 0 1 1 0 345 1 1.1 0.9; + 1 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 2 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 3 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 4 3 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 5 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 6 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 11 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 12 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 13 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 14 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 15 2 0 0 0 0 1 1 0 230 1 1.1 0.9; ]; %% generator data % bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf mpc.gen = [ - 1 232.4 -16.9 10 0 1.06 100 1 332.4 0 0 0 0 0 0 0 0 0 0 0 0; - 2 40 42.4 50 -40 1.045 100 1 140 0 0 0 0 0 0 0 0 0 0 0 0; - 3 0 23.4 40 0 1.01 100 1 100 0 0 0 0 0 0 0 0 0 0 0 0; - 6 0 12.2 24 -6 1.07 100 1 100 0 0 0 0 0 0 0 0 0 0 0 0; - 8 0 17.4 24 -6 1.09 100 1 100 0 0 0 0 0 0 0 0 0 0 0 0; - 16 60.97 0 60 -20 1 100 1 80 0 0 0 0 0 0 0 0 0 0 0 0; - 36 21.59 0 62.5 -15 1 100 1 50 0 0 0 0 0 0 0 0 0 0 0 0; - 41 26.91 0 48.7 -15 1 100 1 55 0 0 0 0 0 0 0 0 0 0 0 0; - 37 19.2 0 40 -10 1 100 1 30 0 0 0 0 0 0 0 0 0 0 0 0; - 27 37 0 44.7 -15 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; - 46 163 6.54 300 -300 1.025 100 1 300 10 0 0 0 0 0 0 0 0 0 0 0; + 1 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; + 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 13 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 14 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 15 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; ]; %% branch data % fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax mpc.branch = [ - 1 2 0.01938 0.05917 0.0528 0 0 0 0 0 1 -360 360; - 1 5 0.05403 0.22304 0.0492 0 0 0 0 0 1 -360 360; - 2 3 0.04699 0.19797 0.0438 0 0 0 0 0 1 -360 360; - 2 4 0.05811 0.17632 0.034 0 0 0 0 0 1 -360 360; - 2 5 0.05695 0.17388 0.0346 0 0 0 0 0 1 -360 360; - 3 4 0.06701 0.17103 0.0128 0 0 0 0 0 1 -360 360; - 4 5 0.01335 0.04211 0 0 0 0 0 0 1 -360 360; - 4 7 0 0.20912 0 0 0 0 0.978 0 1 -360 360; - 4 9 0 0.55618 0 0 0 0 0.969 0 1 -360 360; - 5 6 0 0.25202 0 0 0 0 0.932 0 1 -360 360; - 6 11 0.09498 0.1989 0 0 0 0 0 0 1 -360 360; - 6 12 0.12291 0.25581 0 0 0 0 0 0 1 -360 360; - 6 13 0.06615 0.13027 0 0 0 0 0 0 1 -360 360; - 7 8 0 0.17615 0 0 0 0 0 0 1 -360 360; - 7 9 0 0.11001 0 0 0 0 0 0 1 -360 360; - 9 10 0.03181 0.0845 0 0 0 0 0 0 1 -360 360; - 9 14 0.12711 0.27038 0 0 0 0 0 0 1 -360 360; - 10 11 0.08205 0.19207 0 0 0 0 0 0 1 -360 360; - 12 13 0.22092 0.19988 0 0 0 0 0 0 1 -360 360; - 13 14 0.17093 0.34802 0 0 0 0 0 0 1 -360 360; - 15 16 0.02 0.06 0.03 130 130 130 0 0 1 -360 360; - 15 17 0.05 0.19 0.02 130 130 130 0 0 1 -360 360; - 16 18 0.06 0.17 0.02 65 65 65 0 0 1 -360 360; - 17 18 0.01 0.04 0 130 130 130 0 0 1 -360 360; - 16 19 0.05 0.2 0.02 130 130 130 0 0 1 -360 360; - 16 20 0.06 0.18 0.02 65 65 65 0 0 1 -360 360; - 18 20 0.01 0.04 0 90 90 90 0 0 1 -360 360; - 19 21 0.05 0.12 0.01 70 70 70 0 0 1 -360 360; - 20 21 0.03 0.08 0.01 130 130 130 0 0 1 -360 360; - 20 22 0.01 0.04 0 32 32 32 0 0 1 -360 360; - 20 23 0 0.21 0 65 65 65 0 0 1 -360 360; - 20 24 0 0.56 0 32 32 32 0 0 1 -360 360; - 23 25 0 0.21 0 65 65 65 0 0 1 -360 360; - 23 24 0 0.11 0 65 65 65 0 0 1 -360 360; - 18 26 0 0.26 0 65 65 65 0 0 1 -360 360; - 26 27 0 0.14 0 65 65 65 0 0 1 -360 360; - 26 28 0.12 0.26 0 32 32 32 0 0 1 -360 360; - 26 29 0.07 0.13 0 32 32 32 0 0 1 -360 360; - 26 30 0.09 0.2 0 32 32 32 0 0 1 -360 360; - 28 29 0.22 0.2 0 16 16 16 0 0 1 -360 360; - 30 31 0.08 0.19 0 16 16 16 0 0 1 -360 360; - 29 32 0.11 0.22 0 16 16 16 0 0 1 -360 360; - 32 33 0.06 0.13 0 16 16 16 0 0 1 -360 360; - 33 34 0.03 0.07 0 32 32 32 0 0 1 -360 360; - 24 34 0.09 0.21 0 32 32 32 0 0 1 -360 360; - 24 31 0.03 0.08 0 32 32 32 0 0 1 -360 360; - 24 35 0.03 0.07 0 32 32 32 0 0 1 -360 360; - 24 36 0.07 0.15 0 32 32 32 0 0 1 -360 360; - 35 36 0.01 0.02 0 32 32 32 0 0 1 -360 360; - 29 37 0.1 0.2 0 16 16 16 0 0 1 -360 360; - 36 38 0.12 0.18 0 16 16 16 0 0 1 -360 360; - 37 38 0.13 0.27 0 16 16 16 0 0 1 -360 360; - 38 39 0.19 0.33 0 16 16 16 0 0 1 -360 360; - 39 40 0.25 0.38 0 16 16 16 0 0 1 -360 360; - 39 41 0.11 0.21 0 16 16 16 0 0 1 -360 360; - 42 41 0 0.4 0 65 65 65 0 0 1 -360 360; - 41 43 0.22 0.42 0 16 16 16 0 0 1 -360 360; - 41 44 0.32 0.6 0 16 16 16 0 0 1 -360 360; - 43 44 0.24 0.45 0 16 16 16 0 0 1 -360 360; - 22 42 0.06 0.2 0.02 32 32 32 0 0 1 -360 360; - 20 42 0.02 0.06 0.01 32 32 32 0 0 1 -360 360; - 2 15 0 0.00623 0 0 0 0 0.985 0 1 0 0; - 45 48 0 0.0576 0 250 250 250 0 0 1 -360 360; - 48 49 0.017 0.092 0.158 250 250 250 0 0 1 -360 360; - 49 50 0.039 0.17 0.358 150 150 150 0 0 1 -360 360; - 47 50 0 0.0586 0 300 300 300 0 0 1 -360 360; - 50 51 0.0119 0.1008 0.209 150 150 150 0 0 1 -360 360; - 51 52 0.0085 0.072 0.149 250 250 250 0 0 1 -360 360; - 52 46 0 0.0625 0 250 250 250 0 0 1 -360 360; - 52 53 0.032 0.161 0.306 250 250 250 0 0 1 -360 360; - 53 48 0.01 0.085 0.176 250 250 250 0 0 1 -360 360; - 16 47 0 0.00623 0 0 0 0 0.985 0 1 0 0; - 27 45 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 1 2 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 4 5 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 6 7 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 11 12 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 11 14 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 11 15 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 12 13 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 13 14 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 14 15 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 9 11 0 0.00623 0 0 0 0 0.985 0 1 0 0; +]; + +%%----- OPF Data -----%% +%% generator cost data +% 1 startup shutdown n x1 y1 ... xn yn +% 2 startup shutdown n c(n-1) ... c0 +mpc.gencost = [ + 2 0 0 3 14 0.546881519 0.546881519; + 2 0 0 3 15 0.546881519 0.546881519; + 2 0 0 3 30 0.546881519 0.546881519; + 2 0 0 3 40 0.546881519 0.546881519; + 2 0 0 3 10 0.546881519 0.546881519; + 2 0 0 3 14 0.546881519 0.546881519; + 2 0 0 3 15 0.546881519 0.546881519; + 2 0 0 3 30 0.546881519 0.546881519; + 2 0 0 3 40 0.546881519 0.546881519; + 2 0 0 3 30 0.546881519 0.546881519; + 2 0 0 3 40 0.546881519 0.546881519; + 2 0 0 3 10 0.546881519 0.546881519; ]; diff --git a/05_UI_test/mpc_merge_split.m b/05_UI_test/mpc_merge_split.m index 4e74008..11bb937 100644 --- a/05_UI_test/mpc_merge_split.m +++ b/05_UI_test/mpc_merge_split.m @@ -11,151 +11,80 @@ %% bus data % bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin mpc.bus = [ - 1 3 0 0 0 0 1 1.06 0 0 1 1.06 0.94; - 2 2 21.7 12.7 0 0 1 1.045 -4.98 0 1 1.06 0.94; - 3 2 94.2 19 0 0 1 1.01 -12.72 0 1 1.06 0.94; - 4 1 47.8 -3.9 0 0 1 1.019 -10.33 0 1 1.06 0.94; - 5 1 7.6 1.6 0 0 1 1.02 -8.78 0 1 1.06 0.94; - 6 2 11.2 7.5 0 0 1 1.07 -14.22 0 1 1.06 0.94; - 7 1 0 0 0 0 1 1.062 -13.37 0 1 1.06 0.94; - 8 2 0 0 0 0 1 1.09 -13.36 0 1 1.06 0.94; - 9 1 29.5 16.6 0 19 1 1.056 -14.94 0 1 1.06 0.94; - 10 1 9 5.8 0 0 1 1.051 -15.1 0 1 1.06 0.94; - 11 1 3.5 1.8 0 0 1 1.057 -14.79 0 1 1.06 0.94; - 12 1 6.1 1.6 0 0 1 1.055 -15.07 0 1 1.06 0.94; - 13 1 13.5 5.8 0 0 1 1.05 -15.16 0 1 1.06 0.94; - 14 1 14.9 5 0 0 1 1.036 -16.04 0 1 1.06 0.94; - 15 1 0 0 0 0 1 1 0 135 1 1.05 0.95; - 16 2 21.7 12.7 0 0 1 1 0 135 1 1.1 0.95; - 17 1 2.4 1.2 0 0 1 1 0 135 1 1.05 0.95; - 18 1 7.6 1.6 0 0 1 1 0 135 1 1.05 0.95; - 19 1 0 0 0 0.19 1 1 0 135 1 1.05 0.95; - 20 1 0 0 0 0 1 1 0 135 1 1.05 0.95; - 21 1 22.8 10.9 0 0 1 1 0 135 1 1.05 0.95; - 22 1 30 30 0 0 1 1 0 135 1 1.05 0.95; - 23 1 0 0 0 0 1 1 0 135 1 1.05 0.95; - 24 1 5.8 2 0 0 3 1 0 135 1 1.05 0.95; - 25 1 0 0 0 0 1 1 0 135 1 1.05 0.95; - 26 1 11.2 7.5 0 0 2 1 0 135 1 1.05 0.95; - 27 2 0 0 0 0 2 1 0 135 1 1.1 0.95; - 28 1 6.2 1.6 0 0 2 1 0 135 1 1.05 0.95; - 29 1 8.2 2.5 0 0 2 1 0 135 1 1.05 0.95; - 30 1 3.5 1.8 0 0 2 1 0 135 1 1.05 0.95; - 31 1 9 5.8 0 0 2 1 0 135 1 1.05 0.95; - 32 1 3.2 0.9 0 0 2 1 0 135 1 1.05 0.95; - 33 1 9.5 3.4 0 0 2 1 0 135 1 1.05 0.95; - 34 1 2.2 0.7 0 0 2 1 0 135 1 1.05 0.95; - 35 1 17.5 11.2 0 0 3 1 0 135 1 1.05 0.95; - 36 2 0 0 0 0 3 1 0 135 1 1.1 0.95; - 37 2 3.2 1.6 0 0 2 1 0 135 1 1.1 0.95; - 38 1 8.7 6.7 0 0.04 3 1 0 135 1 1.05 0.95; - 39 1 0 0 0 0 3 1 0 135 1 1.05 0.95; - 40 1 3.5 2.3 0 0 3 1 0 135 1 1.05 0.95; - 41 2 0 0 0 0 3 1 0 135 1 1.1 0.95; - 42 1 0 0 0 0 1 1 0 135 1 1.05 0.95; - 43 1 2.4 0.9 0 0 3 1 0 135 1 1.05 0.95; - 44 1 10.6 1.9 0 0 3 1 0 135 1 1.05 0.95; - 45 1 0 0 0 0 1 1.04 0 345 1 1.1 0.9; - 46 2 0 0 0 0 1 1 0 345 1 1.1 0.9; - 47 1 0 0 0 0 1 1.025 0 345 1 1.1 0.9; - 48 1 0 0 0 0 1 1 0 345 1 1.1 0.9; - 49 1 90 30 0 0 1 1 0 345 1 1.1 0.9; - 50 1 0 0 0 0 1 1 0 345 1 1.1 0.9; - 51 1 100 35 0 0 1 1 0 345 1 1.1 0.9; - 52 1 0 0 0 0 1 1 0 345 1 1.1 0.9; - 53 1 125 50 0 0 1 1 0 345 1 1.1 0.9; + 1 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 2 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 3 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 4 3 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 5 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 6 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 11 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 12 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 13 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; + 14 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; + 15 2 0 0 0 0 1 1 0 230 1 1.1 0.9; ]; %% generator data % bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf mpc.gen = [ - 1 232.4 -16.9 10 0 1.06 100 1 332.4 0 0 0 0 0 0 0 0 0 0 0 0; - 2 40 42.4 50 -40 1.045 100 1 140 0 0 0 0 0 0 0 0 0 0 0 0; - 3 0 23.4 40 0 1.01 100 1 100 0 0 0 0 0 0 0 0 0 0 0 0; - 6 0 12.2 24 -6 1.07 100 1 100 0 0 0 0 0 0 0 0 0 0 0 0; - 8 0 17.4 24 -6 1.09 100 1 100 0 0 0 0 0 0 0 0 0 0 0 0; - 16 60.97 0 60 -20 1 100 1 80 0 0 0 0 0 0 0 0 0 0 0 0; - 36 21.59 0 62.5 -15 1 100 1 50 0 0 0 0 0 0 0 0 0 0 0 0; - 41 26.91 0 48.7 -15 1 100 1 55 0 0 0 0 0 0 0 0 0 0 0 0; - 37 19.2 0 40 -10 1 100 1 30 0 0 0 0 0 0 0 0 0 0 0 0; - 27 37 0 44.7 -15 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; - 46 163 6.54 300 -300 1.025 100 1 300 10 0 0 0 0 0 0 0 0 0 0 0; + 1 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; + 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; + 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 13 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; + 14 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 15 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; ]; %% branch data % fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax mpc.branch = [ - 1 2 0.01938 0.05917 0.0528 0 0 0 0 0 1 -360 360; - 1 5 0.05403 0.22304 0.0492 0 0 0 0 0 1 -360 360; - 2 3 0.04699 0.19797 0.0438 0 0 0 0 0 1 -360 360; - 2 4 0.05811 0.17632 0.034 0 0 0 0 0 1 -360 360; - 2 5 0.05695 0.17388 0.0346 0 0 0 0 0 1 -360 360; - 3 4 0.06701 0.17103 0.0128 0 0 0 0 0 1 -360 360; - 4 5 0.01335 0.04211 0 0 0 0 0 0 1 -360 360; - 4 7 0 0.20912 0 0 0 0 0.978 0 1 -360 360; - 4 9 0 0.55618 0 0 0 0 0.969 0 1 -360 360; - 5 6 0 0.25202 0 0 0 0 0.932 0 1 -360 360; - 6 11 0.09498 0.1989 0 0 0 0 0 0 1 -360 360; - 6 12 0.12291 0.25581 0 0 0 0 0 0 1 -360 360; - 6 13 0.06615 0.13027 0 0 0 0 0 0 1 -360 360; - 7 8 0 0.17615 0 0 0 0 0 0 1 -360 360; - 7 9 0 0.11001 0 0 0 0 0 0 1 -360 360; - 9 10 0.03181 0.0845 0 0 0 0 0 0 1 -360 360; - 9 14 0.12711 0.27038 0 0 0 0 0 0 1 -360 360; - 10 11 0.08205 0.19207 0 0 0 0 0 0 1 -360 360; - 12 13 0.22092 0.19988 0 0 0 0 0 0 1 -360 360; - 13 14 0.17093 0.34802 0 0 0 0 0 0 1 -360 360; - 15 16 0.02 0.06 0.03 130 130 130 0 0 1 -360 360; - 15 17 0.05 0.19 0.02 130 130 130 0 0 1 -360 360; - 16 18 0.06 0.17 0.02 65 65 65 0 0 1 -360 360; - 17 18 0.01 0.04 0 130 130 130 0 0 1 -360 360; - 16 19 0.05 0.2 0.02 130 130 130 0 0 1 -360 360; - 16 20 0.06 0.18 0.02 65 65 65 0 0 1 -360 360; - 18 20 0.01 0.04 0 90 90 90 0 0 1 -360 360; - 19 21 0.05 0.12 0.01 70 70 70 0 0 1 -360 360; - 20 21 0.03 0.08 0.01 130 130 130 0 0 1 -360 360; - 20 22 0.01 0.04 0 32 32 32 0 0 1 -360 360; - 20 23 0 0.21 0 65 65 65 0 0 1 -360 360; - 20 24 0 0.56 0 32 32 32 0 0 1 -360 360; - 23 25 0 0.21 0 65 65 65 0 0 1 -360 360; - 23 24 0 0.11 0 65 65 65 0 0 1 -360 360; - 18 26 0 0.26 0 65 65 65 0 0 1 -360 360; - 26 27 0 0.14 0 65 65 65 0 0 1 -360 360; - 26 28 0.12 0.26 0 32 32 32 0 0 1 -360 360; - 26 29 0.07 0.13 0 32 32 32 0 0 1 -360 360; - 26 30 0.09 0.2 0 32 32 32 0 0 1 -360 360; - 28 29 0.22 0.2 0 16 16 16 0 0 1 -360 360; - 30 31 0.08 0.19 0 16 16 16 0 0 1 -360 360; - 29 32 0.11 0.22 0 16 16 16 0 0 1 -360 360; - 32 33 0.06 0.13 0 16 16 16 0 0 1 -360 360; - 33 34 0.03 0.07 0 32 32 32 0 0 1 -360 360; - 24 34 0.09 0.21 0 32 32 32 0 0 1 -360 360; - 24 31 0.03 0.08 0 32 32 32 0 0 1 -360 360; - 24 35 0.03 0.07 0 32 32 32 0 0 1 -360 360; - 24 36 0.07 0.15 0 32 32 32 0 0 1 -360 360; - 35 36 0.01 0.02 0 32 32 32 0 0 1 -360 360; - 29 37 0.1 0.2 0 16 16 16 0 0 1 -360 360; - 36 38 0.12 0.18 0 16 16 16 0 0 1 -360 360; - 37 38 0.13 0.27 0 16 16 16 0 0 1 -360 360; - 38 39 0.19 0.33 0 16 16 16 0 0 1 -360 360; - 39 40 0.25 0.38 0 16 16 16 0 0 1 -360 360; - 39 41 0.11 0.21 0 16 16 16 0 0 1 -360 360; - 42 41 0 0.4 0 65 65 65 0 0 1 -360 360; - 41 43 0.22 0.42 0 16 16 16 0 0 1 -360 360; - 41 44 0.32 0.6 0 16 16 16 0 0 1 -360 360; - 43 44 0.24 0.45 0 16 16 16 0 0 1 -360 360; - 22 42 0.06 0.2 0.02 32 32 32 0 0 1 -360 360; - 20 42 0.02 0.06 0.01 32 32 32 0 0 1 -360 360; - 2 15 0 0.00623 0 0 0 0 0.985 0 1 0 0; - 45 48 0 0.0576 0 250 250 250 0 0 1 -360 360; - 48 49 0.017 0.092 0.158 250 250 250 0 0 1 -360 360; - 49 50 0.039 0.17 0.358 150 150 150 0 0 1 -360 360; - 47 50 0 0.0586 0 300 300 300 0 0 1 -360 360; - 50 51 0.0119 0.1008 0.209 150 150 150 0 0 1 -360 360; - 51 52 0.0085 0.072 0.149 250 250 250 0 0 1 -360 360; - 52 46 0 0.0625 0 250 250 250 0 0 1 -360 360; - 52 53 0.032 0.161 0.306 250 250 250 0 0 1 -360 360; - 53 48 0.01 0.085 0.176 250 250 250 0 0 1 -360 360; - 16 47 0 0.00623 0 0 0 0 0.985 0 1 0 0; - 27 45 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 1 2 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 1 4 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 1 5 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 2 3 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 3 4 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 4 5 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 6 7 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 6 9 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 6 10 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 7 8 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 8 9 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 9 10 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 1 10 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 11 12 0.00281 0.0281 0.00712 400 400 400 0 0 1 -360 360; + 11 14 0.00304 0.0304 0.00658 0 0 0 0 0 1 -360 360; + 11 15 0.00064 0.0064 0.03126 0 0 0 0 0 1 -360 360; + 12 13 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; + 13 14 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; + 14 15 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; + 9 11 0 0.00623 0 0 0 0 0.985 0 1 0 0; +]; + +%%----- OPF Data -----%% +%% generator cost data +% 1 startup shutdown n x1 y1 ... xn yn +% 2 startup shutdown n c(n-1) ... c0 +mpc.gencost = [ + 2 0 0 3 14 0.546881519 0.546881519; + 2 0 0 3 15 0.546881519 0.546881519; + 2 0 0 3 30 0.546881519 0.546881519; + 2 0 0 3 40 0.546881519 0.546881519; + 2 0 0 3 10 0.546881519 0.546881519; + 2 0 0 3 14 0.546881519 0.546881519; + 2 0 0 3 15 0.546881519 0.546881519; + 2 0 0 3 30 0.546881519 0.546881519; + 2 0 0 3 40 0.546881519 0.546881519; + 2 0 0 3 30 0.546881519 0.546881519; + 2 0 0 3 40 0.546881519 0.546881519; + 2 0 0 3 10 0.546881519 0.546881519; ]; diff --git a/06_opf_extension/build_local_bounds.m b/06_opf_extension/build_local_bounds.m index 386159e..ffad94d 100644 --- a/06_opf_extension/build_local_bounds.m +++ b/06_opf_extension/build_local_bounds.m @@ -1,3 +1,14 @@ function [lb, ub] = build_local_bounds(om) +% BUILD_LOACL_BOUNDS +% +% `[lb, ub] = build_local_bounds(om)` +% +% _extracts local bounds for x from MATPOWER_ +% +% INPUT: +% - $\texttt{om}$ optimization model of reduced splitted case file +% +% OUTPUT: +% - $\texttt{[lb, ub]}$ lower and upper bond for objective variable $x$ of model $\texttt{om}$ of subsystem $i$ [~, lb, ub] = om.params_var(); end \ No newline at end of file diff --git a/06_opf_extension/build_local_constraint_function.m b/06_opf_extension/build_local_constraint_function.m index cd6e245..33d48a5 100644 --- a/06_opf_extension/build_local_constraint_function.m +++ b/06_opf_extension/build_local_constraint_function.m @@ -1,4 +1,11 @@ function [constraint_function, Lxx] = build_local_constraint_function(mpc_opf, om, mpopt) + %BUILD_LOCAL_CONSTRAINT_FUNCTION extracts matpower equality and + %inequality constraints and their jacobian to rapidOPF + % + %Output: - constraint_function @(x)[h, dh, g, dh] + % - Lxx Lagrangian function of complete system in MATPOWER. It + % is not usable by rapidOPF but taken for completeness + % [Ybus, Yf, Yt] = makeYbus(mpc_opf); il = find(mpc_opf.branch(:, 6) ~= 0 & mpc_opf.branch(:, 6) < 1e10); diff --git a/06_opf_extension/build_local_cost_function.m b/06_opf_extension/build_local_cost_function.m index d2e2009..0a72d8e 100644 --- a/06_opf_extension/build_local_cost_function.m +++ b/06_opf_extension/build_local_cost_function.m @@ -1,4 +1,14 @@ function [cost, grad, hess] = build_local_cost_function(om) +% BUILD_LOCAL_COST_FUNCTION +% +% `[mpc_opf, om, copy_buses_local, mpopt] = prepare_case_file(mpc, names))` +% +% INPUT: - om MATPOWER optimization model +% OUTPUT: - cost function handle for costs +% - grad function handle for gradient of costs +% - hess function handle for hessian of cost + + f = @(x)opf_costfcn(x, om); cost = @(x)get_cost(x, f); grad = @(x)get_cost_gradient(x, f); @@ -7,11 +17,11 @@ % helper functions function f = get_cost(x, f_fcn) - [f,~] = f_fcn(x); + [f,~,~] = f_fcn(x); end function df = get_cost_gradient(x, f_fcn) - [~, df] = f_fcn(x); + [~, df, ~] = f_fcn(x); end function d2f = get_cost_hess(x, f_fcn) diff --git a/06_opf_extension/build_local_dimensions.m b/06_opf_extension/build_local_dimensions.m index b9114a9..f06e7eb 100644 --- a/06_opf_extension/build_local_dimensions.m +++ b/06_opf_extension/build_local_dimensions.m @@ -1,15 +1,28 @@ -function dims = build_local_dimensions(mpc_opf, eq, ineq) - % this file assumes that all generators at the copy busses have been turned off - % i.e. prepare_case_file() was called already! +function dims = build_local_dimensions(mpc_opf, eq, ineq, local_buses_to_remove) +% DIMS +% +% `dims = build_local_dimensions(mpc_opf, eq, ineq, local_buses_to_remove)` +% +% _creates a field of dimensions as how they should look like and use it for testing_ +% +% INPUT: - mpc_opf splitted case files +% - eq power flow equations for core nodes plus their jacbian' +% - ineq flow limits inequality constraints plus their jacobian' +% - local_buses_to_remove copy nodes +% OUTPUT: - dims struct containing dimensions + Nbus = size(mpc_opf.bus, 1); Ngen = size(mpc_opf.gen, 1); dims.state = 2 * (Nbus + Ngen); - dims.eq = 2 * Nbus; + dims.eq = 2 * (Nbus - length(local_buses_to_remove)); + + il = find(mpc_opf.branch(:, 6) ~= 0 & mpc_opf.branch(:, 6) < 1e10); + dims.ineq = 2 * length(il); % one inequality for each from and to bus + dims.n.bus = Nbus; dims.n.gen = Ngen; - %% ToDo! - % verification missing!!! + %% Test dimensions x = rand(dims.state, 1); - dims.ineq = numel(ineq(x)); - dims.eq = numel(eq(x)); + % assert (dims.ineq == numel(ineq(x)), 'Error during dimension check of number of inequality constraints'); + assert (dims.eq == numel(eq(x)), 'Error during dimension check of number of equality constraints'); end \ No newline at end of file diff --git a/06_opf_extension/build_local_equalities.m b/06_opf_extension/build_local_equalities.m index 312eac7..6e8fbfa 100644 --- a/06_opf_extension/build_local_equalities.m +++ b/06_opf_extension/build_local_equalities.m @@ -1,5 +1,11 @@ -function [eq, eq_jac] = build_local_equalities(constraint_function, local_buses_to_remove) - inds = [local_buses_to_remove; 2 * local_buses_to_remove]; +function [eq, eq_jac] = build_local_equalities(constraint_function, local_buses_to_remove, total_number_of_nodes) +% BUILD_LOCAL_EQUALITIES +% +% `[eq, eq_jac] = build_local_equalities(constraint_function, local_buses_to_remove)` +% +% _extracts the relevant power flow equation for the core buses. Power flow equations of the copy buses are removed_ +% + inds = [local_buses_to_remove; local_buses_to_remove + total_number_of_nodes]; eq = @(x)get_eq_cons(x, constraint_function, inds); eq_jac = @(x)get_eq_cons_jacobian(x, constraint_function, inds); end diff --git a/06_opf_extension/build_local_inequalities.m b/06_opf_extension/build_local_inequalities.m index 090bafe..7f031ee 100644 --- a/06_opf_extension/build_local_inequalities.m +++ b/06_opf_extension/build_local_inequalities.m @@ -1,4 +1,10 @@ function [ineq, ineq_jac] = build_local_inequalities(constraint_function) +% BUILD_LOCAL_INEQUALITIES +% +% `[ineq, ineq_jac] = build_local_inequalities(constraint_function, local_buses_to_remove)` +% +% _extracts all inequalitites from opf_consfcn.m_ +% ineq = @(x)get_ineq_cons(x, constraint_function); ineq_jac = @(x)get_ineq_cons_jacobian(x, constraint_function); end diff --git a/06_opf_extension/build_local_initial_conditions.m b/06_opf_extension/build_local_initial_conditions.m index 4d3f143..5ff345d 100644 --- a/06_opf_extension/build_local_initial_conditions.m +++ b/06_opf_extension/build_local_initial_conditions.m @@ -1,3 +1,14 @@ function x0 = build_local_initial_conditions(om) - x0 = om.params_var(); +% BUILD_LOACL_INITIAL_CONDITION +% +% `x0 = build_local_initial_conditions(om)` +% +% _extracts initial condition for x from MATPOWER_ +% +% INPUT: +% - $\texttt{om}$ optimization model of reduced splitted case file +% +% OUTPUT: +% - $\texttt{x0}$ initial condition for objective variable $x$ of model $\texttt{om}$ of subsystem $i$ +x0 = om.params_var(); end \ No newline at end of file diff --git a/06_opf_extension/build_local_lagrangian_function.m b/06_opf_extension/build_local_lagrangian_function.m index fc6c312..9976610 100644 --- a/06_opf_extension/build_local_lagrangian_function.m +++ b/06_opf_extension/build_local_lagrangian_function.m @@ -1,38 +1,52 @@ -function [L, dLdx, d2Ldx] = build_local_lagrangian_function(f, df, g, dg, h, dh) -%BUILD_LOCAL_LAGRANGIAN_FUNCTION Bulds the Lagrangian of the local mpc file -% kappa is [lambda; mu] with lambda, mu are column vectors -% dg is the transposed of the jacobian of g, i.e. dimension nx_x \times n_eq -% dh is the transposed jacobian of h -% L = f + lambda'g + mu'h -% dL = grad_f + lambda'(Jac_g)' + mu'(Jac_h)' - - if nargin == 4 - L = @(x, kappa, Neq) f(x) + kappa(1:Neq)'*g(x); - dLdx = @(x, kappa, Neq) df(x) ... - + get_grad_lambda_g(kappa(1:Neq), dg, x); - d2Ldx = @(x, kappa, rho, Neq) get_Hess(dLdx, x, kappa, Neq); - elseif nargin == 6 - L = @(x, kappa, Neq) f(x) + kappa(1:Neq)'*g(x) + kappa(Neq+1:end)'*h(x); - dLdx = @(x, kappa, Neq) df(x) + ... - get_grad_lambda_g(kappa(1:Neq), dg, x) + ... - get_grad_mu_h(kappa(Neq+1:end), dh, x); - d2Ldx = @(x, kappa, rho, Neq) get_Hess(dLdx, x, kappa, Neq); - end +function [L, dLdx, d2Ldx] = build_local_lagrangian_function(f, df, g, dg, h, dh, state) +%BUILD_LOCAL_LAGRANGIAN_FUNCTION +% +% `Builds the Lagrangian of the local mpc file` +% +% INPUT: +% - $\texttt{f}$ scalar valued cost function +% - $\texttt{df}$ gradient of $\textt{f}$ +% - $\texttt{g}$ equality constraints +% - $\texttt{dg}$ transposed jacobian of the 'reduced' equality constraints +% - $\ŧexttt{h}$ inequality constraints +% - $\texttt{dh}$ transposed jacobian of the inequality constraints +% +% OUTPUT: +% - $\texttt{L}$ 'reduced' Lagrangefunction +% - $\texttt{dLdx}$ grandient of the Lagrangian +% - $\ŧexttt{d2Ldx}$ hessian of the Lagrangian +% +% REMARK: +% mu is the langrange multiplier for the +% kappa = [lambda; mu] (with lambda, mu column vectors) +% L = f + lambda'g + mu'h +% dL = grad_f + \sum lambda_i (Jac_g)'(:, i) + \sum mu_i(Jac_h)'(:, i) +x = zeros(length(state), 1); +Neq = numel(g(x)); +Nineq = numel(h(x)); + +if Neq > 0 && Nineq == 0 + L = @(x, kappa) f(x) * kappa'*g(x); + dLdx = @(x, kappa) df(x) + get_grad_lambda_g(kappa, dg, x); + d2Ldx = @(x, kappa, rho, Neq)get_Hess(dLdx, x, kappa); +elseif Neq == 0 && Nineq > 0 + L = @(x, kappa) f(x) * kappa'*h(x); + dLdx = @(x, kappa) df(x) + get_grad_mu_h(kappa, dh, x); + d2Ldx = @(x, kappa, rho, Neq)get_Hess(dLdx, x, kappa); +elseif Neq > 0 && Nineq > 0 + L = @(x, kappa) f(x) * kappa(1:Neq)'*g(x) + kappa(Neq + 1:end)'*h(x); + dLdx = @(x, kappa) df(x) + get_grad_lambda_g(kappa(1:Neq), dg, x) + get_grad_mu_h(kappa(Neq+1:end), dh, x); + d2Ldx = @(x, kappa, rho, Neq)get_Hess(dLdx, x, kappa); +end -% L = @(x, kappa, Neq) f(x) + kappa(1:Neq)'*g(x) + kappa(Neq+1:end)'*h(x); -% dLdx = @(x, kappa, Neq) df(x) + ... -% get_grad_lambda_g(kappa(1:Neq), dg, x) + ... -% get_grad_mu_h(kappa(Neq+1:end), dh, x); -% d2Ldx = @(x, kappa, rho) get_Hess(dLdx, x, kappa, Neq); -end %% get gradient of lambda'*g function grad_lambda_g = get_grad_lambda_g(lambda, dg, x) grad_lambda_g = sparse(length(x), 1); dg_at_x = dg(x); - for i = 1 : length(lambda) + for i = 1 : size(dg_at_x, 2) grad_lambda_g = grad_lambda_g + lambda(i)*dg_at_x(:, i); end end @@ -46,14 +60,16 @@ end %% get Hessian Function -function d2Ldx = get_Hess(dLdx, x, kappa, Neq) -epsilon = 1e-10; -epsilon_inv = 1/epsilon; -nx = length(x); -d2Ldx = zeros(nx, nx); -for i = 1 : nx - dx_i = [ zeros(i-1, 1); 1; zeros(nx-i, 1)]; - d2Ldx(:, i) = (dLdx(x + epsilon*dx_i, kappa, Neq) ... - - dLdx(x - epsilon*dx_i, kappa, Neq)).*0.5.*epsilon_inv; +function d2Ldx = get_Hess(dLdx, x, kappa) + epsilon = 1e-10; + epsilon_inv = 1/epsilon; + nx = length(x); + d2Ldx = zeros(nx, nx); + for i = 1 : nx + dx_i = [ zeros(i-1, 1); 1; zeros(nx-i, 1)]; + d2Ldx(:, i) = (dLdx(x + epsilon*dx_i, kappa) ... + - dLdx(x - epsilon*dx_i, kappa)).*0.5.*epsilon_inv; + end end + end diff --git a/06_opf_extension/build_local_lagrangian_function_old.m b/06_opf_extension/build_local_lagrangian_function_old.m new file mode 100644 index 0000000..761013b --- /dev/null +++ b/06_opf_extension/build_local_lagrangian_function_old.m @@ -0,0 +1,34 @@ +function [L, dLdx, d2Ldx] = build_local_lagrangian_function_old(f, df, g, dg, h, dh) +%BUILD_LOCAL_LAGRANGIAN_FUNCTION Bulds the Lagrangian of the local mpc file +% kappa is [lambda; mu] with lambda, mu are column vectors +% dg is the transposed of g, i.e. dimension nx_x \times n_eq +% dh is the transposed jacobian of h +% L = f + lambda'g + mu'h +% dL = grad_f + lambda'(dg)' + mu'(dh)' + if nargin == 4 + L = @(x, kappa, Neq) f(x) + kappa(1:Neq)'*g(x); + dLdx = @(x, kappa, Neq) df(x) + (kappa(1:Neq)'*dg(x)')'; + d2Ldx = @(x, kappa, rho, Neq) get_Hess(dLdx, x, kappa(1:Neq), kappa(Neq + 1: end)); + elseif nargin == 6 + L = @(x, kappa, Neq) f(x) + kappa(1:Neq)'*g(x) + kappa(Neq+1:end)'*h(x); + dLdx = @(x, kappa, Neq) df(x) + (kappa(1:Neq)'*dg(x)')' + (kappa(Neq+1:end)'*dh(x)')'; + d2Ldx = @(x, kappa, rho, Neq) get_Hess(dLdx, x, kappa(1:Neq), kappa(Neq + 1: end)); + end +end + +%% get Hessian Function +function d2Ldx = get_Hess(dLdx, x, lambda, mu) + epsilon = 1e-10; + epsilon_inv = 1/epsilon; + nx = length(x); + d2Ldx = sparse(nx, nx); + + kappa = [lambda; mu]; + Neq = numel(lambda); + + for i = 1 : nx + dx_i = [ zeros(i-1, 1); 1; zeros(nx-i, 1)]; + d2Ldx(:, i) = (dLdx(x + epsilon*dx_i, kappa, Neq) ... + - dLdx(x - epsilon*dx_i, kappa, Neq)).*0.5.*epsilon_inv; + end +end diff --git a/06_opf_extension/build_local_state.m b/06_opf_extension/build_local_state.m index 349807e..17e8b20 100644 --- a/06_opf_extension/build_local_state.m +++ b/06_opf_extension/build_local_state.m @@ -1,4 +1,29 @@ function state = build_local_state(mpc, names, postfix) +% BUILD_LOCAL_STATE +% +% `state = build_local_state(mpc, names, postfix)` +% +% _returns symbolic representation of optimization variable_ +% +% # Formate +% Input: +% +% - $\texttt{mpc}$ splitted casefile +% - $\texttt{names}$ specific names of mpc struct fields +% - $\texttt{copy}$ either $\texttt{core}$ or $\texttt{copy}$ +% Output +% - $\texttŧ{state}$ symbolic state +% +% Final formate: +% state = (Vang; Vm; Pg; Qg) (column vector) with +% - Vang = (Vang_1; ... ; Vang_{#Nbuses}) +% - Vm = (Vm_1; ... ; Vm_{#Nbuses}) +% - Pg = (Pg_1; ... ; Pg_{#switched_on_generators}) +% - Qg = (Qg_1; ... ; Qg_{#switched_on_generators}) + + assert (size(mpc.gen, 1) == size(mpc.gen(:, 8) == 1, 1), ... + 'mpc file in build_local_state should only contain generators that are switched on'); + Ngen_on = size(mpc.gen, 1); Ncopy = numel(mpc.(names.copy_buses.local)); Ncore = size(mpc.bus, 1) - Ncopy; diff --git a/06_opf_extension/get_local_variable_from_global_objective_variable.m b/06_opf_extension/get_local_variable_from_global_objective_variable.m new file mode 100644 index 0000000..533b0e5 --- /dev/null +++ b/06_opf_extension/get_local_variable_from_global_objective_variable.m @@ -0,0 +1,47 @@ +function x_local = get_local_variable_from_global_objective_variable(x_global, i_subsystem, mpc_split, names) +% get local objective variable of subsystem i from global variable of +% merged system. + +% To be debugged!!! + +N_subsystems = length(mpc_split.regions); + +assert(i_subsystem <= N_subsystems, 'index of subsystem is larger then total number of subsystem'); + +total_number_of_nodes = length(horzcat(mpc_split.regions{:})); +total_number_of_gens = 0; + +for i = 1 : N_subsystems + mpc_split.split_case_files{i, 1} = prepare_case_file(mpc_split.split_case_files{i, 1}, names); + N_gens{i} = sum(mpc_split.split_case_files{i,1}.gen(:, 8)); + total_number_of_gens = total_number_of_gens + N_gens{i}; +end + +% initizalize raw vectors +theta_local = zeros(1, length(mpc_split.connections_with_aux_nodes{i_subsystem})); +V_local = zeros(1, length(mpc_split.connections_with_aux_nodes{i_subsystem})); +Pg_local = zeros(1, N_gens{i_subsystem}); +Qg_local = zeros(1, N_gens{i_subsystem}); + +gens_before = 0; +for i = 1 : i_subsystem - 1 + gens_before = gens_before + N_gens{i}; +end + +theta_local = x_global(mpc_split.connections_with_aux_nodes{i_subsystem})'; +V_local = x_global(mpc_split.connections_with_aux_nodes{i_subsystem} + total_number_of_nodes)'; + +% get indices corresponding to Pg +for i = 1 : length(Pg_local) + Pg_local(i) = x_global(i + gens_before + 2*total_number_of_nodes); +end + +% get indices corresponding to Qg +for i = 1 : length(Qg_local) + Qg_local(i) = x_global(i + gens_before + total_number_of_gens + 2*total_number_of_nodes); +end + +x_local = vertcat(theta_local', V_local', Pg_local', Qg_local'); + +end + diff --git a/06_opf_extension/mpc_merge.m b/06_opf_extension/mpc_merge.m index 9fb853c..7fa34d0 100644 --- a/06_opf_extension/mpc_merge.m +++ b/06_opf_extension/mpc_merge.m @@ -20,12 +20,12 @@ 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; - 10 1 0 0 0 0 1 1.1 0 230 1 1.1 0.9; - 11 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 11 2 0 0 0 0 1 1 0 230 1 1.1 0.9; 12 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 13 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 14 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; - 15 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 15 1 0 0 0 0 1 1 0 230 1 1.1 0.9; ]; %% generator data @@ -35,14 +35,15 @@ 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; - 5 466.51 0 450 -450 1.1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; + 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 11 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 11 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 13 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 14 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; - 15 466.51 0 450 -450 1.1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; ]; %% branch data @@ -67,7 +68,7 @@ 12 13 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; 13 14 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; 14 15 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; - 9 11 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 6 15 0 0.00623 0 0 0 0 0.985 0 1 0 0; ]; %%----- OPF Data -----%% @@ -84,7 +85,8 @@ 2 0 0 2 15 0; 2 0 0 2 30 0; 2 0 0 2 40 0; + 2 0 0 2 14 0; + 2 0 0 2 15 0; 2 0 0 2 30 0; 2 0 0 2 40 0; - 2 0 0 2 10 0; ]; diff --git a/06_opf_extension/mpc_merge_split.m b/06_opf_extension/mpc_merge_split.m index d911eeb..209b807 100644 --- a/06_opf_extension/mpc_merge_split.m +++ b/06_opf_extension/mpc_merge_split.m @@ -20,12 +20,12 @@ 7 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 8 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 9 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; - 10 1 0 0 0 0 1 1.1 0 230 1 1.1 0.9; - 11 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 10 1 0 0 0 0 1 1 0 230 1 1.1 0.9; + 11 2 0 0 0 0 1 1 0 230 1 1.1 0.9; 12 1 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 13 2 300 98.61 0 0 1 1 0 230 1 1.1 0.9; 14 2 400 131.47 0 0 1 1 0 230 1 1.1 0.9; - 15 2 0 0 0 0 1 1 0 230 1 1.1 0.9; + 15 1 0 0 0 0 1 1 0 230 1 1.1 0.9; ]; %% generator data @@ -35,14 +35,15 @@ 1 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 3 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 4 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; - 5 466.51 0 450 -450 1.1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; + 5 466.51 0 450 -450 1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; 6 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; 6 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 8 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 9 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; + 11 40 0 30 -30 1 100 1 40 0 0 0 0 0 0 0 0 0 0 0 0; + 11 170 0 127.5 -127.5 1 100 1 170 0 0 0 0 0 0 0 0 0 0 0 0; 13 323.49 0 390 -390 1 100 1 520 0 0 0 0 0 0 0 0 0 0 0 0; 14 0 0 150 -150 1 100 1 200 0 0 0 0 0 0 0 0 0 0 0 0; - 15 466.51 0 450 -450 1.1 100 1 600 0 0 0 0 0 0 0 0 0 0 0 0; ]; %% branch data @@ -67,7 +68,7 @@ 12 13 0.00108 0.0108 0.01852 0 0 0 0 0 1 -360 360; 13 14 0.00297 0.0297 0.00674 0 0 0 0 0 1 -360 360; 14 15 0.00297 0.0297 0.00674 240 240 240 0 0 1 -360 360; - 9 11 0 0.00623 0 0 0 0 0.985 0 1 0 0; + 6 15 0 0.00623 0 0 0 0 0.985 0 1 0 0; ]; %%----- OPF Data -----%% @@ -84,7 +85,8 @@ 2 0 0 2 15 0; 2 0 0 2 30 0; 2 0 0 2 40 0; + 2 0 0 2 14 0; + 2 0 0 2 15 0; 2 0 0 2 30 0; 2 0 0 2 40 0; - 2 0 0 2 10 0; ]; diff --git a/06_opf_extension/prepare_case_file.m b/06_opf_extension/prepare_case_file.m index 430066f..82115d8 100644 --- a/06_opf_extension/prepare_case_file.m +++ b/06_opf_extension/prepare_case_file.m @@ -4,6 +4,13 @@ % `[mpc_opf, om, copy_buses_local, mpopt] = prepare_case_file(mpc, names))` % % _Prepares the splitted case file to such that MATPOWER opf functions and methodes can be applied_ +% +% INPUT: - mpc splitted case files +% - names names of mpc struct fields +% OUTPUT: - mpc_opf cleaned up matpower casefile (deleted generators) in MATPOWER internal numering +% - om MATPOWER optimization model of mpc_opf +% - copy_buses_local local copy buses +% - mpopt MATPOWER optimization parameters [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ... MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ... @@ -27,10 +34,9 @@ %% we changed the case file after it was switched to internal indexing % we need to account for that - - + % ??? option in line 40 safer??? mpc.order.state = 'e'; - % mpc = int2ext(mpc); + % mpc = int2ext(mpc); %% return values [mpc_opf, mpopt] = opf_args(mpc); mpc_opf = ext2int(mpc_opf); diff --git a/docs/extension_to_opf.html b/docs/extension_to_opf.html index 6412848..47e4801 100644 --- a/docs/extension_to_opf.html +++ b/docs/extension_to_opf.html @@ -10,7 +10,7 @@
-New files:
-The RapidPF splitted casefiles consist of the following fields:
-Additionally to these fields, the field - if existing in the original case file -
-is transferred by an extension located in the file . The field contains costs for any generator that occurs in the field .
-To use the functions provided by MATPOWER we need to know its structure of its objective variables. MATPOWER's optimization vector for the standard AC OPF proble consists of the vectors of voltage angles and magnitudes and the vectors of generator real and reactive injections and , i.e.
--
Here, corresponds to the number of buses in the system and corresponds to the number of generators in the system.
-At this point we need to be careful as the fields and also do contain the generators at the copy nodes that shall not have any impact on the local objectives. Switching them of in the casefile as it is done in the function leads them in MATPOWER to be treated as non existing, thus giving us the wanted effect.
-Function to prepare the rapidPF splitted case for OPF. Generators at the copy nodes are switched off and gen entries and gencost entries are deleted from the file. -Input:
+Output:
+Tests:
+From the casefiles, all information needed for the distributed solver need to be extracted from the casefile of splitted casefiles. To do so, several functions are called within the fuctions
+ +The RapidPF splitted casefiles consist of the following fields:
+Additionally to these fields, the field - if existing in the original case file -
+is transferred by an extension located in the file . The field contains costs for any generator that occurs in the field .
+To use the functions provided by MATPOWER we need to know its structure of its objective variables. MATPOWER's optimization vector for the standard AC OPF proble consists of the vectors of voltage angles and magnitudes and the vectors of generator real and reactive injections and , i.e.
++
Here, corresponds to the number of buses in the system and corresponds to the number of generators in the system.
+At this point we need to be careful as the fields and also do contain the generators at the copy nodes that shall not have any impact on the local objectives. Switching them of in the casefile as it is done in the function leads them in MATPOWER to be treated as non existing, thus giving us the wanted effect.
+Each system has a local decision variable. We need the following values:
+Each system has a local decision variable. We need the following values:
Then writes as
+Then writes as
-
with
+with
Thus the total dimension of is
+Thus the total dimension of is
+
To calculate the cost function for rapidOPF, the MATPOWER function . The call of returns
+with respect to the structure of illustrated above.
+The results are one to one used by rapidOPF
+To calculate the local equality and inequality constraints for rapidOPF, the MATPOWER function is used. We recall the output formate of :
++
+
The function handles are taken as they are. For , the entries of the copy buses are deleted, for , the columns corresponding to the derivatives of the power flow corresponding to the copy buses are deleted
+The ALADIN Solver needs to be handed over a Lagrangian function and its hessian matrix with respect to x
++
These functions are provided by rapidOPF.
+As consensus matrices we call the matrices that guarantee that the voltage angles and voltage magnitudes at the copy nodes correspond to the voltage angles and magnitudes at the corresponding core nodes in their core system. Therefore, the numbers of connections between all systems are needed. The local matrices are of dimension
++
To fill the consensus matrix, for each system information is needed about the the indices of the local core nodes and the local copy nodes. They are given in the form of a connection table- it consists of four columns that are filled for each connection the another system for each system:
++
To enforce consensus, for each row of the connection table two entries are generated:
+We notice, that we need such a matrix not only for voltage angles but also one such matrix for voltage magnitudes, where the core_bus_entry and the copy_bus_entry need to be shifted to the column corresponding to the voltage entry of the optimization variable.
+For clarity, the dimensions of the outputs are summarized
++
+
The number of inequality constraints is equal to the number of non-zero entries of in the branch specifications of the splitted opf case file
+The local cost functions are scalar valued, the gradients are of dimension , its Hessian is of dimension
+The initial conditions and bounds are again one by one taken by MATPOWER functions .
+[mpc_opf, om, copy_buses_local, mpopt] = prepare_case_file(mpc, names)
Function to prepare the rapidPF splitted casefiles for OPF. Generators at the copy nodes are switched off and gen entries and gencost entries are deleted from the file. +Input:
+Output:
+Tests:
+state = build_local_state(mpc, names, postfix)
Function to build symbolic representation of optimization variable
+Input:
+Output
+Final formate: + (column vector) with
+[vang, vmag, pg, qg] = create\_state\_mp(postfix, Nbus, Ngen)
Subfunction of
+Input:
+Output:
+[cost, grad, hess] = build_local_cost_function(om)
Function to extract opf cost function from MATPOWER to be usable in rapidOPF
+Input:
+Output:
+[constraint_function, Lxx] = build_local_constraint_function(mpc_opf, om, mpopt)
returns the local constraint functions and the Lagrangian of the original problem
+Input:
+[eq, eq_jac] = build_local_equalities(constraint_function, local_buses_to_remove)
Extracts the relevant power flow equation for the core buses. Power flow equations of the copy buses are removed
+Input:
+Output:
+[ineq, ineq_jac] = build_local_equalities(constraint_function, local_buses_to_remove)
Extracts the relevant power flow equation for the core buses. Power flow equations of the copy buses are removed
+Input:
+Output:
+Builds the Lagrangian of the local mpc file
Input:
+Output:
+Remark:
+x0 = build_local_initial_conditions(om)
extracts initial condition for x from MATPOWER
+INPUT:
+OUTPUT:
+[lb, ub] = build_local_bounds(om)
extracts local bounds for x from MATPOWER
+INPUT:
+OUTPUT:
+dims = build_local_dimensions(mpc_opf, eq, ineq, local_buses_to_remove)
creates a field of dimensions as how they should look like and uses it for testing
+INPUT:
+OUTPUT:
+A = create_consensus_matrices_opf(tab, number_of_buses_in_region, number_of_generators_in_region)
creates optimal power flow consensus matrix for distributed optization
+INPUT:
+OUTPUT:
+problem = generate_distributed_opf(mpc, names, ~)
stores the information from the splitted case files to run a distributed optimization with ALADIN
+INPUT:
+[cost, ineq, eq, x0, grad_cost, eq_jac, ineq_jac, lagrangian_hessian, state, dims, lb, ub] = build_local_opf(mpc, names, postfix)
extracts the local functions and information needed for opf
+INPUT:
+