Skip to content

Commit

Permalink
adding possibility have non pv generators
Browse files Browse the repository at this point in the history
  • Loading branch information
BDonnot committed Nov 9, 2023
1 parent 6c73b5c commit 800573b
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Change Log
- [ADDED] sets of methods to extract the main component of a grid and perform powerflow only on this
one.
- [ADDED] possibility to set / retrieve the names of each elements of the grid.
- [ADDED] embed in the generator models the "non pv" behaviour. (TODO need to be able to change Q from python side)
- [IMPROVED] now performing the new grid2op `create_test_suite`
- [IMPROVED] now lightsim2grid properly throw `BackendError`

Expand Down
14 changes: 8 additions & 6 deletions lightsim2grid/gridmodel/from_pypowsybl.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,14 @@ def init(net : pypo.network,
min_q[~np.isfinite(min_q)] = np.finfo(np.float32).min * 0.5 + 1.
max_q[~np.isfinite(max_q)] = np.finfo(np.float32).max * 0.5 - 1.
gen_bus, gen_disco = _aux_get_bus(bus_df, df_gen)
model.init_generators(df_gen["target_p"].values,
df_gen["target_v"].values / voltage_levels.loc[df_gen["voltage_level_id"].values]["nominal_v"].values,
min_q,
max_q,
gen_bus
)
model.init_generators_full(df_gen["target_p"].values,
df_gen["target_v"].values / voltage_levels.loc[df_gen["voltage_level_id"].values]["nominal_v"].values,
df_gen["target_q"].values,
df_gen["voltage_regulator_on"].values,
min_q,
max_q,
gen_bus
)
for gen_id, is_disco in enumerate(gen_disco):
if is_disco:
model.deactivate_gen(gen_id)
Expand Down
78 changes: 63 additions & 15 deletions src/DataGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,40 @@ void DataGen::init(const RealVect & generators_p,
gen_slackbus_ = std::vector<bool>(generators_p.size(), false);
gen_slack_weight_ = std::vector<real_type>(generators_p.size(), 0.);
turnedoff_gen_pv_ = true;
voltage_regulator_on_ = std::vector<bool>(generators_p.size(), true);
q_mvar_ = RealVect::Zero(generators_p.size());
}

void DataGen::init_full(const RealVect & generators_p,
const RealVect & generators_v,
const RealVect & generators_q,
const std::vector<bool> & voltage_regulator_on,
const RealVect & generators_min_q,
const RealVect & generators_max_q,
const Eigen::VectorXi & generators_bus_id
)
{
init(generators_p, generators_v, generators_min_q, generators_max_q, generators_bus_id);
voltage_regulator_on_ = voltage_regulator_on;
q_mvar_ = generators_q;
}


DataGen::StateRes DataGen::get_state() const
{
std::vector<real_type> p_mw(p_mw_.begin(), p_mw_.end());
std::vector<real_type> vm_pu(vm_pu_.begin(), vm_pu_.end());
std::vector<real_type> q_mvar(q_mvar_.begin(), q_mvar_.end());
std::vector<real_type> min_q(min_q_.begin(), min_q_.end());
std::vector<real_type> max_q(max_q_.begin(), max_q_.end());
std::vector<int> bus_id(bus_id_.begin(), bus_id_.end());
std::vector<bool> status = status_;
std::vector<bool> slack_bus = gen_slackbus_;
std::vector<bool> voltage_regulator_on = voltage_regulator_on_;
std::vector<real_type> slack_weight = gen_slack_weight_;
DataGen::StateRes res(names_, turnedoff_gen_pv_, p_mw, vm_pu, min_q, max_q, bus_id, status, slack_bus, slack_weight);
DataGen::StateRes res(names_, turnedoff_gen_pv_, voltage_regulator_on,
p_mw, vm_pu, q_mvar,
min_q, max_q, bus_id, status, slack_bus, slack_weight);
return res;
}

Expand All @@ -69,19 +89,23 @@ void DataGen::set_state(DataGen::StateRes & my_state)
turnedoff_gen_pv_ = std::get<1>(my_state);

// the generators themelves
std::vector<real_type> & p_mw = std::get<2>(my_state);
std::vector<real_type> & vm_pu = std::get<3>(my_state);
std::vector<real_type> & min_q = std::get<4>(my_state);
std::vector<real_type> & max_q = std::get<5>(my_state);
std::vector<int> & bus_id = std::get<6>(my_state);
std::vector<bool> & status = std::get<7>(my_state);
std::vector<bool> & slack_bus = std::get<8>(my_state);
std::vector<real_type> & slack_weight = std::get<9>(my_state);
std::vector<bool> & voltage_regulator_on = std::get<2>(my_state);
std::vector<real_type> & p_mw = std::get<3>(my_state);
std::vector<real_type> & vm_pu = std::get<4>(my_state);
std::vector<real_type> & q_mvar = std::get<5>(my_state);
std::vector<real_type> & min_q = std::get<6>(my_state);
std::vector<real_type> & max_q = std::get<7>(my_state);
std::vector<int> & bus_id = std::get<8>(my_state);
std::vector<bool> & status = std::get<9>(my_state);
std::vector<bool> & slack_bus = std::get<10>(my_state);
std::vector<real_type> & slack_weight = std::get<11>(my_state);
// TODO check sizes

// input data
voltage_regulator_on_ = voltage_regulator_on;
p_mw_ = RealVect::Map(&p_mw[0], p_mw.size());
vm_pu_ = RealVect::Map(&vm_pu[0], vm_pu.size());
q_mvar_ = RealVect::Map(&q_mvar[0], q_mvar.size());
min_q_ = RealVect::Map(&min_q[0], min_q.size());
max_q_ = RealVect::Map(&max_q[0], max_q.size());
bus_id_ = Eigen::VectorXi::Map(&bus_id[0], bus_id.size());
Expand Down Expand Up @@ -118,7 +142,7 @@ RealVect DataGen::get_slack_weights(Eigen::Index nb_bus_solver, const std::vecto
void DataGen::fillSbus(CplxVect & Sbus, const std::vector<int> & id_grid_to_solver, bool ac) const {
const int nb_gen = nb();
int bus_id_me, bus_id_solver;
real_type tmp;
cplx_type tmp;
for(int gen_id = 0; gen_id < nb_gen; ++gen_id){
// i don't do anything if the load is disconnected
if(!status_[gen_id]) continue;
Expand All @@ -133,7 +157,11 @@ void DataGen::fillSbus(CplxVect & Sbus, const std::vector<int> & id_grid_to_solv
exc_ << " is connected to a disconnected bus while being connected to the grid.";
throw std::runtime_error(exc_.str());
}
tmp = p_mw_(gen_id);
tmp = {p_mw_(gen_id), 0.};
if(!voltage_regulator_on_[gen_id]){
// gen is pq if voltage regulaton is off
tmp += my_i * q_mvar_(gen_id);
}
Sbus.coeffRef(bus_id_solver) += tmp;
}
}
Expand All @@ -148,12 +176,11 @@ void DataGen::fillpv(std::vector<int> & bus_pv,
for(int gen_id = 0; gen_id < nb_gen; ++gen_id){
// i don't do anything if the generator is disconnected
if(!status_[gen_id]) continue;
if (!voltage_regulator_on_[gen_id]) continue; // gen is purposedly not pv
if ((!turnedoff_gen_pv_) && p_mw_(gen_id) == 0.) continue; // in this case turned off generators are not pv

bus_id_me = bus_id_(gen_id);
bus_id_solver = id_grid_to_solver[bus_id_me];

if ((!turnedoff_gen_pv_) && p_mw_(gen_id) == 0.) continue; // in this case turned off generators are not pv

if(bus_id_solver == _deactivated_bus_id){
// TODO DEBUG MODE only this in debug mode
std::ostringstream exc_;
Expand All @@ -162,7 +189,7 @@ void DataGen::fillpv(std::vector<int> & bus_pv,
exc_ << " is connected to a disconnected bus while being connected to the grid.";
throw std::runtime_error(exc_.str());
}
// if(bus_id_solver == slack_bus_id_solver) continue; // slack bus is not PV

if(is_in_vect(bus_id_solver, slack_bus_id_solver)) continue; // slack bus is not PV
if(has_bus_been_added[bus_id_solver]) continue; // i already added this bus
bus_pv.push_back(bus_id_solver);
Expand Down Expand Up @@ -199,6 +226,7 @@ void DataGen::get_vm_for_dc(RealVect & Vm){
// i don't do anything if the generator is disconnected
if(!status_[gen_id]) continue;

if (!voltage_regulator_on_[gen_id]) continue; // gen is purposedly not pv
if ((!turnedoff_gen_pv_) && p_mw_(gen_id) == 0.) continue; // in this case turned off generators are not pv

bus_id_me = bus_id_(gen_id);
Expand Down Expand Up @@ -232,6 +260,23 @@ void DataGen::change_p(int gen_id, real_type new_p, bool & need_reset)
p_mw_(gen_id) = new_p;
}

void DataGen::change_q(int gen_id, real_type new_q, bool & need_reset)
{
bool my_status = status_.at(gen_id); // and this check that load_id is not out of bound
if(!my_status)
{
// TODO DEBUG MODE only this in debug mode
std::ostringstream exc_;
exc_ << "DataGen::change_q: Impossible to change the reactive value of a disconnected generator (check gen. id ";
exc_ << gen_id;
exc_ << ")";
throw std::runtime_error(exc_.str());
}
// TODO DEBUG MODE : raise an error if generator is regulating voltage, maybe ?
// this would have not effect
q_mvar_(gen_id) = new_q;
}

void DataGen::change_v(int gen_id, real_type new_v_pu, bool & need_reset)
{
bool my_status = status_.at(gen_id); // and this check that load_id is not out of bound
Expand All @@ -255,6 +300,7 @@ void DataGen::set_vm(CplxVect & V, const std::vector<int> & id_grid_to_solver) c
// i don't do anything if the generator is disconnected
if(!status_[gen_id]) continue;

if (!voltage_regulator_on_[gen_id]) continue; // gen is purposedly not pv
if ((!turnedoff_gen_pv_) && p_mw_(gen_id) == 0.) continue; // in this case turned off generators are not pv

bus_id_me = bus_id_(gen_id);
Expand Down Expand Up @@ -329,6 +375,7 @@ void DataGen::init_q_vector(int nb_bus,
{
if(!status_[gen_id]) continue;

if (!voltage_regulator_on_[gen_id]) continue; // gen is purposedly not pv
if ((!turnedoff_gen_pv_) && p_mw_(gen_id) == 0.) continue; // in this case turned off generators are not pv

int bus_id = bus_id_(gen_id);
Expand All @@ -354,6 +401,7 @@ void DataGen::set_q(const RealVect & reactive_mismatch,
real_type real_q = 0.;
if(!status_[gen_id]) continue; // set at 0 for disconnected generators

if (!voltage_regulator_on_[gen_id]) continue; // gen is purposedly not pv
if ((!turnedoff_gen_pv_) && p_mw_(gen_id) == 0.) continue; // in this case turned off generators are not pv

int bus_id = bus_id_(gen_id);
Expand Down
20 changes: 20 additions & 0 deletions src/DataGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ class DataGen: public DataGeneric
bool is_slack;
real_type slack_weight;

bool voltage_regulator_on;
real_type target_p_mw;
real_type target_vm_pu;
real_type target_q_mvar;
real_type min_q_mvar;
real_type max_q_mvar;
bool has_res;
Expand All @@ -62,8 +64,10 @@ class DataGen: public DataGeneric
bus_id(-1),
is_slack(false),
slack_weight(-1.0),
voltage_regulator_on(false),
target_p_mw(0.),
target_vm_pu(0.),
target_q_mvar(0.),
min_q_mvar(0.),
max_q_mvar(0.),
has_res(false),
Expand All @@ -83,8 +87,10 @@ class DataGen: public DataGeneric
is_slack = r_data_gen.gen_slackbus_[my_id];
slack_weight = r_data_gen.gen_slack_weight_[my_id];

voltage_regulator_on = r_data_gen.voltage_regulator_on_[my_id];
target_p_mw = r_data_gen.p_mw_.coeff(my_id);
target_vm_pu = r_data_gen.vm_pu_.coeff(my_id);
target_q_mvar = r_data_gen.q_mvar_.coeff(my_id);
min_q_mvar = r_data_gen.min_q_.coeff(my_id);
max_q_mvar = r_data_gen.max_q_.coeff(my_id);

Expand All @@ -108,8 +114,10 @@ class DataGen: public DataGeneric
typedef std::tuple<
std::vector<std::string>,
bool,
std::vector<bool>, // voltage_regulator_on
std::vector<real_type>, // p_mw
std::vector<real_type>, // vm_pu_
std::vector<real_type>, // q_mvar_
std::vector<real_type>, // min_q_
std::vector<real_type>, // max_q_
std::vector<int>, // bus_id
Expand All @@ -129,6 +137,15 @@ class DataGen: public DataGeneric
const Eigen::VectorXi & generators_bus_id
);

void init_full(const RealVect & generators_p,
const RealVect & generators_v,
const RealVect & generators_q,
const std::vector<bool> & voltage_regulator_on,
const RealVect & generators_min_q,
const RealVect & generators_max_q,
const Eigen::VectorXi & generators_bus_id
);

int nb() const { return static_cast<int>(p_mw_.size()); }

// iterator
Expand Down Expand Up @@ -220,6 +237,7 @@ class DataGen: public DataGeneric
real_type get_qmin(int gen_id) {return min_q_.coeff(gen_id);}
real_type get_qmax(int gen_id) {return max_q_.coeff(gen_id);}
void change_p(int gen_id, real_type new_p, bool & need_reset);
void change_q(int gen_id, real_type new_q, bool & need_reset);
void change_v(int gen_id, real_type new_v_pu, bool & need_reset);

virtual void fillSbus(CplxVect & Sbus, const std::vector<int> & id_grid_to_solver, bool ac) const;
Expand Down Expand Up @@ -271,8 +289,10 @@ class DataGen: public DataGeneric
// physical properties

// input data
std::vector<bool> voltage_regulator_on_;
RealVect p_mw_;
RealVect vm_pu_;
RealVect q_mvar_;
RealVect min_q_;
RealVect max_q_;
Eigen::VectorXi bus_id_;
Expand Down
10 changes: 10 additions & 0 deletions src/GridModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,16 @@ class GridModel : public DataGeneric
const Eigen::VectorXi & generators_bus_id){
generators_.init(generators_p, generators_v, generators_min_q, generators_max_q, generators_bus_id);
}
void init_generators_full(const RealVect & generators_p,
const RealVect & generators_v,
const RealVect & generators_q,
const std::vector<bool> & voltage_regulator_on,
const RealVect & generators_min_q,
const RealVect & generators_max_q,
const Eigen::VectorXi & generators_bus_id){
generators_.init_full(generators_p, generators_v, generators_q, voltage_regulator_on,
generators_min_q, generators_max_q, generators_bus_id);
}
void init_loads(const RealVect & loads_p,
const RealVect & loads_q,
const Eigen::VectorXi & loads_bus_id){
Expand Down
3 changes: 3 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,10 @@ PYBIND11_MODULE(lightsim2grid_cpp, m)
.def_readonly("bus_id", &DataGen::GenInfo::bus_id, DocIterator::bus_id.c_str())
.def_readonly("is_slack", &DataGen::GenInfo::is_slack, DocIterator::is_slack.c_str())
.def_readonly("slack_weight", &DataGen::GenInfo::slack_weight, DocIterator::slack_weight.c_str())
.def_readonly("voltage_regulator_on", &DataGen::GenInfo::voltage_regulator_on, "TODO")
.def_readonly("target_p_mw", &DataGen::GenInfo::target_p_mw, DocIterator::target_p_mw.c_str())
.def_readonly("target_vm_pu", &DataGen::GenInfo::target_vm_pu, DocIterator::target_vm_pu.c_str())
.def_readonly("target_q_mvar", &DataGen::GenInfo::target_q_mvar, "TODO")
.def_readonly("min_q_mvar", &DataGen::GenInfo::min_q_mvar, DocIterator::min_q_mvar.c_str())
.def_readonly("max_q_mvar", &DataGen::GenInfo::max_q_mvar, DocIterator::max_q_mvar.c_str())
.def_readonly("has_res", &DataGen::GenInfo::has_res, DocIterator::has_res.c_str())
Expand Down Expand Up @@ -642,6 +644,7 @@ PYBIND11_MODULE(lightsim2grid_cpp, m)
.def("init_shunt", &GridModel::init_shunt, DocGridModel::_internal_do_not_use.c_str()) // same
.def("init_trafo", &GridModel::init_trafo, DocGridModel::_internal_do_not_use.c_str()) // same
.def("init_generators", &GridModel::init_generators, DocGridModel::_internal_do_not_use.c_str()) // same
.def("init_generators_full", &GridModel::init_generators_full, DocGridModel::_internal_do_not_use.c_str()) // same
.def("init_loads", &GridModel::init_loads, DocGridModel::_internal_do_not_use.c_str()) // same
.def("init_storages", &GridModel::init_storages, DocGridModel::_internal_do_not_use.c_str()) // same
.def("init_sgens", &GridModel::init_sgens, DocGridModel::_internal_do_not_use.c_str()) // same
Expand Down

0 comments on commit 800573b

Please sign in to comment.