@@ -242,14 +242,14 @@ inline auto output_result(Component const& voltage_sensor, MainModelState<Compon
242
242
}
243
243
244
244
// output power sensor
245
- template <power_or_current_sensor_c Component, class ComponentContainer ,
245
+ template <std::derived_from<GenericPowerSensor> Component, class ComponentContainer ,
246
246
steady_state_solver_output_type SolverOutputType>
247
247
requires model_component_state_c<MainModelState, ComponentContainer, Component>
248
- constexpr auto output_result (Component const & power_or_current_sensor , MainModelState<ComponentContainer> const & state,
248
+ constexpr auto output_result (Component const & power_sensor , MainModelState<ComponentContainer> const & state,
249
249
std::vector<SolverOutputType> const & solver_output, Idx const obj_seq) {
250
250
using sym = typename SolverOutputType::sym;
251
251
252
- auto const terminal_type = power_or_current_sensor .get_terminal_type ();
252
+ auto const terminal_type = power_sensor .get_terminal_type ();
253
253
Idx2D const obj_math_id = [&]() {
254
254
switch (terminal_type) {
255
255
using enum MeasuredTerminalType;
@@ -281,7 +281,7 @@ constexpr auto output_result(Component const& power_or_current_sensor, MainModel
281
281
}();
282
282
283
283
if (obj_math_id.group == -1 ) {
284
- return power_or_current_sensor .template get_null_output <sym>();
284
+ return power_sensor .template get_null_output <sym>();
285
285
}
286
286
287
287
switch (terminal_type) {
@@ -295,30 +295,91 @@ constexpr auto output_result(Component const& power_or_current_sensor, MainModel
295
295
case branch3_2:
296
296
[[fallthrough]];
297
297
case branch3_3:
298
- return power_or_current_sensor.template get_output <sym>(
299
- solver_output[obj_math_id.group ].branch [obj_math_id.pos ].s_f );
298
+ return power_sensor.template get_output <sym>(solver_output[obj_math_id.group ].branch [obj_math_id.pos ].s_f );
300
299
case branch_to:
301
- return power_or_current_sensor.template get_output <sym>(
302
- solver_output[obj_math_id.group ].branch [obj_math_id.pos ].s_t );
300
+ return power_sensor.template get_output <sym>(solver_output[obj_math_id.group ].branch [obj_math_id.pos ].s_t );
303
301
case source:
304
- return power_or_current_sensor.template get_output <sym>(
305
- solver_output[obj_math_id.group ].source [obj_math_id.pos ].s );
302
+ return power_sensor.template get_output <sym>(solver_output[obj_math_id.group ].source [obj_math_id.pos ].s );
306
303
case shunt:
307
- return power_or_current_sensor.template get_output <sym>(
308
- solver_output[obj_math_id.group ].shunt [obj_math_id.pos ].s );
304
+ return power_sensor.template get_output <sym>(solver_output[obj_math_id.group ].shunt [obj_math_id.pos ].s );
309
305
case load:
310
306
[[fallthrough]];
311
307
case generator:
312
- return power_or_current_sensor.template get_output <sym>(
313
- solver_output[obj_math_id.group ].load_gen [obj_math_id.pos ].s );
308
+ return power_sensor.template get_output <sym>(solver_output[obj_math_id.group ].load_gen [obj_math_id.pos ].s );
314
309
case node:
315
- return power_or_current_sensor.template get_output <sym>(
316
- solver_output[obj_math_id.group ].bus_injection [obj_math_id.pos ]);
310
+ return power_sensor.template get_output <sym>(solver_output[obj_math_id.group ].bus_injection [obj_math_id.pos ]);
317
311
default :
318
312
throw MissingCaseForEnumError{std::format (" {} output_result()" , Component::name), terminal_type};
319
313
}
320
314
}
321
- template <power_or_current_sensor_c Component, class ComponentContainer ,
315
+ template <std::derived_from<GenericPowerSensor> Component, class ComponentContainer ,
316
+ short_circuit_solver_output_type SolverOutputType>
317
+ requires model_component_state_c<MainModelState, ComponentContainer, Component>
318
+ constexpr auto output_result (Component const & power_or_current_sensor,
319
+ MainModelState<ComponentContainer> const & /* state */ ,
320
+ std::vector<SolverOutputType> const & /* solver_output */ , Idx const /* obj_seq */ ) {
321
+ return power_or_current_sensor.get_null_sc_output ();
322
+ }
323
+
324
+ // output current sensor
325
+ template <std::derived_from<GenericCurrentSensor> Component, class ComponentContainer ,
326
+ steady_state_solver_output_type SolverOutputType>
327
+ requires model_component_state_c<MainModelState, ComponentContainer, Component>
328
+ constexpr auto output_result (Component const & current_sensor, MainModelState<ComponentContainer> const & state,
329
+ std::vector<SolverOutputType> const & solver_output, Idx const obj_seq) {
330
+ using sym = typename SolverOutputType::sym;
331
+
332
+ auto const terminal_type = current_sensor.get_terminal_type ();
333
+ Idx2D const obj_math_id = [&]() {
334
+ switch (terminal_type) {
335
+ using enum MeasuredTerminalType;
336
+
337
+ case branch_from:
338
+ [[fallthrough]];
339
+ case branch_to:
340
+ return state.topo_comp_coup ->branch [obj_seq];
341
+ // from branch3, get relevant math object branch based on the measured side
342
+ case branch3_1:
343
+ return Idx2D{state.topo_comp_coup ->branch3 [obj_seq].group , state.topo_comp_coup ->branch3 [obj_seq].pos [0 ]};
344
+ case branch3_2:
345
+ return Idx2D{state.topo_comp_coup ->branch3 [obj_seq].group , state.topo_comp_coup ->branch3 [obj_seq].pos [1 ]};
346
+ case branch3_3:
347
+ return Idx2D{state.topo_comp_coup ->branch3 [obj_seq].group , state.topo_comp_coup ->branch3 [obj_seq].pos [2 ]};
348
+ default :
349
+ throw MissingCaseForEnumError{std::format (" {} output_result()" , Component::name), terminal_type};
350
+ }
351
+ }();
352
+
353
+ if (obj_math_id.group == -1 ) {
354
+ return current_sensor.template get_null_output <sym>();
355
+ }
356
+
357
+ auto const topological_index = get_topology_index<Branch>(state, obj_math_id);
358
+ auto const branch_nodes = get_branch_nodes<Branch>(state, topological_index);
359
+ auto const node_from_math_id = get_math_id<Node>(state, branch_nodes[0 ]);
360
+ auto const node_to_math_id = get_math_id<Node>(state, branch_nodes[1 ]);
361
+
362
+ switch (terminal_type) {
363
+ using enum MeasuredTerminalType;
364
+
365
+ case branch_from:
366
+ // all power sensors in branch3 are at from side in the mathematical model
367
+ [[fallthrough]];
368
+ case branch3_1:
369
+ [[fallthrough]];
370
+ case branch3_2:
371
+ [[fallthrough]];
372
+ case branch3_3:
373
+ return current_sensor.template get_output <sym>(solver_output[obj_math_id.group ].branch [obj_math_id.pos ].i_f ,
374
+ solver_output[node_from_math_id.group ].u [node_from_math_id.pos ]);
375
+ case branch_to:
376
+ return current_sensor.template get_output <sym>(solver_output[obj_math_id.group ].branch [obj_math_id.pos ].i_t ,
377
+ solver_output[node_to_math_id.group ].u [node_to_math_id.pos ]);
378
+ default :
379
+ throw MissingCaseForEnumError{std::format (" {} output_result()" , Component::name), terminal_type};
380
+ }
381
+ }
382
+ template <std::derived_from<GenericCurrentSensor> Component, class ComponentContainer ,
322
383
short_circuit_solver_output_type SolverOutputType>
323
384
requires model_component_state_c<MainModelState, ComponentContainer, Component>
324
385
constexpr auto output_result (Component const & power_or_current_sensor,
0 commit comments