kryst 4.0.3

Krylov subspace and preconditioned iterative solvers for dense and sparse linear systems, with shared and distributed memory parallelism.
use crate::context::pc_context::NoOpPreconditioner;
use crate::context::pc_context::PcConfig;
use crate::error::KError;
use crate::preconditioner::Preconditioner;

pub fn try_build(cfg: &PcConfig) -> Result<Option<Box<dyn Preconditioner>>, KError> {
    match cfg {
        PcConfig::None => Ok(Some(Box::new(NoOpPreconditioner))),
        PcConfig::FieldSplit {
            block_sizes,
            child_pc_type,
            options,
        } => {
            let pc = crate::preconditioner::fieldsplit::FieldSplitPc::new(
                block_sizes.clone(),
                child_pc_type.clone(),
                options.clone(),
            )?;
            Ok(Some(Box::new(pc)))
        }
        PcConfig::Shell {
            name,
            apply_transpose,
            apply_conjugate_transpose,
            apply_symmetric,
            apply_symmetric_left,
            apply_symmetric_right,
            setup,
            destroy,
            context,
        } => Ok(Some(Box::new(crate::preconditioner::shell::ShellPc::new(
            name.clone(),
            apply_transpose.clone(),
            apply_conjugate_transpose.clone(),
            apply_symmetric.clone(),
            apply_symmetric_left.clone(),
            apply_symmetric_right.clone(),
            setup.clone(),
            destroy.clone(),
            context.clone(),
        )))),
        PcConfig::Ksp {
            ksp_options,
            pc_options,
        } => {
            let pc = crate::preconditioner::ksp_pc::KspAsPc::new(
                ksp_options.clone(),
                pc_options.clone(),
            )?;
            Ok(Some(Box::new(pc)))
        }
        PcConfig::Mg {
            levels,
            cycle_type,
            smoother,
            smoother_steps,
            coarsen_type,
            interpolation_type,
            restriction_type,
            coarse_pc_type,
            coarse_ksp_type,
            coarse_ksp_maxits,
            coarse_ksp_rtol,
            level_policies,
        } => {
            let mut mg = crate::preconditioner::mg::MgPc::new(
                *levels,
                cycle_type.clone().map(|v| v.to_lowercase()),
                smoother.clone().map(|v| v.to_lowercase()),
                *smoother_steps,
                coarsen_type.clone().map(|v| v.to_lowercase()),
                interpolation_type.clone().map(|v| v.to_lowercase()),
                restriction_type.clone().map(|v| v.to_lowercase()),
                coarse_pc_type.clone().map(|v| v.to_lowercase()),
                coarse_ksp_type.clone().map(|v| v.to_lowercase()),
                *coarse_ksp_maxits,
                *coarse_ksp_rtol,
            );
            mg.set_level_policies(level_policies.clone());
            Ok(Some(Box::new(mg)))
        }
        PcConfig::Bddc {
            coarse_ksp_type,
            coarse_pc_type,
            use_vertices,
            constraint_selection,
            scaling,
        } => Ok(Some(Box::new(crate::preconditioner::bddc::BddcPc::new(
            crate::preconditioner::bddc::BddcConfig {
                coarse_ksp_type: coarse_ksp_type.clone(),
                coarse_pc_type: coarse_pc_type.clone(),
                local_ksp_type: None,
                local_pc_type: None,
                use_vertices: *use_vertices,
                constraint_selection: Some(*constraint_selection),
                scaling: Some(*scaling),
            },
        )))),
        PcConfig::Gamg { .. } => Ok(None),
        _ => Ok(None),
    }
}