@@ -15,11 +15,11 @@ use std::fmt::Display;
1515use strum:: IntoEnumIterator ;
1616
1717/// A graph of commodity flows for a given region and year
18- type CommoditiesGraph = Graph < GraphNode , GraphEdge , Directed > ;
18+ pub type CommoditiesGraph = Graph < GraphNode , GraphEdge , Directed > ;
1919
2020#[ derive( Eq , PartialEq , Clone , Hash ) ]
2121/// A node in the commodity graph
22- enum GraphNode {
22+ pub enum GraphNode {
2323 /// A node representing a commodity
2424 Commodity ( CommodityID ) ,
2525 /// A source node for processes that have no inputs
@@ -43,7 +43,7 @@ impl Display for GraphNode {
4343
4444#[ derive( Eq , PartialEq , Clone , Hash ) ]
4545/// An edge in the commodity graph
46- enum GraphEdge {
46+ pub enum GraphEdge {
4747 /// An edge representing a process
4848 Process ( ProcessID ) ,
4949 /// An edge representing a service demand
@@ -196,7 +196,7 @@ fn prepare_commodities_graph_for_validation(
196196/// The validation is only performed for commodities with the specified time slice level. For full
197197/// validation of all commodities in the model, we therefore need to run this function for all time
198198/// slice selections at all time slice levels. This is handled by
199- /// `build_and_validate_commodity_graphs_for_model `.
199+ /// `validate_commodity_graphs_for_model `.
200200fn validate_commodities_graph (
201201 graph : & CommoditiesGraph ,
202202 commodities : & CommodityMap ,
@@ -307,7 +307,26 @@ fn topo_sort_commodities(
307307 Ok ( order)
308308}
309309
310- /// Builds and validates commodity graphs for the entire model.
310+ /// Builds base commodity graphs for each region and year
311+ ///
312+ /// These do not take into account demand and process availability
313+ pub fn build_commodity_graphs_for_model (
314+ processes : & ProcessMap ,
315+ region_ids : & IndexSet < RegionID > ,
316+ years : & [ u32 ] ,
317+ ) -> Result < HashMap < ( RegionID , u32 ) , CommoditiesGraph > > {
318+ let commodity_graphs: HashMap < ( RegionID , u32 ) , CommoditiesGraph > =
319+ iproduct ! ( region_ids, years. iter( ) )
320+ . map ( |( region_id, year) | {
321+ let graph = create_commodities_graph_for_region_year ( processes, region_id, * year) ;
322+ ( ( region_id. clone ( ) , * year) , graph)
323+ } )
324+ . collect ( ) ;
325+
326+ Ok ( commodity_graphs)
327+ }
328+
329+ /// Validates commodity graphs for the entire model.
311330///
312331/// This function creates commodity flow graphs for each region/year combination in the model,
313332/// validates the graph structure against commodity type rules, and determines the optimal
@@ -337,23 +356,12 @@ fn topo_sort_commodities(
337356/// - Any commodity graph contains cycles
338357/// - Commodity type rules are violated (e.g., SVD commodities being consumed)
339358/// - Demand cannot be satisfied
340- pub fn build_and_validate_commodity_graphs_for_model (
359+ pub fn validate_commodity_graphs_for_model (
360+ commodity_graphs : & HashMap < ( RegionID , u32 ) , CommoditiesGraph > ,
341361 processes : & ProcessMap ,
342362 commodities : & CommodityMap ,
343- region_ids : & IndexSet < RegionID > ,
344- years : & [ u32 ] ,
345363 time_slice_info : & TimeSliceInfo ,
346364) -> Result < HashMap < ( RegionID , u32 ) , Vec < CommodityID > > > {
347- // Build base commodity graphs for each region and year
348- // These do not take into account demand and process availability
349- let commodity_graphs: HashMap < ( RegionID , u32 ) , CommoditiesGraph > =
350- iproduct ! ( region_ids, years. iter( ) )
351- . map ( |( region_id, year) | {
352- let graph = create_commodities_graph_for_region_year ( processes, region_id, * year) ;
353- ( ( region_id. clone ( ) , * year) , graph)
354- } )
355- . collect ( ) ;
356-
357365 // Determine commodity ordering for each region and year
358366 let commodity_order: HashMap < ( RegionID , u32 ) , Vec < CommodityID > > = commodity_graphs
359367 . iter ( )
@@ -366,7 +374,7 @@ pub fn build_and_validate_commodity_graphs_for_model(
366374 . try_collect ( ) ?;
367375
368376 // Validate graphs at all time slice levels (taking into account process availability and demand)
369- for ( ( region_id, year) , base_graph) in & commodity_graphs {
377+ for ( ( region_id, year) , base_graph) in commodity_graphs {
370378 for ts_level in TimeSliceLevel :: iter ( ) {
371379 for ts_selection in time_slice_info. iter_selections_at_level ( ts_level) {
372380 let graph = prepare_commodities_graph_for_validation (
0 commit comments