Loading src/lib.rs +29 −21 Original line number Diff line number Diff line Loading @@ -133,29 +133,37 @@ fn simulate_cascade( } } // Create a mapping from each object name to the list of upstream object names. // This avoids scanning all objects in each timestep. let mut upstream_map: HashMap<String, Vec<String>> = HashMap::new(); for (upstream_name, _, upstream_type) in &ordered_objects { // Determine the downstream object for the current upstream object. let downstream_name = match upstream_type.as_str() { "reservoir" => &cascade_data.reservoirs[*upstream_name].downstream_object, "river" => &cascade_data.rivers[*upstream_name].downstream_object, _ => continue, }; // Insert the upstream object into the vector for its downstream object. upstream_map .entry(downstream_name.clone()) .or_default() .push((*upstream_name).clone()); } for t in 0..n { for (name, _, obj_type) in &ordered_objects { let upstream_inflow = ordered_objects.iter() .filter(|(upstream_name, _, upstream_type)| { match upstream_type.as_str() { "reservoir" => { let upstream_obj = &cascade_data.reservoirs[*upstream_name]; upstream_obj.downstream_object == **name }, "river" => { let upstream_obj = &cascade_data.rivers[*upstream_name]; upstream_obj.downstream_object == **name }, _ => false } }) .map(|(upstream_name, _, _)| { match &results[*upstream_name] { let upstream_inflow = if let Some(upstream_objects) = upstream_map.get(&name.to_string()) { upstream_objects.iter() .map(|upstream_name| { match &results[upstream_name] { CascadeResults::Reservoir(res) => res.release[t] + res.spill[t], CascadeResults::River(riv) => riv.flow[t], } }) .sum::<f64>(); .sum::<f64>() } else { 0.0 }; match obj_type.as_str() { "reservoir" => { Loading Loading
src/lib.rs +29 −21 Original line number Diff line number Diff line Loading @@ -133,29 +133,37 @@ fn simulate_cascade( } } // Create a mapping from each object name to the list of upstream object names. // This avoids scanning all objects in each timestep. let mut upstream_map: HashMap<String, Vec<String>> = HashMap::new(); for (upstream_name, _, upstream_type) in &ordered_objects { // Determine the downstream object for the current upstream object. let downstream_name = match upstream_type.as_str() { "reservoir" => &cascade_data.reservoirs[*upstream_name].downstream_object, "river" => &cascade_data.rivers[*upstream_name].downstream_object, _ => continue, }; // Insert the upstream object into the vector for its downstream object. upstream_map .entry(downstream_name.clone()) .or_default() .push((*upstream_name).clone()); } for t in 0..n { for (name, _, obj_type) in &ordered_objects { let upstream_inflow = ordered_objects.iter() .filter(|(upstream_name, _, upstream_type)| { match upstream_type.as_str() { "reservoir" => { let upstream_obj = &cascade_data.reservoirs[*upstream_name]; upstream_obj.downstream_object == **name }, "river" => { let upstream_obj = &cascade_data.rivers[*upstream_name]; upstream_obj.downstream_object == **name }, _ => false } }) .map(|(upstream_name, _, _)| { match &results[*upstream_name] { let upstream_inflow = if let Some(upstream_objects) = upstream_map.get(&name.to_string()) { upstream_objects.iter() .map(|upstream_name| { match &results[upstream_name] { CascadeResults::Reservoir(res) => res.release[t] + res.spill[t], CascadeResults::River(riv) => riv.flow[t], } }) .sum::<f64>(); .sum::<f64>() } else { 0.0 }; match obj_type.as_str() { "reservoir" => { Loading