Skip to content

Commit 6d178cd

Browse files
committed
Add meter_fallback_for_meters parameter to FallbackExpr generator
When true, fallback expressions will consider (single) successor meters as fallback components for meters. Signed-off-by: Sahas Subramanian <[email protected]>
1 parent 01dce3e commit 6d178cd

File tree

8 files changed

+55
-26
lines changed

8 files changed

+55
-26
lines changed

src/graph/formulas/fallback.rs

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ where
2020
&self,
2121
component_ids: impl IntoIterator<Item = u64>,
2222
prefer_meters: bool,
23+
meter_fallback_for_meters: bool,
2324
) -> Result<Expr, Error> {
2425
FallbackExpr {
2526
prefer_meters,
27+
meter_fallback_for_meters,
2628
graph: self,
2729
}
2830
.generate(BTreeSet::from_iter(component_ids))
@@ -35,6 +37,7 @@ where
3537
E: Edge,
3638
{
3739
pub(crate) prefer_meters: bool,
40+
pub(crate) meter_fallback_for_meters: bool,
3841
pub(crate) graph: &'a ComponentGraph<N, E>,
3942
}
4043

@@ -67,9 +70,14 @@ where
6770
/// Returns a fallback expression for a meter component.
6871
fn meter_fallback(&self, component_id: u64) -> Result<Option<Expr>, Error> {
6972
let component = self.graph.component(component_id)?;
70-
if !component.is_meter() || self.graph.has_meter_successors(component_id)? {
73+
if !component.is_meter() {
7174
return Ok(None);
7275
}
76+
let has_successor_meters = self.graph.has_meter_successors(component_id)?;
77+
78+
if !self.meter_fallback_for_meters && has_successor_meters {
79+
return Ok(Some(Expr::component(component_id)));
80+
}
7381

7482
if !self.graph.has_successors(component_id)? {
7583
return Ok(Some(Expr::component(component_id)));
@@ -91,6 +99,13 @@ where
9199

92100
let has_multiple_successors = matches!(sum_of_successors, Expr::Add { .. });
93101

102+
// If a meter has exactly one successor and it is a meter, we consider
103+
// it to be a fallback meter. If there are multiple meter successors,
104+
// we return the meter without fallback.
105+
if has_successor_meters && has_multiple_successors {
106+
return Ok(Some(Expr::component(component_id)));
107+
}
108+
94109
let mut coalesced = Expr::component(component_id);
95110

96111
if !self.prefer_meters {
@@ -102,11 +117,13 @@ where
102117
coalesced = coalesced.coalesce(sum_of_coalesced_successors);
103118
} else {
104119
coalesced = coalesced.coalesce(sum_of_successors);
105-
coalesced = coalesced.coalesce(Expr::number(0.0));
120+
if !has_successor_meters {
121+
coalesced = coalesced.coalesce(Expr::number(0.0));
122+
}
106123
}
107124
} else if has_multiple_successors {
108125
coalesced = coalesced.coalesce(sum_of_coalesced_successors);
109-
} else {
126+
} else if !has_successor_meters {
110127
coalesced = coalesced.coalesce(Expr::number(0.0));
111128
}
112129

@@ -202,26 +219,36 @@ mod tests {
202219
assert_eq!(meter_bat_chain.component_id(), 2);
203220

204221
let graph = builder.build(None)?;
205-
let expr = graph.fallback_expr(vec![1, 2], false)?;
222+
let expr = graph.fallback_expr(vec![1], true, true)?;
223+
assert_eq!(expr.to_string(), "COALESCE(#1, #2)");
224+
225+
let expr = graph.fallback_expr(vec![1, 2], true, true)?;
226+
assert_eq!(expr.to_string(), "COALESCE(#1, #2) + COALESCE(#2, #3, 0.0)");
227+
228+
let expr = graph.fallback_expr(vec![1, 2], false, false)?;
206229
assert_eq!(expr.to_string(), "#1 + COALESCE(#3, #2, 0.0)");
207230

208-
let expr = graph.fallback_expr(vec![1, 2], true)?;
231+
let expr = graph.fallback_expr(vec![1, 2], true, false)?;
209232
assert_eq!(expr.to_string(), "#1 + COALESCE(#2, #3, 0.0)");
210233

211-
let expr = graph.fallback_expr(vec![3], true)?;
234+
let expr = graph.fallback_expr(vec![3], true, false)?;
235+
assert_eq!(expr.to_string(), "COALESCE(#2, #3, 0.0)");
236+
let expr = graph.fallback_expr(vec![3], true, true)?;
237+
assert_eq!(expr.to_string(), "COALESCE(#2, #3, 0.0)");
238+
let expr = graph.fallback_expr(vec![2], true, true)?;
212239
assert_eq!(expr.to_string(), "COALESCE(#2, #3, 0.0)");
213240

214241
let graph = builder.build(Some(ComponentGraphConfig {
215242
disable_fallback_components: true,
216243
..Default::default()
217244
}))?;
218-
let expr = graph.fallback_expr(vec![1, 2], false)?;
245+
let expr = graph.fallback_expr(vec![1, 2], false, false)?;
219246
assert_eq!(expr.to_string(), "#1 + #2");
220247

221-
let expr = graph.fallback_expr(vec![1, 2], true)?;
248+
let expr = graph.fallback_expr(vec![1, 2], true, false)?;
222249
assert_eq!(expr.to_string(), "#1 + #2");
223250

224-
let expr = graph.fallback_expr(vec![3], true)?;
251+
let expr = graph.fallback_expr(vec![3], true, false)?;
225252
assert_eq!(expr.to_string(), "#3");
226253

227254
// Add a battery meter with three inverter and three batteries
@@ -231,7 +258,7 @@ mod tests {
231258
assert_eq!(meter_bat_chain.component_id(), 5);
232259

233260
let graph = builder.build(None)?;
234-
let expr = graph.fallback_expr(vec![3, 5], false)?;
261+
let expr = graph.fallback_expr(vec![3, 5], false, false)?;
235262
assert_eq!(
236263
expr.to_string(),
237264
concat!(
@@ -244,7 +271,7 @@ mod tests {
244271
)
245272
);
246273

247-
let expr = graph.fallback_expr(vec![2, 5], true)?;
274+
let expr = graph.fallback_expr(vec![2, 5], true, false)?;
248275
assert_eq!(
249276
expr.to_string(),
250277
concat!(
@@ -253,7 +280,7 @@ mod tests {
253280
)
254281
);
255282

256-
let expr = graph.fallback_expr(vec![2, 6, 7, 8], true)?;
283+
let expr = graph.fallback_expr(vec![2, 6, 7, 8], true, false)?;
257284
assert_eq!(
258285
expr.to_string(),
259286
concat!(
@@ -262,7 +289,7 @@ mod tests {
262289
)
263290
);
264291

265-
let expr = graph.fallback_expr(vec![2, 7, 8], true)?;
292+
let expr = graph.fallback_expr(vec![2, 7, 8], true, false)?;
266293
assert_eq!(
267294
expr.to_string(),
268295
"COALESCE(#2, #3, 0.0) + COALESCE(#7, 0.0) + COALESCE(#8, 0.0)"
@@ -272,16 +299,16 @@ mod tests {
272299
disable_fallback_components: true,
273300
..Default::default()
274301
}))?;
275-
let expr = graph.fallback_expr(vec![3, 5], false)?;
302+
let expr = graph.fallback_expr(vec![3, 5], false, false)?;
276303
assert_eq!(expr.to_string(), "#3 + #5");
277304

278-
let expr = graph.fallback_expr(vec![2, 5], true)?;
305+
let expr = graph.fallback_expr(vec![2, 5], true, false)?;
279306
assert_eq!(expr.to_string(), "#2 + #5");
280307

281-
let expr = graph.fallback_expr(vec![2, 6, 7, 8], true)?;
308+
let expr = graph.fallback_expr(vec![2, 6, 7, 8], true, false)?;
282309
assert_eq!(expr.to_string(), "#2 + #6 + #7 + #8");
283310

284-
let expr = graph.fallback_expr(vec![2, 7, 8], true)?;
311+
let expr = graph.fallback_expr(vec![2, 7, 8], true, false)?;
285312
assert_eq!(expr.to_string(), "#2 + #7 + #8");
286313

287314
let meter = builder.meter();
@@ -296,7 +323,7 @@ mod tests {
296323
assert_eq!(pv_inverter.component_id(), 14);
297324

298325
let graph = builder.build(None)?;
299-
let expr = graph.fallback_expr(vec![5, 12], true)?;
326+
let expr = graph.fallback_expr(vec![5, 12], true, false)?;
300327
assert_eq!(
301328
expr.to_string(),
302329
concat!(
@@ -305,7 +332,7 @@ mod tests {
305332
)
306333
);
307334

308-
let expr = graph.fallback_expr(vec![7, 14], false)?;
335+
let expr = graph.fallback_expr(vec![7, 14], false, false)?;
309336
assert_eq!(expr.to_string(), "COALESCE(#7, 0.0) + COALESCE(#14, 0.0)");
310337

311338
Ok(())

src/graph/formulas/generators/battery.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ where
5555
}
5656

5757
self.graph
58-
.fallback_expr(self.inverter_ids, false)
58+
.fallback_expr(self.inverter_ids, false, false)
5959
.map(AggregationFormula::new)
6060
}
6161

src/graph/formulas/generators/chp.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ where
5959
}
6060

6161
self.graph
62-
.fallback_expr(self.chp_ids, false)
62+
.fallback_expr(self.chp_ids, false, false)
6363
.map(AggregationFormula::new)
6464
}
6565
}

src/graph/formulas/generators/consumer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ where
9595
// Subtract each successor from the expression.
9696
for successor in successors {
9797
let successor_expr = if successor.1.is_meter() {
98-
self.graph.fallback_expr([successor.0], true)?
98+
self.graph.fallback_expr([successor.0], true, false)?
9999
} else {
100100
Expr::from(successor.1)
101101
};

src/graph/formulas/generators/ev_charger.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ where
6262
}
6363

6464
self.graph
65-
.fallback_expr(self.ev_charger_ids, false)
65+
.fallback_expr(self.ev_charger_ids, false, false)
6666
.map(AggregationFormula::new)
6767
}
6868
}

src/graph/formulas/generators/grid.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ where
3333
pub fn build(self) -> Result<AggregationFormula, Error> {
3434
let mut expr = None;
3535
for comp in self.graph.successors(self.graph.root_id)? {
36-
let comp = self.graph.fallback_expr([comp.component_id()], true)?;
36+
let comp = self
37+
.graph
38+
.fallback_expr([comp.component_id()], true, false)?;
3739
expr = match expr {
3840
None => Some(comp),
3941
Some(e) => Some(comp + e),

src/graph/formulas/generators/producer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ where
4747
)? {
4848
let comp_expr = self
4949
.graph
50-
.fallback_expr([component_id], false)?
50+
.fallback_expr([component_id], false, false)?
5151
.min(Expr::number(0.0));
5252
expr = match expr {
5353
None => Some(comp_expr),

src/graph/formulas/generators/pv.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ where
6262
}
6363

6464
self.graph
65-
.fallback_expr(self.pv_inverter_ids, false)
65+
.fallback_expr(self.pv_inverter_ids, false, false)
6666
.map(AggregationFormula::new)
6767
}
6868
}

0 commit comments

Comments
 (0)