@@ -15,13 +15,19 @@ from .enum import CalculationMethod
1515
1616cimport numpy as cnp
1717from cython.operator cimport dereference as deref
18- from libc.stdint cimport int8_t, int32_t
18+ from libc.stdint cimport int8_t
1919from libcpp cimport bool
2020from libcpp.map cimport map
2121from libcpp.string cimport string
2222from libcpp.vector cimport vector
2323
24- VALIDATOR_MSG = " Try validate_input_data() or validate_batch_data() to validate your data."
24+ # idx and id types
25+ from libc.stdint cimport int32_t as idx_t # isort: skip
26+ cdef np_idx_t = np.int32
27+ from libc.stdint cimport int32_t as id_t # isort: skip
28+ cdef np_id_t = np.int32
29+
30+ cdef VALIDATOR_MSG = " Try validate_input_data() or validate_batch_data() to validate your data."
2531
2632cdef extern from " power_grid_model/auxiliary/meta_data_gen.hpp" namespace " power_grid_model::meta_data" :
2733 cppclass DataAttribute:
@@ -110,10 +116,10 @@ cdef _generate_component_meta_data(MetaData & cpp_component_meta_data):
110116cdef extern from " power_grid_model/auxiliary/dataset.hpp" namespace " power_grid_model" :
111117 cppclass MutableDataPointer:
112118 MutableDataPointer()
113- MutableDataPointer(void * ptr, const int32_t * indptr, int32_t size)
119+ MutableDataPointer(void * ptr, const idx_t * indptr, idx_t size)
114120 cppclass ConstDataPointer:
115121 ConstDataPointer()
116- ConstDataPointer(const void * ptr, const int32_t * indptr, int32_t size)
122+ ConstDataPointer(const void * ptr, const idx_t * indptr, idx_t size)
117123
118124cdef extern from " power_grid_model/main_model.hpp" namespace " power_grid_model" :
119125 cppclass CalculationMethodCPP " ::power_grid_model::CalculationMethod" :
@@ -122,43 +128,48 @@ cdef extern from "power_grid_model/main_model.hpp" namespace "power_grid_model":
122128 bool independent
123129 bool cache_topology
124130 cppclass MainModel:
125- map [string, int32_t ] all_component_count()
131+ map [string, idx_t ] all_component_count()
126132 BatchParameter calculate_sym_power_flow " calculate_power_flow<true>" (
127133 double error_tolerance,
128- int32_t max_iterations,
134+ idx_t max_iterations,
129135 CalculationMethodCPP calculation_method,
130136 const map [string, MutableDataPointer] & result_data,
131137 const map [string, ConstDataPointer] & update_data,
132- int32_t threading
138+ idx_t threading
133139 ) except +
134140 BatchParameter calculate_asym_power_flow " calculate_power_flow<false>" (
135141 double error_tolerance,
136- int32_t max_iterations,
142+ idx_t max_iterations,
137143 CalculationMethodCPP calculation_method,
138144 const map [string, MutableDataPointer] & result_data,
139145 const map [string, ConstDataPointer] & update_data,
140- int32_t threading
146+ idx_t threading
141147 ) except +
142148 BatchParameter calculate_sym_state_estimation " calculate_state_estimation<true>" (
143149 double error_tolerance,
144- int32_t max_iterations,
150+ idx_t max_iterations,
145151 CalculationMethodCPP calculation_method,
146152 const map [string, MutableDataPointer] & result_data,
147153 const map [string, ConstDataPointer] & update_data,
148- int32_t threading
154+ idx_t threading
149155 ) except +
150156 BatchParameter calculate_asym_state_estimation " calculate_state_estimation<false>" (
151157 double error_tolerance,
152- int32_t max_iterations,
158+ idx_t max_iterations,
153159 CalculationMethodCPP calculation_method,
154160 const map [string, MutableDataPointer] & result_data,
155161 const map [string, ConstDataPointer] & update_data,
156- int32_t threading
162+ idx_t threading
157163 ) except +
158164 void update_component(
159165 const map [string, ConstDataPointer] & update_data,
160- int32_t pos
166+ idx_t pos
161167 ) except +
168+ void get_indexer(
169+ const string& component_type,
170+ const id_t* id_begin,
171+ idx_t size,
172+ idx_t* indexer_begin) except +
162173
163174cdef extern from " <optional>" :
164175 cppclass OptionalMainModel " ::std::optional<::power_grid_model::MainModel>" :
@@ -169,7 +180,7 @@ cdef extern from "<optional>":
169180 MainModel & emplace(
170181 double system_frequency,
171182 const map [string, ConstDataPointer] & input_data,
172- int32_t pos) except +
183+ idx_t pos) except +
173184
174185# internally used meta data, to prevent modification
175186cdef _power_grid_meta_data = _generate_meta_data()
@@ -183,7 +194,7 @@ cdef map[string, ConstDataPointer] generate_const_ptr_map(data: Dict[str, Dict[s
183194 data_arr = v[' data' ]
184195 indptr_arr = v[' indptr' ]
185196 result[k.encode()] = ConstDataPointer(
186- cnp.PyArray_DATA(data_arr), < const int32_t * > cnp.PyArray_DATA(indptr_arr),
197+ cnp.PyArray_DATA(data_arr), < const idx_t * > cnp.PyArray_DATA(indptr_arr),
187198 v[' batch_size' ])
188199 return result
189200
@@ -195,7 +206,7 @@ cdef map[string, MutableDataPointer] generate_ptr_map(data: Dict[str, Dict[str,
195206 data_arr = v[' data' ]
196207 indptr_arr = v[' indptr' ]
197208 result[k.encode()] = MutableDataPointer(
198- cnp.PyArray_DATA(data_arr), < const int32_t * > cnp.PyArray_DATA(indptr_arr),
209+ cnp.PyArray_DATA(data_arr), < const idx_t * > cnp.PyArray_DATA(indptr_arr),
199210 v[' batch_size' ])
200211 return result
201212
@@ -234,10 +245,10 @@ cdef _prepare_cpp_array(data_type: str,
234245 data = v
235246 ndim = v.ndim
236247 if ndim == 1 :
237- indptr = np.array([0 , v.size], dtype = np.int32 )
248+ indptr = np.array([0 , v.size], dtype = np_idx_t )
238249 batch_size = 1
239250 elif ndim == 2 : # (n_batch, n_component)
240- indptr = np.arange(v.shape[0 ] + 1 , dtype = np.int32 ) * v.shape[1 ]
251+ indptr = np.arange(v.shape[0 ] + 1 , dtype = np_idx_t ) * v.shape[1 ]
241252 batch_size = v.shape[0 ]
242253 else :
243254 raise ValueError (f" Array can only be 1D or 2D. {VALIDATOR_MSG}" )
@@ -257,7 +268,7 @@ cdef _prepare_cpp_array(data_type: str,
257268 raise ValueError (f" indptr should be increasing. {VALIDATOR_MSG}" )
258269 # convert array
259270 data = np.ascontiguousarray(data, dtype = schema[component_name][' dtype' ])
260- indptr = np.ascontiguousarray(indptr, dtype = np.int32 )
271+ indptr = np.ascontiguousarray(indptr, dtype = np_idx_t )
261272 return_dict[component_name] = {
262273 ' data' : data,
263274 ' indptr' : indptr,
@@ -302,6 +313,29 @@ cdef class PowerGridModel:
302313 self .independent = False
303314 self .cache_topology = False
304315
316+ def get_indexer (self ,
317+ component_type: str ,
318+ ids: np.ndarray ):
319+ """
320+ Get array of indexers given array of ids for component type
321+
322+ Args:
323+ component_type: type of component
324+ ids: array of ids
325+
326+ Returns:
327+ array of inderxers, same shape as input array ids
328+
329+ """
330+ cdef cnp.ndarray ids_c = np.ascontiguousarray(ids, dtype = np_id_t)
331+ cdef cnp.ndarray indexer = np.empty_like(ids_c, dtype = np_idx_t, order = ' C' )
332+ cdef const id_t* id_begin = < const id_t* > cnp.PyArray_DATA(ids_c)
333+ cdef idx_t* indexer_begin = < idx_t* > cnp.PyArray_DATA(indexer)
334+ cdef idx_t size = ids.size
335+ # call c function
336+ self ._get_model().get_indexer(component_type.encode(), id_begin, size, indexer_begin)
337+ return indexer
338+
305339 def copy (self ) -> PowerGridModel:
306340 """
307341
@@ -333,10 +367,10 @@ cdef class PowerGridModel:
333367 calculation_type,
334368 bool symmetric,
335369 double error_tolerance,
336- int32_t max_iterations,
370+ idx_t max_iterations,
337371 calculation_method: Union[CalculationMethod, str ],
338372 update_data: Optional[Dict[str , Union[np.ndarray, Dict[str , np.ndarray]]]],
339- int32_t threading
373+ idx_t threading
340374 ):
341375 """
342376 Core calculation routine
@@ -453,10 +487,10 @@ cdef class PowerGridModel:
453487 def calculate_power_flow (self , *,
454488 bool symmetric = True ,
455489 double error_tolerance = 1e-8 ,
456- int32_t max_iterations = 20 ,
490+ idx_t max_iterations = 20 ,
457491 calculation_method: Union[CalculationMethod , str] = CalculationMethod.newton_raphson ,
458492 update_data: Optional[Dict[str , Union[np.ndarray , Dict[str , np.ndarray]]]] = None ,
459- int32_t threading = - 1
493+ idx_t threading = - 1
460494 ) -> Dict[str , np.ndarray]:
461495 """
462496 Calculate power flow once with the current model attributes.
@@ -519,10 +553,10 @@ cdef class PowerGridModel:
519553 def calculate_state_estimation(self , *,
520554 bool symmetric = True ,
521555 double error_tolerance = 1e-8 ,
522- int32_t max_iterations = 20 ,
556+ idx_t max_iterations = 20 ,
523557 calculation_method: Union[CalculationMethod , str] = CalculationMethod.iterative_linear ,
524558 update_data: Optional[Dict[str , Union[np.ndarray , Dict[str , np.ndarray]]]] = None ,
525- int32_t threading = - 1
559+ idx_t threading = - 1
526560 ) -> Dict[str , np.ndarray]:
527561 """
528562 Calculate state estimation once with the current model attributes.
@@ -592,7 +626,7 @@ cdef class PowerGridModel:
592626 value: integer count of elements of this type
593627 """
594628 all_component_count = {}
595- cdef map[string , int32_t ] cpp_count = self ._get_model().all_component_count()
629+ cdef map[string , idx_t ] cpp_count = self ._get_model().all_component_count()
596630 for map_entry in cpp_count:
597631 all_component_count[map_entry.first.decode()] = map_entry.second
598632 return all_component_count
0 commit comments