1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use super::ResolutionMethod;
use std::fmt;

/// A minimal struct holding the resolution parameters
///
/// # Parameters
/// ## Damping
/// Activate the damping to improve convergence
///
/// Plain resolution according to Newton is made through the formula
/// X = X - J^-1*F(X)
///
/// However, if the proposed update is not performing (deterioriating the solution)
/// it is likely it is due to a much to step-size too important.
/// Reducing the step-size might be the solution
///
/// The damping formula is then :
/// X = X - damping_factor*J^-1*F(X)
/// with 0 < damping_factor <= 1
///
/// As long as the error is reduced damping_factor = 1.
/// If it is not the case, a factor is applied
/// (the value might change according to the versions).
///
/// If the used method is a quasi-newton method
/// and the jacobian has not been updated at the current iteration,
/// damping won't be performed but the jacobian will be recomputed at the next iteration.
///
/// In the case of the jacobian has been recomputed at the current iteration,
/// damping will be performed
///
/// ## Tolerance
/// The tolerance values used by the solver to check for convergence.
///
/// Each residuals must be below this threshold
///
/// ## Max iteration
/// The maximum number of iterations the solver is allowed to make
///
/// This is required to avoid to have an infinte loop
///
/// ## Resolution Method
/// See the enum `ResolutionMethod` for the options available
///
/// ## Problem size
/// The dimension of the problem for the resolution
pub struct SolverParameters {
    problem_size: usize,
    tolerance: f64,
    max_iter: usize,
    resolution_method: ResolutionMethod,
    damping: bool,
}

impl SolverParameters {
    pub fn new(
        problem_size: usize,
        tolerance: f64,
        max_iter: usize,
        resolution_method: ResolutionMethod,
        damping: bool,
    ) -> Self {
        SolverParameters {
            problem_size,
            tolerance,
            max_iter,
            resolution_method,
            damping,
        }
    }

    pub fn get_problem_size(&self) -> usize {
        self.problem_size
    }

    pub fn get_tolerance(&self) -> f64 {
        self.tolerance
    }

    pub fn get_max_iter(&self) -> usize {
        self.max_iter
    }

    pub fn get_resolution_method(&self) -> ResolutionMethod {
        self.resolution_method
    }

    pub fn get_damping(&self) -> bool {
        self.damping
    }
}

impl fmt::Display for SolverParameters {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut content = String::from("Solver parameters\n");
        content.push_str("=================\n\n");
        let separation_line = &"+----------------+-----------------+-----------------+--------------------+---------------------+\n";
        let header          = &"|  Problem size  |  Max iteration  |    Tolerance    |  Damping activated |  Resolution Method  |\n";

        content.push_str(separation_line);
        content.push_str(header);
        content.push_str(separation_line);
        content.push_str(&format!(
            "| {:width$}",
            self.problem_size.to_string(),
            width = 15
        ));
        content.push_str(&format!(
            "| {:width$}",
            self.max_iter.to_string(),
            width = 17
        ));
        content.push_str(&format!(
            "| {:width$}",
            self.tolerance.to_string(),
            width = 15
        ));
        content.push_str(&format!(
            "| {:width$}",
            self.damping.to_string(),
            width = 19
        ));
        content.push_str(&format!(
            "| {:width$}",
            self.resolution_method.to_string(),
            width = 20
        ));
        content.push_str("|\n");
        content.push_str(separation_line);
        content.push('\n');

        write!(f, "{}", content)
    }
}