All Downloads are FREE. Search and download functionalities are using the official Maven repository.

openreac.acopf.run Maven / Gradle / Ivy

The newest version!
###############################################################################
#
# Copyright (c) 2022 2023 2024, RTE (http://www.rte-france.com)
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
#
###############################################################################

###############################################################################
# Reactive OPF
# Author:  Jean Maeght 2022 2023
# Author:  Manuel Ruiz 2023 2024
###############################################################################


###############################################################################
# Initial values of the solving
###############################################################################

# DC values used as initialization for phases
let {n in BUSCC} teta[n] := teta_dc[n];

# Voltages
let {n in BUSVV}            V[n] := bus_V0[1,n];
let {n in BUSCC diff BUSVV} V[n] := voltage_lower_bound[1,bus_substation[1,n]]
  + 0.8 *(voltage_upper_bound[1,bus_substation[1,n]] - voltage_lower_bound[1,bus_substation[1,n]]);

let {n in BUSCC_SLACK} slack1_shunt_B[n] := 0;
let {n in BUSCC_SLACK} slack2_shunt_B[n] := 0;
let alpha := 0.01;
let {(g,n) in UNITON} P_bounded[g,n] := max(P_dcopf[g,n],unit_Pc[1,g,n]);
let {(g,n) in UNITON} Q[g,n] := 0.5*(corrected_unit_Qmax[g,n] + corrected_unit_Qmin[g,n]);
let {(shunt,n) in SHUNT_VAR} shunt_var[shunt,n] := min{(1,shunt,k) in SHUNT} shunt_valnom[1,shunt,k];
let {(svc,n) in SVCON} svc_qvar[svc,n] := 0.1;
let {(v,n) in VSCCONVON} vscconv_qvar[v,n] := if abs(vscconv_targetQ[1,v,n]) < PQmax then vscconv_targetQ[1,v,n] else 0;
let {(qq,m,n) in BRANCHCC_REGL_VAR} branch_Ror_var[qq,m,n] := branch_Ror[qq,m,n];


###############################################################################
# Solve
###############################################################################

let PROBLEM_ACOPF := {1};
let tempstr := ctime();
printf{LOG_KNITRO} "\n######################################################################\n";
printf{LOG_KNITRO} "** ACopf solve: start (%s)\n\n",ctime();

option knitro_options ("opttol=1 opttolabs=1e-1 feastol=1 feastolabs=1e-3 maxit=1000 outlev=3");

let {i in 1.._nvars} _var[i].xscalefactor := default_variable_scaling_factor;
let {i in 1.._ncons} _con[i].cscalefactor := default_constraint_scaling_factor;

let {n in BUSCC_SLACK} slack1_shunt_B[n].xscalefactor := reactive_slack_variable_scaling_factor;
let {n in BUSCC_SLACK} slack2_shunt_B[n].xscalefactor := reactive_slack_variable_scaling_factor;

let {(qq,m,n) in BRANCHCC_REGL_VAR} branch_Ror_var[qq,m,n].xscalefactor := transformer_ratio_variable_scaling_factor;

let {(shunt,n) in SHUNT_VAR} shunt_var[shunt,n].xscalefactor := shunt_variable_scaling_factor;

# solve acopf and avoid knitro printing if user asks
if (log_level_knitro <= 1) then {
  solve problem_acopf_objective > (nullDevice);
} else {
  solve problem_acopf_objective;
}


let nb_iter_last := problem_acopf_objective.numiters;
let nb_iter_total := nb_iter_total + nb_iter_last;

printf{LOG_KNITRO} "\n** ACopf solve: end   (%s -> %s)\n",tempstr,ctime();
printf{LOG_KNITRO} "######################################################################\n\n";

param slack1_balance_Q{n in BUSCC_SLACK};
param slack2_balance_Q{n in BUSCC_SLACK};
for {n in BUSCC_SLACK} {
  let slack1_balance_Q[n] := base100MVA * V[n]^2 * slack1_shunt_B[n].val;
  let slack2_balance_Q[n] := base100MVA * V[n]^2 * slack2_shunt_B[n].val;
}

###############################################################################
# Analysis of solve_result_num
###############################################################################

# <= 103 : feasible
# 200 convergence to unfeasible
# > 200 : failure
if solve_result_num == 200
then {
  let output_results := 0;
  let messageInfo := "Acopf optimization was ***not*** successfull - Convergence to an infeasible solution";
  printf{LOG_ERROR} "%s\n", messageInfo;
  let messagesInfo := messagesInfo union {messageInfo};
  let final_status := "NOK";
}
else if solve_result_num > 103
then {
  let output_results := 0;
  let messageInfo := "Acopf optimization was ***not*** successfull - no solution found";
  printf{LOG_ERROR} "%s\n", messageInfo;
  let messagesInfo := messagesInfo union {messageInfo};
  let final_status := "NOK";
}
else {
  let output_results := 1;
  let final_status := "OK";
}


###############################################################################
# Displays after solving
###############################################################################

printf{LOG_INFO} "\n######################################################################\n";
printf{LOG_INFO} "** ACopf results\n";
if 1 in LOG_INFO then display
  nb_iter_last,nb_iter_total,
  max({(qq,m,n) in BRANCHCC} branch_R[1,qq,m,n]),max({(qq,m,n) in BRANCHCC} branch_X[1,qq,m,n]),
  teta_max, max({n in BUSCC} teta[n]), max({n in BUSCC} teta_dc[n]),
  teta_min, min({n in BUSCC} teta[n]), min({n in BUSCC} teta_dc[n]),
  max({(qq,m,n) in BRANCHCC} (teta[m]-teta[n])), max({(qq,m,n) in BRANCHCC} (teta_dc[m]-teta_dc[n])),
  min({(qq,m,n) in BRANCHCC} (teta[m]-teta[n])), min({(qq,m,n) in BRANCHCC} (teta_dc[m]-teta_dc[n])),
  min({n in BUSCC}V[n]),max({n in BUSCC}V[n])
  ;

let temp1 := max({(qq,m,n) in BRANCHCC} (teta[m]-teta[n]));
let temp2 := min({(qq,m,n) in BRANCHCC} (teta[m]-teta[n]));

for {(qq,m,n) in BRANCHCC: (teta[m]-teta[n])>temp1*0.99 or (teta[m]-teta[n]) Pnull
then {

  if 1 in LOG_INFO then
  display
    sum{n in BUSCC_SLACK} slack1_balance_Q[n],
    sum{n in BUSCC_SLACK} slack2_balance_Q[n],
    max{n in BUSCC_SLACK} slack1_balance_Q[n],
    max{n in BUSCC_SLACK} slack2_balance_Q[n],
    card({n in BUSCC_SLACK: slack2_balance_Q[n]+slack1_balance_Q[n]>Pnull});

  if output_results > 0 then
    if card({n in BUSCC_SLACK: slack1_balance_Q[n]+slack2_balance_Q[n] > Pnull}) > 0 then printf{LOG_WARNING} "WARNING buses with non zero reactive slack :\n";
    for {n in BUSCC_SLACK: slack1_balance_Q[n]+slack2_balance_Q[n] > Pnull}
      printf{LOG_WARNING} "Bus %Q in substation %Q (%ikV) has non zero reactive slacks %.1f %.1f, Vmin=%.3f Vopt=%.3f Vmax=%.3f \n",
        bus_id[1,n],substation_id[1,bus_substation[1,n]],substation_Vnomi[1,bus_substation[1,n]],
        slack1_balance_Q[n],slack2_balance_Q[n],
        voltage_lower_bound[1,bus_substation[1,n]],V[n],voltage_upper_bound[1,bus_substation[1,n]];
}

let PROBLEM_ACOPF := { };




© 2015 - 2024 Weber Informatics LLC | Privacy Policy