use apex_manifolds::ManifoldType;
use slotmap::SlotMap;
use std::collections::HashSet;
use crate::core::VarKey;
use crate::core::variable::ManifoldVariable;
#[derive(Debug, Clone)]
pub struct SchurOrdering {
pub eliminate_types: Vec<ManifoldType>,
pub eliminate_rn_size: Option<usize>,
pub auto_detect: bool,
}
impl Default for SchurOrdering {
fn default() -> Self {
Self {
eliminate_types: vec![ManifoldType::RN],
eliminate_rn_size: Some(3), auto_detect: false,
}
}
}
impl SchurOrdering {
pub fn new() -> Self {
Self::default()
}
pub fn with_auto_detect(mut self, enabled: bool) -> Self {
self.auto_detect = enabled;
self
}
pub fn should_eliminate(&self, manifold_type: &ManifoldType, size: usize) -> bool {
if !self.eliminate_types.contains(manifold_type) {
return false;
}
if let Some(required_size) = self.eliminate_rn_size
&& size != required_size
{
return false;
}
true
}
pub fn should_eliminate_by_name(&self, name: &str, size: usize) -> bool {
match ManifoldType::from_name(name) {
Some(manifold_type) => self.should_eliminate(&manifold_type, size),
None => false,
}
}
}
pub fn effective_landmark_keys(
variables: &SlotMap<VarKey, Box<dyn ManifoldVariable>>,
marked: &HashSet<VarKey>,
ordering: &SchurOrdering,
) -> HashSet<VarKey> {
let mut keys = marked.clone();
if ordering.auto_detect {
for (key, variable) in variables {
if ordering.should_eliminate_by_name(variable.manifold_type_name(), variable.dof()) {
keys.insert(key);
}
}
}
keys
}