@@ -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,25 +281,9 @@ 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
- auto const get_current_or_power_branch_f = [&solver_output, &obj_math_id]<power_or_current_sensor_c Sensor>() {
288
- if constexpr (std::derived_from<Sensor, GenericPowerSensor>) {
289
- return solver_output[obj_math_id.group ].branch [obj_math_id.pos ].s_f ;
290
- } else if constexpr (std::derived_from<Sensor, GenericCurrentSensor>) {
291
- return solver_output[obj_math_id.group ].branch [obj_math_id.pos ].i_f ;
292
- }
293
- };
294
-
295
- auto const get_current_or_power_branch_t = [&solver_output, &obj_math_id]<power_or_current_sensor_c Sensor>() {
296
- if constexpr (std::derived_from<Sensor, GenericPowerSensor>) {
297
- return solver_output[obj_math_id.group ].branch [obj_math_id.pos ].s_t ;
298
- } else if constexpr (std::derived_from<Sensor, GenericCurrentSensor>) {
299
- return solver_output[obj_math_id.group ].branch [obj_math_id.pos ].i_t ;
300
- }
301
- };
302
-
303
287
switch (terminal_type) {
304
288
using enum MeasuredTerminalType;
305
289
@@ -311,25 +295,78 @@ constexpr auto output_result(Component const& power_or_current_sensor, MainModel
311
295
case branch3_2:
312
296
[[fallthrough]];
313
297
case branch3_3:
314
- return power_or_current_sensor.template get_output <sym>(
315
- get_current_or_power_branch_f.template operator ()<Component>());
298
+ return power_sensor.template get_output <sym>(solver_output[obj_math_id.group ].branch [obj_math_id.pos ].s_f );
316
299
case branch_to:
317
- return power_or_current_sensor.template get_output <sym>(
318
- get_current_or_power_branch_t .template operator ()<Component>());
300
+ return power_sensor.template get_output <sym>(solver_output[obj_math_id.group ].branch [obj_math_id.pos ].s_t );
319
301
case source:
320
- return power_or_current_sensor.template get_output <sym>(
321
- 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 );
322
303
case shunt:
323
- return power_or_current_sensor.template get_output <sym>(
324
- 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 );
325
305
case load:
326
306
[[fallthrough]];
327
307
case generator:
328
- return power_or_current_sensor.template get_output <sym>(
329
- 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 );
330
309
case node:
331
- return power_or_current_sensor.template get_output <sym>(
332
- 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 ]);
311
+ default :
312
+ throw MissingCaseForEnumError{std::format (" {} output_result()" , Component::name), terminal_type};
313
+ }
314
+ }
315
+
316
+ // output current sensor
317
+ template <std::derived_from<GenericCurrentSensor> Component, class ComponentContainer ,
318
+ steady_state_solver_output_type SolverOutputType>
319
+ requires model_component_state_c<MainModelState, ComponentContainer, Component>
320
+ constexpr auto output_result (Component const & current_sensor, MainModelState<ComponentContainer> const & state,
321
+ std::vector<SolverOutputType> const & solver_output, Idx const obj_seq) {
322
+ using sym = typename SolverOutputType::sym;
323
+
324
+ auto const terminal_type = current_sensor.get_terminal_type ();
325
+ Idx2D const obj_math_id = [&]() {
326
+ switch (terminal_type) {
327
+ using enum MeasuredTerminalType;
328
+
329
+ case branch_from:
330
+ [[fallthrough]];
331
+ case branch_to:
332
+ return state.topo_comp_coup ->branch [obj_seq];
333
+ // from branch3, get relevant math object branch based on the measured side
334
+ case branch3_1:
335
+ return Idx2D{state.topo_comp_coup ->branch3 [obj_seq].group , state.topo_comp_coup ->branch3 [obj_seq].pos [0 ]};
336
+ case branch3_2:
337
+ return Idx2D{state.topo_comp_coup ->branch3 [obj_seq].group , state.topo_comp_coup ->branch3 [obj_seq].pos [1 ]};
338
+ case branch3_3:
339
+ return Idx2D{state.topo_comp_coup ->branch3 [obj_seq].group , state.topo_comp_coup ->branch3 [obj_seq].pos [2 ]};
340
+ default :
341
+ throw MissingCaseForEnumError{std::format (" {} output_result()" , Component::name), terminal_type};
342
+ }
343
+ }();
344
+
345
+ if (obj_math_id.group == -1 ) {
346
+ return current_sensor.template get_null_output <sym>();
347
+ }
348
+
349
+ auto const topological_index = get_topology_index<Branch>(state, obj_math_id);
350
+ auto const branch_nodes = get_branch_nodes<Branch>(state, topological_index);
351
+ auto const node_from_math_id = get_math_id<Node>(state, branch_nodes[0 ]);
352
+ auto const node_to_math_id = get_math_id<Node>(state, branch_nodes[1 ]);
353
+
354
+ switch (terminal_type) {
355
+ using enum MeasuredTerminalType;
356
+
357
+ case branch_from:
358
+ // all power sensors in branch3 are at from side in the mathematical model
359
+ [[fallthrough]];
360
+ case branch3_1:
361
+ [[fallthrough]];
362
+ case branch3_2:
363
+ [[fallthrough]];
364
+ case branch3_3:
365
+ return current_sensor.template get_output <sym>(solver_output[obj_math_id.group ].branch [obj_math_id.pos ].i_f ,
366
+ solver_output[node_from_math_id.group ].u [node_from_math_id.pos ]);
367
+ case branch_to:
368
+ return current_sensor.template get_output <sym>(solver_output[obj_math_id.group ].branch [obj_math_id.pos ].i_t ,
369
+ solver_output[node_to_math_id.group ].u [node_to_math_id.pos ]);
333
370
default :
334
371
throw MissingCaseForEnumError{std::format (" {} output_result()" , Component::name), terminal_type};
335
372
}
@@ -421,8 +458,7 @@ constexpr ResIt output_result(MainModelState<ComponentContainer> const& state,
421
458
MathOutput<std::vector<SolverOutputType>> const & math_output, ResIt res_it) {
422
459
return detail::produce_output<Component, Idx2D>(
423
460
state, res_it, [&state, &math_output](Component const & component, Idx2D const math_id) {
424
- return output_result<Component>(component, state, math_output.solver_output ,
425
- math_id); // probably here is where all the math_id things are called
461
+ return output_result<Component>(component, state, math_output.solver_output , math_id);
426
462
});
427
463
}
428
464
template <std::derived_from<Base> Component, class ComponentContainer , solver_output_type SolverOutputType,
@@ -431,8 +467,7 @@ template <std::derived_from<Base> Component, class ComponentContainer, solver_ou
431
467
requires (Component const & component, MainModelState<ComponentContainer> const & state,
432
468
std::vector<SolverOutputType> const & solver_output, Idx obj_seq) {
433
469
{
434
- output_result<Component>(component, state, solver_output,
435
- obj_seq) // probably here is where the sensors things are called
470
+ output_result<Component>(component, state, solver_output, obj_seq)
436
471
} -> detail::assignable_to<std::add_lvalue_reference_t <std::iter_value_t <ResIt>>>;
437
472
}
438
473
constexpr ResIt output_result (MainModelState<ComponentContainer> const & state,
0 commit comments