From 1a26d3fe7cc8f4153a5fa6f3d204138d9d8331ad Mon Sep 17 00:00:00 2001 From: DONNOT Benjamin Date: Fri, 22 Mar 2024 10:47:31 +0100 Subject: [PATCH] small speed ups + fix a broken test in DC, load_p was not 0 --- lightsim2grid/lightSimBackend.py | 99 ++++++++-------------- lightsim2grid/tests/test_DCPF.py | 5 +- src/BaseConstants.cpp | 1 + src/BaseConstants.h | 1 + src/GridModel.h | 13 +++ src/Utils.h | 12 ++- src/element_container/DCLineContainer.h | 3 + src/element_container/GeneratorContainer.h | 1 + src/element_container/GenericContainer.cpp | 2 +- src/element_container/LineContainer.cpp | 4 +- src/element_container/LineContainer.h | 3 +- src/element_container/LoadContainer.cpp | 2 - src/element_container/LoadContainer.h | 2 + src/element_container/SGenContainer.h | 1 + src/element_container/ShuntContainer.h | 2 + src/element_container/TrafoContainer.cpp | 6 +- src/element_container/TrafoContainer.h | 2 + src/main.cpp | 13 ++- src/powerflow_algorithm/BaseNRAlgo.tpp | 4 +- 19 files changed, 98 insertions(+), 78 deletions(-) diff --git a/lightsim2grid/lightSimBackend.py b/lightsim2grid/lightSimBackend.py index 81b2ad4..8a1934f 100644 --- a/lightsim2grid/lightSimBackend.py +++ b/lightsim2grid/lightSimBackend.py @@ -141,7 +141,8 @@ def __init__(self, self._timer_postproc = 0. self._timer_solver = 0. self._timer_read_data_back = 0. - self._timer_test_read = 0. + self._timer_fetch_data_cpp = 0. + self._timer_apply_act = 0. self.next_prod_p = None # this vector is updated with the action that will modify the environment # it is done to keep track of the redispatching @@ -187,6 +188,7 @@ def __init__(self, self.sh_p = None self.sh_q = None self.sh_v = None + self.sh_theta = None self.sh_bus = None # voltage angle @@ -222,7 +224,8 @@ def __init__(self, self._timer_preproc = 0. self._timer_solver = 0. self._timer_read_data_back = 0. - self._timer_test_read = 0. + self._timer_fetch_data_cpp = 0. + self._timer_apply_act = 0. # hack for the storage unit: # in grid2op, for simplicity, I suppose that if a storage is alone on a busbar, and @@ -291,25 +294,6 @@ def turnedoff_no_pv(self): def turnedoff_pv(self): self._turned_off_pv = True self._grid.turnedoff_pv() - - def _fill_theta(self): - tick = time.perf_counter() - # line_or_theta = np.empty(self.n_line) - self.line_or_theta[:self.__nb_powerline] = self._grid.get_lineor_theta() - self.line_or_theta[self.__nb_powerline:] = self._grid.get_trafohv_theta() - - # line_ex_theta = np.empty(self.n_line) - self.line_ex_theta[:self.__nb_powerline] = self._grid.get_lineex_theta() - self.line_ex_theta[self.__nb_powerline:] = self._grid.get_trafolv_theta() - - # line_or_theta = np.concatenate((self._grid.get_lineor_theta(), self._grid.get_trafohv_theta())) - # line_ex_theta = np.concatenate((self._grid.get_lineex_theta(), self._grid.get_trafolv_theta())) - self.load_theta[:] = self._grid.get_load_theta() - self.gen_theta[:] = self._grid.get_gen_theta() - - if self.__has_storage: - self.storage_theta[:] = self._grid.get_storage_theta() - self._timer_read_data_back += time.perf_counter() - tick def get_theta(self): """ @@ -852,6 +836,7 @@ def _aux_finish_setup_after_reading(self): self.sh_p = np.full(cls.n_shunt, dtype=dt_float, fill_value=np.NaN).reshape(-1) self.sh_q = np.full(cls.n_shunt, dtype=dt_float, fill_value=np.NaN).reshape(-1) self.sh_v = np.full(cls.n_shunt, dtype=dt_float, fill_value=np.NaN).reshape(-1) + self.sh_theta = np.full(cls.n_shunt, dtype=dt_float, fill_value=np.NaN).reshape(-1) self.sh_bus = np.full(cls.n_shunt, dtype=dt_int, fill_value=-1).reshape(-1) self.p_or = np.full(cls.n_line, dtype=dt_float, fill_value=np.NaN).reshape(-1) @@ -966,6 +951,7 @@ def apply_action(self, backendAction): """ Specific implementation of the method to apply an action modifying a powergrid in the pandapower format. """ + tick = time.perf_counter() active_bus, *_, topo__, shunts__ = backendAction() # change the overall topology @@ -1017,7 +1003,8 @@ def apply_action(self, backendAction): self._grid.change_q_shunt(sh_id, new_q) self._handle_dist_slack() - + self._timer_apply_act += time.perf_counter() - tick + def _handle_dist_slack(self): if self._dist_slack_non_renew: self._grid.update_slack_weights(type(self).gen_redispatchable) @@ -1025,22 +1012,22 @@ def _handle_dist_slack(self): def _fetch_grid_data(self): beg_test = time.perf_counter() if self._lineor_res is None: - self._lineor_res = self._grid.get_lineor_res() + self._lineor_res = self._grid.get_lineor_res_full() if self._lineex_res is None: - self._lineex_res = self._grid.get_lineex_res() + self._lineex_res = self._grid.get_lineex_res_full() if self._load_res is None: - self._load_res = self._grid.get_loads_res() + self._load_res = self._grid.get_loads_res_full() if self._gen_res is None: - self._gen_res = self._grid.get_gen_res() + self._gen_res = self._grid.get_gen_res_full() if self._trafo_hv_res is None: - self._trafo_hv_res = self._grid.get_trafohv_res() + self._trafo_hv_res = self._grid.get_trafohv_res_full() if self._trafo_lv_res is None: - self._trafo_lv_res = self._grid.get_trafolv_res() + self._trafo_lv_res = self._grid.get_trafolv_res_full() if self._storage_res is None: - self._storage_res = self._grid.get_storages_res() + self._storage_res = self._grid.get_storages_res_full() if self._shunt_res is None: - self._shunt_res = self._grid.get_shunts_res() - self._timer_test_read += time.perf_counter() - beg_test + self._shunt_res = self._grid.get_shunts_res_full() + self._timer_fetch_data_cpp += time.perf_counter() - beg_test def runpf(self, is_dc=False): my_exc_ = None @@ -1103,19 +1090,23 @@ def runpf(self, is_dc=False): (self.p_or[:self.__nb_powerline], self.q_or[:self.__nb_powerline], self.v_or[:self.__nb_powerline], - self.a_or[:self.__nb_powerline]) = self._lineor_res + self.a_or[:self.__nb_powerline], + self.line_or_theta[:self.__nb_powerline]) = self._lineor_res (self.p_or[self.__nb_powerline:], self.q_or[self.__nb_powerline:], self.v_or[self.__nb_powerline:], - self.a_or[self.__nb_powerline:]) = self._trafo_hv_res + self.a_or[self.__nb_powerline:], + self.line_or_theta[self.__nb_powerline:]) = self._trafo_hv_res (self.p_ex[:self.__nb_powerline], self.q_ex[:self.__nb_powerline], self.v_ex[:self.__nb_powerline], - self.a_ex[:self.__nb_powerline]) = self._lineex_res + self.a_ex[:self.__nb_powerline], + self.line_ex_theta[:self.__nb_powerline]) = self._lineex_res (self.p_ex[self.__nb_powerline:], self.q_ex[self.__nb_powerline:], self.v_ex[self.__nb_powerline:], - self.a_ex[self.__nb_powerline:]) = self._trafo_lv_res + self.a_ex[self.__nb_powerline:], + self.line_ex_theta[self.__nb_powerline:]) = self._trafo_lv_res self.a_or *= 1000. # kA in lightsim, A expected in grid2op self.a_ex *= 1000. # kA in lightsim, A expected in grid2op @@ -1125,10 +1116,10 @@ def runpf(self, is_dc=False): self.a_ex[~np.isfinite(self.a_ex)] = 0. self.v_ex[~np.isfinite(self.v_ex)] = 0. - self.load_p[:], self.load_q[:], self.load_v[:] = self._load_res - self.prod_p[:], self.prod_q[:], self.prod_v[:] = self._gen_res + self.load_p[:], self.load_q[:], self.load_v[:], self.load_theta[:] = self._load_res + self.prod_p[:], self.prod_q[:], self.prod_v[:], self.gen_theta[:] = self._gen_res if self.__has_storage: - self.storage_p[:], self.storage_q[:], self.storage_v[:] = self._storage_res + self.storage_p[:], self.storage_q[:], self.storage_v[:], self.storage_theta[:] = self._storage_res self.storage_v[self.storage_v == -1.] = 0. # voltage is 0. for disconnected elements in grid2op self._timer_read_data_back += time.perf_counter() - beg_readback @@ -1148,8 +1139,6 @@ def runpf(self, is_dc=False): if type(self).shunts_data_available: self._set_shunt_info() - - self._fill_theta() if (self.line_or_theta >= 1e6).any() or (self.line_ex_theta >= 1e6).any(): raise BackendError(f"Some theta are above 1e6 which should not be happening !") @@ -1200,6 +1189,7 @@ def _fill_nans(self): self.sh_p[:] = np.NaN self.sh_q[:] = np.NaN self.sh_v[:] = np.NaN + self.sh_theta[:] = np.NaN self.sh_bus[:] = -1 if self.__has_storage: @@ -1275,12 +1265,12 @@ def copy(self): "_big_topo_to_obj", "dim_topo", "_idx_hack_storage", "_timer_preproc", "_timer_postproc", "_timer_solver", - "_timer_read_data_back", + "_timer_read_data_back", "_timer_apply_act", "supported_grid_format", "max_it", "tol", "_turned_off_pv", "_dist_slack_non_renew", "_use_static_gen", "_loader_method", "_loader_kwargs", "_stop_if_load_disco", "_stop_if_gen_disco", - "_timer_test_read" + "_timer_fetch_data_cpp" ] for attr_nm in li_regular_attr: if hasattr(self, attr_nm): @@ -1298,7 +1288,7 @@ def copy(self): "load_p", "load_q", "load_v", "prod_p", "prod_q", "prod_v", "storage_p", "storage_q", "storage_v", - "sh_p", "sh_q", "sh_v", "sh_bus", + "sh_p", "sh_q", "sh_v", "sh_bus", "sh_theta", "line_or_theta", "line_ex_theta", "load_theta", "gen_theta", "storage_theta", ] for attr_nm in li_attr_npy: @@ -1409,26 +1399,10 @@ def _compute_shunt_bus_with_compat(self, shunt_bus): def _set_shunt_info(self): tick = time.perf_counter() - self.sh_p[:], self.sh_q[:], self.sh_v[:] = self._shunt_res - # cls = type(self) - # shunt_bus = np.array([self._grid.get_bus_shunt(i) for i in range(cls.n_shunt)], dtype=dt_int) - # shunt_bus = self._grid.get_all_shunt_buses() - # if hasattr(cls, "global_bus_to_local"): - # self.sh_bus[:] = cls.global_bus_to_local(shunt_bus, cls.shunt_to_subid) - # else: - # res = (1 * shunt_bus).astype(dt_int) # make a copy - # if hasattr(cls, "n_busbar_per_sub"): - # n_busbar_per_sub = cls.n_busbar_per_sub - # else: - # # backward compat when this was not defined: - # n_busbar_per_sub = DEFAULT_N_BUSBAR_PER_SUB - # for i in range(n_busbar_per_sub): - # res[(i * cls.n_sub <= shunt_bus) & (shunt_bus < (i+1) * cls.n_sub)] = i + 1 - # res[shunt_bus == -1] = -1 - # self.sh_bus[:] = res + self.sh_p[:], self.sh_q[:], self.sh_v[:], self.sh_theta[:] = self._shunt_res self.sh_v[self.sh_v == -1.] = 0. # in grid2op disco element have voltage of 0. and -1. self._timer_read_data_back += time.perf_counter() - tick - # self._timer_test_read += time.perf_counter() - tick + # self._timer_fetch_data_cpp += time.perf_counter() - tick def _disconnect_line(self, id_): self.topo_vect[self.line_ex_pos_topo_vect[id_]] = -1 @@ -1453,7 +1427,8 @@ def reset(self, grid_path, grid_filename=None): self._timer_preproc = 0. self._timer_solver = 0. self._timer_read_data_back = 0. - self._timer_test_read = 0. + self._timer_fetch_data_cpp = 0. + self._timer_apply_act = 0. self._grid.tell_solver_need_reset() self.sh_bus[:] = 1 # TODO self._compute_shunt_bus_with_compat(self._grid.get_all_shunt_buses()) self.topo_vect[:] = self.__init_topo_vect # TODO diff --git a/lightsim2grid/tests/test_DCPF.py b/lightsim2grid/tests/test_DCPF.py index 3e910d7..6faf256 100644 --- a/lightsim2grid/tests/test_DCPF.py +++ b/lightsim2grid/tests/test_DCPF.py @@ -196,8 +196,9 @@ def _aux_test(self, pn_net): load_p, load_q, load_v = backend.loads_info() max_mis = np.max(np.abs(load_p - load_p_pp)) assert max_mis <= self.tol, f"Error: load_p do not match, maximum absolute error is {max_mis:.5f} MW" - max_mis = np.max(np.abs(load_q - load_q_pp)) - assert max_mis <= self.tol, f"Error: load_q do not match, maximum absolute error is {max_mis:.5f} MVAr" + # PP does not set "load_q" to 0. in DC + # max_mis = np.max(np.abs(load_q - load_q_pp)) + # assert max_mis <= self.tol, f"Error: load_q do not match, maximum absolute error is {max_mis:.5f} MVAr" max_mis = np.max(np.abs(load_v - load_v_pp)) assert max_mis <= self.tol, f"Error: load_v do not match, maximum absolute error is {max_mis:.5f} kV" diff --git a/src/BaseConstants.cpp b/src/BaseConstants.cpp index ba02112..fe1ba35 100644 --- a/src/BaseConstants.cpp +++ b/src/BaseConstants.cpp @@ -14,3 +14,4 @@ const real_type BaseConstants::my_one_ = 1.0; const real_type BaseConstants::my_two_ = 2.0; const real_type BaseConstants::my_half_ = 0.5; const real_type BaseConstants::my_zero_ = 0.; +const real_type BaseConstants::my_180_pi_ = 180. / M_PI; diff --git a/src/BaseConstants.h b/src/BaseConstants.h index 7d6f268..329aabf 100644 --- a/src/BaseConstants.h +++ b/src/BaseConstants.h @@ -24,6 +24,7 @@ class BaseConstants static const real_type my_one_; static const real_type my_two_; static const real_type my_zero_; + static const real_type my_180_pi_; }; enum class FDPFMethod {XB, BX}; // Different type of FDPF powerflow diff --git a/src/GridModel.h b/src/GridModel.h index f9a863b..2ffd4f3 100644 --- a/src/GridModel.h +++ b/src/GridModel.h @@ -496,6 +496,19 @@ class GridModel : public GenericContainer Eigen::Ref get_all_shunt_buses() const {return shunts_.get_buses();} + // complete results (with theta) + tuple4d get_loads_res_full() const {return loads_.get_res_full();} + tuple4d get_shunts_res_full() const {return shunts_.get_res_full();} + tuple4d get_gen_res_full() const {return generators_.get_res_full();} + tuple5d get_lineor_res_full() const {return powerlines_.get_res_or_full();} + tuple5d get_lineex_res_full() const {return powerlines_.get_res_ex_full();} + tuple5d get_trafohv_res_full() const {return trafos_.get_res_hv_full();} + tuple5d get_trafolv_res_full() const {return trafos_.get_res_lv_full();} + tuple4d get_storages_res_full() const {return storages_.get_res_full();} + tuple4d get_sgens_res_full() const {return sgens_.get_res_full();} + tuple4d get_dclineor_res_full() const {return dc_lines_.get_res_or_full();} + tuple4d get_dclineex_res_full() const {return dc_lines_.get_res_ex_full();} + // get some internal information, be cerafull the ID of the buses might not be the same // TODO convert it back to this ID, that will make copies, but who really cares ? Eigen::SparseMatrix get_Ybus(){ diff --git a/src/Utils.h b/src/Utils.h index eeaec05..4cb448e 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -22,6 +22,10 @@ typedef double real_type; // type for real numbers: can be changed if installed typedef std::complex cplx_type; // type for complex number typedef Eigen::Matrix EigenPythonNumType; // Eigen::VectorXd +typedef Eigen::Matrix IntVect; +typedef Eigen::Matrix RealVect; +typedef Eigen::Matrix CplxVect; + typedef std::tuple, Eigen::Ref, Eigen::Ref > tuple3d; @@ -29,9 +33,11 @@ typedef std::tuple, Eigen::Ref, Eigen::Ref, Eigen::Ref > tuple4d; -typedef Eigen::Matrix IntVect; -typedef Eigen::Matrix RealVect; -typedef Eigen::Matrix CplxVect; +typedef std::tuple, + Eigen::Ref, + Eigen::Ref, + Eigen::Ref, + Eigen::Ref > tuple5d; typedef Eigen::Matrix RealMat; typedef Eigen::Matrix CplxMat; diff --git a/src/element_container/DCLineContainer.h b/src/element_container/DCLineContainer.h index a64fb1f..400c1a5 100644 --- a/src/element_container/DCLineContainer.h +++ b/src/element_container/DCLineContainer.h @@ -294,6 +294,9 @@ class DCLineContainer : public GenericContainer tuple3d get_or_res() const {return from_gen_.get_res();} tuple3d get_ex_res() const {return to_gen_.get_res();} + tuple4d get_res_or_full() const {return from_gen_.get_res_full();} + tuple4d get_res_ex_full() const {return to_gen_.get_res_full();} + Eigen::Ref get_theta_or() const {return from_gen_.get_theta();} Eigen::Ref get_theta_ex() const {return to_gen_.get_theta();} diff --git a/src/element_container/GeneratorContainer.h b/src/element_container/GeneratorContainer.h index c8c86e6..a47f7f0 100644 --- a/src/element_container/GeneratorContainer.h +++ b/src/element_container/GeneratorContainer.h @@ -324,6 +324,7 @@ class GeneratorContainer: public GenericContainer virtual void gen_p_per_bus(std::vector & res) const; tuple3d get_res() const {return tuple3d(res_p_, res_q_, res_v_);} + tuple4d get_res_full() const {return tuple4d(res_p_, res_q_, res_v_, res_theta_);} Eigen::Ref get_theta() const {return res_theta_;} const std::vector& get_status() const {return status_;} diff --git a/src/element_container/GenericContainer.cpp b/src/element_container/GenericContainer.cpp index fc8ce14..e7c7ccd 100644 --- a/src/element_container/GenericContainer.cpp +++ b/src/element_container/GenericContainer.cpp @@ -162,6 +162,6 @@ void GenericContainer::v_deg_from_va(const Eigen::Ref & Va, exc_ << " is connected to a disconnected bus"; throw std::runtime_error(exc_.str()); } - theta(el_id) = Va(bus_solver_id) * 180. / my_pi; + theta(el_id) = Va(bus_solver_id) * my_180_pi_; } } diff --git a/src/element_container/LineContainer.cpp b/src/element_container/LineContainer.cpp index 662a1b1..fdcf6bc 100644 --- a/src/element_container/LineContainer.cpp +++ b/src/element_container/LineContainer.cpp @@ -426,8 +426,8 @@ void LineContainer::compute_results(const Eigen::Ref & Va, res_powerline_vex_(line_id) = v_ex * bus_vn_kv_ex; // retrieve the voltage angle in degree (instead of radian) - res_powerline_thetaor_(line_id) = Va(bus_or_solver_id) * 180. / my_pi; - res_powerline_thetaex_(line_id) = Va(bus_ex_solver_id) * 180. / my_pi; + res_powerline_thetaor_(line_id) = Va(bus_or_solver_id) * my_180_pi_; + res_powerline_thetaex_(line_id) = Va(bus_ex_solver_id) * my_180_pi_; // results of the powerflow cplx_type Eor = V(bus_or_solver_id); diff --git a/src/element_container/LineContainer.h b/src/element_container/LineContainer.h index 7e6acf4..531729f 100644 --- a/src/element_container/LineContainer.h +++ b/src/element_container/LineContainer.h @@ -247,7 +247,8 @@ class LineContainer : public GenericContainer tuple4d get_lineor_res() const {return tuple4d(res_powerline_por_, res_powerline_qor_, res_powerline_vor_, res_powerline_aor_);} tuple4d get_lineex_res() const {return tuple4d(res_powerline_pex_, res_powerline_qex_, res_powerline_vex_, res_powerline_aex_);} - + tuple5d get_res_or_full() const {return tuple5d(res_powerline_por_, res_powerline_qor_, res_powerline_vor_, res_powerline_aor_, res_powerline_thetaor_);} + tuple5d get_res_ex_full() const {return tuple5d(res_powerline_pex_, res_powerline_qex_, res_powerline_vex_, res_powerline_aex_, res_powerline_thetaex_);} Eigen::Ref get_theta_or() const {return res_powerline_thetaor_;} Eigen::Ref get_theta_ex() const {return res_powerline_thetaex_;} const std::vector& get_status() const {return status_;} diff --git a/src/element_container/LoadContainer.cpp b/src/element_container/LoadContainer.cpp index afd0718..e7c7483 100644 --- a/src/element_container/LoadContainer.cpp +++ b/src/element_container/LoadContainer.cpp @@ -26,7 +26,6 @@ void LoadContainer::init(const RealVect & loads_p, reset_results(); } - LoadContainer::StateRes LoadContainer::get_state() const { std::vector p_mw(p_mw_.begin(), p_mw_.end()); @@ -54,7 +53,6 @@ void LoadContainer::set_state(LoadContainer::StateRes & my_state ) reset_results(); } - void LoadContainer::fillSbus(CplxVect & Sbus, const std::vector & id_grid_to_solver, bool ac) const diff --git a/src/element_container/LoadContainer.h b/src/element_container/LoadContainer.h index 0483f3f..7b41a2c 100644 --- a/src/element_container/LoadContainer.h +++ b/src/element_container/LoadContainer.h @@ -177,6 +177,8 @@ class LoadContainer : public GenericContainer void reset_results(); tuple3d get_res() const {return tuple3d(res_p_, res_q_, res_v_);} + tuple4d get_res_full() const {return tuple4d(res_p_, res_q_, res_v_, res_theta_);} + Eigen::Ref get_theta() const {return res_theta_;} const std::vector& get_status() const {return status_;} const Eigen::VectorXi & get_bus_id() const {return bus_id_;} diff --git a/src/element_container/SGenContainer.h b/src/element_container/SGenContainer.h index b50a269..549afc0 100644 --- a/src/element_container/SGenContainer.h +++ b/src/element_container/SGenContainer.h @@ -198,6 +198,7 @@ class SGenContainer: public GenericContainer void reset_results(); tuple3d get_res() const {return tuple3d(res_p_, res_q_, res_v_);} + tuple4d get_res_full() const {return tuple4d(res_p_, res_q_, res_v_, res_theta_);} Eigen::Ref get_theta() const {return res_theta_;} const std::vector& get_status() const {return status_;} const Eigen::VectorXi & get_bus_id() const {return bus_id_;} diff --git a/src/element_container/ShuntContainer.h b/src/element_container/ShuntContainer.h index 40cf7cb..e2dee42 100644 --- a/src/element_container/ShuntContainer.h +++ b/src/element_container/ShuntContainer.h @@ -182,6 +182,8 @@ class ShuntContainer : public GenericContainer void reset_results(); tuple3d get_res() const {return tuple3d(res_p_, res_q_, res_v_);} + tuple4d get_res_full() const {return tuple4d(res_p_, res_q_, res_v_, res_theta_);} + Eigen::Ref get_theta() const {return res_theta_;} const std::vector& get_status() const {return status_;} diff --git a/src/element_container/TrafoContainer.cpp b/src/element_container/TrafoContainer.cpp index b38ce8a..488c2e7 100644 --- a/src/element_container/TrafoContainer.cpp +++ b/src/element_container/TrafoContainer.cpp @@ -46,7 +46,7 @@ void TrafoContainer::init(const RealVect & trafo_r, x_ = trafo_x; h_ = trafo_b; ratio_ = ratio; - shift_ = trafo_shift_degree / 180. * my_pi; // do not forget conversion degree / rad here ! + shift_ = trafo_shift_degree / my_180_pi_; // do not forget conversion degree / rad here ! bus_hv_id_ = trafo_hv_id; bus_lv_id_ = trafo_lv_id; is_tap_hv_side_ = trafo_tap_hv; @@ -317,8 +317,8 @@ void TrafoContainer::compute_results(const Eigen::Ref & Va, res_v_hv_(trafo_id) = v_hv * bus_vn_kv_hv; res_v_lv_(trafo_id) = v_lv * bus_vn_kv_lv; - res_theta_hv_(trafo_id) = Va(bus_hv_solver_id) * 180. / my_pi; - res_theta_lv_(trafo_id) = Va(bus_lv_solver_id) * 180. / my_pi; + res_theta_hv_(trafo_id) = Va(bus_hv_solver_id) * my_180_pi_; + res_theta_lv_(trafo_id) = Va(bus_lv_solver_id) * my_180_pi_; if(ac){ // results of the ac powerflow diff --git a/src/element_container/TrafoContainer.h b/src/element_container/TrafoContainer.h index fbb07f8..6d6e07f 100644 --- a/src/element_container/TrafoContainer.h +++ b/src/element_container/TrafoContainer.h @@ -237,6 +237,8 @@ class TrafoContainer : public GenericContainer tuple4d get_res_hv() const {return tuple4d(res_p_hv_, res_q_hv_, res_v_hv_, res_a_hv_);} tuple4d get_res_lv() const {return tuple4d(res_p_lv_, res_q_lv_, res_v_lv_, res_a_lv_);} + tuple5d get_res_hv_full() const {return tuple5d(res_p_hv_, res_q_hv_, res_v_hv_, res_a_hv_, res_theta_hv_);} + tuple5d get_res_lv_full() const {return tuple5d(res_p_lv_, res_q_lv_, res_v_lv_, res_a_lv_, res_theta_lv_);} Eigen::Ref get_theta_hv() const {return res_theta_hv_;} Eigen::Ref get_theta_lv() const {return res_theta_lv_;} Eigen::Ref get_bus_from() const {return bus_hv_id_;} diff --git a/src/main.cpp b/src/main.cpp index a73fad7..84050b6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -818,7 +818,18 @@ PYBIND11_MODULE(lightsim2grid_cpp, m) .def("get_trafolv_theta", &GridModel::get_trafolv_theta, DocGridModel::_internal_do_not_use.c_str()) .def("get_all_shunt_buses", &GridModel::get_all_shunt_buses, DocGridModel::_internal_do_not_use.c_str()) - + .def("get_loads_res_full", &GridModel::get_loads_res_full, DocGridModel::_internal_do_not_use.c_str()) + .def("get_shunts_res_full", &GridModel::get_shunts_res_full, DocGridModel::_internal_do_not_use.c_str()) + .def("get_gen_res_full", &GridModel::get_gen_res_full, DocGridModel::_internal_do_not_use.c_str()) + .def("get_lineor_res_full", &GridModel::get_lineor_res_full, DocGridModel::_internal_do_not_use.c_str()) + .def("get_lineex_res_full", &GridModel::get_lineex_res_full, DocGridModel::_internal_do_not_use.c_str()) + .def("get_trafohv_res_full", &GridModel::get_trafohv_res_full, DocGridModel::_internal_do_not_use.c_str()) + .def("get_trafolv_res_full", &GridModel::get_trafolv_res_full, DocGridModel::_internal_do_not_use.c_str()) + .def("get_storages_res_full", &GridModel::get_storages_res_full, DocGridModel::_internal_do_not_use.c_str()) + .def("get_sgens_res_full", &GridModel::get_sgens_res_full, DocGridModel::_internal_do_not_use.c_str()) + .def("get_dclineor_res_full", &GridModel::get_dclineor_res_full, DocGridModel::_internal_do_not_use.c_str()) + .def("get_dclineex_res_full", &GridModel::get_dclineex_res_full, DocGridModel::_internal_do_not_use.c_str()) + // do something with the grid // .def("init_Ybus", &DataModel::init_Ybus) // temporary .def("deactivate_result_computation", &GridModel::deactivate_result_computation, DocGridModel::deactivate_result_computation.c_str()) diff --git a/src/powerflow_algorithm/BaseNRAlgo.tpp b/src/powerflow_algorithm/BaseNRAlgo.tpp index 70af122..e889771 100644 --- a/src/powerflow_algorithm/BaseNRAlgo.tpp +++ b/src/powerflow_algorithm/BaseNRAlgo.tpp @@ -152,9 +152,11 @@ bool BaseNRAlgo::compute_pf(const Eigen::SparseMatrix & if(Vm_.minCoeff() < 0.) { // update Vm and Va again in case - // we wrapped around with a negative Vm TODO more efficient way maybe ? + // we wrapped around with a negative Vm + // TODO more efficient way maybe ? Vm_ = V_.array().abs(); Va_ = V_.array().arg(); + // TODO do I need to change V here ??? } timer_Va_Vm_ += timer_va_vm.duration();